简体   繁体   English

片段着色器中的条件语句

[英]Conditional statement in fragment shader

I'm just beginner in shaders matter, so I'm probably missing something obvious here. 我只是有关着色器的初学者,因此我可能在这里缺少明显的东西。 I'm writing an android app using OpenGL ES 2.0. 我正在使用OpenGL ES 2.0编写一个android应用程序。 What I'm trying to do is to manipulate fragment's color depending on it's actual r value. 我想做的是根据片段的实际r值来操纵片段的颜色。 Simple exercise but it made me to ask my very first question here. 简单的练习,但是让我在这里问我的第一个问题。 The basic code looks like this: 基本代码如下所示:

void main() {
    vec4 tex = texture2D(u_TextureUnit, v_TextureCoordinates);
    float r = tex.r;
    float g = tex.g;
    float b = tex.b;

    if (tex.r > 0.5f) {
        r = 1;
    } else {
        r = 0;
    }

    gl_FragColor = vec4(r, g, b, tex.a);
}

The problem is the if-else block. 问题是if-else块。 When it's there, I'm getting nothing but black screen. 当它在那里时,除了黑屏外我什么都没有。 After removing it, objects are rendered properly, without any color modification of course. 删除对象后,可以正确渲染对象,而无需进行任何颜色修改。

When I remove if-else block and change the last line to for example: 当我删除if-else块并将最后一行更改为例如时:

gl_FragColor = vec4(1, g, b, tex.a);

it's working fine too, so I'm guessing that the conditional statement makes the problem itself. 它也可以正常工作,所以我猜条件语句本身就是问题所在。

How can I get the fragment's r value modified instead of constantly getting whole screen black? 如何修改片段的r值,而不是不断使整个屏幕变黑?

You should check the success of your shader compilations. 您应该检查着色器编译是否成功。 The code to do this will be something like this: 执行此操作的代码将如下所示:

int[] statusVal = new int[1];
GLES20.glGetShaderiv(shaderId, GLES20.GL_COMPILE_STATUS, statusVal, 0);
if (statusVal[0] == GLES20.GL_FALSE) {
    String statusStr = GLES20.glGetShaderInfoLog(shaderId);
    // Look at statusStr to see error messages.
}

In your if statement: 在您的if语句中:

if (tex.r > 0.5f) {
    r = 1;
} else {
    r = 0;
}

there are two issues: 有两个问题:

  1. There are no automatic type conversions in the GLSL version in ES 2.0. ES 2.0中的GLSL版本中没有自动类型转换。 1 and 0 are of type int , and you assign them to a float variable. 10的类型为int ,并将它们分配给float变量。 While that's just a bad habit (IMHO) in languages like C and C++, it is not supported in ES 2.0 shaders. 尽管在C和C ++等语言中这只是一个坏习惯(IMHO),但ES 2.0着色器不支持它。

  2. 0.5f is not a valid float constant. 0.5f不是有效的float常量。 The f postfix is not supported in ES 2.0 shaders. ES 2.0着色器不支持f后缀。 Some vendors let you get away with it without reporting a compiler error, others will correctly fail the shader compilation. 一些供应商让您在不报告编译器错误的情况下摆脱了阴影,而其他供应商将正确使着色器编译失败。

With these two issues fixed, the code will look like this: 修复了这两个问题后,代码将如下所示:

if (tex.r > 0.5) {
    r = 1.0;
} else {
    r = 0.0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM