将平移应用于顶点的正确方法

Proper way to apply translation to vertices

我有简单的顶点着色器:

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();
        }
    }
}

您需要转置一个矩阵。您可以手动完成,也可以在此处传递参数:

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