简体   繁体   English

用于纹理、颜色和纹理/颜色的片段着色器 GLSL

[英]Fragment Shader GLSL for texture, color and texture/color

I want to accomplish a GLSL Shader, that can texture and color my vertex objects.我想完成一个 GLSL 着色器,它可以对我的顶点对象进行纹理化和着色。 In fact, it works for me in 2 from 3 cases:事实上,它在 3 个案例中的 2 个对我有用:

1) If I only have an texture assigned (but no specific color - so the color is "white"), I simply get an textured object - works 1)如果我只分配了一个纹理(但没有特定颜色 - 所以颜色是“白色”),我只是得到一个带纹理的 object - 有效

2) If I have an texture and an color assigned, I get an textured Object modulated with that color - works 2)如果我分配了纹理和颜色,我会得到一个用该颜色调制的纹理 Object - 有效

3) If I only have an color assigned but no texture, I get an black object - doesn't work 3) 如果我只指定了颜色但没有纹理,我会得到黑色 object - 不起作用

My Shader looks like this:我的着色器看起来像这样:

varying lowp vec4 colorVarying;
varying mediump vec2 texcoordVarying;
uniform sampler2D texture;

void main(){
    gl_FragColor = texture2D(texture, texcoordVarying) * colorVarying;
}

I guess that, texture2D(...,...) returns zero if no texture is assigned - so that seems to be the problem.我猜想,如果没有分配纹理,则 texture2D(...,...) 返回零 - 所以这似乎是问题所在。 Is there a way in GLSL I can check, if no texture is assigned (in this case, I want simply gl_FragColor = colorVarying;)有没有办法在 GLSL 中检查,如果没有分配纹理(在这种情况下,我只想 gl_FragColor = colorVarying;)

"If" isn't really an option in an GLSL Shader, if I understanded correctly - any ideas to accomplish this?如果我理解正确的话,“如果”在 GLSL 着色器中并不是一个真正的选项 - 有什么想法可以做到这一点吗? Or is it really necessary to make 2 different shaders for both cases?还是真的有必要为这两种情况制作 2 个不同的着色器?

Like you I'd picked up the general advice that 'if' is to be avoided on current mobile hardware, but a previous optimisation discussion on StackOverflow seemed to suggest it wasn't a significant hurdle.和你一样,我接受了一般建议,即在当前的移动硬件上要避免使用“如果”,但之前关于 StackOverflow 的优化讨论似乎表明这不是一个重大障碍。 So don't write it off.所以不要把它写下来。 In any case, the GLSL compiler is reasonably smart and may chose to switch which code it actually runs depending on the values set for uniforms, though in that case all you're getting is the same as if you'd just supplied alternative shaders.在任何情况下,GLSL 编译器都相当聪明,并且可能会根据为制服设置的值选择切换它实际运行的代码,尽管在这种情况下,您得到的一切都与您刚刚提供替代着色器一样。

That said, if you're absolutely certain you want to use the same shader for all purposes and want to avoid if statements then you probably want something like:也就是说,如果您绝对确定要为所有目的使用相同的着色器并希望避免使用 if 语句,那么您可能想要类似的东西:

uniform lowp float textureFlag;

[...]

gl_FragColor = textureFlag * texture2D(texture, texcoordVarying) * colorVarying + 
               (1.0 - textureFlag) * colorVarying;

Or even:甚至:

gl_FragColor = mix(
                     colorVarying,
                     texture2D(texture, texcoordVarying) * colorVarying,
                     textureFlag
                  )

With you setting textureFlag to 1.0 or 0.0 depending on whether you want the texture values to be factored in.将 textureFlag 设置为 1.0 或 0.0,具体取决于您是否希望将纹理值考虑在内。

I'm not aware of any way to determine (i) whether a sampler2D is pointed to an actual texture unit;我不知道有什么方法可以确定(i)sampler2D 是否指向实际的纹理单元; and (ii) whether a particular texture unit has a buffer bound to it for which data has been uploaded. (ii) 一个特定的纹理单元是否有一个绑定到它的缓冲区,数据已被上传。

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

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