Jump to content
  • Advertisement
Sign in to follow this  
Hseptic

Using partial derivatives to light circular waves

This topic is 2321 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm doing an exercise in a book that asks to add ambient, diffuse and specular lighting to an existing demo that animates circular waves over a basic flat grid. My attempt as it stands doesn't seem to work as expected though. Instead of looking circular in tune with the waves themselves, my lighting has a strange moire like pattern to it. I've forgotten most of my calculus, but fortunately the book's exercise spoon feeds me the formula for computing the partial derivatives neccessary for calcuating the vertex normals. The way I understand it, once I compute the partial derivatives, I simply plug them into the tangent vectors u and v and take the cross product to get my vertex normal.

Here is my shader...

// CHAPTER 10 10.12 EXERCISE 6
// LIGHTING SHADER FOR WAVES

uniform extern float4x4 gWorld;
uniform extern float4x4 gWorldInverseTranspose;
uniform extern float4x4 gWVP;
uniform extern float gTime;
uniform extern float4 gAmbientMtrl;
uniform extern float4 gAmbientLight;
uniform extern float4 gDiffuseMtrl;
uniform extern float4 gDiffuseLight;
uniform extern float4 gSpecularMtrl;
uniform extern float4 gSpecularLight;
uniform extern float gSpecularPower;
uniform extern float3 gLightVecW;
uniform extern float3 gEyePosW;
struct OutputVS
{
float4 posH : POSITION0;
float3 normalW : TEXCOORD0;
float3 posW : TEXCOORD1;
};
// Amplitudes
static float a[3] = {0.8f, 0.2f, 0.1};

// Angular wave numbers.
static float k[3] = {1.0, 8.0f, 10.0f};

// Angular frequency.
static float w[3] = {1.0f, 8.0f, 0.6f};

// Phase shifts.
static float p[3] = {0.0f, 1.0f, 2.0f};
float SumOfRadialSineWaves(float x, float z)
{
// Distance of vertex from source of waves (which we set
// as the origin of the local space).
float d = sqrt(x*x + z*z);

// Sum the waves.
float sum = 0.0f;
for(int i = 0; i < 2; ++i)
sum += a*sin(k*d - gTime*w + p);

return sum;
}
void Partials(float x, float z, out float dhOverdx, out float dhOverdz)
{
float d = sqrt(x*x + z*z);
dhOverdx = 0.0f;
dhOverdz = 0.0f;
for(int i = 0; i < 3; ++i)
{
dhOverdx += (a*k*x*cos(k*d - gTime*w + p))/d;
dhOverdz += (a*k*z*cos(k*d - gTime*w + p))/d;
}
}
OutputVS ColorVS(float3 posL : POSITION0, float3 normalL : NORMAL0)
{
// Zero out our output.
OutputVS outVS = (OutputVS)0;

// Get the height of the vertex--the height is given by
// summing sine waves.
posL.y = SumOfRadialSineWaves(posL.x, posL.z);

// calc normal
float derivx;
float derivz;
Partials(posL.x, posL.z, derivx, derivz);

float3 v = float3 (1, derivx, 0);
float3 u = float3 (0, derivz, 1);
normalL = cross(u, v);
// Transform normal to world space.
outVS.normalW = mul(float4(normalL, 0.0f), gWorldInverseTranspose).xyz;
outVS.normalW = normalize(outVS.normalW);
// Transform vertex position to world space.
outVS.posW = mul(float4(posL, 1.0f), gWorld).xyz;
// Transform to homogeneous clip space.
outVS.posH = mul(float4(posL, 1.0f), gWVP);

// Done--return the output.
return outVS;
}
float4 ColorPS(float3 normalW : TEXCOORD0, float3 posW : TEXCOORD1) : COLOR
{
normalW = normalize(normalW);
// Compute the vector from the vertex to the eye position.
float3 toEye = normalize(gEyePosW - posW);

// Compute the reflection vector.
float3 r = reflect(-gLightVecW, normalW);
// Determine how much (if any) specular light makes it into the eye.
float t = pow(max(dot(r, toEye), 0.0f), gSpecularPower);
// Determine the diffuse light intensity that strikes the vertex.
float s = max(dot(gLightVecW, normalW), 0.0f);

// Compute the ambient, diffuse and specular terms separatly.
float3 spec = t*(gSpecularMtrl*gSpecularLight).rgb;
float3 diffuse = s*(gDiffuseMtrl*gDiffuseLight).rgb;
float3 ambient = gAmbientMtrl*gAmbientLight;
return float4(ambient + diffuse + spec, gDiffuseMtrl.a);
}
technique LightedWaveTech
{
pass P0
{
// Specify the vertex and pixel shader associated with this pass.
vertexShader = compile vs_2_0 ColorVS();
pixelShader = compile ps_2_0 ColorPS();
}
}


What am I doing wrong?

Share this post


Link to post
Share on other sites
Advertisement
Please note, this is not homework. I'm simply studying this on my own for fun. So, can anyone help me?

Share this post


Link to post
Share on other sites
If you can post the entire code in a ZIP file and let me know which SDK I need to compile it, I'd be happy to try.

Share this post


Link to post
Share on other sites
Hi, your normal calculation seem correct to me, maybe you are doing something wrong in the pixel shader when calculating the lighting? Can you post some code or executable we can try? What you exactly mean by "a strange moire like pattern". Can you show an image of the result?

Share this post


Link to post
Share on other sites
Here's my project and a screenshot attached. I'm using June 2010 DirectX SDK 9.29.1962

[attachment=9294:mywaves.PNG]
[attachment=9295:ColoredWavesDemo.zip]

Share this post


Link to post
Share on other sites
I see that it's almost right, but it's like one or two axes are being mixed up in the calculation somewhere.

I'm downloading the SDK right now and will play around tonight, if no one else fixes it first.

Share this post


Link to post
Share on other sites
I can't seem to download your ZIP file. The download dies at about 11MB or so.

Is there any chance that you exclude any PCB files in the ZIP file? Apologies. Not sure why the download is failing.

Share this post


Link to post
Share on other sites
Confirmed, download loops at 9.8MB for me, seems to be broken. Did you upload it fully before posting? Don't know why this happens...

Share this post


Link to post
Share on other sites
I couldn't find any files with extension pcb, though I removed a file that was taking way too much space. I'm re-uploading it here.

[attachment=9300:ColoredWavesDemo.zip] Edited by Hseptic

Share this post


Link to post
Share on other sites
Whoops! I only have 5.17MB of space left to upload. Therefore, I cannot post the sdf file that I removed. Why am I only allowed a certain amount of upload space? I'm sorry.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!