将立方体贴图投影到2D纹理上

4
我想通过将整个立方体贴图渲染到一个二维纹理上,来调试我的立方体贴图渲染函数,就像这个链接中的图片一样:

在我的纹理着色器中,我只有UV纹理坐标(范围从(0,0)到(1,1))。我该如何在单次绘制调用中投影立方体贴图到屏幕上?

之前的回答是正确的,但在我的情况下(商业),直接投影不是一个有效的选择。从立方体贴图中获取2D纹理需要一些方法,比如模糊处理来渲染出逼真的场景。推荐使用CMFT - LiShaoyuan
2个回答

4
您可以通过渲染6个基础图形并使用3D纹理坐标(s,t,p)指向立方体每个顶点(共8种变化)来实现此操作。

2D UV坐标(s,t),如4种变化的(0/1,0/1),不适用于整个CUBE_MAP,只适用于其各自的面。

请查找此处的txr_skybox

了解在片段着色器中使用CUBE_MAP的情况。

PSOpenGL中,纹理坐标称为s,t,p,q而不是u,v,w,...

以下是相关QA:


谢谢!我会尝试的。之前不知道纹理坐标名称的约定。 - Bruno Sena
@BrunoSena 在旧版的GL中使用s,t,r,q,但在GLSL中与r,g,b冲突,所以将其重命名为s,t,p,q...然而,我几个小时前尝试做这个,看起来我的当前GL实现在使用2D QUADs时存在问题,如果不起作用,您仍然可以使用3D立方体而无需投影...还有一种可能性是绑定平面而不是立方体贴图,每个面分别绑定。 - Spektre

2
我的答案基本上与被接受的答案相同,但我曾经使用这种技术来调试我的深度立方图(用于阴影投射)在我的当前项目中,所以我想包含一个我使用的片段着色器代码的工作样本。
展开立方图
这应该被渲染到屏幕顶部的矩形上,宽高比为3/4,直接在屏幕上,并且s,t从左下角的(0,0)到右上角的(1,1)。
请注意,在这种情况下,我使用的立方图是反转的,即在立方体映射原点的+(x,y,z)侧的对象被渲染到-(x,y,z),我选择作为顶部/底部四边形的上方向是完全任意的;因此,为了使此示例正常工作,您可能需要更改一些符号或有时交换s和t,还请注意,我仅读取一个通道,因为它是深度图:
问题中的四边形地图的片段着色器代码:
//Should work in most other versions
#version 400 core

uniform samplerCube dynamic_texture;

out vec4 out_color;
in vec2 ST;

void main()
{
    //In this example i use a debthmap with only 1 channel, but the projection should work with a colored cubemap to, just replace this with a vec3 or vec4    
    float debth=0;
    vec2 localST=ST;
    
    
    
    
    //Scale Tex coordinates such that each quad has local coordinates from 0,0 to 1,1
    localST.t = mod(localST.t*3,1);
    localST.s = mod(localST.s*4,1);
    

    //Due to the way my debth-cubemap is rendered, objects to the -x,y,z side is projected to the positive x,y,z side

    
    //Inside where tob/bottom is to be drawn?
    if (ST.s*4>1 && ST.s*4<2)
    {
        //Bottom (-y) quad
        if (ST.t*3.f < 1)
        {
            vec3 dir=vec3(localST.s*2-1,1,localST.t*2-1);//Get lower y texture, which is projected to the +y part of my cubemap
            
            debth = texture( dynamic_texture, dir ).r;
        }
        //top (+y) quad
        else if (ST.t*3.f > 2)
        {
            vec3 dir=vec3(localST.s*2-1,-1,-localST.t*2+1);//Due to the (arbitrary) way I choose as up in my debth-viewmatrix, i her emultiply the latter coordinate with -1
            
            debth = texture( dynamic_texture, dir ).r;
        }
        else//Front (-z) quad
        {
            vec3 dir=vec3(localST.s*2-1,-localST.t*2+1,1);
            
            debth = texture( dynamic_texture, dir ).r;
            
        }

    
    }
    //If not, only these ranges should be drawn
    else if (ST.t*3.f > 1 && ST.t*3 < 2)
    {
        if (ST.x*4.f < 1)//left (-x) quad
        {
            vec3 dir=vec3(-1,-localST.t*2+1,localST.s*2-1);
            
            debth = texture( dynamic_texture, dir ).r;
                    
        }
        else if (ST.x*4.f < 3)//right (+x) quad (front was done above)
        {
            vec3 dir=vec3(1,-localST.t*2+1,-localST.s*2+1);
            
            debth = texture( dynamic_texture, dir ).r;
                    
        }
        else //back (+z) quad 
        {
            vec3 dir=vec3(-localST.s*2+1,-localST.t*2+1,-1);
            
            debth = texture( dynamic_texture, dir ).r;
                    
        }

        
    }
    else//Tob/bottom, but outside where we need to put something
    {
        discard;//No need to add fancy semi transparant borders for quads, this is just for debugging purpose after all
    }
    
    out_color = vec4(vec3(debth),1);
}

这是一种技术,用于在屏幕的右下角呈现深度图的截图(使用点光源放置在空房间的中心,除了墙壁和玩家角色,没有其他物体): Looking at a wall, with the player's shadow visible 等距投影:
然而,我更喜欢使用等距投影来调试立方贴图,因为它没有任何洞;幸运的是,这比展开立方贴图更容易制作,只需使用像这样的片段着色器(仍然使用从左下角到右上角的(0,0)到(1,1)的s、t,但这次纵横比为1/2):
//Should work in most other versions
#version 400 core

uniform samplerCube dynamic_texture;

out vec4 out_color;
in vec2 ST;

void main()
{
    float phi=ST.s*3.1415*2;
    float theta=(-ST.t+0.5)*3.1415;
    
    
    vec3 dir = vec3(cos(phi)*cos(theta),sin(theta),sin(phi)*cos(theta));

    //In this example i use a debthmap with only 1 channel, but the projection should work with a colored cubemap to
    float debth = texture( dynamic_texture, dir ).r;
    out_color = vec4(vec3(debth),1);
}

这里是一张截图,使用等距圆柱投影在右下角显示我的深度图: 等距圆柱投影

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接