Войти
ПрограммированиеТермины

Per-pixel lighting (Попиксельное освещение)

Один из способов расчета освещения, в котором освещенность расчитывается для отдельно взятого пикселя. Данная техника позволяет осуществить ряд попиксельных эффектов, таких как Bump mapping или Parallax mapping. С появлением программируемых конвееров попиксельное освещение стало часто использоваться в играх. Яркий пример такой игры - Doom 3.

Попиксельное освещение реализуется относительно просто. Вот пример GLSL шейдера:

<vertex>
varying vec3 v_FragmentPosition;
varying vec3 v_FragmentNormal;

void main( void )
{
    gl_Position    = gl_ModelViewProjectionMatrix * gl_Vertex;
    gl_TexCoord[0] = gl_MultiTexCoord0;

    // ** Записываем координаты вершины, во фрагментом шейдере получим
    // ** интерполированное значение - координаты фрагмента
    v_FragmentPosition  = gl_Vertex.xyz;

    v_FragmentNormal  = gl_Normal;
}

<fragment>
uniform sampler2D u_DiffuseMap;
uniform vec3 u_Light;
uniform vec3 u_Camera;

varying vec3 v_FragmentPosition;
varying vec3 v_FragmentNormal;

const vec4  k_LightColor = vec4( 1.0, 0.5, 0.25, 1.0 );
const float k_Shininess = 64.0;

// ** Коэфициенты затухания света
const float k_ConstAttenuation = 0.5;
const float k_LinearAttenuation = 0.05;
const float k_QuadricAttenuation = 0.001;

void main( void )
{
    vec3  L = u_Light - v_FragmentPosition;

    // ** Используется при расчете затухания света
    float distance = length( L );

    L = normalize( L );
    vec3  N = normalize( v_FragmentNormal );

    // ** Вектор H используются для расчета глянцевости (specular) фрагмента
    vec3  E = normalize( u_Camera - v_FragmentPosition );
    vec3  H = normalize( L + E ); // ** Half-vector

    // ** Расчет коэф. затухания
    float attenuation = 1.0 / ( k_ConstAttenuation + k_LinearAttenuation * distance + k_QuadricAttenuation * distance * distance );

    float diffuse = clamp( dot( L, N ), 0.0, 1.0 );
    float specular  = pow( clamp( dot( N, H ), 0.0, 1.0 ), k_Shininess );
  
    if( diffuse <= 0.0 ) {
        specular = 0.0;
    }
  
    vec4 diffuseColor  = diffuse * gl_FrontMaterial.diffuse * k_LightColor * attenuation;
    vec4 specularColor = specular * k_LightColor * attenuation;

    // ** Собираем все в кучу :)
    gl_FragColor = ( diffuseColor + specularColor + gl_FrontMaterial.ambient + gl_FrontMaterial.emission ) *
                  texture2D( u_DiffuseMap, gl_TexCoords[0].xy );
}

Результат работы шейдера:
term_ppl | Per-pixel lighting (Попиксельное освещение)

Что такое Per-pixel lighting (Попиксельное освещение)?

20 мая 2007 (Обновление: 18 мар. 2008)