Затухание точечного света / прожектора в glsl 1.3+? - PullRequest
1 голос
/ 03 апреля 2011

Я работал над примерами из OpenBL Superbible (5th Edition).

Я обнаружил, что в них отсутствуют постоянные, линейные и квадратичные значения ослабления, интегрированные в старую модель освещения, поэтому я пошел и написал точечный шейдер освещения со значениями ослабления, основанными на этом огре .

Результаты были совершенно странными. Что можно сделать, чтобы получить ощутимое ослабление света на новом glsl?Есть ли таблица glsl для констант ослабления?

Фотографии

Затухание на расстоянии 99 - сфера черная, свет синий -
enter image description here

Затухание на расстоянии 50 - сфера черная, свет - синий -
enter image description here

Затухание на расстоянии 16 - сфера черная, свет синий -
enter image description here

Затухание на расстоянии 2 - сфера черная, свет синий -
enter image description here

Примеры программ вершин и фрагментов:

Программы вершин:

//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
        }
    }

Ответы [ 2 ]

1 голос
/ 04 апреля 2011

Ваша формула затухания совершенно неверна:

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

Должно быть вместо:

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

Вот почему вы получаете сферу светлее, когда расстояние увеличивается. Попробуйте правильную формулу и опубликуйте результат.

0 голосов
/ 04 апреля 2011

В итоге я использовал только эти значения затухания, все работает приемлемо:

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

Там также отсутствует пара скобок на делении затухания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...