我使用头发粒子系统用Blender 2.66创造了一个发型。这看起来像这样:
如您所见,亮度已应用于线条片段。转换后,我将我的发型网格导出为OBJ文件格式。我在我的程序中解析它,渲染看起来像这样:
粒子被绘制为GL_LINES(在我的OBJ文件中,每面有2个顶点)。
在另一个测试程序中,我想用简单的线段来测试亮度。这是我的顶点缓冲区:
static GLfloat vertices[6] =
{
0.000000f, 0.000000f, -2.000000f,
0.000000f, 0.000000f, 2.000000f
};
static GLfloat normals[6] =
{
0.000000f, 1.000000f, 0.000000f,
0.000000f, 1.000000f, 0.000000f
};
static GLfloat colors[6] =
{
0.000000f, 0.000000f, 1.000000f,
0.000000f, 0.000000f, 1.000000f
};
结果(线在X轴正交的原点旋转 - >我称为glLineWidth(5.0f)以获得更好的可见结果):
通过实时动画,我可以看到光度是正确的,但只是在线的特定侧面。这是正常的,因为线段应该具有无穷大的法线并且我只有两个法线(每个顶点一个)。我想要精确地确定这两个法线是等式Y = 0的平面的法线 - > n(0.0,1.0,0.0)。所以我想知道是否可以为每个顶点添加几个法线?我相信OpengL无法做到这一点。但也许另一种方式是可能的。这是一张图,解释了我想要做什么来计算线段的每个部分的正确亮度:
就像你在第一张照片上看到的那样,Blender可以在线段上实时计算亮度。此外,它是这张图片上的OpenGL渲染。所以我相信这样做是可能的。我尝试重复相同的线段坐标两次,但对于第二行,我应用相反的法线n2(0.0,-1.0,0.0),但它不起作用。 “另一面”是“黑暗”。两个多边形也是一样的。目前,我使用GLSL着色器。我认为可以使用像Geometry着色器或tesselation着色器这样的特殊着色器。也许CUDA语言是必需的。但我不确定。
有人可以帮助我吗?
答案 0 :(得分:2)
这是一个复杂的话题。您应首先阅读头发照明上的Marschner's 2003 paper。一旦你感到困惑,请查看此模型的nvidia's explanation(第23.3节,头发着色),其中包括漂亮的图表和着色器代码。
希望这有帮助!
答案 1 :(得分:1)
ananthonline已经为您提供了一些参考资料,但对于简单的线束照明模型来说,这些都是过度杀伤。
如果您的要求不是那么先进,您可以将Phong照明模型应用到线束上。你可能会问“等什么,绳子没有法线,但你需要那些Phong?”嗯,是的,不。线段具有无限数量的法线,也称为平面。或者换句话说,线条本身是平面的法线。
phong模型从朗伯散射模型的假设开始,即“更多”垂直于入射角,它越亮。描述这个的数学是
I(phi) = I_max * cos( phi )
或者,用一个向量代替phi,用cos( angle(↑a,↑b) ) = ↑a · ↑b
代替||↑a|| = ||↑b|| = 1
I(↑a, ↑b) = I_max * ↑a · ↑b
现在让↑c · ↑b = 0
,||↑c|| = 1
,然后↑a · ↑b = 1 - ↑a · ↑c
。但↑c · ↑b = 0
是正常的定义。这意味着对于方向↑b
的线段和光源↑c
的方向,您可以将强度写为
I(↑b, ↑c) = I_max * (1 - ↑b · ↑c)
这是线条的Phong照明模型。事实上它也正是Blender所做的。
您只需要眼睛位置来计算镜面反射。你也可以这样做,假设线股的法线是垂直于线股的光方向向量。让↑b
再次成为线段的方向,↑c
指向光线的方向。然后应用Gram-Schmidt正交归一化方法,您可以通过
↑n
↑n = normalize(↑c - ↑b·↑c)
使用它你可以建立一套通常的
- vertex position
- vertex "normal"
- light direction
- light half direction
在一个线条顶点着色器中,并将其传递给常规的Phong片段着色器并像往常一样进行数学运算。