Hi, I'm writing an HLSL effect file for visualizing wave functions. I create a simple 2D mesh and use the shader to compute the different y-values.
In one block of code, I use a renderMode var to keep track of whether I'm rendering the real, imaginary or absolute square values. I've tried several different methods of checking the var. You'd think that it would be a simple if-then-else check convering 3 possible numbers.
Here are some examples (the code in question is at the bottom of the section):
float time = 0.0;
float timeOffset = 0.0f;
int nRenderMode = 0;
int numWaveFuncs = 1; //7;
bool bAbsSquare = false;
static const float TWOPI = 6.283185307179586476925286766559;
static const float cExp = 0.25f;
float x0 = -20.0f;
float z0 = 0.0f;
float sigmaX = 0.25f;
float sigmaZ = 0.25f;
float v0 = 4.0f;
float4x4 matWorldViewProj: WORLDVIEWPROJECTION;
///////////////////////////////////////////////
Float WaveAmplitude(VSInput In)
{
float ampX = pow(TWOPI, cExp);
ampX *= sqrt(sigmaX);
ampX = 1.0f / ampX;
float ampZ = pow(TWOPI, cExp);
ampZ *= sqrt(sigmaZ);
ampZ = 1.0f / ampZ;
float a = 1.0f,
b = 0.0f,
c = 1.0f;
float ax = a * ( (In.Pos.x - x0 - v0*timeOffset) * (In.Pos.x - x0 - v0*timeOffset) ),
bxz = b * (In.Pos.x - x0 - v0*timeOffset) * (In.Pos.z - z0),
cz = c * (In.Pos.z - z0) * (In.Pos.z - z0);
float ex = ax + bxz + cz;
ex = exp(-ex);
return ampX * ampZ * ex;
}
Float Phase(VSInput In)
{
float3 pos = {In.Pos.x, 0.0f, In.Pos.z};
float3 dir = {1.0f, 0.0f, 0.0f};
float dv = dot(dir, pos);
return dv - timeOffset;
}
Complex WaveFunction(VSInput In)
{
Complex psi = (Complex) 0;
float amp = WaveAmplitude(In);
float theta = Phase(In);
psi.real = amp * cos(theta);
psi.imag = amp * sin(theta);
return psi;
}
///////////////////////////////////////////////////////////////
VSOutput VS_FreeParticle(VSInput In)
{
VSOutput Out = (VSOutput) 0;
Complex psi;// = (Complex) 0;
psi.real = 0.0f;
psi.imag = 0.0f;
float y = 0.0f;
float yval = 0.0f;
float ySum = 0.0f;
float hue;
float r = 0.0f,
i = 0.0f;
float4 tempcolor;
timeOffset = time;
psi = WaveFunction(In);
r = psi.real;
i = psi.imag;
/***********************************
************************************
* Here is the logic block in
* question
************************************
************************************/
if (bAbsSquare == true)
{
if (nRenderMode == 0)
y = r * r + i * i;
}
else
{
if (nRenderMode == 1)
y = r;
else if (nRenderMode == 2)
y = i;
}
/***********************************
************************************
* END logic block in
* question
************************************
************************************/
y = abs(ySum);
tempcolor = float4(y, y, y, 1.0f);
hue = (y * 360.0f + 225) / 360.0f;
hue = modf(hue, yval);
hue *= 360.0f;
Out.Color = ConvertFromHSV(hue, 1.0f, y);
//Finally project
In.Pos.y = ySum;
Out.Pos = mul(In.Pos, matWorldViewProj);
return Out;
}
No matter what I set bAbsSquare to, it always falls into the first block (true), UNLESS I set manually bAbsSquare to false THE LINE BEFORE. In this form, when I change nRenderMode to something other than zero (and bAbsSquare to the proper value), the graph remains in the first form regardless. It SHOULD fall to the lower block and choose one of those values to graph. It doesn't. But when I comment the check for (nRenderMode == 0) out, the graph goes flat/normal when I change to other modes, meaning that it seems to skip the first block but miss the second block entirely.
Even when I use the original method I had:
if (nRenderMode == 0)
y = r * r + i * i;
else if (nRenderMode == 1)
y = r;
else if (nRenderMode == 2)
y = i;
it always seems to hit more than one of the blocks. When I leave the check for the absolute square (nRenderMode == 0) commented out (in this second form), the other values work just fine. When I put it back in and comment the imaginary part out (nRenderMode == 2), both the AbsSqr and Real parts graph correctly. If I comment the real part out (nRenderMode == 1), both the AbsSqr and Imaginary blocks seem to hit, as the graph for AbsSqr begins to fluctuate like the real or imaginary parts do (and it shouldn't).
So when all 3 if's are in, the imaginary and AbsSqr values seem to affect one another, but the real doesn't.
It seems in both forms of nRenderMode checking, leaving the check for the imaginary part seems to interfere only with the AbsSqr.
The only place I change the bAbsSquare and nRenderMode values are on the C++ side of things and I have verified that each is correct.
I know this is long and convoluted but any help would be appreciated.