gpt4 book ai didi

c++ - GLSL 着色器纹理 alpha splatting

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:24:49 24 4
gpt4 key购买 nike

我正在尝试使用着色器加载地形上的四个纹理细节图 block ,方法是根据第五张图像合并它们,其中 r、g、b 和 a 组件用于确定每个纹理应该混合多少。混合工作正常,但是当我尝试添加我的“mixmap”图像时,它失败了,我猜是因为纹理坐标有问题。

首先,这里是着色器:
顶点着色器

void main() {
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}

片段着色器

uniform sampler2D Texture0;
uniform sampler2D Texture1;
uniform sampler2D Texture2;
uniform sampler2D Texture3;
uniform sampler2D Mixmap;

varying vec3 pos;

void main()
{

vec4 texel0 = texture2D(Texture0, gl_TexCoord[0].st).rgba;
vec4 texel1 = texture2D(Texture1, gl_TexCoord[0].st).rgba;
vec4 texel2 = texture2D(Texture2, gl_TexCoord[0].st).rgba;
vec4 texel3 = texture2D(Texture3, gl_TexCoord[0].st).rgba;
vec4 mixmapTexel = texture2D(Mixmap, gl_TexCoord[0].st).rgba;

texel0 *= mixmapTexel.r;
texel1 = mix(texel0, texel1, mixmapTexel.g);
texel2 = mix(texel1, texel2, mixmapTexel.b);
gl_FragColor = mix(texel2, texel3, mixmapTexel.a);
}

正如我所说,混合效果很好。问题在于从我的混合图中读取的值不正确。

这里有一些关于我在做什么的更多解释。我正在构建一个从高度图加载地形的分页地形系统。然后我想使用我的 mixmap 图像来表示 rgba 组件应该根据高度混合多少纹理。

  • r是水

  • g是沙子

  • b是草

  • 一个是摇滚

所以我需要能够从我的着色器中获取正确的像素值以正确地混合我的纹理。

Blending between crate and text

这里是一个箱子和文本之间混合的例子,这样你就可以清楚地看到纹理是如何应用的。

现在,如果我使用一个简单的混合图图像(一半是红色,一半是绿色),它应该给我地形左侧的 crate 和右侧的文本,我得到 with argb alpha splatting example rgba image

这是地形生成过程的一部分:它遍历顶点数组并创建地形三角形

void TerrainPage::generateDisplayList()
{
// create one display list
mDisplayListIndex = glGenLists(1);

// compile the display list, store a triangle in it
glNewList(mDisplayListIndex, GL_COMPILE);
glFrontFace( GL_CW ); // Vertex are added clockwise. Used to calculate normals
std::vector<Vertex>::iterator it;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
texShader.enable();
texShader.bindTexture(mTexture0, "Texture0", 0);
texShader.bindTexture(mTexture1, "Texture1", 1);
texShader.bindTexture(mTexture2, "Texture2", 2);
texShader.bindTexture(mTexture3, "Texture3", 3);
texShader.bindTexture(mMixmapTexture, "Mixmap", 4);
Vertex v;
int j=0;
glEnable(GL_TEXTURE_2D);
//mTexture.bind();
glBegin(GL_TRIANGLE_STRIP);
for(int i = 0; i<mVertices.size(); i++) {
if(i%(2*mWidth) == 0) glEnd(); glBegin(GL_TRIANGLE_STRIP);
v = mVertices[i];
glTexCoord2f(v.texcoords[0], v.texcoords[1]);
glVertex3f(v.position[0], v.position[1], v.position[2]);
}
glEnd();
glDisable(GL_TEXTURE_2D);
texShader.disable();
glEndList();
}

如果需要,我可以提供更多屏幕截图,还有我的一些代码。

作为所提供答案的后续,我尝试通过在着色器中计算 UV 来做到这一点。

首先,这是新的着色器

顶点着色器

varying vec4 VertexPosition;

void main() {

gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
VertexPosition = gl_ModelViewMatrix * gl_Vertex;;
}

片段着色器

uniform sampler2D Texture0;
uniform sampler2D Texture1;
uniform sampler2D Texture2;
uniform sampler2D Texture3;
uniform sampler2D Mixmap;

varying vec4 VertexPosition;
float side = 500.;

void main()
{

vec4 texel0 = texture2D(Texture0, gl_TexCoord[0].st).rgba;
vec4 texel1 = texture2D(Texture1, gl_TexCoord[0].st).rgba;
vec4 texel2 = texture2D(Texture2, gl_TexCoord[0].st).rgba;
vec4 texel3 = texture2D(Texture3, gl_TexCoord[0].st).rgba;
vec4 mixmapTexel = texture2D(Mixmap, VertexPosition.xz/(2.*side)).rgba;

texel0 *= mixmapTexel.r;
texel1 = mix(texel0, texel1, mixmapTexel.g);
//texel2 = mix(texel1, texel2, mixmapTexel.b);
//vec4 tx = mix(texel2, texel3, mixmapTexel.a);
//vec4 tx = mixmapTexel; //vec4(1, 1, 1, 1.);
gl_FragColor = texel1;

//if(test > 250. )
// gl_FragColor = vec4(1.,1.,1.,1.);
}

这是结果

enter image description here

但是如果我移动相机:

enter image description here

如您所见,这次箱子和文本并排放置。但看起来我是在屏幕坐标而不是世界坐标中计算。我一定又对坐标系感到困惑了。我会尽力找到合适的!我只是想确保我的方向是正确的。我也会寻找多纹理坐标,一旦我弄清楚它是如何工作的,它可能会更方便;)

最佳答案

如果我没理解错的话,您的混合贴图需要不同的纹理坐标。现在它使用每个单元格的整个混合映射,这就是为什么你得到一半的文本,每个单元格的一半 crate 。

尝试使用多个纹理坐标。您还可以在着色器中计算正确的 UV,方法是用顶点的当前 x 位置除以地形在 x 方向上的长度,对于 y 也是如此。但是,如果您缩放地形,请务必将地形的长度也乘以比例。

如果您不明白我在说什么,地形的每个单元格都在获取以下任一的 UV:(0,0)、(1,0)、(0,1) 或 (1,1)。这对于 crate 和文本纹理来说很好,但 mixmap 应该更加碎片化和多样化。

这是一个link到另一个地形教程。它使用 DirectX,但顶点/UV 生成具有可比性。最大的不同是他为整个地形使用了一个大纹理,这是你需要为你的 mixmap 而不是为你的其他纹理做的。

我想我知道出了什么问题。显式存储顶点位置。不要将它乘以 modelviewmatrix 即:

varying vec4 VertexPosition;

void main() {

gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
//VertexPosition = gl_ModelViewMatrix * gl_Vertex;;
VertexPosition = gl_Vertex;
}

这会修复它,抱歉,我将你的固定着色器放入 rendermonkey,它不再随相机移动。希望这可以帮助。我正在平移,但现在看起来像:

Fixed render

关于c++ - GLSL 着色器纹理 alpha splatting,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13433902/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com