lordmule

12-27-2010, 11:51 PM

Hello, I have recently tried reading back some computations of vector data on the GPU, but I can't seem to get the right numbers. So as a test, I started played around with just reading back vertex data and still could not get it right.

I figured the best way to readback a non-normalised vector, is to save it as a normalized vector with its length. In case the length is greater than 1, I pre-scale that value to the range [0,1]. So my test fragment shader is:

// transformed vertex

varying vec3 g_vertex;

// specify an scale to use eg 10

uniform float scale;

void main()

{

vec3 v;

// we let the 4th coord be the vector scale

float w = length(g_vertex) / scale;

v = normalize(g_vertex);

v = 0.5 * v + 0.5;

gl_FragColor = vec4(v, w);

}

reconstruction after readback:

float *pix = vertexmap + 4*i;

vertex[0] = (pix[0] - 0.5) * 2.0;

vertex[1] = (pix[1] - 0.5) * 2.0;

vertex[2] = (pix[2] - 0.5) * 2.0;

vertex[0] *= pix[3] * vmap_scale;

vertex[1] *= pix[3] * vmap_scale;

vertex[2] *= pix[3] * vmap_scale;

It's ok when the scale is close to one, but for every point further from (0,0,0) I start to get concentric circle effect based on the scale I choose. For example scale = 6, then there will be some bands where vertices will round to. I've tried in different spaces object/eye and get the same result, I might be going about it the wrong way. It's something about that 4th component not working right...

I've made 3 snaps of scale = 1, and 3 snaps of scale = 6

images (http://img24.imageshack.us/g/cmcapture1c.png/)

Any suggestions?

edit: re-rendered as a 3D point cloud

I figured the best way to readback a non-normalised vector, is to save it as a normalized vector with its length. In case the length is greater than 1, I pre-scale that value to the range [0,1]. So my test fragment shader is:

// transformed vertex

varying vec3 g_vertex;

// specify an scale to use eg 10

uniform float scale;

void main()

{

vec3 v;

// we let the 4th coord be the vector scale

float w = length(g_vertex) / scale;

v = normalize(g_vertex);

v = 0.5 * v + 0.5;

gl_FragColor = vec4(v, w);

}

reconstruction after readback:

float *pix = vertexmap + 4*i;

vertex[0] = (pix[0] - 0.5) * 2.0;

vertex[1] = (pix[1] - 0.5) * 2.0;

vertex[2] = (pix[2] - 0.5) * 2.0;

vertex[0] *= pix[3] * vmap_scale;

vertex[1] *= pix[3] * vmap_scale;

vertex[2] *= pix[3] * vmap_scale;

It's ok when the scale is close to one, but for every point further from (0,0,0) I start to get concentric circle effect based on the scale I choose. For example scale = 6, then there will be some bands where vertices will round to. I've tried in different spaces object/eye and get the same result, I might be going about it the wrong way. It's something about that 4th component not working right...

I've made 3 snaps of scale = 1, and 3 snaps of scale = 6

images (http://img24.imageshack.us/g/cmcapture1c.png/)

Any suggestions?

edit: re-rendered as a 3D point cloud