// Declare pixel shader version ps.1.1 // Define a few masks and biasing values for putting things // in the right place def c3, 0.5, 0.0, 0.0, 0.0 def c4, 0.0, 1.0, 1.0, 1.0 def c5, 1.0, 0.0, 0.0, 0.0 def c6, 0.0, 0.0, 1.0, 0.0 def c7, 0.5, 0.5, 0.5, 0.5 // Constant to determine equilibrium position // A gentle force pulls the blue and alpha to this // value. // Height must be in blue and alpha components // Red = force // green = velocity // Get colors from all 4 texture stages // A vertex shader sets up texture coordinates so that the sampled // texels are the following for the pixel being rendered: // // t0 = texel at coordinate we are rendering to, and for which // we are computing the force. // t1 = 1st neighbor to the t0 texel // t2 = 2nd neighbor // t3 = 3rd neighbor tex t0 tex t1 tex t2 tex t3 sub r0.rgb, t1, t0 // Diff between 1st neighbor and center texel + sub r0.a, t2.b, t0.b // Diff between 2nd neighbor and center texel // Use blue replicate to move blue into alpha // as the alpha might be dirty from a previous // alpha blend //@@ + sub r0.a, t2.a, t0.a // Diff between 2nd neighbor and center texel // c7 - t0 sub r1.rgb, c7, t0 // Force to pull t0 center to the c7 equilibrium value + sub r1.a, t3.b, t0.b // Diff between 3rd neighbor and center texel to .a // Use blue replicate to move blue into alpha // as the alpha might be dirty from a previous // alpha blend //@@ + sub r1.a, t3.a, t0.a // Diff between 3rd neighbor and center texel to .a // Multiply r1.rgb by PCN_EQ_REST_FAC, and add it to the r0.rgb // Also add the .a components with no scaling factor -- all neighbor differences // scale the same. // Reason for multiplying by PCN_EQ_REST_FAC is to vary the strength of the // force pulling the center position to the value defined in c7 mad r1.rgb, r1, c[2], r0 // scale the equilibrium restore force + add r1.a, r1.a, r0.a // Add 3rd neighbor diff to 2nd neighbor diff // Add the force components in alpha to the force components in blue add r1, r1, r1.a // r1 = r1.rgba + r1.aaaa // Blue now holds the correct total 'force' before // biasing to the unsigned range. // Replicate blue to rgba with a dp3 // This is to move the total force into the red component so we can // store it in the texture render target. dp3 r1.rgba, r1, c6 // Mask force to red only, and add 0.5 red to bias the signed // force value up to center about 0.5. This is so we can store // the force value in the unsigned bits of the texture target mad r1.rgba, r1, c5, c3 // Mask off red of t0 source and put the r1 force result into red. // This carries forward the t0 position (blue,alpha) and velocity (green) // to the next stage // The output contains ( 0, t0.g, t0.b, t0.a ) + ( r1.r, 0, 0, 0 ) mad r0.rgba, t0, c4, r1