【问题标题】:Point light/spotlight attenuation in glsl 1.3+?glsl 1.3+中的点光/聚光灯衰减?
【发布时间】:2011-04-10 20:00:17
【问题描述】:

我一直在研究 OpenGL 的 Superbible(第 5 版)点光源示例。

我发现它们缺少集成到旧光照模型中的常量、线性和二次衰减值,所以我根据ogre guide 编写了一个带有衰减值的点光着色器。

结果完全离奇。 如何在新的 glsl 上获得明显的光衰减?有衰减常数的 glsl 表吗?

图片

99 距离处的衰减 - 球体为黑色,光为蓝色-

50 距离处的衰减 - 球体为黑色,光为蓝色-

距离 16 处的衰减 - 球体为黑色,光为蓝色-

距离 2 处的衰减 - 球体为黑色,光为蓝色-

示例顶点和片段程序:

顶点程序:

//point light per pixel vertex program 
#version 130

// Incoming per vertex... position and normal
in vec4 vVertex;
in vec3 vNormal;


uniform mat4   mvpMatrix;
uniform mat4   mvMatrix;
uniform mat3   normalMatrix;
uniform vec3   vLightPosition;

// Color to fragment program
smooth out vec3 vVaryingNormal;
smooth out vec3 vVaryingLightDir;

out float dist;
out float constantAttenuation;
out float linearAttenuation;
out float quadraticAttenuation; 

void main(void) 
    { 
    // Get surface normal in eye coordinates
    vVaryingNormal = normalMatrix * vNormal;

    // Get vertex position in eye coordinates
    vec4 vPosition4 = mvMatrix * vVertex;
    vec3 vPosition3 = vPosition4.xyz / vPosition4.w;

    //get distance to light source
     dist=length(vLightPosition-vPosition3);

     //write proper attenuation values

    if (dist<7.0){
      constantAttenuation=1.0;
      linearAttenuation=0.7;
      quadraticAttenuation=1.8; 
    }

    else if (dist<13.0){
      constantAttenuation=1.0;
      linearAttenuation=0.35;
      quadraticAttenuation=0.44; 
    }

    else if (dist<20.0){
      constantAttenuation=1.0;
      linearAttenuation=0.22;
      quadraticAttenuation=0.20; 
    }

    if (dist<32.0){
      constantAttenuation=1.0;
      linearAttenuation=0.14;
      quadraticAttenuation=0.07; 
    }
    if (dist<50.0){
      constantAttenuation=1.0;
      linearAttenuation=0.09;
      quadraticAttenuation=0.32; 
    }

    if (dist<65.0){
      constantAttenuation=1.0;
      linearAttenuation=0.07;
      quadraticAttenuation=0.017; 
    }

    if (dist<100.0){
      constantAttenuation=1.0;
      linearAttenuation=0.045;
      quadraticAttenuation=0.0075; 
    }



    // Get vector to light source
    vVaryingLightDir = normalize(vLightPosition - vPosition3);

    // Don't forget to transform the geometry!
    gl_Position = mvpMatrix * vVertex;
    }

片段程序:

//point light per pixel fragment program 

#version 130

out vec4 vFragColor;

uniform vec4    ambientColor;
uniform vec4    diffuseColor;   
uniform vec4    specularColor;

smooth in vec3 vVaryingNormal;
smooth in vec3 vVaryingLightDir;

in float dist;
in float constantAttenuation;
in float linearAttenuation;
in float quadraticAttenuation; 

void main(void){ 

    float att;

    att = 1.0 / constantAttenuation + linearAttenuation*dist +quadraticAttenuation*dist*dist;

    // Dot product gives us diffuse intensity
    float diff = max(0.0, dot(normalize(vVaryingNormal), normalize(vVaryingLightDir)));

    // Multiply intensity by diffuse color, force alpha to 1.0
    vFragColor = att*(diff * diffuseColor +ambientColor); // attenuation affects the diffuse component

    // Specular Light
    vec3 vReflection = normalize(reflect(-normalize(vVaryingLightDir), normalize(vVaryingNormal)));

    float spec = max(0.0, dot(normalize(vVaryingNormal), vReflection));
    if(diff != 0) {
        float fSpec = pow(spec, 128.0);
        vFragColor.rgb += (att*vec3 (fSpec, fSpec, fSpec)); // attenuation affects the specular component
        }
    }

【问题讨论】:

  • 图片是否有机会帮助澄清“离奇”?

标签: glsl


【解决方案1】:

你的衰减公式完全不正确:

att = 1.0 / constantAttenuation + linearAttenuation*dist +quadraticAttenuation*dist*dist;

应该改为:

att = constantAttenuation / ((1+linearAttenuation*dist)*(1+quadraticAttenuation*dist*dist)).

这就是距离增加时球体变亮的原因。尝试正确的公式并发布结果。

【讨论】:

  • 是的,我也注意到了。谢谢。
  • 文档中记录的公式在哪里?我在opengl.org/sdk/docs/man2/xhtml/glLight.xml 发现“它的强度被常数因子之和的倒数衰减,线性因子乘以光和被照亮的顶点之间的距离”,这看起来像第一个公式。
【解决方案2】:

我最终只使用了这个衰减值,效果可以接受:

      constantAttenuation=1.0;
      linearAttenuation=0.22;
      quadraticAttenuation=0.20; 

衰减部分也缺少几个括号。

【讨论】:

    猜你喜欢
    • 2015-06-19
    • 1970-01-01
    • 2018-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-28
    • 2015-05-02
    相关资源
    最近更新 更多