- Home /
Unity Shader World/Object Matrix
Hi all,
I'm trying to modify vertex position in the vertex shader, but this code does not work.
float4 temp = mul(_Object2World, v.vertex);
temp = mul(_World2Object,temp);
o.pos = mul(UNITY_MATRIX_MVP, temp);
while o.pos = mul(UNITY_MATRIX_MVP, temp);
does work. Why does multiplying by a matrix and it's inverse break things?
oops. did a big answer and realized I'd misread the question. If its any help, I do this and it works, so the inverse must be working ok when applying to another matrix. Not sure why it wouldn't work in your case.
float4 temp = mul(Object2World, v.vertex) float4x4 VP = mul (UNITY$$anonymous$$ATRIX_$$anonymous$$VP,_World2Object); o.pos = mul (VP, temp);
Answer by PEOWIfjpwoiqjf · Jul 11, 2012 at 05:02 PM
So the issue was that mul(_Object2World, _World2Object) was not the identity matrix. I was able to fix it by multiplying the _World2Object Matrix by unity_Scale.w. Doing this resulted in it half working, with some objects working and some not. I fixed this by changing the scale on the objects that weren't working by +-0.0001 (WTF?). Seems to be mostly a random unity issue.
Answer by Bezzy · Apr 10, 2014 at 10:03 AM
float4 worldPos = mul(_Object2World, v.vertex);
//mess with worldPos.xyz
o.pos = mul(UNITY_MATRIX_VP, worldPos);
Note, that's UNITY_MATRIX_ VP not MVP. So, convert the vertex point from model space to world space, then manipulate, then convert from world space through view/proj to screen space. Boom.
Not sure why _Object2World followed by _World2Object doesn't work right, but this helped me out in Unity 5! I needed to convert to world space, do some manipulation, and then continue to screen space.
Initially, I thought I'd have to do _Object2World, change things, then _World2Object and then multiply by $$anonymous$$VP. But this did the trick nicely!
Oh! Well, when you're doing a vertex shader, you're trying to go from model space all the way to camera space... from the local 3D coordinate system of the model you're rendering to the (sorta) 2D space of the computer screen.
So, _Object2World moves you part way there... from the local coords of the model to the global coords of the world.
_World2Object is doing the opposite. It'll take a world coordinate, and transform it back to the local model coordinates. It's how you take a step backwards.
UNITY_$$anonymous$$ATRIX_VP is the bit that goes from World->Camera coordinates.
Hope this helps.
Answer by DenverCoulson · Sep 29, 2014 at 05:06 AM
Here is a solution that works better than PEOWlfjpwoiqjf's solution (did get me on the right track, thanks!). You still must multiply _World2Object by unity_Scale.w but this should NOT be applied to the bottom right value of the matrix.
Here is an example.
float tmp = _World2Object[3][3];
float4x4 I_Object2World = _World2Object * unity_Scale.w;
I_Object2World[3][3] = tmp;
v.vertex = mul(I_Object2World, pos);
Answer by spalmer · Mar 30, 2015 at 04:35 PM
Well, they removed unity_Scale.w in Unity 5, so that leaves future people stumped. In theory now they should be proper inverses of each other.
Answer by RazHollander13 · Sep 15, 2021 at 03:24 PM
[SOLVED] Had the same problem, the solution was to set the w value to 1.0:
float3 worldPosObject = mul (unity_ObjectToWorld, float4(v.vertex.xyz, 1.0)); // object space to world space
// do stuff in word space
v.vertex = mul (unity_WorldToObject, float4(worldPosObject,1.0)); // world to object space }
Your answer
Follow this Question
Related Questions
CG - Using Matrix as texcoord 1 Answer
Apply a bumped shader on top of a custom vertex shader 1 Answer
How to move vertices up/down randomly in shader. 1 Answer
Add new vertex attributes for a shader,Create vertex attributes 0 Answers
Vertex Displacement Shader Graph With The Camera Moving Issue 1 Answer