Shadow Mapping 2

阴影图实现起来确实很多坑等着我…

没有stage3D的资料…是最坑,需要自己摸索

还有几个坑分别是
1.如何创建深度图
2.如何进行深度图采样
3.深度测试
4.AOI3D的封装

今天先从创建深度图开始

首先

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
            //准备阴影图,并开启为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");

阴影图的大小决定阴影图的精度,越小的阴影图边缘锯齿越严重. 解决方案有很多啦,比如应用模糊滤镜后,再作为查询图.

然后准备我们的shader程序

之后开始渲染,先设置将接下来的模型操作渲染到阴影图.

1
2
m_context.clear();
m_context.setRenderToTexture(m_shaderMap,true);

之后开始模型的渲染
准备灯光空间中, 灯光的位置,灯光的相机,灯光的投影

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
            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.<Number>([m_zFar,1,1,1]));
            //1,255,255*255,255*255*255
            m_context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT,1, Vector.<Number>([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.<Number>([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();

最后是这张阴影图的预览Demo
鼠标中键可控制相机. 原理相机的像素颜色加深~
Demo is here:http://www.dreamfairy.cn/blog/work/flash/3d/stage3dshadowMapping/ShadowMapFinalTest.html

下一篇再实现 深度图查询并渲染~

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.