- Home /
Surface shader: Wrong lighting when moving vertices
Hi everyone. I'm currently trying to make a shader that rotates the mesh. I have a float as an input that represents the rotation in degrees around the z-axis (so in the picture below the actual rotation (transform.rotation) is still zero in both cases).
By the way, I'm using the Strumpy Shader Editor and am not very experienced with shaders in general. I also uploaded my graphs
The problem is that the light coming from a directional light somehow rotates with the mesh (can't explain it better) and the light of the point light acts weird, too.
What am I missing here?
Answer by Owen-Reynolds · Aug 05, 2011 at 07:00 PM
If you are literally moving the verts in the mesh, then you need to recalculate the normals (Mesh.RecalculateNormals is a built-in, if you don't want to do it by hand.) The thing is, if you are only rotating the verts, then why not just rotate the model? Everything is set up to do the math for you when you use Transform.rotate.
The shader has no good way of knowing which way a face is "aimed," so we tell it with normals. For example, normals on the "top" verts are pre-made pointing upish. If you twist the verts around so that your top verts are now facing forwards, those normals still say the face counts as pointing up, so lights wrong (and the new top still counts as pointing backwards.)
But why don't all rotated models light wrong? When you spin a model overall, using the rotation, that rotation is sent to the shader. The auto-part of the surface shader knows how to fix the normals based on rotation. So, surface shaders work fine with rotated models, they expect it and even calculate the "fixed" normals for a non-rotated model. FYI, original normals are modelView and fixed ones are worldView (if you have to look these things up.)
If all you are doing is a rotate on verts, and you can't rotate the whole model, you'll need to also rotate the normals by the same angle (could also use recalNorms, but it does the same thing, slower, since it starts from scratch.)
Thank's for the explanation. It was more or less an experiment and for learning purposes. For example, if I had about 200 wheels that should all be rotated I could - of course - call Rotate() on everyone - or just set one float value for the material they are all sharing. That's why I did that :D