使用 AGAL 计算出4x4矩阵中XYZ三个轴的缩放值

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中

若有异议,请告知我,谢谢。

 

posted @ 2014-11-07 16:11  vily_雷  阅读(961)  评论(0)    收藏  举报