3d图形系统中的 Billboard 或者叫广告版 是一直对着摄像机的,没有透视只有缩放和位置变化,如果是旋转只能是绕摄像机空间的z轴旋转。
在flash stage 3d 中相关的计算可以全部交给 AGAL Shader去做,而不需要cpu去计算计算。例如当这类显示对象包含在容器中的时候,必须要转换到正确的容器空间,不然显示就错了,那么如果靠cpu计算就会有很多矩阵计算例如会用矩阵的decompose(),如果用AGAL做,cpu计算的压力就很小了。
计算Billboard的空间位置,很简单,但是缩放要正确还是要从 其父级矩阵中获取,例如当Billboard在容器中的时候,容器缩放值改变,就会影响到Billboard的缩放效果
这里给出在 AGAL 中计算出4x4矩阵中XYZ三个轴的缩放值的代码
// 这里vc0到vc3存放一个完整的 4 x 4 矩阵 // 从物体世界矩阵中取出,scalex,scaley,scalez分量的计算开始 // 从矩阵中获取scalex开始计算 var str:String = "mov vt1,vc0\n" + "mul vt1.x,vt1.x,vc0.x\n" + "mov vt1.y,vc1.x\n" + "mul vt1.y,vt1.y,vc1.x\n" + "mov vt1.z,vc2.x\n" + "mul vt1.z,vt1.z,vc2.x\n" + "add vt1.x,vt1.x,vt1.y\n" + "add vt1.x,vt1.x,vt1.z\n" + "sqt vt1.x,vt1.x\n" + // scalex 计算结束 "mov vt2,vt1\n" + // 从矩阵中获取scaley开始计算 "mov vt1.x,vc0.y\n" + "mul vt1.x,vt1.x,vc0.y\n" + "mov vt1.y,vc1.y\n" + "mul vt1.y,vt1.y,vc1.y\n" + "mov vt1.z,vc2.y\n" + "mul vt1.z,vt1.z,vc2.y\n" + "add vt1.x,vt1.x,vt1.y\n" + "add vt1.x,vt1.x,vt1.z\n" + "sqt vt1.x,vt1.x\n" + // scaley 计算结束 "mov vt2.y,vt1.x\n" + // 从矩阵中获取scalez开始计算 "mov vt1.x,vc0.z\n" + "mul vt1.x,vt1.x,vc0.z\n" + "mov vt1.y,vc1.z\n" + "mul vt1.y,vt1.y,vc1.z\n" + "mov vt1.z,vc2.z\n" + "mul vt1.z,vt1.z,vc2.z\n" + "add vt1.x,vt1.x,vt1.y\n" + "add vt1.x,vt1.x,vt1.z\n" + "sqt vt1.x,vt1.x\n" + // scalez 计算结束,计算结果全部存放在vt2.xyz中 "mov vt2.z,vt1.z\n" + // 计算结束 // vc0.x * (vc1.y * vc2.z - vc2.y*vc1.z) start "mov vt1.x,vc1.y\n" + "mul vt1.x,vt1.x,vc2.z\n" + "mov vt1.y,vc2.y\n" + "mul vt1.y,vt1.x,vc1.z\n" + "sub vt2.w,vt1.x,vt1.y\n" + // "mul vt2.w,vt2.w,vc0.x\n" + // end // vc1.x*(vc0.y*vc2.z - vc2.y*vc0.z) start "mov vt1.x,vc0.y\n" + "mul vt1.x,vt1.x,vc2.z\n" + "mov vt1.y,vc2.y\n" + "mul vt1.y,vt1.x,vc0.z\n" + "sub vt1.w,vt1.x,vt1.y\n" + // "mul vt1.w,vt1.w,vc1.x\n" + // end // vc2.x*(vc0.y*vc1.z - vc1.y*vc0.z) start "mov vt1.x,vc0.y\n" + "mul vt1.x,vt1.x,vc1.z\n" + "mov vt1.y,vc1.y\n" + "mul vt1.y,vt1.x,vc0.z\n" + "sub vt1.y,vt1.x,vt1.y\n" + // "mul vt1.y,vt1.y,vc2.x\n" + // end // 修正 scalez start "sub vt2.w,vt2.w,vc1.w\n" + "sub vt2.w,vt2.w,vc1.y\n" + // 计算 < 0, "vc"+_wscalevcI+".w"这个顶点常量寄存器的w存的是0 "slt vt2.w,vt2.w,vc"+_wscalevcI+".w\n" + // (1-2*vt2.w) 计算过程是 vt2.w=1结果为-1, vt2.w=0结果为1 // "vc"+_camposvcI+".w"这个顶点常量寄存器的w存的是2 "mul vt2.w,vt2.w,vc"+_camposvcI+".w\n" + "sub vt2.w,vc"+_wposvcI+".w,vt2.w\n" + // 计算 scalez修正结果 "mul vt2.z,vt2.z,vt2.w\n"; // 修正 scalez end // 至此,从物体世界矩阵中取出,scalex,scaley,scalez分量的计算结束 // 计算结果分别放在 vt2.xyz中
若有异议,请告知我,谢谢。