- Home /
Vertex position problem in vertex shader
I am having strange problems in shaders with procedurally generated mesh. My actual scenario is a little bit complicated but I managed to track it down to following:
Create square mesh with 4 vertices (-10, -10), (-10, 10), (10, 10) and (10, -10)
Apply a material with fragment shader which simply uses x-coordinate of vertex for color output
for some reason vertex positions in fragment shader are not in range from -10 to 10 but from 0 to 1 instead!
Illustration of expected result (lots > of full black & full white)
Illustration of actual result (smooth > fade from black to white, why?
I would expect result to be like shown in first image because vertex position (both local position and world position since it doesn't have rotation, scale or transform at all) goes from -10 to 10, resulting in all black when value is from -10 to 0, smooth fade when value is 0 to 1, and full white when value is 1 to 10. However, the result is like the vertex position would simply go from 0 to 1. Why is that? (I have done lots of 3D programming with pure OpenGL and DirectX so I know the basics of rendering pipeline, and this behavior seems very odd for me)
I use following piece of code to generate mesh:
Mesh mesh = new Mesh ();
GetComponent<MeshFilter>().mesh = mesh;
float w = 10.0f;
float h = 10.0f;
Vector3[] vertices = new Vector3[4];
vertices[0] = new Vector3(-w, -h, 0);
vertices[1] = new Vector3(-w, h, 0);
vertices[2] = new Vector3( w, h, 0);
vertices[3] = new Vector3( w, -h, 0);
int[] indices = new int[6];
indices[0] = 0;
indices[1] = 1;
indices[2] = 2;
indices[3] = 2;
indices[4] = 3;
indices[5] = 0;
mesh.vertices = vertices;
mesh.triangles = indices;
Shader is following:
Shader "Custom/LightShader" {
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float4 vpos : COLOR0;
};
v2f vert (appdata_base v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.vpos = v.vertex;
//o.vpos = mul (_Object2World, v.vertex); // doesn't matter if I use this one - the result will be same
return o;
}
half4 frag (v2f i) : COLOR
{
float d = i.vpos.x;
return half4 (d,d,d,1);
}
ENDCG
}
}
Fallback "VertexLit"
}
Hi sahaaja. I think I'm seeing the same or very similar issue as you.
The values co$$anonymous$$g into the vertex shader don't seem to be in the local space of the model, as all of my experience tells me they should be. If I create a bunch of instances of a really simple custom mesh (defined with vertices in the range of 0.0-1.0) and then pass the raw vertex position through to the fragment shader to be used as the colour (not the $$anonymous$$VP transformed ones, of course), the colours of the meshes vary across the world as if they're already in world space.
I would expect that each mesh should be coloured the same way since they should have local position coords that should be equal to each other.
$$anonymous$$y normal data is being transformed the same way (and I'm actually trying to pass in vertex-specific data using the normals so I really don't want the data messed with before it hits the vertex shader). The uvs aren't being transformed so I may end up just using them for this data..
I don't see anything in the Unity docs that would suggest any pre-transforms being done to the vertex data in Unity. Can anyone shed any light on this?