我想通过将整个对象投影到2D纹理上来调试渲染到cubemap函数,就像这样:
在使用纹理着色器进行渲染时,我只有可用的UV纹理坐标(范围从(0,0)到(1,1))。如何在一次绘制调用中将立方体贴图投影到屏幕上?
答案 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
。
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);
}
以下是此技术的屏幕截图,用于在屏幕的右下角渲染我的深度图(使用点光源放置在空房间的正中央进行渲染,墙上没有其他对象)和玩家角色):
但是,我必须说,我更喜欢使用等角投影来调试立方体贴图,因为它没有任何孔;而且幸运的是,它们比展开的立方体贴图更容易制作,只需使用像这样的片段着色器(仍然使用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);
}
以下是屏幕截图,其中等角投影用于在右下角显示我的深度图: