Juggler
This sample displays a site-swap juggling pattern with animation done by a vertex shader.
1 Hand
2 Hands
3 Hands
4 Hands
Animate
Pair Hands
// the 4x4 world view projection matrix float4x4 worldViewProjection : WorldViewProjection; // positions of the light and camera float3 light_pos; float3 camera_pos; // phong lighting properties of the material float4 light_ambient; float4 light_diffuse; float4 light_specular; // shininess of the material (for specular lighting) float shininess; // time for animation float time; // coefficients for a t^2 + b t + c for each of x, y, z float3 coeff_a; float3 coeff_b; float3 coeff_c; // flag and coefficient for optional LERP with rate t * coeff_lerp; float coeff_lerp; // coefficients for a t^2 + b t + c for each of x, y, z, for optional LERP float3 coeff_l_a; float3 coeff_l_b; float3 coeff_l_c; // coefficients for d sin(f t) + e cos(e t) for each of x, y, z float3 coeff_d; float3 coeff_e; float3 coeff_f; // to be subtracted from time to get the t for the above equation float time_base; // input parameters for our vertex shader struct VertexShaderInput { float4 position : POSITION; float3 normal : NORMAL; float4 color : COLOR; }; // input parameters for our pixel shader // also the output parameters for our vertex shader struct PixelShaderInput { float4 position : POSITION; float3 lightVector : TEXCOORD0; float3 normal : TEXCOORD1; float3 viewPosition : TEXCOORD2; float4 color : COLOR; }; /** * Vertex Shader - vertex shader for phong illumination */ PixelShaderInput vertexShaderFunction(VertexShaderInput input) { /** * We use the standard phong illumination equation here. * We restrict (clamp) the dot products so that we * don't get any negative values. * All vectors are normalized for proper calculations. * * The output color is the summation of the * ambient, diffuse, and specular contributions. * * Note that we have to transform each vertex and normal * by the world view projection matrix first. */ PixelShaderInput output; float t = time - time_base; float3 offset = float3(0, 0, 0); offset += t * t * coeff_a + t * coeff_b + coeff_c; offset += coeff_d * sin(t * coeff_f); offset += coeff_e * cos(t * coeff_f); float3 lerpOffset = t * t * coeff_l_a + t * coeff_l_b + coeff_l_c; if (coeff_lerp > 0) { float rate = min(coeff_lerp * t, 1); float3 lerpVector = float3(rate, rate, rate); offset = lerp(offset, lerpOffset, lerpVector); } else if (coeff_lerp < 0) { float rate = min(-coeff_lerp * t, 1); float3 lerpVector = float3(rate, rate, rate); offset = lerp(lerpOffset, offset, lerpVector); } input.position = input.position + float4(offset.xyz, 0); output.position = mul(input.position, worldViewProjection); /** * lightVector - light vector * normal - normal vector * viewPosition - view vector (from camera) */ // NOTE: In this case we do not need to multiply by any matrices since the // WORLD transformation matrix is the identity. If you were moving the // object such that the WORLD transform matrix was not the identity, you // would need to multiply the normal by the WORLDINVERSETTRANSFORM matrix // since the normal is in object space. Other values (light_pos, camera_pos) // are already in world space. float3 lightVector = light_pos - input.position.xyz; float3 normal = input.normal; float3 viewPosition = camera_pos - input.position.xyz; output.lightVector = lightVector; output.normal = normal; output.viewPosition = viewPosition; output.color = input.color; return output; } /** * Pixel Shader */ float4 pixelShaderFunction(PixelShaderInput input): COLOR { float3 lightVector = normalize(input.lightVector); float3 normal = normalize(input.normal); float3 viewPosition = normalize(input.viewPosition); float3 halfVector = normalize(lightVector + viewPosition); // use lit function to calculate phong shading // x component contains the ambient coefficient // y component contains the diffuse coefficient: // max(dot(normal, lightVector),0) // z component contains the specular coefficient: // dot(normal, lightVector) < 0 || dot(normal, halfVector) < 0 ? // 0 : pow(dot(normal, halfVector), shininess) // NOTE: This is actually Blinn-Phong shading, not Phong shading // which would use the reflection vector instead of the half vector float4 phong_coeff = lit(dot(normal, lightVector), dot(normal, halfVector), shininess); float4 ambient = light_ambient * phong_coeff.x * input.color; float4 diffuse = light_diffuse * phong_coeff.y * input.color; float4 specular = light_specular * phong_coeff.z * input.color; return ambient + diffuse + specular; } // Here we tell our effect file *which* functions are // our vertex and pixel shaders. // #o3d VertexShaderEntryPoint vertexShaderFunction // #o3d PixelShaderEntryPoint pixelShaderFunction // #o3d MatrixLoadOrder RowMajor