Working on support for specular components in deferred lights.

This commit is contained in:
Andrzej Kapolka 2014-09-12 14:11:56 -07:00
parent 618f6415da
commit 7074d96c04
4 changed files with 121 additions and 48 deletions

View file

@ -17,10 +17,44 @@ uniform sampler2D diffuseMap;
// the normal texture
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) {
// 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);
gl_FragColor = vec4((texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor +
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);
vec4 normalizedNormal = normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0);
// 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);
}

View file

@ -17,6 +17,9 @@ uniform sampler2D diffuseMap;
// the normal texture
uniform sampler2D normalMap;
// the specular texture
uniform sampler2D specularMap;
// the depth texture
uniform sampler2D depthMap;
@ -51,15 +54,27 @@ void main(void) {
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[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);
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 *
(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 +
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);
}

View file

@ -17,6 +17,9 @@ uniform sampler2D diffuseMap;
// the normal texture
uniform sampler2D normalMap;
// the specular texture
uniform sampler2D specularMap;
// the depth texture
uniform sampler2D depthMap;
@ -46,15 +49,27 @@ void main(void) {
// compute the corresponding texture coordinates
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);
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 *
(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 +
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);
}

View file

@ -60,6 +60,12 @@ void DeferredLightingEffect::render() {
glActiveTexture(GL_TEXTURE1);
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)
int viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
@ -68,15 +74,15 @@ void DeferredLightingEffect::render() {
float sMin = viewport[VIEWPORT_X_INDEX] / (float)primaryFBO->width();
float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)primaryFBO->width();
if (Menu::getInstance()->getShadowsEnabled()) {
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID());
glActiveTexture(GL_TEXTURE3);
ProgramObject* program = &_directionalLight;
const LightLocations* locations = &_directionalLightLocations;
bool shadowsEnabled = Menu::getInstance()->getShadowsEnabled();
if (shadowsEnabled) {
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID());
ProgramObject* program = &_directionalLightShadowMap;
const LightLocations* locations = &_directionalLightShadowMapLocations;
program = &_directionalLightShadowMap;
locations = &_directionalLightShadowMapLocations;
if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) {
program = &_directionalLightCascadedShadowMap;
locations = &_directionalLightCascadedShadowMapLocations;
@ -90,38 +96,42 @@ void DeferredLightingEffect::render() {
program->setUniformValue(locations->shadowScale,
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 {
_directionalLight.bind();
renderFullscreenQuad(sMin, sMin + sWidth);
_directionalLight.release();
program->bind();
}
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);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
freeFBO->release();
@ -145,8 +155,6 @@ void DeferredLightingEffect::render() {
glEnable(GL_DEPTH_TEST);
glDepthMask(true);
glDisable(GL_ALPHA_TEST);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
@ -160,8 +168,9 @@ void DeferredLightingEffect::loadLightProgram(const char* name, ProgramObject& p
program.bind();
program.setUniformValue("diffuseMap", 0);
program.setUniformValue("normalMap", 1);
program.setUniformValue("depthMap", 2);
program.setUniformValue("shadowMap", 3);
program.setUniformValue("specularMap", 2);
program.setUniformValue("depthMap", 3);
program.setUniformValue("shadowMap", 4);
locations.shadowDistances = program.uniformLocation("shadowDistances");
locations.shadowScale = program.uniformLocation("shadowScale");
locations.nearLocation = program.uniformLocation("near");