I’ve started working on a unity scene that’s going to involve a bit of shader, modelling and vfx work.

Today I worked on the foliage vertex shader. Its a pretty simple shader, with a sine wave doing a little wobble and two colour inputs to create a gradated albedo. I picked up a couple of nice things on how to recalculate lighting and normal information from this tutorial by Hugo Scott-Slade.

Getting correct light info is actually very simple – you just need to add vertex:vert addshadow to your pragma. Initially I had it as vertex: vert and nothing worked, so worth noting that the lack of space is important!

To recalculate the normals, I started with a function that returns the new position that the vertex is going to be in.

I used this function with the vertex plus the tangent, then the vertex plus the bitangent, to approximate what the new tangent and bitanget will be.

The appdata_full struct provided me with the tangent, and I got the bitangent by crossing the tangent and the normal.

Once I had the new tangent and bitangents, I crossed them to get the new normal and set that as the vert’s normal.

//creates new verts to approximate new position for normal recalculation

float3 getNewVertPosition(float3 p, float vertexColor) {
p.x += (sin(_Time.y * _SpeedX + p.y) * _AmountX) * vertexColor;
p.y += (sin(_Time.y * _SpeedY + p.y) * _AmountY) * vertexColor;
p.z += (sin(_Time.y * _SpeedZ + p.y) * _AmountZ) * vertexColor;
return p;
}

void vert (inout appdata_full v) {

//Change Vert Normal

float3 bitangent = cross(v.normal, v.tangent);
float3 position = getNewVertPosition(v.vertex, v.color.r);
float3 positionTangent = getNewVertPosition(v.vertex + v.tangent * 0.01, v.color.r);
float3 positionBitangent = getNewVertPosition(v.vertex + bitangent * 0.01, v.color.r);

float3 newTangent = positionTangent – position;
float3 newBitangent = positionBitangent – position;

float3 newNormal = cross(newTangent, newBitangent);
v.normal = newNormal;