I'm trying to create a vertex shader that produces a waving flag. I got the vertex positions going fine, but I'm having trouble adjusting the NORMALS to be what they should be in a waving flag. I did a little kludge, but it works from only SOME angles.
Here is the pertinent vertex shader code:
vec4 aPos=input_XYZ;
float aTime=(uniform_timer/75.)*7.;
aPos.y+=sin(aTime)*.15f*input.XYZ.x; // The wave
output_XYZ=aPos*uniform_ComboMatrix; // Into scene space
vec4 aWorkNormal=input_Normal;
aWorkNormal.y+=sin(aTime)*.25f; // <-- Here's the kludge to inexpensively tip the normal into the "wave" pattern
output_Normal=aWorkNormal*uniform_NormalizedWorldMatrix; // Put into same space as the light's vector
So I want to lose the kludge and actually give it the correct normal for flag waving... what's the right way to transform/rotate a normal on a waving flag to point correctly after the y position is modifier by sin?
The transformation you apply to aPos
is a linear one, which can be described by the matrix:
[ 1 0 0 ]
M = [ C 1 0 ]
[ 0 0 1 ]
C = sin(aTime)*0.15
The normals then need to be transformed by the matrix W = transpose(inverse(M))
:
[ 1 -C 0 ]
W = [ 0 1 0 ]
[ 0 0 1 ]
Turning it back into code:
vec4 aWorkNormal = input_Normal;
aWorkNormal.x -= sin(aTime)*.15f*aWorkNormal.y;