GLSL软平面阴影:矩阵变换
GLSL soft planar shadows: matrix transformation
我正在为 older video game engine. It has simple planar shadows, using the stencil buffer and a projection matrix popularized in SGI's cookbook 年前添加一些适度的功能。
这些效果相当好,除了它们不会根据光源的衰减而减弱强度。这就是我想在我的着色器中完成的。不幸的是,我无法找出允许这样做的正确转换。这是我的着色器源代码。我坚持 #version 120
.
编辑:这是现在可用的更新着色器
/*
* @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
是光源在眼中的坐标space。 LIGHT.w
是光的半径(衰减)。我感到困惑的是如何在片段着色器中从 light
到 point
进行有意义的比较——或者实际上,为什么我在那里尝试的是错误的。我最终完全没有阴影;换句话说,计算出的 intensity
值总是 <= 0.0
.
Freenode 上##OpenGL 的热心社区成员指出了我的错误。由于投影矩阵 MATRIX
不产生仿射变换,我需要将距离计算除以 point.w
。这会产生 LIGHT.xyz
和 point.xyz
之间的正确距离。
简而言之,如果您正在使用这样的投影矩阵,请确保您了解如何处理所有 4 个坐标分量,或者知道该问谁:)
我正在为 older video game engine. It has simple planar shadows, using the stencil buffer and a projection matrix popularized in SGI's cookbook 年前添加一些适度的功能。
这些效果相当好,除了它们不会根据光源的衰减而减弱强度。这就是我想在我的着色器中完成的。不幸的是,我无法找出允许这样做的正确转换。这是我的着色器源代码。我坚持 #version 120
.
编辑:这是现在可用的更新着色器
/*
* @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
是光源在眼中的坐标space。 LIGHT.w
是光的半径(衰减)。我感到困惑的是如何在片段着色器中从 light
到 point
进行有意义的比较——或者实际上,为什么我在那里尝试的是错误的。我最终完全没有阴影;换句话说,计算出的 intensity
值总是 <= 0.0
.
Freenode 上##OpenGL 的热心社区成员指出了我的错误。由于投影矩阵 MATRIX
不产生仿射变换,我需要将距离计算除以 point.w
。这会产生 LIGHT.xyz
和 point.xyz
之间的正确距离。
简而言之,如果您正在使用这样的投影矩阵,请确保您了解如何处理所有 4 个坐标分量,或者知道该问谁:)