0
\$\begingroup\$

I'm experiencing a very strange result in my very simple normal map implementation on iOS 7 - OpenGL ES 2.0. I'm only using the bare parameters necessary and I'm also skipping on all the tangent and bi-normal stuff, since the object is a flat quad in the background that's not going to move.

The quad is placed in the center and fills the entire screen. The light source is placed directly above it and there's no falloff calculation. The normal map itself is baked out from 3ds max using a noise map as displacement/height-map. So the result looks right I guess, however, it's split diagonally (see below)... why?

Here's my vertex Shader, I believe the parameters are self explanatory:

attribute vec4 a_pos;
attribute vec2 a_tex_coord;

uniform mat4 u_projection;
uniform mat4 u_model_view;
const vec4 u_light_position = vec4(0.0,0.0,1.0,1.0);

varying vec4 v_world_pos;
varying vec2 v_tex_coord;
varying float v_distance;


void main(void) {
  v_world_pos = u_model_view * a_pos;
  v_distance = length(u_light_position - v_world_pos);
  v_tex_coord = a_tex_coord;//(a_tex_coord + u_texture_offset) * u_texture_multiplier;

  gl_Position = u_projection * v_world_pos;
}

and the fragment shader

uniform sampler2D u_texture;

varying vec4 v_world_pos;
varying vec2 v_tex_coord;
varying float v_distance;

const vec4 u_light_position = vec4(0.0,0.0,1.0,1.0);

void main(void) {
  vec3 light_vector = normalize(u_light_position - v_world_pos).xyz;
  float light_diffuse = max(dot(normalize(texture2D(u_texture, v_tex_coord).rgb * 2.0 - 1.0), light_vector), c_zero);
  gl_FragColor = (vec4(1.0,1.0,1.0,1.0)) * light_diffuse;
}

and this is the weird result i get, why would this happen? I believe it's here

Weird normal map behaviour

float light_diffuse = max(dot(normalize(texture2D(u_texture, v_tex_coord).rgb * 2.0 - 1.0), light_vector), c_zero);

but I couldn't get better results by removing the scaling of the rgb value...

EDIT:

When rotating the mesh the light remains at the bottom right half of it:

Normal map behaviour on rotated mesh

EDIT2:

I've downloaded a normal map online which seems to give the right results, on the left of the picture below the normal map seems to behave as expected even when rotating (that is as correct as it can with this simplified method). The one on the right side is the old texture result when I change my shader diffuse calculation to this:

  float light_diffuse = max(dot(normalize(normalize(texture2D(u_texture, v_tex_coord).rgb) * 2.0 - c_one), light_vector), c_zero);

Which looks almost right, but there is still that slight shadow that remains on the top left...

So I am gonna check my export settings again, but I still can't explain that shadow.

More normal map results

\$\endgroup\$
7
  • \$\begingroup\$ v_world_pos = u_model_view * a_pos. Your world position appears to actually be a camera-space position. \$\endgroup\$
    – bcrist
    Commented Mar 20, 2014 at 17:34
  • \$\begingroup\$ Is your light behind the quad? What's the quad data? Is N dot L negative? \$\endgroup\$
    – Syntac_
    Commented Mar 20, 2014 at 17:42
  • \$\begingroup\$ @bcrist no, i just named the matrix wrong :( \$\endgroup\$
    – cboe
    Commented Mar 20, 2014 at 18:16
  • \$\begingroup\$ @Syntac the quads position is at 0,0,0, the light is at 0,0,1, so it's right above (closer to the camera), the quad is what you'd get from exporting a plane from 3ds max, no adjustments made - it display's fine with every other shader and for example vertex lighted shader, i doubt that's the culprit. N dot L might be negative I guess, see max(dot(normalize(texture2D(u_texture, v_tex_coord).rgb * 2.0 - 1.0), light_vector), c_zero)... but the math is right isn't it? \$\endgroup\$
    – cboe
    Commented Mar 20, 2014 at 18:22
  • \$\begingroup\$ You need to add more information on camera position and geometry. \$\endgroup\$
    – Syntac_
    Commented Mar 21, 2014 at 12:54

1 Answer 1

2
\$\begingroup\$

I finally found the error. It was just wrong export settings, I just didn't expect that to have this sort of impact. In 3ds Max I changed the projection options -> normal map space -> red: right to red: left

What a gigantic waste of time.

\$\endgroup\$
1
  • \$\begingroup\$ You're also multiplying the alpha of the colour by the diffuse value - I assume you don't want to do that. \$\endgroup\$
    – Syntac_
    Commented Mar 21, 2014 at 15:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .