Could use some help with cubemap sphere normal mapping

Could use some help with cubemap sphere normal mapping

Postby smcameron » 10 Jan 2016, 18:59

I am using OpenGL, my own custom rendering engine in C, and I am trying to get cubemapped spheres to do normal mapping for planets in my open source (GPL) space game, "Space Nerds In Space".

I have detailed what I've got so far here:
https://github.com/smcameron/space-nerd ... /issues/79

I am attempting to use the method described here to calculate tangents and bitangents:
http://www.iquilezles.org/www/articles/ ... sphere.htm
That only describes how to do one face. I have tried to extrapolate to the other 5 faces
(the issue linked above goes into a bit more detail.)

I am not sure how to even know if I am doing it correctly though. I am in a bit over my head.
smcameron
 
Posts: 377
Joined: 29 Oct 2010, 23:44

Re: Could use some help with cubemap sphere normal mapping

Postby NaN » 10 Jan 2016, 20:24

The tangent/bitangent have to follow the u/v coords of the normal map, so you need six separate faces -> normalized cube as in the tutorial. Alternatively you could try constructing them in the shader. Although this might be somewhat complicated as you have to deal with six texture faces. Another idea would be to pre-generate a tangent cube map, assuming it is a sphere.
NaN
 
Posts: 151
Joined: 18 Jan 2010, 10:32

Re: Could use some help with cubemap sphere normal mapping

Postby smcameron » 10 Jan 2016, 20:43

NaN {l Wrote}:The tangent/bitangent have to follow the u/v coords of the normal map, so you need six separate faces -> normalized cube as in the tutorial.


Yep, that's why I wrote in the issue "I will have to change from using a subdivided icosohedron to six subdivided normalized quads with duplicated vertices at the edges to get the normal map interpolation to work correctly at the boundaries at some point, but, one thing at a time." For now, was just trying to get the calculations right knowing that there would be problems for triangles that span the cube edges using the subdivided icosohedron.
smcameron
 
Posts: 377
Joined: 29 Oct 2010, 23:44

Re: Could use some help with cubemap sphere normal mapping

Postby NaN » 10 Jan 2016, 21:39

I would probably focus on getting one face right. You can get the other faces using rotation/reflection transformations.
NaN
 
Posts: 151
Joined: 18 Jan 2010, 10:32

Re: Could use some help with cubemap sphere normal mapping

Postby andrewj » 10 Jan 2016, 23:46

I have run mesh_viewer and your tangent lines (green and blue) looks correct to me.

Where in the code are the red lights (etc) added? I'd like to see the results with a single white light.
User avatar
andrewj
 
Posts: 194
Joined: 15 Dec 2009, 16:32
Location: Tasmania

Re: Could use some help with cubemap sphere normal mapping

Postby smcameron » 11 Jan 2016, 00:33

andrewj {l Wrote}:I have run mesh_viewer and your tangent lines (green and blue) looks correct to me.

Where in the code are the red lights (etc) added? I'd like to see the results with a single white light.


Thanks for trying it.

The code to tint things red green and blue is in the shader, in share/snis/shader/textured-cubemap-and-lit-per-pixel.shader. It's for trying to debug... the per-pixel normal's x,y,z is mapped to r,g,b (at 85%, 15% is diffuse lighting). The following change will make the lighting more "ordinary". You can right-drag the mouse while holding down the CTRL key to move the light around.

{l Code}: {l Select All Code}
diff --git a/share/snis/shader/textured-cubemap-and-lit-per-pixel.shader b/share/snis/shader/textured-cubemap-and-lit-per-pixel.shader
index 407d496..9344fc9 100644
--- a/share/snis/shader/textured-cubemap-and-lit-per-pixel.shader
+++ b/share/snis/shader/textured-cubemap-and-lit-per-pixel.shader
@@ -108,8 +108,8 @@ varying mat3 tbn;
                gl_FragColor = textureCube(u_AlbedoTex, v_TexCoord);
 
                gl_FragColor.rgb *= diffuse;
-               gl_FragColor.rgb *= diffuse * 0.15;
-               gl_FragColor.rgb += 0.85 * pixel_normal;
+               //gl_FragColor.rgb *= diffuse * 0.15;
+               //gl_FragColor.rgb += 0.85 * pixel_normal;
                //gl_FragColor.rgb = pixel_normal;
 
                /* tint with alpha pre multiply */


the "gl_FragColor.rgb *= diffuse;" is correct (if the value of diffuse were correct.)

