Set Matrix correctly.

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!
The_Glitch
Competition winner
Posts: 523
Joined: Tue Jan 15, 2013 6:36 pm

Set Matrix correctly.

Post by The_Glitch »

I've been working on a new Tangent Space shader. It use ViewProjection and ViewInverse matrix.

I set them like this:

Code: Select all

 
         MVIEWProj *= driver->getTransform(video::ETS_PROJECTION);
        MVIEWProj *= driver->getTransform(video::ETS_VIEW);
        MVIEWProj *= driver->getTransform(video::ETS_WORLD);
 
        MPVW = MVIEWProj.getTransposed();
        
        
        core::matrix4 inverseView = driver->getTransform(video::ETS_VIEW).getInverse(inverseView);
        
          core::matrix4 matWorldViewProj1 = MPVW;
        services->setVertexShaderConstant(ViewMat, matWorldViewProj1.pointer(), 16);
        services->setVertexShaderConstant(InvViewMat, inverseView.pointer(), 16);
 
 
But my shader lighting looks all messed up.
Thanks
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Set Matrix correctly.

Post by Vectrotek »

You've probably seen this before but mine is like this (don't mind how I named the matrices):

You'll see I've got an extra "M17WorldInverseTranspose.makeInverse();"

Code: Select all

 
       M01World = TheDriver->getTransform(video::ETS_WORLD);
       M05WorldViewProjection =   TheDriver->getTransform(video::ETS_PROJECTION);
       M05WorldViewProjection *=  TheDriver->getTransform(video::ETS_VIEW);
       M05WorldViewProjection *=  TheDriver->getTransform(video::ETS_WORLD);
       M17WorldInverseTranspose = M01World.getTransposed();  // For Irrlicht this replaces the commonly used "world matrix!"
       M17WorldInverseTranspose.makeInverse();
       // You may (under "pipeline") have to use.. MyMatrix = services->getVertexShaderConstantID("my_matrix"); etc..
       TheMATRENDServices->setVertexShaderConstant("M01World", M01World.pointer(), 16);
       TheMATRENDServices->setVertexShaderConstant("M05WorldViewProjection",   M05WorldViewProjection.pointer(), 16);
       TheMATRENDServices->setVertexShaderConstant("M17WorldInverseTranspose", M17WorldInverseTranspose.pointer(), 16);
 
My Vertex Program part of the HLSL code looks like this..

Code: Select all

 
 // Data from Irrlicht's Vertex Buffer..
 struct appdata 
  {float3 Position       : POSITION;   // O.K.
   float4 Normal         : NORMAL;
   float4 UVCoords       : TEXCOORD0;  
   // These Tangents and Binormals depend on being correctly calculated and correctly updated in your appcode or engine.
   // The appcode does the updates in this case..(only skinned or morphed meshes need this update)..
   // Static objects need Tangents and Binormals but they needn't be updated..
   float4 Tangent        : TEXCOORD1;  // As per Irrlicht Specific HLSL or GLSL..
   float4 Binormal       : TEXCOORD2;  
  };
  
 // Structured Data passed from "Vertex Program" to "Fragment(Pixel) Shader"..
 struct vertexOutput 
  {float4 HPosition             : POSITION;
   float2 UVCoords              : TEXCOORD0;   
   float3 PassedWORLDVertPos    : TEXCOORD1;
   float3 WorldITNormal         : TEXCOORD2;
   float3 WorldITTangent        : TEXCOORD3;
   float3 WorldITBinormal       : TEXCOORD4;
  };
 
 // ===============  V E R T E X   P R O G R A M  ================= 
 vertexOutput vertexMain(appdata IN)
  {vertexOutput OUT       = (vertexOutput)0;
 
   // OpenGL matrix convention is column-major order while Direct3D convention is row-major order.
   // That explains why the order of matrices multiplication is not the same in OpenGL and Direct3D.
 
   OUT.WorldITNormal      = mul(IN.Normal,   M17WorldInverseTranspose).xyz;  // SWAP the params between GLSL ad HLSL ! (be very aware of this issue)..
   OUT.WorldITTangent     = mul(IN.Tangent,  M17WorldInverseTranspose).xyz;  // Happens to NOT be "World" as in so many examples!!.. 
   OUT.WorldITBinormal    = mul(IN.Binormal, M17WorldInverseTranspose).xyz;
   OUT.PassedWORLDVertPos = (mul(float4(IN.Position.xyz,1),M01World).xyz);
   OUT.UVCoords           = IN.UVCoords.xy;
   OUT.HPosition          = mul(float4(IN.Position.xyz,1),M05WorldViewProjection);   // Needed even if not visibly used..
   return OUT;
  }
 
 
