GLSL 2.0颜色和纹理

3

你好,我是一个GLSL新手,遇到了一些问题。

我正在尝试创建一对GLSL着色器,以使用颜色或纹理,但肯定做错了什么。 问题在于,如果将uUseTexture设置为0(应该表示颜色),它不起作用(对象没有上色)。我知道上色代码是单独工作的,有什么提示可以解决if语句不起作用的问题吗?

以下是代码:

// 片段着色器

precision mediump float;

uniform int uUseTexture;
uniform sampler2D uSampler;

varying vec4 vColor;
varying vec2 vTextureCoord;

void main(void) {

    if(uUseTexture == 1) {
        gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
    } else {
        gl_FragColor = vColor;
    }

}

// 顶点

attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;
attribute vec2 aTextureCoord;

uniform int uUseTexture;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;

varying vec4 vColor;
varying vec2 vTextureCoord;

void main(void) {
    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);

    if(uUseTexture == 1) {
        vTextureCoord = aTextureCoord;
    } else {
        vColor = aVertexColor;
    }

这个 vec2(vTextureCoord.s, vTextureCoord.t) 应该改为 vTextureCoord.st。你应该查一下 GLSL 中 swizzle masks 的工作原理。 - Nicol Bolas
你的意思是,如果将 if(uUseTexture == 1) 替换为 if (true),相同的着色器代码就能够工作了吗? - rotoglup
1个回答

5

快速浏览您的代码后,我没有发现明显问题。但是,我想花点时间指出:不需要使用if语句即可完成此用例。例如,我们可以将uUseTexture视为浮点数,而不是整数(您可以在着色器中进行类型转换,但这更有趣):

// 顶点

attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;
attribute vec2 aTextureCoord;

uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;

varying vec4 vColor;
varying vec2 vTextureCoord;

void main(void) {
    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
    // It may actually be faster to just assign both of these anyway
    vTextureCoord = aTextureCoord;
    vColor = aVertexColor;
}

// 片段

uniform float uUseTexture;
uniform sampler2D uSampler;

varying vec4 vColor;
varying vec2 vTextureCoord;

void main(void) {
    // vTextureCoord is already a vec2, BTW
    vec4 texColor = texture2D(uSampler, vTextureCoord) * uUseTexture;
    vec4 vertColor = vColor * (1.0 - uUseTexture); 
    gl_FragColor = texColor + vertColor;
}

现在,UseTexture仅作为每个颜色源要使用多少的调制器。它更加灵活,因为您可以将其设置为0.5并获得一半纹理/一半顶点颜色!

令您惊讶的是,当您像这样使用if语句时,着色器编译器在幕后很可能正在执行此操作。这通常对硬件更有效。


感谢您的快速回复,我找到了问题,与着色器无关,原来是我使用了22个项目大小缓冲纹理坐标而不是2个...我需要多睡觉 :)还有感谢您提供的调制器提示,我会尝试一下 :) - brunom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接