1
\$\begingroup\$

I render my hair geometry in line segments. The problem I have is with the correct shading of the hair.

From what I've read I understood that I need the direction of the line segment and the direction to the light source. Then the dot product of these direction vectors defines how the current vertex is shaded.

My vertex data is in one array buffer and I've decided to pass to GLSL 2 pointers - one for the current vertex and one for the next vertex, so I can calculate the direction of the line segment.

glEnableVertexAttribArray(gpuProgram->attrib("vert"));
glVertexAttribPointer(gpuProgram->attrib("vert"), 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(gpuProgram->attrib("vertNext"));
glVertexAttribPointer(gpuProgram->attrib("vertNext"), 3, GL_FLOAT, GL_FALSE, 0, (void*)sizeof(Vertex));

Where Vertex is a struct with 3 floats.

My vertex shader:

#version 150

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
in vec3 vert;
in vec3 vertNext;
in vec3 color;
out vec3 fragVert;
out vec3 fragColor;
out vec3 fragVertNext;

void main(void)
{
    fragColor = color;
    fragVert = vert;
    fragVertNext = vertNext;
    gl_Position = projection * view * model * vec4(vert, 1);
}

My fragment shader:

#version 150

uniform mat4 model;
uniform vec3 lightPosition;
uniform vec4 surfaceColor;
in vec3 fragVertNext;
in vec3 fragVert;
in vec3 fragColor;
out vec4 finalColor;

void main(void)
{
    vec3 lightColor = vec3(1.0, 1.0, 1.0);

    vec3 vertPos1 = vec3(model * vec4(fragVert, 1));
    vec3 vertPos2 = vec3(model * vec4(fragVertNext, 1));

    vec3 segmentDir = normalize(vertPos1-vertPos2); 
    vec3 dirToLight = normalize(lightPosition-vertPos1);

    float diffCoef = 1.0 - dot(segmentDir, dirToLight);

    vec3 diffuse = ambient + lightColor * diffCoef * fragColor;

    vec3 result = min(diffuse, vec3(1.0));
    finalColor = vec4(result, 1);
}

This is just the diffuse shading without specular reflection. And the result is wrong. I have to mention that 1 hair strand is composed of a couple line segments, and also there seems to be bug in the shading of the very last line segment - it appears black.

\$\endgroup\$
5
  • \$\begingroup\$ be sure you set your buffers correctly. For simple chains/hair-like topologies, you need an offset of one vertex for the second buffer. Also, the last vertex should be paired with the first. \$\endgroup\$
    – teodron
    Commented Jul 2, 2014 at 13:03
  • \$\begingroup\$ To render hair you need anisotropic lighting. \$\endgroup\$
    – msell
    Commented Jul 2, 2014 at 13:46
  • \$\begingroup\$ Could the problem be, because my data in the vertex buffer is like this: 0,1,1,2,2,3,3,4,4,5 ..., where each number corresponds to a vertex (same numbers=same vertex) \$\endgroup\$
    – Geto
    Commented Jul 2, 2014 at 14:11
  • \$\begingroup\$ @msell that's only if you're representing hair as a surface mesh, whereas OP is trying to use line segments. I think surface meshes are better, though. \$\endgroup\$ Commented Dec 22, 2014 at 5:51
  • \$\begingroup\$ @congusbongus Could you explain why line segments don't need anisotropic lighting? With them you get the tangents naturally from the data, but the lighting model should still be the same. Check the pictures from ftp.sgi.com/opengl/contrib/blythe/advanced99/notes/node154.html. Btw the original question doesn't use view direction at all, which sounds wrong. \$\endgroup\$
    – msell
    Commented Dec 22, 2014 at 6:18

0

You must log in to answer this question.

Browse other questions tagged .