There's a mistake in the code I now see... The last two lines below were intended to put in 15% of the color as "ordinary" lighting and 85% as the normal mapped to RGB for debugging. So for my intended effect, either the first line should be active, or the last two, but not all three.

{l Code}: {l Select All Code}
               gl_FragColor.rgb *= diffuse;
               gl_FragColor.rgb *= diffuse * 0.15;
               gl_FragColor.rgb += 0.85 * pixel_normal;


It seems almost correct, but not quite. For example, with the light in the upper left, this looks right (I think -- it is actually surprisingly hard to tell if it's *really* right):
Image

But this, with the model rotated 180 degrees about the axis coming out of the screen, doesn't look right
(for example the left hand side of the lips and mouth are lit, but should be in shadow, and the right hand side of the back of the head is in shadow, but should be lit. The lighting seems to be ok as the light moves in the vertical axis, but wrong as the light moves in the horizontal axis -- when the model is inverted.)
Image
smcameron
 
Posts: 377
Joined: 29 Oct 2010, 23:44

Re: Could use some help with cubemap sphere normal mapping

Postby andrewj » 14 Jan 2016, 12:45

Been playing with this some more today.

I think the tangent/bitangent vectors are actually wrong. How I confirmed that was compute the dot products between the a_Normal, a_Tangent and a_BiTangent vectors in the shader and display them as the rgb color. Since these vectors are meant to be orthogonal, their dot products should be zero (or close to zero) and we should render a mostly flat grey ball. Instead it looks like the attachment.

Also I'm fairly sure that "tbn" should be set to "mat3(v_Normal, v_BiTangent, v_Tangent)" -- as that is what TBN stands for (apparently). I think once the tangent/bitangent vectors are correct, the tbn matrix will do what it should and the lighting will be correct.
Attachments
dotproducts.jpg
User avatar
andrewj
 
Posts: 194
Joined: 15 Dec 2009, 16:32
Location: Tasmania

Re: Could use some help with cubemap sphere normal mapping

Postby smcameron » 14 Jan 2016, 17:53

Hi, and thanks for looking. I am pretty sure they are wrong as well, although actually I don't think the tangent and bitangent are supposed to be quite at right angles to one another -- see this: http://www.iquilezles.org/www/articles/ ... sphere.htm at the bottom. I think they are supposed to follow the direction of the rows and columns of texels of the square textures after they've been stretched into 1/6th of a sphere. But their cross product *should* point in the same direction as the normal.
smcameron
 
Posts: 377
Joined: 29 Oct 2010, 23:44

Re: Could use some help with cubemap sphere normal mapping

Postby smcameron » 15 Jan 2016, 00:02

So I implemented a spherified-cube mesh to replace the subdivided icosohedron, and computed the tangents and bitangents empirically rather than analytically by sampling. Still doesn't really work -- the tangents and bitangents "look right", but there's still some problem with what the shader is doing, but it is progress, I think. I also noticed a bug in my attempt to analytically calculate the tangents and bitangents -- using abs() when I needed to use fabsf() instead -- although fixing that bug did not make the analytic calculation work.)

Also, I realize now the Hairy Ball Theorem comes into play since it means that there does not exist a continuous field of tangent/bitangent/normals to cover a sphere -- there have to be discontinuities in any such field, which makes me wonder if I am barking up the wrong tree with this whole tangent/bitangent/normal thing.

Image

Image

Updated the bug.
smcameron
 
Posts: 377
Joined: 29 Oct 2010, 23:44

Re: Could use some help with cubemap sphere normal mapping

Postby smcameron » 15 Jan 2016, 04:01

Ok, tentatively, as of commit e05c4ff I think maybe it's working:


youtu.be/GbBlPy2lpcA

Oh, and, andrewj, you were right about this:
Also I'm fairly sure that "tbn" should be set to "mat3(v_Normal, v_BiTangent, v_Tangent)"
smcameron
 
Posts: 377
Joined: 29 Oct 2010, 23:44

Re: Could use some help with cubemap sphere normal mapping

Postby NaN » 15 Jan 2016, 12:33

Looking good.

Although as you have noticed sharing edge vertices is wrong. The bi/tangents can not be continuous over the sphere, neither are the uv coordinates of the cubemap.

I think the only true way to fix this is to sample the height map in the pixel shader.

Here is one example of how to do it: http://www.rorydriscoll.com/2012/01/11/derivative-maps/

In GLSL ddx, ddy are called dFdx, dFdy.
NaN
 
Posts: 151
Joined: 18 Jan 2010, 10:32

Who is online

Users browsing this forum: No registered users and 1 guest