New shader uniform proposals

I would like to propose two new shader uniforms to be added:





WorldMatrixInverseTranspose - needed to convert normals from object to world space, if there is another way to do it please enlighten me!



ResolutionInverse - well, the inverse of the resolution of the current viewport… find myself needing this from time to time :slight_smile:



com.jme3.renderer.RenderManager#updateUniformBindings

[java]

case ResolutionInverse:

tempVec2.set(1f/viewWidth, 1f/viewHeight);

u.setValue(VarType.Vector2, tempVec2);

break;

[/java]



com.jme3.renderer.RenderManager#updateUniformBindings

[java]

case WorldMatrixInverseTranspose:

worldMatrix.toRotationMatrix(tempMat3);

tempMat3.invertLocal().transposeLocal();

u.setValue(VarType.Matrix3, tempMat3);

break;

[/java]



com.jme3.shader.UniformBinding should be updated accordingly :slight_smile:

1 Like

bumping myself before i’m get lost int the history :slight_smile:

And I will specifically tag @momoko_fan since he is one of the few who can weigh in intelligently on how necessary these are from the engine’s perspective. (ie: maybe there is something that already does this that we didn’t see)

@pspeed Thanks :slight_smile:

@kwando said:
WorldMatrixInverseTranspose - needed to convert normals from object to world space, if there is another way to do it please enlighten me!


As long as there's no ununiform scaling, you can do it like this:
[java]
vec3 wsNormal = normalize(mat3(g_WorldMatrix) * inNormal); // object space -> world space
[/java]

But that's a bit risky. I agree, WorldMatrixInverseTranspose would be nice. It would also be nice if one could somehow influence how the lights are passed to the shader. Perhaps a CustomLightUniformSetter interface or something.
@kwando said:
I would like to propose two new shader uniforms to be added:

WorldMatrixInverseTranspose - needed to convert normals from object to world space, if there is another way to do it please enlighten me!

This one already exists it's called NormalMatrix, you also have NormalMatrixInverse if you want it the other way around.

@kwando said:
ResolutionInverse - well, the inverse of the resolution of the current viewport.. find myself needing this from time to time :)

yep could be nice.

To have an exhaustive list of what's supported you can refer to UniformBinding.java
@nehon said:
This one already exists it's called NormalMatrix, you also have NormalMatrixInverse if you want it the other way around.

Nope, according to the docs this matrix transforms normal from model/object space to
View space (not world space).

I just saw it missing while building my deferred renderer, but I'm most likely not going to need it anyway now since I plan to do all lighting in view space instead of world space.

BTW. You are the goto JME shader guru. Is there a clean example of finding the ViewSpace position based on linear depth anyware in JME shaders?

Ho true sorry,

Yeah usually it’s done in viewspace.


@kwando said:
BTW. You are the goto JME shader guru. Is there a clean example of finding the ViewSpace position based on linear depth anyware in JME shaders?

Yes, in SSAO and Water i reconstruct fragment position from depth.
http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core-data/Common/MatDefs/SSAO/ssao.frag
look at the getPosition(vec2 uv) function.
It returns the position of the fragment in view space and use the frustum corners method.

in the water shader the get position returns position in worldspace (as it was more convenient for water), but ity's bit slower because it uses a matrixtranformation
http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core-data/Common/MatDefs/SSAO/ssao.frag

However both of these methods works with the hardware depth buffer computed in the forward rendering, i don't know how you render your depth buffer.

EDIT : i just noticed you said "linear depth" so the first method may not work out of the box, but you just have to rip off the depth linearisation:
remove this line and it should work : float depth= (2.0 * m_FrustumNearFar.x) / (m_FrustumNearFar.y + m_FrustumNearFar.x - depthv* (m_FrustumNearFar.y-m_FrustumNearFar.x));

Also you could consider taking advantage of the hardware depth buffer computed with the albedo.

I think adding those two is useful. @kwando can you post a diff patch?

[patch]

Index: /Users/kwando/jmonkeyengine-read-only/engine/src/core/com/jme3/renderer/RenderManager.java

===================================================================

— /Users/kwando/jmonkeyengine-read-only/engine/src/core/com/jme3/renderer/RenderManager.java (revision 9193)

+++ /Users/kwando/jmonkeyengine-read-only/engine/src/core/com/jme3/renderer/RenderManager.java (working copy)

@@ -380,6 +380,11 @@

tempMat4.invertLocal();

u.setValue(VarType.Matrix4, tempMat4);

break;

  •            case WorldMatrixInverseTranspose:<br />
    
  •                worldMatrix.toRotationMatrix(tempMat3);<br />
    
  •                tempMat3.invertLocal().transposeLocal();<br />
    
  •                u.setValue(VarType.Matrix3, tempMat3);<br />
    
  •                break;<br />
    

