卡通阴影的构造原理--OpenGL笔记

看了两篇关于卡通阴影构造的教程, 觉得有必要写下自己的理解
原理教程: http://www.gamedev.net/reference/programming/features/celshading/
实例教程: http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=37
其实实例教程是作者写的第二个版本, 以解他人求代码之苦, 呵呵
本文并非翻译, 如有谬误之处, 请指出
卡通阴影主要是指那些漫画手绘绘出的阴影效果, 不用光照实现的虚拟效果.
首先构造一个一维纹理, 其像素值只有白色, 不同程度的灰色, 黑色. 如下图所示

上图为16个像素的一维纹理数据.
然后根据顶点的法线与光线方向的角度设置纹理坐标.其中顶点法线与光线成0度角, 则取纹理坐标1(cos0).如果顶点法线与光线方向垂直,则取纹理坐标0(cos(∏/2)).
本实例的一维纹理有32个像素,如下图所示

用三角形来实现效果, 假设顶点1和顶点3的法线平行于光线方向. 而顶点2的法线则垂直于光线方向.
则效果如下:

代码为:
glBegin(GL_TRIANGLES);
glTexCoord1f(0.0);
glVertex3f(-0.5, -0.5, 0.0);
glTexCoord1f(1.0);
glVertex3f(0.5, -0.5, 0.0);
glTexCoord1f(1.0);
glVertex3f(0, 0.5, 0.0);
glEnd();
结论:
如果绘制一个模型, 已知顶点法线向量N, 光线向量L, 顶点坐标V.
则 V*N = |V|*|N|cos(V和N的夹角) (其中*为点积)
所以 V*N / (|V|*|N|) 就等于其纹理坐标向量, 标记为T.
然后 绘制的时候,设置顶点和设置纹理坐标的语句如下:
glTexCoord1f(T);
glVertex3fv(V);
在使用纹理过程中注意要禁止光照,禁止混合, 允许一维纹理.
在实例教程中, 还涉及了法线向量旋转的问题.
假设原法线向量在单元矩阵中为N, 旋转后的矩阵为
M =
{x1, x2, x3, x4,
x5, x6, x7, x8,
x9, x10, x11, x12,
x13, x14, x15, x16};
取子矩阵
M1 =
{x1, x2, x3,
x5, x6, x7,
x9, x10, x11}.
N*M1 就可以得到旋转后的法线向量N1.
本例实现图像, 模型数据来自于实例教程.

评论

此博客中的热门博文

《绿箭》——1x01

WordPress 安装记

Vim插件 - NERDTree