Simulating a cubemap

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?

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.

it’s for shadow mapping, and afaik i cannot have depth cube maps. but thanks, i’ll have a look there.

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.

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, &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);
}

awesome! thank you :smiley:

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))

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.