GLSL每像素点光阴影

时间:2011-12-16 08:18:32

标签: c++ opengl glsl shader

VC ++,OpenGL,SDL

我想知道是否有办法在单个四维几何体上实现更平滑的着色。现在,阴影看起来很平滑,但是,强度沿着脸部的[/]对角线细分上升。照明在顶点之间基本上是不可见的。

enter image description here

enter image description here

enter image description here

当灯光从左向右移动时会发生这种情况

当我将光线移过表面时,它会持续地做到这一点。在每个顶点变得最亮并从那里淡出。

我是否被迫向上细分以获得更光滑,更加径向的阴影?或者有解决方法吗?

以下是我使用的着色器:

VERT

varying vec3 vertex_light_position;
varying vec3 vertex_normal;

void main() 
{            
    vertex_normal = normalize(gl_NormalMatrix * gl_Normal);
    vertex_light_position = normalize(gl_LightSource[0].position.xyz);

    gl_FrontColor = gl_Color;
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

FRAG

varying vec3 vertex_light_position;
varying vec3 vertex_normal;

void main() 
{
    float diffuse_value = max(dot(vertex_normal, vertex_light_position), 0.0);
    gl_FragColor = gl_Color * diffuse_value;
}

我的几何形状,万一有人想知道:

glBegin(GL_QUADS);
    glNormal3f(0.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(pos_x, pos_y - size_y, depth);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(pos_x + size_x, pos_y - size_y, depth);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(pos_x + size_x, pos_y, depth);
    glTexCoord2f(0.0f, 0.0f); glVertex3f(pos_x, pos_y, depth);
glEnd();

3 个答案:

答案 0 :(得分:5)

我认为有几件事可能是问题。

除非我弄错了,否则您使用normalize(gl_LightSource[0].position.xyz);来计算光矢量,但这完全取决于灯光的位置,而不是基于您正在操作的顶点。这意味着每个顶点的值都相同,并且只会根据当前的模型视图矩阵和灯光位置进行更改。我认为通过像normalize(glLightSource[0].position.xyz - (gl_ModelViewMatrix * gl_Vertex).xyz)那样计算光矢量会更接近你想要的。

其次,你应该在片段着色器和顶点着色器中规范化矢量,因为两个单位矢量的插值不能保证是单位矢量本身。

答案 1 :(得分:2)

我认为问题在于光矢量......

我建议使用:

vec3 light_vector = normalize(gl_LightSource[0].position.xyz - vertex_pos)

vertex_pos可以使用:

计算
vertex_pos = gl_ModelViewMatrix * gl_Vertex

请注意,所有矢量应位于相同的空间(相机,世界,物体)

答案 2 :(得分:1)

  

我被迫向上细分以实现更平滑,更放射状   灯罩?或者有解决方法吗?

不,你可以自由地做任何你想做的事。您需要更改的唯一代码是片段着色器。尝试使用它,看看你是否得到了更好的结果。

例如,你可以这样做:

diffuse_value = pow(diffuse_value, 3.0);

解释here