PDA

View Full Version : simulating a cubemap



Vexator
05-14-2007, 01:56 AM
let's say i cannot use a real cube map, to fetch depth e.g., so i put the six images next to each other in one texture, 3 in the top row and 3 in the bottom row. could i somehow compute the correct texture coordinates in a framgent shader to access the texture just like a cubemap?

Zengar
05-14-2007, 05:13 AM
I haven't done anythign like this before, but all cubemap coordinate calculations are described in the GL specs (or in the extension specs). You shoudl start looking there, probably. Also, if your card doesn't support cube maps in hardware, I can't imagine it will have support for shaders.

Vexator
05-14-2007, 09:08 AM
it's for shadow mapping, and afaik i cannot have depth cube maps. but thanks, i'll have a look there.

Vexator
05-14-2007, 10:18 AM
ok the spec gives this table. i'm not sure how i have to use this data, though. would would i get the major axis direction?


170 CHAPTER 3. RASTERIZATION
Major Axis Direction Target sc tc ma
+rx TEXTURE_CUBE_MAP_POSITIVE_X -rz -ry rx
-rx TEXTURE_CUBE_MAP_NEGATIVE_X rz -ry rx
+ry TEXTURE_CUBE_MAP_POSITIVE_Y rx rz ry
-ry TEXTURE_CUBE_MAP_NEGATIVE_Y rx -rz ry
+rz TEXTURE_CUBE_MAP_POSITIVE_Z rx -ry rz
-rz TEXTURE_CUBE_MAP_NEGATIVE_Z -rx -ry rz

Table 3.19: Selection of cube map images based on major axis direction of texture
coordinates.

jra101
05-14-2007, 10:30 AM
One possible implementation would be to use a 1x1 RGBA cubemap like this:


GLfloat faceData[] = { 1.0, 0.0, 0.0, 1.0,
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 1.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0 };

for (int i = 0; i < 6; i++)
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_FLOAT, &amp;faceData[i*4]);Then use this cubemap to figure out which face of your shadow map texture to use:

uniform sampler2D faces[6];
uniform samplerCube faceSelector;

varying vec3 reflection;

vec4 sampleFace(sampler2D tex, vec2 uv, float ma)
{
uv = (uv / ma + 1.0) * 0.5;
return texture2D(tex, uv);
}

vec4 textureCubemap(sampler2D faces[6], vec3 r)
{
vec4 face = textureCube(faceSelector, r);

// calculate major axis
float ma = dot(face.xyz, abs(r));

vec3 s0 = sampleFace(faces[0], vec2(-r.z, -r.y), ma).rgb;
vec3 s1 = sampleFace(faces[1], vec2( r.z, -r.y), ma).rgb;
vec3 s2 = sampleFace(faces[2], vec2( r.x, r.z), ma).rgb;
vec3 s3 = sampleFace(faces[3], vec2( r.x, -r.z), ma).rgb;
vec3 s4 = sampleFace(faces[4], vec2( r.x, -r.y), ma).rgb;
vec3 s5 = sampleFace(faces[5], vec2(-r.x, -r.y), ma).rgb;

vec3 posFace = (s0 * face.x) + (s2 * face.y) + (s4 * face.z);
vec3 negFace = (s1 * face.x) + (s3 * face.y) + (s5 * face.z);

return vec4(mix(negFace, posFace, face.w), 1.0);
}

void main()
{
gl_FragColor = textureCubemap(faces, reflection);
}

Vexator
05-14-2007, 01:41 PM
awesome! thank you :D

oc2k1
05-14-2007, 06:10 PM
brrrr 7 lookups. You could use a dual parabolic map, there is only a single lookup needed.

You could use a RGBA cube, there the 6 faces are filled with texcoords for addressing the sampler2D.

texture2D(2dtexture,textureCube(cubemap,vec3 invec).xy))