📄 卡通渲染.txt
字号:
卡通渲染
现在市面上流行的3D游戏画面越来越炫目,不过也有一些为了营造一种特殊的效果而使用了卡通渲染技术,比如PC游戏中的《杀手XIII》,《忍者神龟》;PS2游戏中的《真红之泪》,《犬夜叉》等等。这些游戏的画面看上去很像漫画,感觉比较有趣。下面就介绍一种简单的实现方法。
所谓用卡通渲染技术绘制的三维物体一般都有两个明显的特征,一个特征是物体表面覆盖着大块的单调颜色,而且光影变化比较剧烈;另一个特征是物体拥有粗重的边缘效果。如果能自己控制光照和阴影,就可以达到目的。而DirectX 9.0 中的顶点渲染(Vertex Shaders)提供了这样一个途径,使我们可以实现自己的想法。
顶点渲染与以前的T&L在渲染流程中处于二选一的地位,一段代码最多只能有128条指令,而且不能有循环,判断和跳转指令,全是线性执行指令。每次只能有一个Shader程序是激活的,Vertex Shaders让我们可以实时地控制模型的空间变换,光照处理以及像素渲染。
那么现在先来解决第一个问题。我们可以用光线的亮度值作为物体的纹理坐标,这就产生一种带状纹理的效果,然后再调整相应的颜色即可。下面是渲染表面的Vertex Shaders代码:
//v0 点位置
//v1 法向量
//c0 (0,0.5,1.0,2.0)
//c1-4 WV矩阵
//c5-9 WVP矩阵
//c9 光的颜色
//c10 光的方向
vs_2_0
dcl_position v0
dcl_normal v1
dcl_texcoord v2
dcl_color v3
def c0,0.0,0.5,1.0,2.0
m4x4 oPos,v0,c5 //变换点位置到WorldViewProj空间
m3x4 r1,v1,c1 //变换法向量到WorldView空间
dp3 r2,-r1,c10 //计算光照
max r2,r2,c0.x
mov oT0.x,r2 //纹理坐标[r2,0.5]
mov oT0.y,c0.y
mov oD0,c9 //设置光照
这段代码先把每个点的坐标变换到相应的空间,然后使用一维的坐标来表示带状纹理的效果。最后设置材质的颜色并添加照明。程序中之所以选择0.5作为水平方向上的纹理坐标,是为了避免一些边缘采样的问题。
接着解决第二个问题。为了体现出粗重的边缘效果,我们必须要找出所有的边缘轮廓。一般的话,如果两个面的朝向相反,那么它们的公共边就是边缘轮廓。法向量和视觉向量的点积越接近0,就离边缘越近,然后把这些靠近边缘的三角形渲染成黑色即可。为了控制卡通化的程度,可以设置一个阀值,然后使用alpha检测来决定每个点的颜色。
vs_2_0
dcl_position v0
dcl_normal v1
dcl_texcoord v2
dcl_color v3
def c0,0.0,0.5,1.0,2.0
m4x4 oPos,v0,c5 //变换点位置到WorldViewProj空间
m3x4 r0,v0,c1 //变换点位置到WorldView空间
m3x4 r1,v1,c1 //变换法向量到WorldView空间
nrm r2,r0 //归一化
dp3 r3.x,r2,-r1 //计算点积
mad oD0.w,r3.x,c0.y,c0.y //设置alpha值
mov oD0.xyz,c0.x //设置漫射光
这段代码先把每个点的坐标变换到相应的空间,然后计算点积,最后添加光照。另外还要在程序中使用alpha检测来过滤像素,代码如下所示:
m_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE,1);
m_pd3dDevice->SetRenderState(D3DRS_ALPHAFUNC,D3DCMP_GREATEREQUAL);
m_pd3dDevice->SetRenderState(D3DRS_ALPHAREF,200);
实际渲染要执行两遍,第一遍绘制表面,第二遍绘制边缘,这样就基本达到了我们的目的。还要说明的一点是,因为Geforce FX系列以前的显卡不是硬件支持VS2.0,所以必须在程序中设置成软件模拟方式。就是在 d3dapp.cpp 的 Initialize3DEnvironment 中把 behaviorFlags 赋值为D3DCREATE_SOFTWARE_VERTEXPROCESSING即可,这样才能看到效果。本文附带的D3D9Cartoon例程是用DirectX 9 SDK开发的,这个开发包在微软网站上有下载,大概有218MB,地址是http://download.microsoft.com/download/b/6/a/b6ab32f3-39e8-4096-9445-d38e6675de85/dx90bsdk.exe,安装后再编译此例程就可以运行了。D3D9Cartoon例程是在 VS.NET2002+WinXP 下面调试通过。
参考文献:
Cartoon Rendering in DirectX 8.0 Using Vertex Shaders
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -