【问题标题】:OpenGL how to use texture maps in shadersOpenGL如何在着色器中使用纹理贴图
【发布时间】:2021-11-10 00:56:02
【问题描述】:

我有一个带有高度图的场景,并加载了两个纹理:sand.png 和 sandmap.png。我想编写一个着色器,它只会使用 sandmap.png 在正确的位置绘制沙子纹理。

这是我的绘制方法:(glClear 在别处被调用)

void Terrain::Draw(OGLRenderer& r)
{
    r.BindShader(shader);
    r.UpdateShaderMatrices();
    r.SetTextureRepeating(sand, true);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, sand);
    glUniform1i(glGetUniformLocation(shader->GetProgram(), "sandTex"), 0);

    glActiveTexture(GL_TEXTURE0 + 1);
    glBindTexture(GL_TEXTURE_2D, sandMap);
    glUniform1i(glGetUniformLocation(shader->GetProgram(), "sandMap"), 1);

    terrainHeightMap->Draw();   
}   

纹理和着色器像这样加载到其他地方:

terrainHeightMap = new HeightMap(TEXTUREDIR"islandmap.PNG");

sand = SOIL_load_OGL_texture(TEXTUREDIR"sand.PNG", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS);

sandMap  = SOIL_load_OGL_texture(TEXTUREDIR"sandmap.PNG ", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS);

shader = new Shader(SHADERDIR"terrainVertex.glsl", SHADERDIR"terrainFragment.glsl");

这是片段着色器:

#version  330  core

uniform sampler2D sandTex;

uniform sampler2D sandMap;

in Vertex
{
 vec2  texCoord;
} IN;


vec4 getTexture() 
{
    if (texture(sandMap, IN.texCoord ).g >= 0.2) 
    {
        return texture(sandTex, IN.texCoord);
    }
    //return texture(grassTex, IN.texCoord);
   
}

out  vec4  fragColour;

void  main(void)
{
   fragColour = getTexture();
}

预计大部分高度图将是黑色的,除了应该是沙子的地方。但是,整个高度图是用沙子纹理绘制的:

我还可以通过将沙子纹理替换为绘制沙地图纹理的 sandmap.png 来确认我使用的是正确的 sandmap.png 路径:

我在这里做错了什么?

【问题讨论】:

  • 试试fragColour = texture(sandTex, IN.texCoord) * texture(sandMap, IN.texCoord);
  • 肯定getTexture() 需要在不是沙子的时候返回一个值!

标签: opengl glsl shader


【解决方案1】:

如果沙子条件失败,您的 getTexture 函数不会返回值:

vec4 getTexture() {
    if (texture(sandMap, IN.texCoord ).g >= 0.2) {
        return texture(sandTex, IN.texCoord);
    }
    // ??? what if we reach here ???   
}

我在规范中找不到确切的措辞——但我很确定默认不会是“黑色”(很可能是未定义的行为)。

您应该指定默认颜色:

vec4 getTexture() {
    if (texture(sandMap, IN.texCoord ).g >= 0.2) {
        return texture(sandTex, IN.texCoord);
    }
    return vec4(0,0,0,1);
}

【讨论】:

    【解决方案2】:

    好的,所以这里的问题非常愚蠢。 沙子纹理和沙子贴图纹理都应用了相同的缩放比例。这意味着您在第二张图像上看到的是贴图纹理的实际大小,除了它没有设置为重复。这意味着实际的纹理映射发生在地形的最边缘(在图像中被截断)。正如@Yakov 指出的那样,地图的其余部分被纹理绘制的原因很可能是由于getTexture 函数中未定义的行为

    【讨论】:

      猜你喜欢
      • 2021-03-31
      • 1970-01-01
      • 2021-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多