Normal transformation problem of Shaders example

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
iceguan
Posts: 10
Joined: Tue Mar 27, 2018 1:19 pm

Normal transformation problem of Shaders example

Post by iceguan »

From example 10. Shaders example, in d3d9.hlsl,

Code: Select all

 
// transform normal
float3 normal = mul(float4(vNormal,0.0), mInvWorld);
 
The normal is transformed by mInvWorld. But I think it should be transformed by mInvWorldTrans, which is transposed of the inversed world matrix.

Which one is correct? I am very confused.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Normal transformation problem of Shaders example

Post by CuteAlien »

Could be because it's mul(vector, matrix) instead of mul(matrix, vector). But just guessing, one of those simple questions which would take me a few hours to answer until I figure it all out again.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
devsh
Competition winner
Posts: 2057
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Re: Normal transformation problem of Shaders example

Post by devsh »

Should be correct if mul(matrix, vector) means a transpose of front multiply (since A^T.B^T = (AB)^T )
iceguan
Posts: 10
Joined: Tue Mar 27, 2018 1:19 pm

Re: Normal transformation problem of Shaders example

Post by iceguan »

CuteAlien wrote:Could be because it's mul(vector, matrix) instead of mul(matrix, vector). But just guessing, one of those simple questions which would take me a few hours to answer until I figure it all out again.
Thanks for reply! In mul(vector, matrix) form just like the one in the example shader, the matrix I think should be the transpose of inverted world matrix.

I think this is an error in this shader. However, this defect is not visible on the fly in this example because the world matrix is always a diagonal matrix. When I manually change the world matrix to some matrix other than diagonal matrix (e.g. a rotation matrix), the normal seem to be failed to calculated.
Last edited by iceguan on Thu Oct 17, 2019 3:08 am, edited 1 time in total.
iceguan
Posts: 10
Joined: Tue Mar 27, 2018 1:19 pm

Re: Normal transformation problem of Shaders example

Post by iceguan »

devsh wrote:Should be correct if mul(matrix, vector) means a transpose of front multiply (since A^T.B^T = (AB)^T )
Yes, mul(invWorld, normal) should be correct.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Normal transformation problem of Shaders example

Post by CuteAlien »

Uh... looking at shaders. Nothing makes sense?
- mLightPos is actually the camera position (maybe deliberate - but then still bad naming...)
- worldpos is calculated using the transpose world matrix instead of just world-matrix.
- normal should use either world-matrix (without non-uniform scaling that works I think?) Or invers-transpose world matrix as you said.

Well, shader says "Please note that these example shaders don't do anything really useful." I guess I'll just add a few more comments.

edit: Added comments now as I don't really know much about the idea behind it. Probably should write a different shader-example some day. Actually at least one more shader-example will be added soon (for cubemap, already working, just want to do some more cleanup before adding the example to the engine).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
iceguan
Posts: 10
Joined: Tue Mar 27, 2018 1:19 pm

Re: Normal transformation problem of Shaders example

Post by iceguan »

CuteAlien wrote:Uh... looking at shaders. Nothing makes sense?
- mLightPos is actually the camera position (maybe deliberate - but then still bad naming...)
- worldpos is calculated using the transpose world matrix instead of just world-matrix.
- normal should use either world-matrix (without non-uniform scaling that works I think?) Or invers-transpose world matrix as you said.

Well, shader says "Please note that these example shaders don't do anything really useful." I guess I'll just add a few more comments.

edit: Added comments now as I don't really know much about the idea behind it. Probably should write a different shader-example some day. Actually at least one more shader-example will be added soon (for cubemap, already working, just want to do some more cleanup before adding the example to the engine).
LOL. I think I can probably write a shader example of Blinn shading model with very basic normal mapping or Screen Quad for post processing if required.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Normal transformation problem of Shaders example

Post by CuteAlien »

I think we even have some light shaders in OGL branch already.
Doing something with a ScreenQuad is also a good idea. Still considering if I should adding a screenquad class or struct to Irrlicht, thought not quite sure where it fits. So just adding it as example for now is maybe a way to do that.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
iceguan
Posts: 10
Joined: Tue Mar 27, 2018 1:19 pm

Re: Normal transformation problem of Shaders example

Post by iceguan »

CuteAlien wrote:I think we even have some light shaders in OGL branch already.
Doing something with a ScreenQuad is also a good idea. Still considering if I should adding a screenquad class or struct to Irrlicht, thought not quite sure where it fits. So just adding it as example for now is maybe a way to do that.
I think it may fit into some new kind of namespace such as utils, in order not to couple tightly with the engine.

Screen Quad for OpenGL is painful because for render target, the texture matrix is vertically flipped. In result, displaying a static texture and render target give different results with the same piece of shader code. Do I miss something? Or it is a problem caused by OpenGL version or driver?
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Normal transformation problem of Shaders example

Post by CuteAlien »

OpenGL indeed flips the texture matrix (I think this is going back to some image format, TGA probably, which was used in the OpenGL predecessor IRIS GL).

