首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GLSL阴影纹理α飞溅

GLSL阴影纹理α飞溅
EN

Stack Overflow用户
提问于 2012-11-17 19:16:04
回答 1查看 4.8K关注 0票数 6

我试着用着色器在一个地形上加载四个纹理细节块,根据第五个图像将它们合并,其中r,g,b和a组件被用来确定每个纹理的多少应该混合在一起。混合很好,但是当我尝试添加我的"mixmap“图像时,它失败了,因为我猜是因为纹理坐标的问题。

首先,这里是着色器:

顶点着色机

代码语言:javascript
复制
void main() {
    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_Position = ftransform();
}

破片着色机

代码语言:javascript
复制
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读取的值不是正确的值。

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

  • R是水
  • G是沙子
  • B是草
  • A是岩石

因此,我需要能够从我的着色器获得正确的像素值,以正确地混合我的纹理。

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

现在,如果我使用一个简单的mixmap图像(半红色,半绿色),它应该给我左边的板条箱,右边的文字,我得到

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

代码语言:javascript
复制
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();
}

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

作为对所提供的答案的跟进,我试图通过计算着色器中的紫外线来做到这一点。

首先,这是新的着色器。

顶点着色机

代码语言:javascript
复制
varying vec4 VertexPosition;

void main() {

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

破片着色机

代码语言:javascript
复制
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.);
}

下面是结果

但如果我移动相机:

正如你所看到的,机箱和文本是并排的。但看起来我是用屏幕坐标而不是世界坐标来计算的。我肯定又和坐标系搞混了。我会试着找对的!我只想确保我走对了方向。我也将寻找多纹理坐标,一旦我知道它是如何工作的,它可能会更方便;)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-17 20:01:01

如果我对你的理解是正确的,你将需要不同的纹理和弦为你的mixmap。现在它使用的是每个单元的整个mixmap,这就是为什么每个单元得到一半的文本,一半的纸箱。

尝试使用多个纹理和弦。你也可以在阴影中计算出正确的紫外线,方法是让它被顶点的当前x点除以x方向上的地形长度,对y也是一样的。不过,如果你缩放你的地形,也一定要把地形的长度乘以比例。

如果你不明白我在说什么,那么地形上的每个单元格都会得到(0,0),(1,0),(0,1)或(1,1)的超视距。这对于机箱和文本纹理是很好的,但是mixmap应该是分数和多样化得多的。

这里是另一个地形教程的链接。它使用DirectX,但顶点/UV的生成是可比的。最大的区别是,他使用一个大纹理的整个地形,这是你需要做的,你的mixmap,而不是你的其他纹理。

我想我知道出了什么问题。显式地存储顶点位置。不要将其乘以模型视图矩阵(即:

代码语言:javascript
复制
varying vec4 VertexPosition;

void main() {

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

这将修复它,抱歉我把你的固定着色器扔到渲染猴子,它不再移动与相机。希望这能有所帮助。我得到了洗衣,但现在看起来:

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13433902

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档