[SOLVED] Normals and lighting


photo

Recommended Posts

Hi,

 

I have a model which is a flat surface (two triangles) with a simple grey diffuse texture.

 

post-418-0-63739100-1346210723_thumb.png

 

I clone the model four times and place them connected to each other.

 

post-418-0-63758700-1346210761_thumb.png

 

Everything looks perfect with any light condition, thank you guys. Then I turn one of the tile to 180 degrees. Because I did not change an angle of normals and my texture is a solid grey color, I would expect to see the same color for all tiles but this is what I've got

 

post-418-0-38142600-1346210829_thumb.png

 

Why does the surface change its color? Any idea?

 

Steps to reproduce:

 

1. replace "data\library\worlds\materials\probes.cpp" by attached file.

2. run "demos\library_materials_d3d11.bat"

3. observe different color on tiles.

 

probes.cpp:

 

#include <library/scripts/materials.h>

void create_scene() {

   // create a mesh
   {
       ObjectMeshDynamic mesh = new ObjectMeshDynamic();

       mesh.addVertex(dvec3(0, 0, 0));
       mesh.addTexCoord(dvec4(0, 0, 0, 0));

       mesh.addVertex(dvec3(2, 0, 0));
       mesh.addTexCoord(dvec4(0, 1, 0, 0));

       mesh.addVertex(dvec3(0, 2, 0));
       mesh.addTexCoord(dvec4(1, 0, 0, 0));

       mesh.addVertex(dvec3(2, 2, 0));
       mesh.addTexCoord(dvec4(1, 1, 0, 0));

       mesh.addIndex(0);
       mesh.addIndex(1);
       mesh.addIndex(2);

       mesh.addIndex(3);
       mesh.addIndex(2);
       mesh.addIndex(1);

       mesh.setMaterial("mesh_base", 0);

       mesh.setMaterialTexture("diffuse", "grey.dds", 0);

       mesh.updateNormals();
       mesh.updateTangents();

       node_save("my.node", mesh);

       delete mesh;
   }

   {
       ObjectMeshDynamic mesh = node_load("my.node");

   	mat4 mat;
   	mat.m00m01m02m03 = vec4(1, 0, 0, 0);
   	mat.m10m11m12m13 = vec4(0, 1, 0, 0);
   	mat.m20m21m22m23 = vec4(0, 0, 1, 2);
   	mat.m30m31m32m33 = vec4(0, 0, 0, 1);

       mesh.setTransform(mat);

       engine.editor.addNode(class_remove(mesh));
   }

   {
       ObjectMeshDynamic mesh = node_load("my.node");

   	mat4 mat;
   	mat.m00m01m02m03 = vec4(1, 0, 0, 2);
   	mat.m10m11m12m13 = vec4(0, 1, 0, 0);
   	mat.m20m21m22m23 = vec4(0, 0, 1, 2);
   	mat.m30m31m32m33 = vec4(0, 0, 0, 1);

       mesh.setTransform(mat);

       engine.editor.addNode(class_remove(mesh));
   }

   {
       ObjectMeshDynamic mesh = node_load("my.node");

   	mat4 mat;
   	mat.m00m01m02m03 = vec4(1, 0, 0, 0);
   	mat.m10m11m12m13 = vec4(0, 1, 0, 2);
   	mat.m20m21m22m23 = vec4(0, 0, 1, 2);
   	mat.m30m31m32m33 = vec4(0, 0, 0, 1);

       mesh.setTransform(mat);

       engine.editor.addNode(class_remove(mesh));
   }

   {
       ObjectMeshDynamic mesh = node_load("my.node");

       /*
   	mat4 mat;
   	mat.m00m01m02m03 = vec4(1, 0, 0, 2);
   	mat.m10m11m12m13 = vec4(0, 1, 0, 2);
   	mat.m20m21m22m23 = vec4(0, 0, 1, 2);
   	mat.m30m31m32m33 = vec4(0, 0, 0, 1);
       mesh.setTransform(mat);
       */

   	mat4 mat;
   	mat.m00m01m02m03 = vec4(-1, 0, 0, 4);
   	mat.m10m11m12m13 = vec4(0, -1, 0, 4);
   	mat.m20m21m22m23 = vec4(0, 0, 1, 2);
   	mat.m30m31m32m33 = vec4(0, 0, 0, 1);
       mesh.setTransform(mat);

       engine.editor.addNode(class_remove(mesh));
   }

   return "Gold, silver, metal, car paint, concrete, stucco, tile, glass, rubber";
}

 

probes.cpp

Link to post
  • 2 weeks later...

First of all, that you for a good description of your issue! It was so nice to see a really good description, with screenshots and code to sustain it.

 

As for a issue with a mirrored normal map, it's caused by the fact that normal maps are unsigned. A normal map stores values in the range [0, 256] and to represent 0 (no offset), 127 is used.

 

De facto 0 must be represented in the unsigned normal map as 127.5. This would be the real halfway point, but since the normal map can only store integers, this is not an option. When in pixel shader the input range is transformed to [-1, 1], 0 is a little bit off, which results in a very slight bend of the normal. Mirroring a texture brings it out and you see a tangent space seam.

 

Try using a 16-bit normal map for normal maps on plains, it might improve the situation.

Edited by manguste
Link to post