【问题标题】:Passing float to GLSL shader does nothing将浮点数传递给 GLSL 着色器什么都不做
【发布时间】:2012-04-22 08:55:28
【问题描述】:

我在将光泽度因子发送到凹凸贴图着色器时遇到问题。 结果总是这样:http://i.imgur.com/unzdx.jpg

但是,如果我将着色器中的值硬编码为 0.0,它就可以正常工作。 当我将 0.0 发送到着色器时,结果如上图所示。

有什么想法吗?

这是我的着色器

#version 110

uniform sampler2D tex;
uniform sampler2D bmap;

uniform bool boolBump;
uniform vec4 vecColor;
uniform bool onlyColor;

uniform float fTransparencyThresh;
uniform float fShininess;
uniform float alpha;

varying vec3 vecLight;
varying vec3 vecEye;
varying vec3 vecNormal;

vec4 getLighting()
{
    //Ambient part
    vec4 color = (gl_FrontLightModelProduct.sceneColor * gl_FrontMaterial.ambient) + (gl_LightSource[0].ambient * gl_FrontMaterial.ambient);

    //For bump mapping, the normal comes from the bump map texture lookup
    vec3 n = normalize(vecNormal);
    if(boolBump)
    {
         n = normalize(texture2D(bmap, gl_TexCoord[0].st).xyz * 2.0 - 1.0);
    }

    vec3 l = normalize(vecLight);

    //Lambert term
    float NdotL = dot(n, l);

    if(NdotL > 0.0)
    {
        //Diffuse part
        color += gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * max(0.0, NdotL);

        //Specular part
        vec3 e = normalize(vecEye);
        vec3 r = normalize(-reflect(l,n));  

        float spec = pow(max(0.0, dot(r, e)), fShininess);

        color += gl_LightSource[0].specular * gl_FrontMaterial.specular * spec;
    }

    return color;
}

void main(void)
{
    vec4 texel = texture2D(tex, gl_TexCoord[0].st);
    if(texel.a < fTransparencyThresh)
        discard;

    //Get shading
        vec4 color = getLighting();

    //Color only mode?
    if(onlyColor)
    {
        color *= vecColor;
    }
    else
    {
        color *= texel;
    }   

    //Set fragment color, alpha comes from MTL file
    gl_FragColor = vec4(color.xyz, alpha);
}

编辑,OpenGL 代码:

void MyClass::sendToShader(const OBJ::StelModel* pStelModel, Effect cur, bool& tangEnabled, int& tangLocation)
{
    int location;
    tangEnabled = false;

    if(cur != No)
    {
        location = curShader->uniformLocation("fTransparencyThresh");
        curShader->setUniform(location, fTransparencyThresh);

        location = curShader->uniformLocation("alpha");
        curShader->setUniform(location, pStelModel->pMaterial->alpha);

        location = curShader->uniformLocation("fShininess");
        curShader->setUniform(location, 0.0f);

...

编辑:即使这样也行不通:

GLint loc = glGetUniformLocation(curShader->program, "fShininess");
glUniform1f(loc, 0.0f);

【问题讨论】:

  • 请同时显示opengl代码。
  • 已编辑,抱歉忘记了 :)

标签: opengl glsl shader


【解决方案1】:

注意 pow(0, 0) 是未定义的。这意味着如果dot(r, e) == 0fShininess == 0spec 是未定义的。

【讨论】:

  • 我想这就是问题所在。我稍后会检查一下。谢谢
  • 问题是,如果我将着色器内的 fShininess 硬编码为 0.0,它可以正常工作。如果我将 0.0 发送到着色器 -> 黑色斑点。
  • 如果在着色器中将其设置为0.0f 会怎样?我不知道;在 UB 和我缺乏复杂的知识之间,这很难推测。
  • 我假设您的意思是硬编码 0.0f?例如:float power = pow(max(0.0, dot(r,e)), 0.0f)) 我这样做了,效果很好,这就是为什么我对此感到如此困惑
  • 是的。 0.0 怎么样?还是double power?无论如何,我建议您使用 .00001(即 0 的近似值)或 if 来解决 0^0 问题。
【解决方案2】:

当你调用 glUniform 时,你确定程序是主动绑定的吗?你在任何地方检查 glGetError 吗?

【讨论】:

  • 不,我没有,但其他值似乎没问题。如果我将镜面反射部分拿走或将其设置为 0.0,则照明工作正常。如果程序没有绑定就不会这样吧?
  • 请手动检查 glGetError 和 glGetUniformLocation 的返回值。它可以节省大量的调试时间来确定。
  • 错误总是 0 位置是 3 这是上面的 GLint loc = ... 代码
  • 这真的很奇怪,如果我在其中发送 0.0f,我会得到所有这些黑色伪影,但如果我发送 0.1f 似乎没问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-03
  • 1970-01-01
相关资源
最近更新 更多