Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
WaveSurface.vsh
!!ARBvp1.0 |
ATTRIB vertexPosition = vertex.position; |
ATTRIB vertexTexcoord = vertex.texcoord; |
# Get simTime as a environment value |
PARAM simTime = program.env[0]; |
PARAM EmitterPosX = { 0, 100, 200, 0}; |
PARAM EmitterPosY = { 0, 60, 150, 50}; |
PARAM EmitterAmp = { 5, 8, 3, 2}; |
PARAM EmitterFreq = { 1.2, 0.8, 0.3, 2.0}; |
PARAM EmitterDecay = { 20, 40, 10, 20}; |
# some standard and custom parameters that follow me around |
PARAM negOne = {-1.0, -1.0, -1.0, -1.0}; |
PARAM epsilon = { 5.0E-6, 5.0E-6, 5.0E-6, 5.0E-6}; |
PARAM ptOne = { 0.1, 0.1, 0.1, 0.1}; |
PARAM one = { 1.0, 1.0, 1.0, 1.0}; |
PARAM _Pi = { 3.1415926535, 3.1415926535, 3.1415926535, 3.1415926535}; |
PARAM invPi = { 0.3183098861, 0.3183098861, 0.3183098861, 0.3183098861}; |
PARAM _2Pi = { 6.2831853071, 6.2831853071, 6.2831853071, 6.2831853071}; |
PARAM inv2Pi = { 0.1591549439, 0.1591549439, 0.1591549439, 0.1591549439}; |
PARAM ten = { 10, 10, 10, 10}; |
# Factorial table for computing cosine and exp using sum of products functions |
PARAM InvFact_2 = { 2, -2, 0.500000000000000, -0.500000000000000}; |
PARAM InvFact_3 = { 6, -6, 0.166666666666667, -0.166666666666667}; |
PARAM InvFact_4 = { 24, -24, 0.041666666666667, -0.041666666666667}; |
PARAM InvFact_5 = { 120, -120, 0.008333333333333, -0.008333333333333}; |
PARAM InvFact_6 = { 720, -720, 0.001388888888889, -0.001388888888889}; |
PARAM InvFact_7 = { 5040, -5040, 1.98412698413e-04, -1.98412698413e-04}; |
PARAM InvFact_8 = { 40320, -40320, 2.48015873016e-05, -2.48015873016e-05}; |
PARAM InvFact_10 = { 3.6288e06, -3.6288e06, 2.75573192240e-07, -2.75573192240e-07}; |
PARAM InvFact_12 = { 4.79002e08, -4.79002e08, 2.08767569879e-09, -2.08767569879e-09}; |
PARAM InvFact_14 = { 8.71783e10, -8.71783e10, 1.14707455977e-11, -1.14707455977e-11}; |
PARAM InvFact_16 = { 2.09228e13, -2.09228e13, 4.77947733239e-14, -4.77947733239e-14}; |
PARAM select = {1, 0, 0, 0}; |
TEMP dist, cos, exp, pos, temp0, temp1, temp2, temp3; |
# compute distance from emitter |
# xVec = vec_sub(emitterX[k], vec_ld(0, (vector float *)&xPos[ii + j])); |
# yVec = vec_sub(emitterY[k], vec_ld(0, (vector float *)&yPos[ii + j])); |
MAD temp0, negOne, vertexPosition.xxxx, EmitterPosX; # temp0 = Emitter.position.x - position.x |
MAD temp1, negOne, vertexPosition.yyyy, EmitterPosY; # temp1 = Emitter.position.y - position.y |
# dist = sqrt(x*x + y*y) * 0.1; |
MUL temp0, temp0, temp0; |
MUL temp1, temp1, temp1; |
ADD dist, temp0, temp1; |
RSQ temp0, dist.x; |
RSQ temp1, dist.y; |
RSQ temp2, dist.z; |
RSQ temp3, dist.w; |
RCP temp0, temp0.x; # temp0 = dist0 |
RCP temp1, temp1.x; # temp1 = dist1 |
RCP temp2, temp2.x; # temp2 = dist2 |
RCP temp3, temp3.x; # temp3 = dist3 |
# put temp0, temp1, temp2 and temp3 into temp0.xyzw |
MUL temp0, temp0, select.xwww; |
MAD temp0, temp1, select.wxww, temp0; |
MAD temp0, temp2, select.wwxw, temp0; |
MAD temp0, temp3, select.wwwx, temp0; |
# temp0 = dist * 0.1 |
MUL dist, temp0, ptOne; |
# this is the emitter function we have to compute |
# z += amp * cos(freq * dist + sim_time) / exp(decay / dist); |
# compute freq * dist + sim_time |
MAD temp0, EmitterFreq, dist, simTime.xxxx; |
# bound tempVec to 0 <-> 2 pi |
MUL temp0, temp0, inv2Pi; # div by 2 Pi |
FRC temp0, temp0; # take frational result (opposite of mod) |
MUL temp0, temp0, _2Pi; # mult fractional result by 2 Pi to get bounded value |
# temp0 is now between -pi and pi |
# compute cos(freq * dist + sim_time) |
# Cos = sum (-1)^n*x^2n/2n! |
# compute sum of products for cos(freq * dist + sim_time) |
MUL temp1, temp0, temp0; # temp1 = x^2; |
MAD cos, InvFact_2.wwww, temp1, one; # cos = 1 - 1/fact(2)*x^2 |
MUL temp0, temp1, temp1; # temp0 = x^4, temp1 = x^2; |
MAD cos, InvFact_4.zzzz, temp0, cos; # cos = 1 - 1/fact(2)*x^2 + 1/fact(4)*x^4 |
MUL temp0, temp0, temp1; # temp0 = x^6, temp1 = x^2; |
MAD cos, InvFact_6.wwww, temp0, cos; # cos = 1 - 1/fact(2)*x^2 + 1/fact(4)*x^4 - 1/fact(6)*x^6 |
MUL temp0, temp0, temp1; # temp0 = x^8, temp1 = x^2; |
MAD cos, InvFact_8.zzzz, temp0, cos; # cos = 1 - 1/fact(2)*x^2 + 1/fact(4)*x^4 - 1/fact(6)*x^6 + 1/fact(8)*x^8 |
MUL temp0, temp0, temp1; # temp0 = x^10, temp1 = x^2; |
MAD cos, InvFact_10.wwww, temp0, cos; # cos = 1 - 1/fact(2)*x^2 + 1/fact(4)*x^4 - 1/fact(6)*x^6 + 1/fact(8)*x^8 - 1/fact(10)*x^10 |
MUL temp0, temp0, temp1; # temp0 = x^12, temp1 = x^2; |
MAD cos, InvFact_12.zzzz, temp0, cos; # cos = 1 - 1/fact(2)*x^2 + 1/fact(4)*x^4 - 1/fact(6)*x^6 + 1/fact(8)*x^8 - 1/fact(10)*x^10 + |
# 1/fact(12)*x^12 |
MUL temp0, temp0, temp1; # temp0 = x^14, temp1 = x^2; |
MAD cos, InvFact_14.wwww, temp0, cos; # cos = 1 - 1/fact(2)*x^2 + 1/fact(4)*x^4 - 1/fact(6)*x^6 + 1/fact(8)*x^8 - 1/fact(10)*x^10 + |
# 1/fact(12)*x^12 - 1/fact(14)*x^14 |
MUL temp0, temp0, temp1; # temp0 = x^16, temp1 = x^2; |
MAD cos, InvFact_16.zzzz, temp0, cos; # cos = 1 - 1/fact(2)*x^2 + 1/fact(4)*x^4 - 1/fact(6)*x^6 + 1/fact(8)*x^8 - 1/fact(10)*x^10 + |
# 1/fact(12)*x^12 - 1/fact(14)*x^14 + 1/fact(16)*x^16 |
# now we have the cos(freq * dist + sim_time) |
MIN cos, cos, one; |
# amp * cos(freq * dist + sim_time) |
MUL cos, EmitterAmp, cos; |
# compute decay / dist |
MAD temp0, negOne, vertexPosition.xxxx, EmitterPosX; # temp0 = Emitter.position.x - position.x |
MAD temp1, negOne, vertexPosition.yyyy, EmitterPosY; # temp1 = Emitter.position.y - position.y |
# dist = sqrt(x*x + y*y); |
MUL temp0, temp0, temp0; |
MUL temp1, temp1, temp1; |
ADD dist, temp0, temp1; |
RSQ temp0, dist.x; |
RSQ temp1, dist.y; |
RSQ temp2, dist.z; |
RSQ temp3, dist.w; |
# put temp0, temp1, temp2 and temp3 into temp0 |
MUL temp0, temp0, select.xwww; |
MAD temp0, temp1, select.wxww, temp0; |
MAD temp0, temp2, select.wwxw, temp0; |
MAD temp0, temp3, select.wwwx, temp0; |
# compute decay / dist |
MAX temp0, temp0, epsilon; |
MUL temp0, EmitterDecay, temp0; |
# now temp0 = decay / dist |
ADD exp, one, temp0; # temp0 = x |
# exp = 1 + x |
MUL temp1, temp0, temp0; # temp0 = x, temp1 = x^2 |
MAD exp, temp1, InvFact_2.zzzz, exp; # exp = 1 + x + 1/fact(2)*x^2 |
MUL temp1, temp1, temp0; # temp0 = x, temp1 = x^3 |
MAD exp, temp1, InvFact_3.zzzz, exp; # exp = 1 + x + 1/fact(2)*x^2 + 1/fact(3)*x^3 |
MUL temp1, temp1, temp0; # temp0 = x, temp1 = x^4 |
MAD exp, temp1, InvFact_4.zzzz, exp; # exp = 1 + x + 1/fact(2)*x^2 + 1/fact(3)*x^3 + 1/fact(4)*x^4 |
MUL temp1, temp1, temp0; # temp0 = x, temp1 = x^5 |
MAD exp, temp1, InvFact_5.zzzz, exp; # exp = 1 + x + 1/fact(2)*x^2 + 1/fact(3)*x^3 + 1/fact(4)*x^4 + 1/fact(5)*x^5 |
# compute 1 / exp |
RCP temp0, exp.x; |
RCP temp1, exp.y; |
RCP temp2, exp.z; |
RCP temp3, exp.w; |
# put temp0, temp1, temp2 and temp3 into exp |
MUL temp0, temp0, select.xwww; |
MAD temp0, temp1, select.wxww, temp0; |
MAD temp0, temp2, select.wwxw, temp0; |
MAD temp0, temp3, select.wwwx, temp0; |
# compute amp * cos(freq * dist + sim_time) / exp (decay / dist) |
MUL exp, temp0, cos; |
# compute sum for z value |
MOV temp0, exp.xxxx; |
ADD temp0, temp0, exp.yyyy; |
ADD temp0, temp0, exp.zzzz; |
#ADD temp0, temp0, exp.wwww; # use only 3 emitters, the host CPU does this also |
SWZ pos, vertexPosition, x,y,0,1; # clear z |
SWZ temp0, temp0, 0,0,z,0; # clear all but z |
ADD pos, pos, temp0; # add z back in |
SWZ pos, pos, x,y,z,1; # set w to 1 |
DP4 temp0.x, state.matrix.mvp.row[0], pos; |
DP4 temp0.y, state.matrix.mvp.row[1], pos; |
DP4 temp0.z, state.matrix.mvp.row[2], pos; |
DP4 temp0.w, state.matrix.mvp.row[3], pos; |
MOV result.position, temp0; |
MOV result.texcoord, vertexTexcoord; |
END |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-07-07