Show us your Shader Code.. (I know you use HLSL)
The matrix setup here depends on what goes on in your shader's Fragment part..
Also make sure your Normal Maps are "Y Up Standard" and If not, make sure your shader knows it..
(ps: if you give screenshots, try to re-scale them in Photoshop or something to smaller pictures
because your images are always very big and take a long time to load in some browsers.. )
The_Glitch
Competition winner
Posts: 523
Joined: Tue Jan 15, 2013 6:36 pm

Re: Set Matrix correctly.

Post by The_Glitch »

I've seen your setup before, here's the Vertex Shader:


I've setup matrix similar to yours for testing minus your naming scheme but the results looked terrible.

I'm not sure maybe Irrlicht lights our not in the right space. Works fine In rendermonkey but not in Irrlicht.
Any ideas?
Last edited by The_Glitch on Fri Jul 29, 2016 6:05 pm, edited 1 time in total.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Set Matrix correctly.

Post by mongoose7 »

You shouldn't be using the projection matrix at all. It collapses the view frustum into the unit cube. The inverse would map the unit cube into the view frustum. Points in the view frustum can be sent anywhere by the inverse. How can that help?
The_Glitch
Competition winner
Posts: 523
Joined: Tue Jan 15, 2013 6:36 pm

Re: Set Matrix correctly.

Post by The_Glitch »

mongoose7 I don't know all the math behind matrix use I just tried to set the matrix according to what I used in rendermonkey so I'm sure what's wrong is how to setup the matrix properly in Irrlicht.

Usually is not much of a problem but this one I just can't get working even scoured irrlicht and Google.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Set Matrix correctly.

Post by mongoose7 »

I don't grok Render Monkey so I don't know if it even uses the projection matrix. Also, you use GLSL so I can't help you there. But I would just stick with the view and object matrices. If your lighting doesn't look right, your tangent matrix may be transposed. I know there is a lot of bad code on the internet relating to the tangent matrix.
The_Glitch
Competition winner
Posts: 523
Joined: Tue Jan 15, 2013 6:36 pm

Re: Set Matrix correctly.

Post by The_Glitch »

mongoose7 thanks for the reply I'm actually using an hlsl shader I don't use opengl so if that changes anything please take a look. Also I took out the projection matrix and used the view and world but the character does not render. I use WVP which seems fine I believe my problem is setting the View Inverse.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Set Matrix correctly.

Post by Vectrotek »

@The_Glitch.. I know that you have a heavily customised version of Irrlicht.
So. I want to ask..
Can you still compile programs written for "Standard" Irrlicht 1.8.2 ; 1.8.3 or 1.8.4 ?
The_Glitch
Competition winner
Posts: 523
Joined: Tue Jan 15, 2013 6:36 pm

Re: Set Matrix correctly.

Post by The_Glitch »

Yeah I would just download the regular irrlicht and compile.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Set Matrix correctly.

Post by Vectrotek »

Do you have all the Direct X SDK (June 2010) stuff you need for such a recompile?
The_Glitch
Competition winner
Posts: 523
Joined: Tue Jan 15, 2013 6:36 pm

Re: Set Matrix correctly.

Post by The_Glitch »

Vectrotek yes I do you can't use shaders on dx9 unless you have the SDK or it's files when irrlicht goes to compile the shaders. I believe I found part of my issue.

Image

It's using the ViewInverse like it should. I believe the problem is in RenderMonkey the camera moves around the axis of the model and the lighting always appears correct but in irrlicht when the light or object itself moves the lighting appears wrong. I need to setup a good ambient lighting to avoid the harsh falloff of the point light.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Set Matrix correctly.

Post by Vectrotek »

This "Falloff" you're talking about..
Does your use of the word "Falloff" mean the distance between the light
and the fragment (surface), or does it refer to the "Sharpness" of your Specular Highlight? (glass in helmet)
Just asking because I've seen it mean two things..

