使用OpenGL在立方体面上重复立方体贴图纹理

lsmd5eda  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(248)

是否可以使用OpenGL使立方体贴图纹理(GL_TEXTURE_CUBE_MAP_POSITIVE_X...)在给定面上重复?
我有一个简单的单位立方体,有24个顶点,以原点为中心(xyz介于(-0.5、-0.5、-0.5)和(0.5,0.5,0.5))。在其属性中,最初,我在片段着色器中将uvw坐标设置为xyz位置,就像在立方体贴图learnopengl.com tutorial中所做的那样。显然,我也尝试将单独的uvw坐标设置为与比例相等的值,但纹理并没有在任何立方体面上重复,如下图所示(我在片段着色器中绘制了uvw坐标):

在上面的图像中,height(顶部像素的y坐标)= 3.5,因此通过为顶部的顶点设置v = 3.5,我希望梯度垂直重复(实际情况并非如此)。
如果这是不可能的,唯一的办法留给我来解决它是分配一个2D纹理与自定义紫外线坐标的每个顶点,对不对?

6jygbczu

6jygbczu1#

不,立方体贴图不可能使用GL_REPEAT进行 Package 。您可能应该考虑人们在评论中建议的替代方法
这是因为传递给立方体图采样器的坐标被解释为一个方向。该方向的长度被忽略。您可以将其视为用于采样的vec 3被归一化-因此,不会发生环绕。
如果出于任何原因需要使用立方体贴图,则可以在着色器中修改采样方向。

vec3 tweakSampleDirForReapeat(vec3 dir, float repeatScale)
{
    for(int i = 0; i < 3; i++) {
        float d = abs(dir[i]);
        if(abs(d) >= 0.5) // skip dominant direction (assuming a coordinate in a unit cube centered at the origin)
            continue;
        d += 0.5; // transform from [-0.5, +0.5] range to [0, 1]
        d *= repeatScale; // transform from [0, 1] range to [0, repeatScale]
        d = fract(d); // wrap [0, repeatScale] to multiple [0, 1] ranges
        d -= 0.5; // transform from [0, 1] range to [-0.5, +0.5]
        dir[i] = d;
    }
    return dir;
}

免责声明:这段代码应该工作,但我还没有真正尝试过。
此代码可以调整为支持每个面的不同repearScales。
编辑:我将试着解释这段代码的作用。
假设我们有一个点位于立方体的+X面。x1c 0d1x
我们正在尝试修改这个蓝点的位置。我们还不知道这个点的确切位置。但这个点将在同一个面上。
在这种情况下,X值等于+0.5。其他坐标(Y和Z)的绝对值将小于0.5。
如果出现以下情况,我们将在此进行检查:

if(abs(d) >= 0.5) // skip dominant direction
    continue;

所以基本上,如果X是-0.5或+0.5,我们不想改变X,为了保持它在同一个面上。
我们将只修改Y和Z。
现在让我们从另一个Angular 来看立方体。现在我们看到+X面朝向我们。

从这个Angular 来看,我们可以清楚地看到Y和Z都〈0.5(绝对值),因为点在盒子里面。
现在让我们引入纹理。

默认情况下,我们会得到整个纹理飞溅到脸上。
但是我们想要这样的东西。

这就是这次转型的目的:

d += 0.5; // transform from [-0.5, +0.5] range to [0, 1]
d *= repeatScale; // transform from [0, 1] range to [0, repeatScale]
d = fract(d); // wrap [0, repeatScale] to multiple [0, 1] ranges
d -= 0.5; // transform from [0, 1] range to [-0.5, +0.5]

我建议你用纸和笔,通过几个例子来完成这个算法。我相信你最终会理解它的,这只是一个投入一些时间的问题。祝你好运!
测验题:上一个图像的“repeatScale”是什么?

相关问题