mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 10:47:11 +02:00
Working on support for specular components in deferred lights.
This commit is contained in:
parent
618f6415da
commit
7074d96c04
4 changed files with 121 additions and 48 deletions
|
@ -17,10 +17,44 @@ uniform sampler2D diffuseMap;
|
||||||
// the normal texture
|
// the normal texture
|
||||||
uniform sampler2D normalMap;
|
uniform sampler2D normalMap;
|
||||||
|
|
||||||
|
// the specular texture
|
||||||
|
uniform sampler2D specularMap;
|
||||||
|
|
||||||
|
// the depth texture
|
||||||
|
uniform sampler2D depthMap;
|
||||||
|
|
||||||
|
// the distance to the near clip plane
|
||||||
|
uniform float near;
|
||||||
|
|
||||||
|
// scale factor for depth: (far - near) / far
|
||||||
|
uniform float depthScale;
|
||||||
|
|
||||||
|
// offset for depth texture coordinates
|
||||||
|
uniform vec2 depthTexCoordOffset;
|
||||||
|
|
||||||
|
// scale for depth texture coordinates
|
||||||
|
uniform vec2 depthTexCoordScale;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// compute the base color based on OpenGL lighting model
|
// compute the view space position using the depth
|
||||||
|
float z = near / (texture2D(depthMap, gl_TexCoord[0].st).r * depthScale - 1.0);
|
||||||
|
vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 0.0);
|
||||||
|
|
||||||
|
// get the normal from the map
|
||||||
vec4 normal = texture2D(normalMap, gl_TexCoord[0].st);
|
vec4 normal = texture2D(normalMap, gl_TexCoord[0].st);
|
||||||
gl_FragColor = vec4((texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor +
|
vec4 normalizedNormal = normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0);
|
||||||
gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * max(0.0, dot(normal * 2.0 -
|
|
||||||
vec4(1.0, 1.0, 1.0, 2.0), gl_LightSource[0].position)))).rgb, normal.a);
|
// compute the base color based on OpenGL lighting model
|
||||||
|
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);
|
||||||
|
float facingLight = step(0.0, diffuse);
|
||||||
|
vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor +
|
||||||
|
gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
||||||
|
|
||||||
|
// compute the specular multiplier (sans exponent)
|
||||||
|
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(position)),
|
||||||
|
normalizedNormal));
|
||||||
|
|
||||||
|
// add specular contribution
|
||||||
|
vec4 specularColor = texture2D(specularMap, gl_TexCoord[0].st);
|
||||||
|
gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 255.0) * specularColor.rgb, normal.a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,9 @@ uniform sampler2D diffuseMap;
|
||||||
// the normal texture
|
// the normal texture
|
||||||
uniform sampler2D normalMap;
|
uniform sampler2D normalMap;
|
||||||
|
|
||||||
|
// the specular texture
|
||||||
|
uniform sampler2D specularMap;
|
||||||
|
|
||||||
// the depth texture
|
// the depth texture
|
||||||
uniform sampler2D depthMap;
|
uniform sampler2D depthMap;
|
||||||
|
|
||||||
|
@ -51,15 +54,27 @@ void main(void) {
|
||||||
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[shadowIndex], position),
|
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[shadowIndex], position),
|
||||||
dot(gl_EyePlaneR[shadowIndex], position));
|
dot(gl_EyePlaneR[shadowIndex], position));
|
||||||
|
|
||||||
// compute the color based on OpenGL lighting model, use the alpha from the normal map
|
// get the normal from the map
|
||||||
vec4 normal = texture2D(normalMap, gl_TexCoord[0].st);
|
vec4 normal = texture2D(normalMap, gl_TexCoord[0].st);
|
||||||
float diffuse = dot(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0), gl_LightSource[0].position);
|
vec4 normalizedNormal = normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0);
|
||||||
|
|
||||||
|
// average values from the shadow map
|
||||||
|
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);
|
||||||
float facingLight = step(0.0, diffuse) * 0.25 *
|
float facingLight = step(0.0, diffuse) * 0.25 *
|
||||||
(shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
(shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r +
|
shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r +
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r +
|
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r +
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r);
|
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r);
|
||||||
|
|
||||||
|
// compute the base color based on OpenGL lighting model
|
||||||
vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor +
|
vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor +
|
||||||
gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
||||||
gl_FragColor = vec4(baseColor.rgb, normal.a);
|
|
||||||
|
// compute the specular multiplier (sans exponent)
|
||||||
|
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))),
|
||||||
|
normalizedNormal));
|
||||||
|
|
||||||
|
// add specular contribution
|
||||||
|
vec4 specularColor = texture2D(specularMap, gl_TexCoord[0].st);
|
||||||
|
gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 255.0) * specularColor.rgb, normal.a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,9 @@ uniform sampler2D diffuseMap;
|
||||||
// the normal texture
|
// the normal texture
|
||||||
uniform sampler2D normalMap;
|
uniform sampler2D normalMap;
|
||||||
|
|
||||||
|
// the specular texture
|
||||||
|
uniform sampler2D specularMap;
|
||||||
|
|
||||||
// the depth texture
|
// the depth texture
|
||||||
uniform sampler2D depthMap;
|
uniform sampler2D depthMap;
|
||||||
|
|
||||||
|
@ -46,15 +49,27 @@ void main(void) {
|
||||||
// compute the corresponding texture coordinates
|
// compute the corresponding texture coordinates
|
||||||
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[0], position), dot(gl_EyePlaneT[0], position), dot(gl_EyePlaneR[0], position));
|
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[0], position), dot(gl_EyePlaneT[0], position), dot(gl_EyePlaneR[0], position));
|
||||||
|
|
||||||
// compute the color based on OpenGL lighting model, use the alpha from the normal map
|
// get the normal from the map
|
||||||
vec4 normal = texture2D(normalMap, gl_TexCoord[0].st);
|
vec4 normal = texture2D(normalMap, gl_TexCoord[0].st);
|
||||||
float diffuse = dot(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0), gl_LightSource[0].position);
|
vec4 normalizedNormal = normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0);
|
||||||
|
|
||||||
|
// average values from the shadow map
|
||||||
|
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);
|
||||||
float facingLight = step(0.0, diffuse) * 0.25 *
|
float facingLight = step(0.0, diffuse) * 0.25 *
|
||||||
(shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
(shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r +
|
shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r +
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r +
|
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r +
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r);
|
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r);
|
||||||
|
|
||||||
|
// compute the base color based on OpenGL lighting model
|
||||||
vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor +
|
vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor +
|
||||||
gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
||||||
gl_FragColor = vec4(baseColor.rgb, normal.a);
|
|
||||||
|
// compute the specular multiplier (sans exponent)
|
||||||
|
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))),
|
||||||
|
normalizedNormal));
|
||||||
|
|
||||||
|
// add specular contribution
|
||||||
|
vec4 specularColor = texture2D(specularMap, gl_TexCoord[0].st);
|
||||||
|
gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 255.0) * specularColor.rgb, normal.a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,12 @@ void DeferredLightingEffect::render() {
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryNormalTextureID());
|
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryNormalTextureID());
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimarySpecularTextureID());
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE3);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID());
|
||||||
|
|
||||||
// get the viewport side (left, right, both)
|
// get the viewport side (left, right, both)
|
||||||
int viewport[4];
|
int viewport[4];
|
||||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||||
|
@ -68,15 +74,15 @@ void DeferredLightingEffect::render() {
|
||||||
float sMin = viewport[VIEWPORT_X_INDEX] / (float)primaryFBO->width();
|
float sMin = viewport[VIEWPORT_X_INDEX] / (float)primaryFBO->width();
|
||||||
float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)primaryFBO->width();
|
float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)primaryFBO->width();
|
||||||
|
|
||||||
if (Menu::getInstance()->getShadowsEnabled()) {
|
ProgramObject* program = &_directionalLight;
|
||||||
glActiveTexture(GL_TEXTURE2);
|
const LightLocations* locations = &_directionalLightLocations;
|
||||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID());
|
bool shadowsEnabled = Menu::getInstance()->getShadowsEnabled();
|
||||||
|
if (shadowsEnabled) {
|
||||||
glActiveTexture(GL_TEXTURE3);
|
glActiveTexture(GL_TEXTURE4);
|
||||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID());
|
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID());
|
||||||
|
|
||||||
ProgramObject* program = &_directionalLightShadowMap;
|
program = &_directionalLightShadowMap;
|
||||||
const LightLocations* locations = &_directionalLightShadowMapLocations;
|
locations = &_directionalLightShadowMapLocations;
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) {
|
||||||
program = &_directionalLightCascadedShadowMap;
|
program = &_directionalLightCascadedShadowMap;
|
||||||
locations = &_directionalLightCascadedShadowMapLocations;
|
locations = &_directionalLightCascadedShadowMapLocations;
|
||||||
|
@ -90,38 +96,42 @@ void DeferredLightingEffect::render() {
|
||||||
program->setUniformValue(locations->shadowScale,
|
program->setUniformValue(locations->shadowScale,
|
||||||
1.0f / Application::getInstance()->getTextureCache()->getShadowFramebufferObject()->width());
|
1.0f / Application::getInstance()->getTextureCache()->getShadowFramebufferObject()->width());
|
||||||
|
|
||||||
float left, right, bottom, top, nearVal, farVal;
|
|
||||||
glm::vec4 nearClipPlane, farClipPlane;
|
|
||||||
Application::getInstance()->computeOffAxisFrustum(
|
|
||||||
left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
|
||||||
program->setUniformValue(locations->nearLocation, nearVal);
|
|
||||||
program->setUniformValue(locations->depthScale, (farVal - nearVal) / farVal);
|
|
||||||
float nearScale = -1.0f / nearVal;
|
|
||||||
float sScale = 1.0f / sWidth;
|
|
||||||
float depthTexCoordScaleS = (right - left) * nearScale * sScale;
|
|
||||||
program->setUniformValue(locations->depthTexCoordOffset, left * nearScale - sMin * depthTexCoordScaleS,
|
|
||||||
bottom * nearScale);
|
|
||||||
program->setUniformValue(locations->depthTexCoordScale, depthTexCoordScaleS, (top - bottom) * nearScale);
|
|
||||||
|
|
||||||
renderFullscreenQuad(sMin, sMin + sWidth);
|
|
||||||
|
|
||||||
program->release();
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE2);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_directionalLight.bind();
|
program->bind();
|
||||||
renderFullscreenQuad(sMin, sMin + sWidth);
|
}
|
||||||
_directionalLight.release();
|
|
||||||
|
float left, right, bottom, top, nearVal, farVal;
|
||||||
|
glm::vec4 nearClipPlane, farClipPlane;
|
||||||
|
Application::getInstance()->computeOffAxisFrustum(
|
||||||
|
left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||||
|
program->setUniformValue(locations->nearLocation, nearVal);
|
||||||
|
program->setUniformValue(locations->depthScale, (farVal - nearVal) / farVal);
|
||||||
|
float nearScale = -1.0f / nearVal;
|
||||||
|
float sScale = 1.0f / sWidth;
|
||||||
|
float depthTexCoordScaleS = (right - left) * nearScale * sScale;
|
||||||
|
program->setUniformValue(locations->depthTexCoordOffset, left * nearScale - sMin * depthTexCoordScaleS,
|
||||||
|
bottom * nearScale);
|
||||||
|
program->setUniformValue(locations->depthTexCoordScale, depthTexCoordScaleS, (top - bottom) * nearScale);
|
||||||
|
|
||||||
|
renderFullscreenQuad(sMin, sMin + sWidth);
|
||||||
|
|
||||||
|
program->release();
|
||||||
|
|
||||||
|
if (shadowsEnabled) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
glActiveTexture(GL_TEXTURE3);
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
freeFBO->release();
|
freeFBO->release();
|
||||||
|
|
||||||
|
@ -145,8 +155,6 @@ void DeferredLightingEffect::render() {
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDepthMask(true);
|
glDepthMask(true);
|
||||||
|
|
||||||
glDisable(GL_ALPHA_TEST);
|
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
@ -160,8 +168,9 @@ void DeferredLightingEffect::loadLightProgram(const char* name, ProgramObject& p
|
||||||
program.bind();
|
program.bind();
|
||||||
program.setUniformValue("diffuseMap", 0);
|
program.setUniformValue("diffuseMap", 0);
|
||||||
program.setUniformValue("normalMap", 1);
|
program.setUniformValue("normalMap", 1);
|
||||||
program.setUniformValue("depthMap", 2);
|
program.setUniformValue("specularMap", 2);
|
||||||
program.setUniformValue("shadowMap", 3);
|
program.setUniformValue("depthMap", 3);
|
||||||
|
program.setUniformValue("shadowMap", 4);
|
||||||
locations.shadowDistances = program.uniformLocation("shadowDistances");
|
locations.shadowDistances = program.uniformLocation("shadowDistances");
|
||||||
locations.shadowScale = program.uniformLocation("shadowScale");
|
locations.shadowScale = program.uniformLocation("shadowScale");
|
||||||
locations.nearLocation = program.uniformLocation("near");
|
locations.nearLocation = program.uniformLocation("near");
|
||||||
|
|
Loading…
Reference in a new issue