[Solved] How to get only the world scale in a Shader

I am working on a custom shader, and I need to define a varying vec3 that represents the world position of each vertex without factoring in the world translation or world rotation (so I only want to know the world scale of the model in the .vert shader), but I am having trouble figuring out how to get this value.

A bit more info on what exactly I need to do this for:

I need this vec3 in order to generate a 3D noise value - and I cannot use the vertex coordinates once they have been fully transformed into world sapce, otherwise the return value of the noise equation fluctuates for every pixel as the model is translated or rotated with java code. I also cannot use the modelSpacePos before applying the WorldTransformMatrix, because many of my models using this shader were created by different artists at different scales in blender, and thus the Identity scale of each mesh varies, which also leads to inconsistent visual appearances between different models using the shader.

idk about shader solution(since inPosition is after transform as i know), but i see Java/shader solution.

Cant you send to shader this “before world parsed” coord via textCoord2 or 3 whatever?
there you have r,g,b,a so r,g,b can be x,y,z?

while for textCoord2 for certain verticle you just set this x,y,z in java. so you can read local space(before transforms) for this verticle too.

I need to define a varying vec3 that represents the world position of each vertex without factoring in the world translation or world rotation

ah sorry, i think i get you wrong,

but if you want world position for verticles why not just add Geom position + inPosition?

attribute vec3 inPosition;

i belive its after java transforms(except location), right?

myself i were using it for “grass wind effect”

while later it is used:

gl_Position = TransformWorldViewProjection(modelSpacePos); // inPosition == modelSpacePos

still, if i tell stupid things, dont listen me, because i could not understand what you want exactly to do :slight_smile: just trying to help.

That is true, I could just send over the world scale as a uniform when the spatial is loaded.

Although that could add an extra step for someone else to make a mistake while loading in a spatial using the shader, so it would be more desirable to do all of the code in the shader

This works for most of my shaders that use noise, but for this unique case, I do not want the full world position, I only want to know the world scale.

So I’m hoping to learn how I can figure out which part of the WorldMatrix contains the scale. I am not very good with matrix math, but from my understanding, the value mat4 g_WorldMatrix contains the location, rotation, and scale of the model, and can be multiplied by the inPosition value to put the vertices into world space, equivalent to the method TransformWorld(inPosition) - but I do not know which part of the this g_WorldMatrix value contains the vec3 that represents only the scale.

1 Like

i understand, so you need matrix calculation to get simple vec3 float for just world scale.

didnt knew it is hidden there, good to know.

Well i had matrix calculations on study, but it was long time ago and i dont remember much too :rofl:

i found something from unity shader, but idk if it will help:

half3 ObjectScale() {
return half3(
    length(unity_ObjectToWorld._m00_m10_m20),
    length(unity_ObjectToWorld._m01_m11_m21),
    length(unity_ObjectToWorld._m02_m12_m22)
);
1 Like

Same here haha, I only took one calculus course in school, and I was a business major at the time, so I despised learning matrix math, and I immediately forgot everything about matrices after passing the class with the bare minimum grade. Now here I am working on game dev, wishing I had paid more attention and taken more math courses :laughing:

Yes I noticed that the only thing I can find is related to Unity, when I google “how to get the world scale in glsl shader” .

But I do not know what the equivalent code would be in JME unfortunately.

but hey, since we know “location before scale” and “location after scale”

cant we just a/b and have scale for each x,y,z?

well, i understand if there were “rotations” it would be wrong anyway.

Hmmm I think that could work, although I believe that would still return different values if the model is rotated. So I think I would still need to invert the rotation to get a consistent value during rotation.

Doesnt a Transform contain a scale?

Yes there is a .getScale() method for the java Transform object. Is there a way to get a Transform in the .vert shader though? As far as I have found, I can only get the full world matrix in the shader.

well, you can do it just via sending new MaterialDefinition field for it and setting it via java.

“Vector3 Scale” in material definition
“uniform vec3 m_Scale” in vertex shader
.setVector3(“Scale”, transform.getScale()) (or similar name) in java

but i belive you know it all, so idk why you ask :smiley:

sometimes solution is very easy, but people like us search hard ways…

or maybe there is reason why you cant do it this way?

@yaRnMcDonuts

is this ok, or do you need avoid uniforms?

Sending the value as a uniform ened up working okay for this situation, I just finished changing my code and got things working.

In this situation, the shader is used exclusively by the NPCs and players in my game, who conveniently all share a parent class - so I was able pass the value as a uniform in a parent method, so now the worldScale uniform will be assigned automatically for any newly loaded spatials in the parent.

It would still be useful to know how to get the WorldScale from the world matrix in the shader, but it seems as though there isn’t any simple copy/paste solution out there to learn from like I was hoping for :laughing: Doing it all in the shader would definitely be the cleaner approach

A transform matrix has the scale built into it… as you’ve already discovered. Regarding the unity example, it’s not about “translating to JME” it’s about “transating to GLSL”.

…but it’s pretty trivial to extract the matrix components from a GLSL matrix, so I’m not sure what part is giving you trouble.

i belive "pretty trivial " part :smiley: that you could provide already.

Unfortunately, trivial matrix math is still confusing to me :laughing:

I tried googling it a lot, and I can understand how it is simple to get the location from the World Matrix.

But I’m struggling with the scale part.

I would have to lookup GLSL docs about matrix3… which you all could do just as easily.

…which you haven’t.

? why do you think so. if you know proper document, its your knowledge about document itself.

for you note, i spend myself 15 minutes looking how to extract scale from this matrix, no info found, and when found, it was Unity info.

Above, you have the exact matrix elements to lookup… but you guys haven’t figured out how to look matrix elements up in a GLSL matrix.

…so you haven’t looked at GLSL matrix3 docs.

Here, I’ll walk you right to it in 2 seconds of google searching:
https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)

Scroll down to the matrix section. See if you can figure out how to translate m01 to a GLSL matrix element reference.

Why you can do this is a 3D math problem. A matrix3 transform is the three axes vectors in the new coordinate space. So taking the length of any of those axes will show you the scale of x, y, or z respectively.

1 Like