逐像素光照渲染

逐像素的渲染的精度比顶点的要高,效果也要好.
一般做像素渲染最好的做法就是准备一张法线贴图.

说到法线贴图,实际上就是凹凸贴图. 其设计的目的是为了在简模(顶点数低)上实现复杂的凹凸效果. 而凹凸效果实际上是通过虚假的阴影绘制后给人眼造成的立体假象.
本例使用的是 Doom3 模型的MD5模型,其附带的法线贴图是3通道贴图,即 r,g,b 分别表示法线的 x,y,z.
实际上为了节省硬碟空间,还有2通道贴图. 不过貌似现在大家显存和内存都很足的说~

如果将法线贴图丢入shader. 可以直接用float4进行采样,很容易就取出r,g,b 分量.
如果想用CPU计算Normal的话,用如下方式

1
2
3
4
5
6
//先取出颜色
var color : uint = bmd.getPixel(x,y);
//然后取出分量
var red : Number = ((color & 0xFF0000) >> 16)/256;
var green : Number = ((color & 0x00FF00) >> 8)/256;
var blue : Number = ((color & 0x0000FF)/256;

接下来shader就容易多了
将法线于灯光进行点乘
然后取出大于0的部分
对于这部分进行纹理混合即可.

doom3 法线贴图

doom3 漫反射贴图

fragmentShader Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fragmentShader = new AGALMiniAssembler();
            fragmentShader.assemble(Context3DProgramType.FRAGMENT,
                //纹理采样
                "tex ft0, v0, fs0<2d, linear, repeat>n" +
                "tex ft1, v0, fs1<2d, linear, repeat>n" +
                //灯光点乘法线
                "dp3 ft2, ft1, fc2n" +
                "neg ft2, ft2n" +
                "sat ft2, ft2n"+
               
                //混合环境光
                "mul ft3, ft0, ft2n" +
                //混合灯光颜色
                "mul ft3, ft3, fc1n" +
                //输出
                "add oc, ft3, fc0");

ft0 是采样的是模型贴图
ft1 采样的就是法线贴图

直接取出法线贴图,进行灯光的dp3点乘即可。

GitHub : https://github.com/dreamfairy/3DDemo/blob/master/StencilShadow/src/MD5Test.as

Demo 地址: http://www.dreamfairy.cn/blog/work/flash/3d/stage3DNormalTex/md5test.html

啊~Demo中的灯光使用Cube做的,做完才觉得好难看~~ 下次用Sphere 来做吧!
原版计划开搞引擎的,嘛~突然又对shadow map 感兴趣了。 嘛~ 还是再挑战一下自己吧!

发表评论

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

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