In my game I'm generating a terrain in realtime on the GPU using an fBm noise function. This works fine.
Now what I need is to be able to workout the height of a given position on the landscape on the CPU side so that I can do things such as position objects on the surface of the terrain. This means I need to port the GPU code over to the CPU.
So far I've come across a couple of interesting things when running the HLSL code in the Visual Studio 2012 debugger and then doing the same for the CPU....
Firstly I can the code through the GPU and for a given pixel the debugger showed:
PosW = x = 1214.034000000, z = -1214.034000000
When I tried putting these same values in the CPU side I found that on the CPU the values were actually:
PosW = x 1214.03406, z = -1214.03406
i.e. the CPU couldn't represent the GPU float values exactly. Is this to be expected? Do they not both conform to the exact IEEE standard for a float? I noticed this in several places.
The second problem, the one I'm struggling with is regarding how to emulate a Sample HLSL function on the CPU.
Here is what I have in HLSL:
const float mipLevel = 0; float4 n; n.x = g_NoiseTexture.SampleLevel(SamplerRepeatPoint, i, mipLevel).x; n.y = g_NoiseTexture.SampleLevel(SamplerRepeatPoint, i, mipLevel, int2(1,0)).x; n.z = g_NoiseTexture.SampleLevel(SamplerRepeatPoint, i, mipLevel, int2(0,1)).x; n.w = g_NoiseTexture.SampleLevel(SamplerRepeatPoint, i, mipLevel, int2(1,1)).x;(Where g_NoiseTexture is a 256x256 grayscale texture. I thinkt he Sampler name is self explanatory)
And I've tried to emulate this on the CPU like this:
float nx, ny, nz, nw; nx = m_NoiseData[(int)(iy) % 256][(int)(ix) % 256] / 256.0f; ny = m_NoiseData[(int)(iy) % 256][(int)(ix + 1.0f) % 256] / 256.0f; nz = m_NoiseData[(int)(iy + 1.0f) % 256][(int)(ix) % 256] / 256.0f; nw = m_NoiseData[(int)(iy + 1.0f) % 256][(int)(ix + 1.0f) % 256] / 256.0f;(Where m_NoiseData is defined as "unsigned char m_NoiseData[256][256]" and contains the same data as the g_NoiseTexture)
The problem is that I'm getting completely different for n.x vs nx, n.y vs ny etc.
I've even tried to compensate for pixel centres by adding 0.5f to each pixel like this:
float nx, ny, nz, nw; nx = m_NoiseData[(int)(iy + 0.5f) % 256][(int)(ix + 0.5f) % 256] / 256.0f; ny = m_NoiseData[(int)(iy + 0.5f) % 256][(int)(ix + 1.5f) % 256] / 256.0f; nz = m_NoiseData[(int)(iy + 1.5f) % 256][(int)(ix + 0.5f) % 256] / 256.0f; nw = m_NoiseData[(int)(iy + 1.5f) % 256][(int)(ix + 1.5f) % 256] / 256.0f;
Any ideas?
Any help much appreciated.
Kind Regards
Ben






