- Home /
Does Unity modify mesh Normals or Vertex before rendering?
Or do I just have a bug in my own code?
I have a special mesh where my vertices are in groups of four. I would like to have a vertex shader that linearly scales so that with scale value of 1.0 all vertices would have orginal positions and with scale value of 0.0 all vertices would be in the center of their groups of four.
To solve this task I have calculated all centers and save offsets to them in Normals array. Then in shader I add them lineary multiplied with [0-1] scaling value.
Problem is that when I scale mesh with Material Property "_Scale" vertices scales toward the center as ment but also toward origo of the mesh. So the whole mesh scales down with _Scale property and it's not intended.
Mesh code:
//tiles:
for (int x = 0; x < currentTileCount; x++)
{
float newT = Mathf.Min(t / offsetOfAnimations.Evaluate(x / (float)currentTileCount), 1f);
tiles[x].CopyVerticesToArray(newT, vertices, x * 4);
tiles[x].CopyTrianglesToArray(4 + x * 4, triangles, x * 6);
tiles[x].CopyColorsToArray(newT, vertexColors, x * 4);
}
//centers as normals
for(int x = 0; x < currentTileCount * 4; x += 4)
{
Vector3 normalAsCenter = (vertices[x + 0] + vertices[x + 1] + vertices[x + 2] + vertices[x + 3]) * 0.25f;
normals[x + 0] = normalAsCenter - vertices[x + 0];
normals[x + 1] = normalAsCenter - vertices[x + 1];
normals[x + 2] = normalAsCenter - vertices[x + 2];
normals[x + 3] = normalAsCenter - vertices[x + 3];
}
mesh.Clear();
mesh.vertices = vertices;
mesh.colors32 = vertexColors;
mesh.triangles = triangles;
mesh.RecalculateNormals();
mesh.normals = normals;
Shader code: (Problem is in vert function)
Shader "NeduTileTales/OpaqueVertexColor"
{
Properties{
_Scale("Scale", Range(0.0,1.0)) = 1.0
}
SubShader
{
Tags{ "RenderType" = "Opaque"}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//#include "UnityCG.cginc"
uniform float _Scale;
struct v2f {
float4 pos : SV_POSITION;
fixed4 color : COLOR;
};
struct appdata {
float4 vertex : POSITION;
float4 color : COLOR;
float4 normal : NORMAL;
};
v2f vert(appdata v)
{
v2f o;
//pos calculations doesn't work as wanted
float4 pos = (v.vertex + v.normal * (1 - _Scale));
o.pos = mul(UNITY_MATRIX_MVP, pos);
o.color = v.color;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
return i.color;
}
ENDCG
}
}
}
Didn't read it all, but: Unity 5 claims to pre-rotate normals to correct them for non-uniformly scaled objects.
Hi, didn't check the code in detail but: if the meshes are small, dynamic batching may merge multiple meshes into one, then changing all the meshes' origin. You can disable this in the Player's settings.
Thank you for your input. Own Reynolds: All objects with this material/shader are uniformly scaled. dns: some of those meshes are small (<100 vertices) and others are kind of big (9000 vertices and 4000 triangles). Actually Unity was batching couple of them and I turned batchin off and it didn't affect on this issue.
I have checked my own code so many times now that I'm pretty sure that my logic should work. So may be Unity does some modifications to my data at some point :( Any work arounds on this?
Answer by tkoknordic · May 27, 2015 at 02:27 PM
My friend looked this issue and had a lucky quess that my vertex positions W-components will go wild when I add a normal to it.
The fix:
Old:
float4 pos = (v.vertex + v.normal * (1 - _Scale));
New:
float4 pos = float4((v.vertex + v.normal * (1 - _Scale)).xyz, v.vertex.w);
Your answer

Follow this Question
Related Questions
Material doesn't have a color property '_Color' 4 Answers
Find all materials using a specific shader 1 Answer
Standard shader WebGL 0 Answers
Animate changing the material 0 Answers
Cutout Material is not showing texture transparency? 0 Answers