mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 06:44:06 +02:00
Limit what we render for deferred point/spot lights based on the light's
radius.
This commit is contained in:
parent
08fda3bbef
commit
446c2193ff
3 changed files with 76 additions and 10 deletions
60
interface/resources/shaders/deferred_light_limited.vert
Normal file
60
interface/resources/shaders/deferred_light_limited.vert
Normal file
|
@ -0,0 +1,60 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// deferred_light_limited.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/19/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the radius (hard cutoff) of the light effect
|
||||
uniform float radius;
|
||||
|
||||
void main(void) {
|
||||
// find the right "right" direction
|
||||
vec3 firstRightCandidate = cross(gl_LightSource[1].spotDirection, vec3(0.0, 1.0, 0.0));
|
||||
vec3 secondRightCandidate = cross(gl_LightSource[1].spotDirection, vec3(1.0, 0.0, 0.0));
|
||||
vec3 right = mix(firstRightCandidate, secondRightCandidate, step(length(firstRightCandidate), length(secondRightCandidate)));
|
||||
right = normalize(right);
|
||||
|
||||
// and the "up"
|
||||
vec3 up = cross(right, gl_LightSource[1].spotDirection);
|
||||
|
||||
// and the "back," which depends on whether this is a spot light
|
||||
vec3 back = -gl_LightSource[1].spotDirection * step(gl_LightSource[1].spotCosCutoff, 0.0);
|
||||
|
||||
// find the eight corners of the bounds
|
||||
vec4 c0 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (-up - right + back), 1.0);
|
||||
vec4 c1 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (-up + right + back), 1.0);
|
||||
vec4 c2 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (up - right + back), 1.0);
|
||||
vec4 c3 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (up + right + back), 1.0);
|
||||
vec4 c4 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (-up - right + gl_LightSource[1].spotDirection), 1.0);
|
||||
vec4 c5 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (-up + right + gl_LightSource[1].spotDirection), 1.0);
|
||||
vec4 c6 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (up - right + gl_LightSource[1].spotDirection), 1.0);
|
||||
vec4 c7 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (up + right + gl_LightSource[1].spotDirection), 1.0);
|
||||
|
||||
// find their projected extents
|
||||
vec2 extents = max(
|
||||
max(max(gl_Vertex.xy * (c0.xy / max(c0.w, 0.001)), gl_Vertex.xy * (c1.xy / max(c1.w, 0.001))),
|
||||
max(gl_Vertex.xy * (c2.xy / max(c2.w, 0.001)), gl_Vertex.xy * (c3.xy / max(c3.w, 0.001)))),
|
||||
max(max(gl_Vertex.xy * (c4.xy / max(c4.w, 0.001)), gl_Vertex.xy * (c5.xy / max(c5.w, 0.001))),
|
||||
max(gl_Vertex.xy * (c6.xy / max(c6.w, 0.001)), gl_Vertex.xy * (c7.xy / max(c7.w, 0.001)))));
|
||||
|
||||
// make sure they don't extend beyond the screen
|
||||
extents = min(extents, vec2(1.0, 1.0));
|
||||
|
||||
gl_Position = vec4(gl_Vertex.xy * extents, 0.0, 1.0);
|
||||
gl_TexCoord[0] = vec4(dot(gl_Position, gl_ObjectPlaneS[3]), dot(gl_Position, gl_ObjectPlaneT[3]), 0.0, 1.0);
|
||||
}
|
|
@ -27,13 +27,13 @@ void DeferredLightingEffect::init() {
|
|||
_glowIntensityLocation = _simpleProgram.uniformLocation("glowIntensity");
|
||||
_simpleProgram.release();
|
||||
|
||||
loadLightProgram("shaders/directional_light.frag", _directionalLight, _directionalLightLocations);
|
||||
loadLightProgram("shaders/directional_light_shadow_map.frag", _directionalLightShadowMap,
|
||||
loadLightProgram("shaders/directional_light.frag", false, _directionalLight, _directionalLightLocations);
|
||||
loadLightProgram("shaders/directional_light_shadow_map.frag", false, _directionalLightShadowMap,
|
||||
_directionalLightShadowMapLocations);
|
||||
loadLightProgram("shaders/directional_light_cascaded_shadow_map.frag", _directionalLightCascadedShadowMap,
|
||||
loadLightProgram("shaders/directional_light_cascaded_shadow_map.frag", false, _directionalLightCascadedShadowMap,
|
||||
_directionalLightCascadedShadowMapLocations);
|
||||
loadLightProgram("shaders/point_light.frag", _pointLight, _pointLightLocations);
|
||||
loadLightProgram("shaders/spot_light.frag", _spotLight, _spotLightLocations);
|
||||
loadLightProgram("shaders/point_light.frag", true, _pointLight, _pointLightLocations);
|
||||
loadLightProgram("shaders/spot_light.frag", true, _spotLight, _spotLightLocations);
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::bindSimpleProgram() {
|
||||
|
@ -216,6 +216,11 @@ void DeferredLightingEffect::render() {
|
|||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
|
||||
glm::vec4 sCoefficients(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f);
|
||||
glm::vec4 tCoefficients(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f);
|
||||
glTexGenfv(GL_S, GL_OBJECT_PLANE, (const GLfloat*)&sCoefficients);
|
||||
glTexGenfv(GL_T, GL_OBJECT_PLANE, (const GLfloat*)&tCoefficients);
|
||||
|
||||
if (!_pointLights.isEmpty()) {
|
||||
_pointLight.bind();
|
||||
_pointLight.setUniformValue(_pointLightLocations.nearLocation, nearVal);
|
||||
|
@ -233,7 +238,7 @@ void DeferredLightingEffect::render() {
|
|||
glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, light.linearAttenuation);
|
||||
glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, light.quadraticAttenuation);
|
||||
|
||||
renderFullscreenQuad(sMin, sMin + sWidth, tMin, tMin + tHeight);
|
||||
renderFullscreenQuad();
|
||||
}
|
||||
_pointLights.clear();
|
||||
|
||||
|
@ -260,7 +265,7 @@ void DeferredLightingEffect::render() {
|
|||
glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, light.exponent);
|
||||
glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, glm::degrees(light.cutoff));
|
||||
|
||||
renderFullscreenQuad(sMin, sMin + sWidth, tMin, tMin + tHeight);
|
||||
renderFullscreenQuad();
|
||||
}
|
||||
_spotLights.clear();
|
||||
|
||||
|
@ -319,8 +324,9 @@ void DeferredLightingEffect::render() {
|
|||
_postLightingRenderables.clear();
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::loadLightProgram(const char* name, ProgramObject& program, LightLocations& locations) {
|
||||
program.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/deferred_light.vert");
|
||||
void DeferredLightingEffect::loadLightProgram(const char* name, bool limited, ProgramObject& program, LightLocations& locations) {
|
||||
program.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
||||
(limited ? "shaders/deferred_light_limited.vert" : "shaders/deferred_light.vert"));
|
||||
program.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + name);
|
||||
program.link();
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ private:
|
|||
int radius;
|
||||
};
|
||||
|
||||
static void loadLightProgram(const char* name, ProgramObject& program, LightLocations& locations);
|
||||
static void loadLightProgram(const char* name, bool limited, ProgramObject& program, LightLocations& locations);
|
||||
|
||||
ProgramObject _simpleProgram;
|
||||
int _glowIntensityLocation;
|
||||
|
|
Loading…
Reference in a new issue