Some other engines using OpenGL just have all textures with origin on top because of that (so they fix it on loading and whenever you draw a texture as image the image is flipped then on drawing). But we won't change that (at least no plans for it). Also I think very modern OpenGL might have a flag (never used it, just remembering seeing one mentioned once).

In Irrlicht we flip RTT textures when they are used for draw calls inside the OpenGL driver by modifying the texture matrix. But only for fixed-function materials. If you work with shader materials you have to flip it yourself (we can't handle it for users in that case as they pass their own texture matrices to shaders, so there is no longer a central place which can be fixed). So in shaders you have to take care if a texture comes from rendertarget or otherwise. In general you know that when writing shaders, otherwise you have to pass an additional flag or texture matrix to your shader.

You can also flip the projection matrix when rendering to a RTT, but then you also have to flip front/backface culling for all materials. This will actually be in the cubemap example which I plan to add soon. For now you can check cubemap.cpp at https://bitbucket.org/mzeilfelder/irr-p ... rc/default which is 99% what the example will later be. Search for "CUBEMAP_UPSIDE_DOWN_GL_PROJECTION" to see how I solved it there.

If you use Irrlicht trunk you can use ITexture::lock() with the new ETLF_FLIP_Y_UP_RTT flag to get data the other way. But that's obviously slow and you shouldn't do so in most cases. For an example for that again look at my cubemap.cpp and search for "CUBEMAP_USPIDE_DOWN_RTT".
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
iceguan
Posts: 10
Joined: Tue Mar 27, 2018 1:19 pm

Re: Normal transformation problem of Shaders example

Post by iceguan »

CuteAlien wrote:OpenGL indeed flips the texture matrix (I think this is going back to some image format, TGA probably, which was used in the OpenGL predecessor IRIS GL)...
I wrote a simple post processing example recently and hosted it on Github at https://github.com/BoshenGuan/Irrlicht- ... ng-Example. Hope this helps.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Normal transformation problem of Shaders example

Post by CuteAlien »

Oh that's cool! I'll check it once more next week, but on first view looks pretty good - I think we can use it like that. That's if you are OK, with us putting it into the engine?

Tiny details I'm thinking about (but probably don't matter)...

Not sure about mipmap filter... it's likely not doing anything in that case (should only be active in combination with trilinear filter and we have no depth here), but then again also won't hurt to disable it.

Not sure if we should use MeshBuffer instead of directly using indices, vertices, maybe I'll switch to that (works better on WebGL which needs buffers for everything, but I also haven't switched rest of Irrlicht yet completely to that). I guess I can do that also once I support WebGL officially.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
iceguan
Posts: 10
Joined: Tue Mar 27, 2018 1:19 pm

Re: Normal transformation problem of Shaders example

Post by iceguan »

CuteAlien wrote:Oh that's cool! I'll check it once more next week, but on first view looks pretty good - I think we can use it like that. That's if you are OK, with us putting it into the engine?

Tiny details I'm thinking about (but probably don't matter)...

Not sure about mipmap filter... it's likely not doing anything in that case (should only be active in combination with trilinear filter and we have no depth here), but then again also won't hurt to disable it.

Not sure if we should use MeshBuffer instead of directly using indices, vertices, maybe I'll switch to that (works better on WebGL which needs buffers for everything, but I also haven't switched rest of Irrlicht yet completely to that). I guess I can do that also once I support WebGL officially.
It's OK with no problem. You can certainly use it and modify it.

Enable mipmap, bilinear and trilinear filters are all OK. That all depends on user's purpose. I think you are right. It should not be put in the quad definition.

The only concern to all those filters is the texture sampling scheme in D3D and OpenGL. Specifically, how to calculate u,v/s,t to get the color of surrounding pixel.

D3D seems to sample the texture in Texture coordinate space, and that is why it needs to add "1.0 / TextureSize / 2.0" to (u, v) to offset (u, v) to pixel center. However, this trick seems not applying to OpenGL, in whose fragment shader, (u, v) (maybe it should be called (s, t)? I am not sure) are interpolated in a different way. OpenGL seems to firstly put the texture on the surface (the quad in this case), calculate the (u, v) and then do interpolation.

This makes no difference when render target size is the same with the viewport. However, if those two sizes are not the same, (u, v) need to be calculated very very carefully. Otherwise, filters are applied and the result is blurred.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Normal transformation problem of Shaders example

Post by CuteAlien »

Is there any chance you could change the license to zlib license for this? Then it'll fit into Irrlicht.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
iceguan
Posts: 10
Joined: Tue Mar 27, 2018 1:19 pm

Re: Normal transformation problem of Shaders example

Post by iceguan »

CuteAlien wrote:Is there any chance you could change the license to zlib license for this? Then it'll fit into Irrlicht.
Okay. I will check for that on Github.

EDIT:

I have changed the license to zlib. Please let me know if there is a problem. :wink:
Post Reply