Page 2 of 2 FirstFirst 12
Results 11 to 18 of 18

Thread: Normal mapping

  1. #11
    This was good image, explaining the difference between the 2 normal maps:


    I know it's situational, but i like being able to use models that others do in games So far i've only encountered ones shown on left.

  2. #12
    so did you get it to work? if you need help with shaders you can post both vertex and pixel shader and I'll fix them for you.

  3. #13
    No, it's frustratingly close to work though I see that the direction of light is rotating around the object faster than itself rotates, causes some angles to work and some not. Would be nice if you can see error in this.

    From my tests, result is the same if i multiply normal with mv_rotation or if i multiply light in vertex-shader. But i assume it's more efficient if it's done per-vertex basis instead of per-pixel so i put it for light.
    mv_rotation is 3x3 part of Modelview-matrix. So main program has this after camera is set:
    Code:
        glGetFloatv(GL_MODELVIEW_MATRIX, @m4);
        m:=GetRotation3(m4);
        glUniformMatrix3fv(locRotation, 1, bytebool(GL_FALSE), @m);
    Vertex shader:
    Code:
    uniform mat3 mv_rotation;
    varying vec3 lightDir;
    void main()
    {
      gl_Position = ftransform();
      gl_TexCoord[0] = gl_MultiTexCoord0;
      lightDir = mv_rotation * gl_LightSource[0].position.xyz;
      lightDir = normalize(lightDir);
    }
    Fragment shader:
    Code:
    uniform sampler2D colorMap;
    uniform sampler2D normalMap;
    //uniform mat3 mv_rotation;
    varying vec3 lightDir;
    
    void main()
    {
      vec3 l = lightDir;
      vec3 n = texture2D(normalMap, gl_TexCoord[0].st).xyz * 2.0 - 1.0;
      n = normalize(n);
      float specular = max(dot(l, n), 0.0);
      specular = pow(specular, gl_FrontMaterial.shininess);
      vec4 vAmbient = gl_LightSource[0].ambient * gl_FrontMaterial.ambient;
      float diffuse = max(dot(l, n), 0.0);
      vec4 vDiffuse = gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * diffuse;
      vec4 vSpecular = gl_LightSource[0].specular * gl_FrontMaterial.specular * specular;
      gl_FragColor = (vAmbient + vDiffuse) * texture2D(colorMap, gl_TexCoord[0].st) + vSpecular;
    }
    Last edited by User137; 02-10-2012 at 07:35 PM.

  4. #14
    if you want to work in the model space aka transfrom the light vector instead of the normal - you are asking for a world of pain, especially if you are planning to add skinning to this code. btw if you still want to work in model space you need to multiply your light direction by a transpose of the rotation matrix (or just swap the order of multiplication, instead of l = mat * vec do l = vec * mat). also there is no need to normalize the light direction vector in vertex shader because you still have to normalize it in pixel shader (which you are not doing btw).
    so here's the code that I think should work:
    vertex shader
    Code:
    //it is a good idea to specify which version of GLSL
    //specification you want to work with
    #version 120
    uniform mat4 WVP;
    uniform mat4 W;
    uniform vec3 CamPos; //this is needed for specular reflactions (camera position)
    varying vec3 LightDir;
    varying vec3 CamDir;
    void main () {
      //this way of transforming the position is deprecated in later versions
      //of GLSL so I strongly suggest that you use the attributes of the vertex
      //gl_Position = ftransform();
      gl_Position = WVP * gl_Vertex;
      //again I recommend using the texture coord attribute here
      //but lets just keep it as is for now
      gl_TexCoord[0] = gl_MultiTexCoord0;
      vec3 VertexPosition = vec3(W * gl_Vertex);
      LightDir = gl_LightSource[0].position.xyz - VertexPosition;
      CamDir = VertexPosition - CamPos; //Direction from camera to vertex
      //absolutely no need to do this in vertex shader
      LightDir = normalize(LightDir);
    }
    pixel shader
    Code:
    #version 120
    uniform sampler2D colorMap;
    uniform sampler2D normalMap;
    uniform mat4 W;
    varying vec3 LightDir;
    varying vec3 CamDir;
    void main() {
      vec3 l = normalize(LightDir);
      vec3 n = texture2D(normalMap, gl_TexCoord[0].xy).xyz * 2.0 - 1.0;
      n = normalize(mat3(W) * n);
      vec3 r = CamDir - 2 * n * dot(CamDir, n);
      float DiffuseLight = clamp(dot(n, LightDir), 0, 1);
      float SpecularLight = pow(clamp(dot(n, r), 0, 1), gl_FrontMaterial.shininess);
      vec4 AmbientColor = vec4(gl_LightSource[0].ambient.xyz * gl_FrontMaterial.ambient.xyz, 1);
      vec4 DiffuseColor = vec4(gl_LightSource[0].diffuse.xyz * gl_FrontMaterial.diffuse.xyz * DiffuseLight, 1);
      vec4 SpecularColor = vec4(gl_LightSource[0].specular.xyz * gl_FrontMaterial.specular.xyz * SpecularLight, 1);
      gl_FragColor = texture2D(colorMap, gl_TexCoord[0].xy) * (DiffuseColor + AmbientColor) + SpecularColor;
    }
    for these shaders you will need to send additional uniforms to the shader like WVP is the combined matrix of ModelView * Projection, W is the transformation of the model, CamPos is just your camera position
    Last edited by Dan; 03-10-2012 at 04:06 AM.

  5. #15
    You didn't test it i assume? There seems to be alot of new things, although it showed up black to me.

    First i changed just this line, and i was able to see the ambient color:
    Code:
    //vec4 AmbientColor = vec4(gl_LightSource[0].ambient.xyz * gl_FrontMaterial.ambient.xyz, 1);
    vec4 vAmbient = gl_LightSource[0].ambient;
    edit: What was i thinking here.. When i add " * gl_FrontMaterial.ambient", i get black. Main program has this (tried gl_back just in case):
    Code:
      v4:=vector4f(0.6, 0.6, 0.6, 1.0);
      glMaterialfv(GL_FRONT, GL_AMBIENT, @v4);
      glMaterialfv(GL_BACK, GL_AMBIENT, @v4);
    *Pulls hair*
    Proceeded to change other materials too to this format, but all i see is ambient color still. Meaning some part of normal calculation or number feeding is failing.

    That fail can be partly my fault too, because when i swap these comments around i get different shape of model:
    Code:
    //gl_Position = ftransform();
    gl_Position = WVP * gl_Vertex;
    I was previously doing just glTranslate, glRotate commands without own camera handler in use at all, so i'm now experimenting with it aswell. Object didn't have own rotation, but now i removed glRotate's and rotated object matrix instead. Oddly i had replaced ftransform(); one point before with custom multiplication and it worked back then. I have tried each multiplication other way around now, it just always makes a deformed model.

    btw if you still want to work in model space you need to multiply your light direction by a transpose of the rotation matrix (or just swap the order of multiplication, instead of l = mat * vec do l = vec * mat)
    It was one of the things i tried before

    PS. I was able to make specular map texture work in yesterday's version, with the problems it had with normals though. It was simply new uniform and:
    Code:
    specular = pow(specular, gl_FrontMaterial.shininess) * texture2D(specMap, gl_TexCoord[0].st);
    Will see if i can make a standalone project for testing with Lazarus, but i might be busy with other things than programming today.
    Last edited by User137; 03-10-2012 at 11:20 AM.

  6. #16
    if you could post a standalone project that would be helpful, so I could test the code.

  7. #17
    I put back exactly the shaders you posted after i managed to get main program better. Deforming and some problems were due to not passing right uniforms. I can see the pixel-shaded model (with no specular at all), but with light direction problems i had in my own version before. Not sure the code is right, but this is what i'm doing in loop:
    Code:
    glGetFloatv(GL_PROJECTION_MATRIX, @p4);
      glLoadIdentity;
      glTranslatef(0, 0, -2.2);
      glMultMatrixf(@mat);
    
      glGetFloatv(GL_MODELVIEW_MATRIX, @m4);
      m4:=m4*p4;
      if locWVP>0 then glUniformMatrix4fv(locWVP, 1, bytebool(GL_FALSE), @m4);
      if locW>0 then glUniformMatrix4fv(locW, 1, bytebool(GL_FALSE), @mat);
      campos:=vector(0, 0, 2.2);
      if locCam>0 then glUniform3fv(locCam, 1, @campos);
    
      //glMultMatrixf(@mat); // I think this must be called before getting model_view
      model.Render; // (Model diameter is 0.5)

  8. #18
    I made a tool for nxPascal that's able to create a normalmap texture, when the object normals are known. Naturally it's rough, but if there is a high quality model available in addition to low quality, then the result can be good. After little blurring maybe... I created a 12k triangle sphere for the normal map, and using 800 triangle model in the attached demo. This way i can be sure that color red means normal (1, 0, 0), exactly where the texture coordinate tells. Added some noise on gray background for specular map.

    I already met 2 testers who had just black screen. Reason for other being that gl_Vertex stuff isn't even supported by his new card anymore, i think. Other had little different error, i assume his card is older than mine though. But i have improved the shaders error logging greatly after that, it should tell exactly what's wrong, and write it in errorlog.txt.

    The attached project is standalone Lazarus project, included nxPascal files needed to compile and run. It's still buggy with light directions, and to help testing, i'm using 3 of the objects in the scene. 1 of them is rotating. Also i do not know why ambient light isn't taken into account. Dark side of each object should not be completely black, but they seem so.
    Control keys are: W, S, A, D, Spacebar, C, and mouse dragging

    Also just narrowed down the ambient color to this in fragment shader:
    Code:
    gl_FragColor = gl_FrontMaterial.ambient * texture2D(colorMap, gl_TexCoord[0].xy);
    So gl_FrontMaterial.ambient returns black. I don't know why, it is set to higher color in main program.
    Attached Images Attached Images
    Attached Files Attached Files
    Last edited by User137; 15-10-2012 at 06:04 PM.

Page 2 of 2 FirstFirst 12

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •