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

时间:2019-01-08 23:42:43

标签: opengl graphics rendering

我想通过将整个对象投影到2D纹理上来调试渲染到cubemap函数,就像这样:

在使用纹理着色器进行渲染时,我只有可用的UV纹理坐标(范围从(0,0)到(1,1))。如何在一次绘制调用中将立方体贴图投影到屏幕上?

2 个答案:

答案 0 :(得分:0)

您可以通过渲染6个四边形并使用指向立方体每个顶点的3D纹理坐标(s,t,p)来实现( +/-1,+/-1,+/-1 )的8种变化。

(s,t)的4个变体一样,UV 2D坐标(0/1,0/1)不能用于整个CUBE_MAP,只能用于其单独的侧面。

在此处查找txr_skybox

如何在片段着色器中使用CUBE_MAP

OpenGL

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

答案 1 :(得分:0)

我的答案与被接受的答案基本相同,但是我已经使用这种技术调试了我当前项目中的depth-cubemap(用于阴影投射),因此我想我应该包含一个片段的工作样本。我使用的着色器代码。

展开立方体贴图

应该将其渲染为屏幕顶部的矩形,直接在屏幕上以3/4的纵横比显示,并且s,t从左下角的(0,0)变为(1,1 )在右上角。

请注意,在这种情况下,我使用的立方体贴图是反转的,也就是说,立方体贴图原点+(x,y,z)一侧的对象将呈现为-(x,y,z),方向I选择作为顶部/底部方形完全是任意的;因此,要使此示例正常工作,您可能需要更改一些符号或交换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

矩形投影

但是,我必须说,我更喜欢使用等角投影来调试立方体贴图,因为它没有任何孔;而且幸运的是,它们比展开的立方体贴图更容易制作,只需使用像这样的片段着色器(仍然使用s,t从(0,0)到(1,1)从左下角到右上角) ,但这一次的宽高比为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);
}

以下是屏幕截图,其中等角投影用于在右下角显示我的深度图:

Equirectangula