GPU based spherical harmonics
I did this code a long time ago, however I was asked to post it online so here it is.
The code takes a sphere mesh and distorts the points based on a four by two matrix and the following equation.
The code takes a sphere mesh and distorts the points based on a four by two matrix and the following equation.
float3 Eval(float theta, float phi) { float r = 0; float3 p = float3(0, 0, 0); r += pow(sin(M[0] * phi), M[1]); r += pow(cos(M[2] * phi), M[3]); r += pow(sin(M[4] * theta), M[5]); r += pow(cos(M[6] * theta), M[7]); p.x = (r * sin(phi) * cos(theta)); p.y = (r * cos(phi)); p.z = (r * sin(phi) * sin(theta)); return (p); }
The vertex shader feeds the vertex's texture coordinates into this equation to work out the position of the vertex.
It then does an approximation of the surface normal by calculating two more points either side of the current point.
It then does an approximation of the surface normal by calculating two more points either side of the current point.
VertexShaderOutput VertexShaderFunction(VertexShaderInput input) { VertexShaderOutput output; float u = 2*3.141597*input.TexCoord.x; float v = 3.141597*input.TexCoord.y; float3 p1 = Eval(u,v); float3 p2 = Eval(u+0.0245,v); float3 p3 = Eval(u,v+0.0245); p2=p1-p2; p3=p1-p3; p2=cross(p2,p3); float4 worldPosition = mul(float4(p1,1), World); float4 viewPosition = mul(worldPosition, View); output.Position = mul(viewPosition, Projection); output.Normal = normalize(mul(p2,World)); output.Light = normalize(LightDirection); output.Color = length(p1)/2; return output; }
That's it really, it's not very complex.
Have fun.
Have fun.
sphericalharmonics.zip | |
File Size: | 26 kb |
File Type: | zip |