2015-01-31 3 views
2

Я добавляю некоторые скромные функции в older video game engine. Он имеет простые плоские тени, используя буфер трафарета и projection matrix popularized in SGI's cookbook лет назад.GLSL мягкие плоские тени: преобразование матрицы

Not half bad looking But if the shadow could fade out with the light's radius..

Они работают достаточно хорошо, за исключением того, что они не выцветают в интенсивности в зависимости от затухания источника света. Это то, что я хотел бы сделать в своем шейдере. К сожалению, я не могу понять правильное преобразование, чтобы это разрешить. Вот мой исходный код шейдера. Я застрял с #version 120.

EDIT: Это теперь обновленный шейдер, который работает

/* 
* @brief Planar shadows vertex shader. 
*/ 

#version 120 

uniform mat4 MATRIX; 

varying vec4 point; 

/* 
* @brief 
*/ 
void ShadowVertex() { 

    point = gl_ModelViewMatrix * MATRIX * gl_Vertex;  
} 

/* 
* @brief Program entry point. 
*/ 
void main(void) { 

    // mvp transform into clip space 
    gl_Position = gl_ModelViewProjectionMatrix * MATRIX * gl_Vertex; 

    // and primary color 
    gl_FrontColor = gl_Color; 

    ShadowVertex(); 
} 
/* 
* @brief Planar shadows fragment shader. 
*/ 

#version 120 

uniform vec4 LIGHT; 

varying vec4 point; 

/* 
* @brief 
*/ 
void ShadowFragment(void) { 

    float dist = distance(LIGHT.xyz, point.xyz/point.w); 

    float intensity = (LIGHT.w - dist)/LIGHT.w; 

    if (intensity <= 0.0) 
     discard; 

    gl_FragColor.a = min(gl_Color.a, intensity); 
} 

/* 
* @brief Program entry point. 
*/ 
void main(void) { 

    gl_FragColor = gl_Color; 

    ShadowFragment(); 
} 

MATRIX является проекцией матрицы из плоской теневой учебник. Форма тени правильная, поэтому я не верю, что там есть какая-то проблема. Я понимаю, что это не аффинная трансформация, но я не понимаю последствий.

LIGHT.xyz - координаты источника света в пространстве глаза. LIGHT.w - радиус света (затухание). Я запутался в том, как получить значимое сравнение от light до point в шейдере фрагментов - или действительно, почему то, что я пытаюсь сделать, ошибочно. В конечном итоге у меня нет теней; другими словами, вычисленное значение intensity всегда равно <= 0.0.

ответ

1

Полезные члены сообщества ## OpenGL на Freenode указали мою ошибку. Поскольку проекционная матрица MATRIX не дает аффинного преобразования, мне нужно было разделить расчет расстояния на point.w. Это дает правильное расстояние между LIGHT.xyz и point.xyz.

Короче говоря, если вы работаете с матрицей проекций, убедитесь, что вы понимаете, как обращаться со всеми четырьмя компонентами координат или знать, кого спросить :)