将平移应用于顶点的正确方法
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);
我有简单的顶点着色器:
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);