Comments and answers for "Get local position in surface shader"
http://answers.unity.com/questions/561900/get-local-position-in-surface-shader.html
The latest comments and answers for the question "Get local position in surface shader"Comment by Arwahanoth on Arwahanoth's comment
http://answers.unity.com/comments/1698189/view.html
Long time not used Unity but if I take you're advice the code should be:
float3 localPos = mul(unity_WorldToObject, IN.worldPos);
struct Input {
/// [....]
float4 worldPos;
};
Right?Sat, 08 Feb 2020 18:26:08 GMTArwahanothComment by Bunny83 on Bunny83's answer
http://answers.unity.com/comments/1697763/view.html
This does only work in very special cases. Your object must **not be scaled** and must **not be rotated** in any way. Otherwise your result is completely wrong. Also using a matrix multiplication to get the last column of a matrix is just a waste of GPU power.
float3 pos = unity_ObjectToWorld._m03_m13_m23;
This will get the x,y and z of the last column. The best solution is to just pass the local space position along in the vertex shader. Note that a surface shader will still compile a vertex and a fragment shader anyways. It's just a fancy highlevel way to write shaders. If you really need to convert the worldspace position back to local space, use the `unity_WorldToObject` matrix ins$$anonymous$$d
float3 localPos = mul(unity_WorldToObject, IN.worldPos);
$$anonymous$$eep in mind that worldPos need to be a `float4`, **not** a float3. We're dealing with homogeneous coordinates here. Alternatively you can use something like
float3 localPos = mul(unity_WorldToObject, float4(IN.worldPos, 1));Fri, 07 Feb 2020 09:43:55 GMTBunny83Comment by Nearo1 on Nearo1's answer
http://answers.unity.com/comments/1697738/view.html
This way is a good way, to consider the scale,Fri, 07 Feb 2020 07:27:25 GMTNearo1Comment by Arwahanoth on Arwahanoth's comment
http://answers.unity.com/comments/1487624/view.html
Thanks for the explanation I am a little bit rusty. And btw since it is a local position we could probably use a half3 localPos ins$$anonymous$$d of float3 for optimization sake.Sat, 31 Mar 2018 10:55:36 GMTArwahanothComment by ahung89 on ahung89's comment
http://answers.unity.com/comments/1486988/view.html
It's doing a matrix multiplication of (0, 0, 0, 1) with the object's model matrix. An object's model matrix = the matrix that you multiply with to convert things from the object's local space into world space. The columns of that matrix contain the X, Y, and Z axes of the object's local space. These columns contain information about the scale, rotation, and translation of the object. For example if the object has a scale of 2 in the x-direction but has no rotation, then its first column will be (2, 0, 0). The fourth column contains translation - so if the object is positioned at (2, 4, 6) in world space, the last column will contain (2, 4, 6). The fourth column is what's important here - since (0, 0, 0, 1) has a 1 in the fourth column and a 0 everywhere else, the final result of the matrix multiplication will just be the translation value from the object's model matrix. In other words, the result of the multiplication will just be the GameObject's position in world space (the same thing you'd get from transform.position).
I recommend this article to learn more about how matrix multiplication works: https://learnopengl.com/Getting-started/Transformations - there's a lot more detail to it than I can fully explain in this reply, but this is the gist of it. I definitely recommend reading that article and learning the subject deeply though. It will make shader and graphics code a lot easier to understand.Thu, 29 Mar 2018 14:48:11 GMTahung89Comment by mani3307 on mani3307's comment
http://answers.unity.com/comments/1486917/view.html
Can you clearly explain to me how mul(unity_ObjectToWorld, float4(0,0,0,1)).xyz works?Thu, 29 Mar 2018 10:13:49 GMTmani3307Comment by ahung89 on ahung89's comment
http://answers.unity.com/comments/1486869/view.html
He's converting the origin of the *object*, which is by definition (0, 0, 0) in its local space, into world space. Then he's subtracting that from IN.worldPos (which is the interpolated world position of the fragment) in order to get the difference between the fragment and the origin of the object. The difference between the fragment's position and the object's origin = its local position.
This is sometimes better than just getting the local position directly from the vertex shader input (via the POSITION semantic) because imported 3d models are often rotated, so the object's local axes won't be aligned with the world space axes.Thu, 29 Mar 2018 06:21:39 GMTahung89Comment by mani3307 on mani3307's answer
http://answers.unity.com/comments/1485384/view.html
Can you explain me what you are doing in the first line codeMon, 26 Mar 2018 08:23:41 GMTmani3307Comment by chuckbergeron on chuckbergeron's answer
http://answers.unity.com/comments/1320299/view.html
Thanks for this addition! It kicked ass for me. Fixed the weird model import "what is y/up?" problem above. :)Wed, 01 Mar 2017 21:12:49 GMTchuckbergeronAnswer by Arwahanoth
http://answers.unity.com/answers/1275441/view.html
In fact I just discovered that we don't need the "vert" and we could do it only in "surf" with:
float3 localPos = IN.worldPos - mul(unity_ObjectToWorld, float4(0,0,0,1)).xyz;
Don't forget to declare worldPos in Input:
struct Input {
/// [....]
float3 worldPos;
};Wed, 23 Nov 2016 18:25:11 GMTArwahanothComment by MaT227 on MaT227's answer
http://answers.unity.com/comments/628746/view.html
It works well !
**BUT**, what about objects with different axis. It's always the same problem with axis in different applications (3DSMax, Unity, Maya, Blender, etc...) wen you import them.
Is there a way to correct that in the shader ?Thu, 30 Jan 2014 20:24:53 GMTMaT227Answer by tanoshimi
http://answers.unity.com/answers/561928/view.html
Untested, but here's an idea:
First, add a member to your Input structure:
struct Input {
float2 uv_MainTex;
float3 localPos;
};
Then add a vertex modifier function that populates the localPos member with the vertex information from appdata:
#pragma surface surf Lambert vertex:vert
void vert (inout appdata_full v, out Input o) {
UNITY_INITIALIZE_OUTPUT(Input,o);
o.localPos = v.vertex.xyz;
}
Now in your surf function you should be able to access IN.localPos as:
void surf (Input IN, inout SurfaceOutput o) {
// Do something with IN.localPos....
}Wed, 23 Oct 2013 19:12:32 GMTtanoshimi