case ViewMatrixInverse:

tempMat4.set(viewMatrix);

tempMat4.invertLocal();

Index: /Users/kwando/jmonkeyengine-read-only/engine/src/core/com/jme3/shader/UniformBinding.java

===================================================================

— /Users/kwando/jmonkeyengine-read-only/engine/src/core/com/jme3/shader/UniformBinding.java (revision 9193)

+++ /Users/kwando/jmonkeyengine-read-only/engine/src/core/com/jme3/shader/UniformBinding.java (working copy)

@@ -79,7 +79,15 @@

*/

ViewProjectionMatrix,


  • /**
  • * The world matrix inverse transpose. Converts a normals from Model space<br />
    
  • * to world space.<br />
    
  • * Type: mat3<br />
    
  • */<br />
    
  • WorldMatrixInverseTranspose,



    +

    +

    WorldMatrixInverse,

    ViewMatrixInverse,

    ProjectionMatrixInverse,



    [/patch]



    @Momoko_Fan there is no test case, but the engine compiles without errors.
1 Like

OK Committed

@Momoko_Fan Ofcourse I forgot the ResolutionInverse…



[patch]

Index: /Users/kwando/jmonkeyengine-read-only/engine/src/core/com/jme3/renderer/RenderManager.java

===================================================================

— /Users/kwando/jmonkeyengine-read-only/engine/src/core/com/jme3/renderer/RenderManager.java (revision 9199)

+++ /Users/kwando/jmonkeyengine-read-only/engine/src/core/com/jme3/renderer/RenderManager.java (working copy)

@@ -429,6 +429,10 @@

tempVec2.set(viewWidth, viewHeight);

u.setValue(VarType.Vector2, tempVec2);

break;

  •            case ResolutionInverse:<br />
    
  •                tempVec2.set(1f/viewWidth, 1f/viewHeight);<br />
    
  •                u.setValue(VarType.Vector2, tempVec2);<br />
    
  •                break;<br />
    

case Aspect:

float aspect = ((float) viewWidth) / viewHeight;

u.setValue(VarType.Float, aspect);

Index: /Users/kwando/jmonkeyengine-read-only/engine/src/core/com/jme3/shader/UniformBinding.java

===================================================================

— /Users/kwando/jmonkeyengine-read-only/engine/src/core/com/jme3/shader/UniformBinding.java (revision 9199)

+++ /Users/kwando/jmonkeyengine-read-only/engine/src/core/com/jme3/shader/UniformBinding.java (working copy)

@@ -119,6 +119,12 @@

  • Type: vec2

    */

    Resolution,

    +
  • /**
  • * The inverse of the resolution, 1/width and 1/height.<br />
    
  • * Type: vec2<br />
    
  • */<br />
    
  • ResolutionInverse,



    /**
  • Aspect ratio of the resolution currently set. Width/Height.

    [/patch]



    BTW



    The docs for UniformBinding seems to be wrong… those two matrices is not the same… ViewProjectionMatrix converts from Clip/Projection space to view space :slight_smile:
Code:
/** * The world view projection matrix. Converts Model space to Clip/Projection * space. * Type: mat4 */ WorldViewProjectionMatrix,
/**
 * The view projection matrix. Converts Model space to Clip/Projection
 * space.
 * Type: mat4
 */
ViewProjectionMatrix,</div>
1 Like

please use the [ patch ] code tags

@normen okidoki, :slight_smile:

There’s also a bug in the calculation of WorldMatrixInverse. That’s why I used this line …

[java]v_wsNormal = normalize(mat3(g_WorldMatrix) * inNormal); // object space -> world space[/java]

… to calculate world space normals in my POM shader. I tried to use WorldMatrixInverse before, …

[java]

v_wsNormal = normalize(inNormal * mat3(g_WorldMatrixInverse)); // is the same as …

// v_wsNormal = normalize(mat3(transpose(g_WorldMatrixInverse)) * inNormal); // … this

[/java]

… but it gave me strange results. And since I’m no math genius, I expected the bug between my ears. But sometimes, digging into the depths of the jme3 core pays off.



@Momoko_Fan:[patch]Index: RenderManager.java

— RenderManager.java Base (BASE)

+++ RenderManager.java Locally Modified (Based On LOCAL)

@@ -376,7 +376,7 @@

u.setValue(VarType.Matrix4, tempMat4);

break;

case WorldMatrixInverse:

  •                tempMat4.multLocal(worldMatrix);<br />
    
  •                tempMat4.set(worldMatrix);<br />
    

tempMat4.invertLocal();

u.setValue(VarType.Matrix4, tempMat4);

break;

[/patch]

1 Like

Thanks, it is fixed in SVN