Правильный способ применения перевода к вершинам

У меня есть простой вершинный шейдер:

m44 op, va0, vc0 
mov v0, va1

и фрагмент шейдера:

mov oc, v0

Я передаю эти вершины ему:

  x     y   z  w  r  g  b
-0.3, -0.3, 0, 1, 1, 0, 0,
 0,    0.3, 0, 1, 0, 1, 0,
 0.3, -0.3, 0, 1, 0, 0, 1

Результат треугольника выглядит так, как я ожидал. Теперь я хочу применить перевод к треугольнику результата. Я объявил матрицу, позвоните appendTranslation(0.2, 0, 0) и передать его вершинному шейдеру. Проблема в том, что треугольник остался в той же позиции, но с разным расположением вершин. Это выглядит так:

Плохой треугольник

Почему я получил этот результат, и как правильно применить перевод к вершинам?

Вот полный код моей программы:

package tests 
{
    import com.adobe.utils.AGALMiniAssembler;
    import flash.display.Sprite;
    import flash.display3D.Context3D;
    import flash.display3D.Context3DProgramType;
    import flash.display3D.Context3DRenderMode;
    import flash.display3D.Context3DVertexBufferFormat;
    import flash.display3D.IndexBuffer3D;
    import flash.display3D.Program3D;
    import flash.display3D.VertexBuffer3D;
    import flash.events.Event;
    import flash.geom.Matrix3D;
    import flash.utils.ByteArray;

    [swf(width="500", height="500")]
    public class Stage3dTest extends Sprite
    {
        private var _context:Context3D;
        private var _vertexBuffer:VertexBuffer3D;
        private var _indexBuffer:IndexBuffer3D;
        private var _program:Program3D;
        private var _mat:Matrix3D;

        public function Stage3dTest() {
            if (stage) {
                onAddedToStage();
            } else {
                addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
            }
        }
        private function onAddedToStage(event:Event = null):void {
            this.stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, onStage3dContext3DCreate);
            this.stage.stage3Ds[0].requestContext3D(Context3DRenderMode.SOFTWARE);
        }
        private function onStage3dContext3DCreate(event:Event):void {
            _mat = new Matrix3D();
            _mat.appendTranslation(0.2, 0, 0);
            _context = this.stage.stage3Ds[0].context3D;
            _context.configureBackBuffer(500, 500, 0, false);
            _vertexBuffer = _context.createVertexBuffer(3, 7);
            _indexBuffer = _context.createIndexBuffer(3);
            var p:Number = 0.3;
            var vertexData:Vector.<Number> = new <Number>[
                -p, -p, 0, 1, 1, 0, 0,
                0,   p, 0, 1, 0, 1, 0,
                p,  -p, 0, 1, 0, 0, 1
            ];
            _vertexBuffer.uploadFromVector(vertexData, 0, 3);
            _indexBuffer.uploadFromVector(new <uint>[0, 1, 2], 0, 3);
            createAndCompileProgram();
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }
        private function createAndCompileProgram():void {
            _program = _context.createProgram();
            var assembler:AGALMiniAssembler = new AGALMiniAssembler();
            var code:String = "";
            code += "m44 op, va0, vc0\n"+
                    "mov v0, va1\n";
            var vertexShader:ByteArray = assembler.assemble(Context3DProgramType.VERTEX, code);
            code = "mov oc, v0\n";
            var fragmentShader:ByteArray = assembler.assemble(Context3DProgramType.FRAGMENT, code);
            _program.upload(vertexShader, fragmentShader);
        }
        private function onEnterFrame(event:Event):void {
            _context.clear(0.9, 0.9, 0.9, 1);
            _context.setProgram(_program);
            _context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, _mat);
            _context.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_4);
            _context.setVertexBufferAt(1, _vertexBuffer, 4, Context3DVertexBufferFormat.FLOAT_3);
            _context.drawTriangles(_indexBuffer);
            _context.present();
        }
    }
}

1 ответ

Решение

Вам нужно транспонировать матрицу. Вы можете сделать это вручную или передать параметр здесь:

_context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, _mat, true);

Другие вопросы по тегам