检测glsl兼容性配置文件中是否启用了gl_LightSource

时间:2012-07-06 15:22:41

标签: opengl glsl maya

我正在编写一个GLSL程序,作为在封闭源3D应用程序Maya中运行的插件的一部分。 Maya使用固定功能管道来定义它的灯光,因此我的程序必须使用兼容性配置文件从gl_LightSource阵列获取它的轻量信息。我的光评估工作正常(thanks Nicol Bolas)除了一件事,我无法弄清楚如何确定数组中的特定光是启用还是禁用。以下是我到目前为止的情况:

#version 410 compatibility

vec3 incidentLight (in gl_LightSourceParameters light, in vec3 position)
{
    if (light.position.w == 0) {
        return normalize (-light.position.xyz);
    } else {
        vec3 offset = position - light.position.xyz;
        float distance = length (offset);
        vec3 direction = normalize (offset);
        float intensity;
        if (light.spotCutoff <= 90.) {
            float spotCos = dot (direction, normalize (light.spotDirection));
            intensity = pow (spotCos, light.spotExponent) *
                    step (light.spotCosCutoff, spotCos);
        } else {
            intensity = 1.;
        }
        intensity /= light.constantAttenuation +
                light.linearAttenuation * distance +
                light.quadraticAttenuation * distance * distance;
        return intensity * direction;
    }
}

void main ()
{
    for (int i = 0; i < gl_MaxLights; ++i) {
        if (/* ??? gl_LightSource[i] is enabled ??? */ 1) {
            vec3 incident = incidentLight (gl_LightSource[i], position);
            <snip>
        }
    }
    <snip>
}

当Maya启用新灯时,我的程序按预期工作,但是当Maya禁用之前启用的灯(可能使用glDisable (GL_LIGHTi))时,它的参数不会在gl_LightSource数组和gl_MaxLights中重置不会改变,所以我的程序继续在它的着色计算中使用那些陈旧的光信息。虽然我没有在上面显示它,但是浅色(例如gl_LightSource[i].diffuse)在禁用后仍会继续具有陈旧的非零值。

Maya使用固定功能pipline(无GLSL)绘制所有其他几何体,并且这些对象正确地忽略禁用的光,我如何在GLSL中模仿这种行为?

2 个答案:

答案 0 :(得分:2)

const vec4 AMBIENT_BLACK = vec4(0.0, 0.0, 0.0, 1.0);
const vec4 DEFAULT_BLACK = vec4(0.0, 0.0, 0.0, 0.0);

bool isLightEnabled(in int i)
{    
    // A separate variable is used to get    
    // rid of a linker error.    
    bool enabled = true;       
    // If all the colors of the Light are set    
    // to BLACK then we know we don't need to bother    
    // doing a lighting calculation on it.    

    if ((gl_LightSource[i].ambient  == AMBIENT_BLACK) &&        
        (gl_LightSource[i].diffuse  == DEFAULT_BLACK) &&        
        (gl_LightSource[i].specular == DEFAULT_BLACK))        
    enabled = false;    
    return(enabled);
}

答案 1 :(得分:1)

不幸的是我查看了GLSL规范,但我没有看到提供此信息的任何内容。我也看到another thread似乎得出了同样的结论。

有什么方法可以修改插件中的灯光值,或者添加一个可以用作启用/禁用标志的额外制服?