1

我正在编写一个 GLSL 程序,作为在 Maya(一个闭源 3D 应用程序)内部运行的插件的一部分。gl_LightSourceMaya 使用固定函数管道来定义它的灯光,因此我的程序必须使用兼容性配置文件从阵列中获取它的灯光信息。我的灯光评估工作正常(感谢 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_LightSourcegl_MaxLightsgl_LightSource[i].diffuse

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

4

2 回答 2

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);
}
于 2013-05-07T17:20:24.570 回答
1

不幸的是,我查看了 GLSL 规范,但没有看到任何提供此信息的内容。我还看到另一个线程似乎得出了相同的结论。

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

于 2012-07-06T18:18:33.093 回答