If your "Falloff" is related to "Distance from Light to Surface" then it may mean that your light would have a MAX Spherical Radius
so that you can have a curve (squared or linear) between ZERO and Max Distance.
If this is the case then your curve might drop off "suddenly" at Max Distance.
(I don't think matrices would cause this)

I don't know if it will help but here is a snippet from my shader that deals with this falloff..

Code: Select all

 
    // You should have calculated "LDist" allready.. Something like this:
      float3 LFDeltas = LightsPosArray[LghtI].xyz - IN.PassedWORLDVertPos.xyz;  // O.K.
      float LDist = sqrt ((LFDeltas.x * LFDeltas.x) + (LFDeltas.y * LFDeltas.y) + (LFDeltas.z * LFDeltas.z)); // Pyth..
 
 
    // In the real world a light has a VERY VERY far max radius, but in CG we have to give it a definite MAX..(we don't want an infinite sphere)
    CurvedIntensity =  1.0 - (1.0 / LightsMaxRadiusArray[LghtI] *  LDist); // You know what your light Max Radius is..
    CurvedIntensity *= CurvedIntensity; // Squared for the curve.. (Even without this a linear value should be Zero at Max Dist)
 
    // = = other code = = = 
 
    // Additive Diffuse (looping though lights with "LghtI")..
    FinalRGB +=  CurvedIntensity * (MappedDiffuse.xyz  * (max(dot(FinalNormal, // DIFFUSE PART..
                                              (normalize(LightsPosArray[LghtI] - IN.PassedWORLDVertPos))),0.0)
                                              * LightsColArray[LghtI]  * PassFloatArray [FAI_000_GLOBAL_BRIGHTNESS] ));
    // Additive Specular  (looping though lights with "LghtI")..
    FinalRGB +=  CurvedIntensity * (clamp(pow(clamp(dot(normalize(( normalize(CameraPos - IN.PassedWORLDVertPos)
                      + normalize(LightsPosArray[LghtI] -      IN.PassedWORLDVertPos))),
                       FinalNormal),0.0,1.0),   7.777   ), 0.0 , 1.0)    // 7.777 is just an example of your Specular "Tightness".. * difficult to control with maps..
                      * LightsColArray[LghtI] * MappedSpecular.x) * 1.0;
 
See how both Specular and Diffuse was multiplied by this curve..
Ignore the Mapped stuff but understand how Curved Intensity is created and used.
I don't know about your Matrices but I do know that RenderMonkey uses a totally
different setup than what is needed in Irrlicht (for me at least).
It does not use Camera Position, Camera Target and Geometry Position.
It simply rotates the object or orbits the camera which isn't good enough
for where we have a world of moving lights and rotating objects and cameras.
(this is why its matrix setups are lacking)

Oh, I'm sure your Normals are "Normalised"..

If you use a totally different procedure then I don't know buddy..
You could look at my latest post and others where we discussed this because those matrices work for my HLSL shader.
The reason I asked if you could compile standard Irrlicht stuff is because most of my old posts use Vanilla Irrlicht
and I think that if you compiled at least one of them successfully you'd have a good grip on this.
I'm busy with a set of batch files that puts my whole work desk in either Vanilla or Custom mode..
(copying, and overwriting Headers, LIBs and DLLs etc). Anyhow you will find a solution.
Cheers! Master Chief looks nice and polished!
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Set Matrix correctly.

Post by Vectrotek »

Oh, Irrlicht don't need the whole 20M SDK to compile the shaders it only needs the DX Runtime Libraries.
For an Engine Recompile you need the whole SDK, but you know that..
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Set Matrix correctly.

Post by Vectrotek »

Looking at your screenshot, it seems your matrices are fine. Normal Map also looks good.
The real test for matrices come in when you scale and rotate that model.
If your light is hooked to your camera and your model rotates, and scales you'll soon see if the light starts acting unnaturally.
I posted a "Test Fusion Ball" for this earlier. It is a "*.x" model that clearly shows deviations in lighting if your matrices are faulty.
The Ball uses bones to animate the halves. Now when this ball is Skin-Animated, Rotated, Moved and Scaled you'll very quickly see if something is wrong..
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Set Matrix correctly.

Post by Vectrotek »

Lose the Irrlicht Lights and their attenuation completely..
I think this is why there is a sharp break at a given distance..
Post Reply