- Home /
Where is model space origin in shaderlab?
I have a problem with a shader regarding the origin position in model space. I want to scale an object in the world z axis (world space), so it looks "squashed" in the same plane orientation no matter which rotation the object has. To do that, I convert the point (0,0,0) from model space to world space, and scale its z related to that point. The problem is that the object has its pivot point in its base, so rotation is done from its base, but the scale is applied as if the origin I converted to world space is the object's centroid, so when I rotate it, it displaces in z axis. Shouldn't be model space's origin the object's pivot? If this is not like this, is there any way to get the object's pivot inside the shader, without passing it as an external variable?
Thanks in advance!
Here is the vertex shader: (only vertex, since it's the only thing relevant)
v2f vert (appdata_base v)
{
v2f out;
float4 lOriginWorld = mul(_Object2World, float4(0,0,0,1));
out.pos = mul (_Object2World, v.vertex);
float3 lDistance = out.pos - lOriginWorld;
out.pos.x = lOriginWorld.x + lDistance.x;
out.pos.y = lOriginWorld.y + lDistance.y;
out.pos.z = lOriginWorld.z + lDistance.z * 0.05;
out.pos = mul(UNITY_MATRIX_VP, out.pos);
return out;
}
Is your pivot really at the bottom? You can't use an empty GameObject to shift the pivot. If you use an empty GameObject, the rotation of that object it's part of the ObjectToWorld matrix. So are you sure that the pivot of the mesh itself is at the bottom?
I'm totally sure, what you see in the picture, is the selection of the mesh itself, not an empty GO. Also checked in $$anonymous$$aya, and the pivot is at the bottom
Hi, I think your mesh has too many triangles for the dynamic batching to kick in, but if you have some other objects that share the same material in the scene, maybe it does. It would merge some objects in a single mesh, causing the origin of each mesh to be "lost"/not the same as before.
@dns I don't think that's the case. As you say, the mesh has ~2000 tris, so dynamic batching doesn't apply. Even if it does, I assume shaders doesn't take that batching into account, because otherwise tons of shaders would work in different ways wether batching is acting, or not, and I've never seen this
Ok, it doesn't apply to your case. Yes, I wrote some vertex displacement shaders and dynamic batching caused me lots of trouble because it just merges multiple meshes and you can't rely on the local coordinate anymore. It causes differences only in some vertex shaders so that's why not so much people saw this (and I also saw other complains about this in the "answers" so it's not only me).
Sorry I can't help for your problem, everything seems ok in your code.
Answer by Bunny83 · Jun 15, 2017 at 08:14 PM
Ok since this question got already bumped i quickly created a test case in my UA project. I creates a script that will offset a given mesh at runtime by a fix offset:
// MeshShift.cs
using UnityEngine;
public class MeshShift : MonoBehaviour
{
public Vector3 offset;
void Start()
{
var mf = GetComponent<MeshFilter>();
var mesh = Instantiate(mf.sharedMesh);
mf.sharedMesh = mesh;
var vertices = mesh.vertices;
for(int i = 0; i < vertices.Length; i++)
{
vertices[i] += offset;
}
mesh.vertices = vertices;
}
}
This allowed me to quickly "convert" a mesh and move the origin. I simply used a default cube and offset it by 0.5 on the y-axis. That will make the origin of the mesh being at the bottom center of the cube.
I created a new unlit shader and basically copy& paste the vertex shader. I had to adjust a few names as "out" was an invalid variable name. However the actual functionality is exactly the same. When i test that shader on my shifted cube, everything works as it should:
As you can see the origin of the object stays at the same point after a 70° rotation and the scaling is still applied correctly around that pivot.
Note that positive world-z-axis is to the right. So it's the side view of the cube