逐像素光照渲染

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

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

如果将法线贴图丢入shader. 可以直接用float4进行采样,很容易就取出r,g,b 分量.
如果想用CPU计算Normal的话,用如下方式
[cc lang=”actionscript3]
//先取出颜色
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;
[/cc]

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

doom3 法线贴图

doom3 漫反射贴图

fragmentShader Code
[cc lang=”actionscript3″]
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”);
[/cc]
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 感兴趣了。 嘛~ 还是再挑战一下自己吧!

发表评论

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