阴影图实现起来确实很多坑等着我…
没有stage3D的资料…是最坑,需要自己摸索
还有几个坑分别是
1.如何创建深度图
2.如何进行深度图采样
3.深度测试
4.AOI3D的封装
今天先从创建深度图开始
首先
[cc lang=”actionscript3″]
//准备阴影图,并开启为RTT优化
m_shaderMap = m_context.createTexture(
1024,
1024,
Context3DTextureFormat.BGRA,
true
);
/**
* 阴影shader
* 将顶点丢入fragmentShader
*/
var depthPassVertexShader : AGALMiniAssembler = new AGALMiniAssembler();
depthPassVertexShader.assemble(Context3DProgramType.VERTEX,
“m44 vt0 va0 vc0n”+
“mov op vt0n”+
“mov v0 vt0n”);
var depthPassFragmengShader : AGALMiniAssembler = new AGALMiniAssembler();
depthPassFragmengShader.assemble(Context3DProgramType.FRAGMENT,
//将深度缩放在 zFar 之内
“div ft0 v0.z fc0.xn”+
//将颜色编码为 32 位浮点型数据存入RGBA
“mul ft0 ft0 fc1n”+
//取出小数部分
“frc ft0 ft0n”+
//255掩码
“mul ft1 ft0.yzww fc2n”+
“sub ft0 ft0 ft1n”+
“mov oc ft0n”);
[/cc]
阴影图的大小决定阴影图的精度,越小的阴影图边缘锯齿越严重. 解决方案有很多啦,比如应用模糊滤镜后,再作为查询图.
然后准备我们的shader程序
之后开始渲染,先设置将接下来的模型操作渲染到阴影图.
[cc lang=”actionscript3″]
m_context.clear();
m_context.setRenderToTexture(m_shaderMap,true);
[/cc]
之后开始模型的渲染
准备灯光空间中, 灯光的位置,灯光的相机,灯光的投影
[cc lang=”actionscript3″]
m_lightModel.identity();
m_lightModel.appendRotation(-90,Vector3D.X_AXIS);
m_lightModel.appendRotation(t, Vector3D.Y_AXIS);
m_lightModel.appendScale(.1,.1,.1);
m_lightModel.appendTranslation(0,-6,-20);
m_lightView.identity();
m_lightView.appendTranslation(-50,0,0);
m_lightView.pointAt(new Vector3D(0,-6,-20),CAM_FACING,CAM_UP);
m_lightView.invert();
m_lightProj.identity();
m_lightProj.append(m_lightModel);
m_lightProj.append(m_lightView);
m_lightProj.append(m_projMatrix);
//vc0 灯光投影矩阵
m_context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, m_lightProj, true);
//fc0 m_zFar 最大深度
m_context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT,0, Vector.([m_zFar,1,1,1]));
//1,255,255*255,255*255*255
m_context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT,1, Vector.([1,255,65025,16581375]));
//[(1.0/255.0),(1.0/255.0),(1.0/255.0),0.0]
m_context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT,2, Vector.([1/255,1/255,1/255,0]));
//使用shadowMapShader渲染模型
m_context.setProgram(m_shaderPassShader);
for(var i : int = 0; i < md5Result.meshDataNum; i++){
var vertexBuffer : VertexBuffer3D = md5Result.vertexBufferList[i];
var uvBuffer : VertexBuffer3D = md5Result.uvBufferList[i];
var indexBuffer : IndexBuffer3D = md5Result.indexBufferList[i];
m_context.setVertexBufferAt(0, vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
// m_context.setVertexBufferAt(1,uvBuffer,0,Context3DVertexBufferFormat.FLOAT_2);
m_context.drawTriangles(indexBuffer);
}
//输出到纹理
m_context.present();
[/cc]
最后是这张阴影图的预览Demo
鼠标中键可控制相机. 原理相机的像素颜色加深~
Demo is here:http://www.dreamfairy.cn/blog/work/flash/3d/stage3dshadowMapping/ShadowMapFinalTest.html
下一篇再实现 深度图查询并渲染~