Implemented multi-resolution rendering for volumetric lighting

--HG--
extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40154
This commit is contained in:
kearwood
2012-11-10 00:51:03 +00:00
parent 152e0139a6
commit 1d22aa189d
9 changed files with 137 additions and 30 deletions

View File

@@ -23,6 +23,7 @@
E42CB1ED158446940066E0D8 /* KRQuaternion.h in Headers */ = {isa = PBXBuildFile; fileRef = E42CB1EB158446940066E0D8 /* KRQuaternion.h */; settings = {ATTRIBUTES = (Public, ); }; };
E42CB1F0158446AB0066E0D8 /* KRQuaternion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E42CB1EF158446AB0066E0D8 /* KRQuaternion.cpp */; };
E42CB1F1158446AB0066E0D8 /* KRQuaternion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E42CB1EF158446AB0066E0D8 /* KRQuaternion.cpp */; };
E431C1B8164DB7B200BE1575 /* volumetric_fog_downsampled.fsh in Sources */ = {isa = PBXBuildFile; fileRef = E431C1B7164DB7B200BE1575 /* volumetric_fog_downsampled.fsh */; };
E4324BA416444C0D0043185B /* KRParticleSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = E4324BA316444C0D0043185B /* KRParticleSystem.h */; };
E4324BA516444C0D0043185B /* KRParticleSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = E4324BA316444C0D0043185B /* KRParticleSystem.h */; };
E4324BA816444C230043185B /* KRParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4324BA716444C230043185B /* KRParticleSystem.cpp */; };
@@ -225,6 +226,8 @@
E42CB1EF158446AB0066E0D8 /* KRQuaternion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KRQuaternion.cpp; path = Classes/KRQuaternion.cpp; sourceTree = "<group>"; };
E430D08015F8882F0010558D /* occlusion_test.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = occlusion_test.fsh; path = Shaders/occlusion_test.fsh; sourceTree = "<group>"; };
E430D08815F88AD10010558D /* occlusion_test.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = occlusion_test.vsh; path = Shaders/occlusion_test.vsh; sourceTree = "<group>"; };
E431C1B6164DB79A00BE1575 /* volumetric_fog_downsampled.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = volumetric_fog_downsampled.vsh; path = Shaders/volumetric_fog_downsampled.vsh; sourceTree = "<group>"; };
E431C1B7164DB7B200BE1575 /* volumetric_fog_downsampled.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = volumetric_fog_downsampled.fsh; path = Shaders/volumetric_fog_downsampled.fsh; sourceTree = "<group>"; };
E4324BA316444C0D0043185B /* KRParticleSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KRParticleSystem.h; path = Classes/KRParticleSystem.h; sourceTree = "<group>"; };
E4324BA716444C230043185B /* KRParticleSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KRParticleSystem.cpp; path = Classes/KRParticleSystem.cpp; sourceTree = "<group>"; };
E4324BAA16444DEF0043185B /* KRParticleSystemBrownian.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KRParticleSystemBrownian.h; path = Classes/KRParticleSystemBrownian.h; sourceTree = "<group>"; };
@@ -346,7 +349,7 @@
E4CE184C15FF124600F80870 /* light_point_inside.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; lineEnding = 0; name = light_point_inside.fsh; path = Shaders/light_point_inside.fsh; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.glsl; };
E4CE184E15FF125700F80870 /* light_point_inside.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_point_inside.vsh; path = Shaders/light_point_inside.vsh; sourceTree = "<group>"; };
E4D133B91538F7480070068C /* light_directional.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_directional.fsh; path = Shaders/light_directional.fsh; sourceTree = "<group>"; };
E4D133BB1538F7560070068C /* light_directional.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_directional.vsh; path = Shaders/light_directional.vsh; sourceTree = "<group>"; };
E4D133BB1538F7560070068C /* light_directional.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; lineEnding = 0; name = light_directional.vsh; path = Shaders/light_directional.vsh; sourceTree = "<group>"; };
E4F711A41512BB56007EE923 /* libfbxsdk-2012.2-static.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libfbxsdk-2012.2-static.a"; path = "../../../../../../../../Applications/Autodesk/FBXSDK20122/lib/gcc4/ub/libfbxsdk-2012.2-static.a"; sourceTree = "<group>"; };
E4F975311536220900FD60B2 /* KRNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = KRNode.h; path = Classes/KRNode.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
E4F975351536221C00FD60B2 /* KRNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = KRNode.cpp; path = Classes/KRNode.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
@@ -424,6 +427,8 @@
E45AC0491643452000DC3C3B /* particle.vsh */,
E443C612164B5BE500FC4FD8 /* volumetric_fog.fsh */,
E443C615164B5BFB00FC4FD8 /* volumetric_fog.vsh */,
E431C1B6164DB79A00BE1575 /* volumetric_fog_downsampled.vsh */,
E431C1B7164DB7B200BE1575 /* volumetric_fog_downsampled.fsh */,
);
name = Shaders;
sourceTree = "<group>";
@@ -951,6 +956,7 @@
E4324BA816444C230043185B /* KRParticleSystem.cpp in Sources */,
E4324BAE16444E120043185B /* KRParticleSystemBrownian.cpp in Sources */,
E443C602164B122C00FC4FD8 /* KRVolumetricFog.cpp in Sources */,
E431C1B8164DB7B200BE1575 /* volumetric_fog_downsampled.fsh in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@@ -106,15 +106,16 @@ KRCamera::KRCamera(KRContext &context) : KRContextObject(context) {
volumetricLightAccumulationTexture = 0;
memset(shadowFramebuffer, sizeof(GLuint) * 3, 0);
memset(shadowDepthTexture, sizeof(GLuint) * 3, 0);
memset(shadowFramebuffer, sizeof(GLuint) * KRENGINE_MAX_SHADOW_BUFFERS, 0);
memset(shadowDepthTexture, sizeof(GLuint) * KRENGINE_MAX_SHADOW_BUFFERS, 0);
m_iFrame = 0;
m_skyBoxName = "";
m_pSkyBoxTexture = NULL;
volumetric_light_downsample = 4;
volumetric_light_downsample = 8;
invalidateShadowBuffers();
}
KRCamera::~KRCamera() {
@@ -443,22 +444,32 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
if(m_cShadowBuffers >= 1) {
// Set render target
GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, volumetricLightAccumulationBuffer));
GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, compositeDepthTexture, 0));
GLDEBUG(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
GLDEBUG(glClear(GL_COLOR_BUFFER_BIT));
KRShader *pFogShader = m_pContext->getShaderManager()->getShader("volumetric_fog", this, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
KRViewport volumetricLightingViewport = KRViewport(m_viewport.getSize() / volumetric_light_downsample, m_viewport.getViewMatrix(), m_viewport.getProjectionMatrix());
if(pFogShader->bind(volumetricLightingViewport, m_shadowViewports, KRMat4(), lightDirection, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_ADDITIVE_PARTICLES)) {
if(volumetric_light_downsample != 1) {
// Set render target
GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, volumetricLightAccumulationBuffer));
GLDEBUG(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
GLDEBUG(glClear(GL_COLOR_BUFFER_BIT));
// Disable z-buffer test
GLDEBUG(glDisable(GL_DEPTH_TEST));
m_pContext->getTextureManager()->selectTexture(0, NULL, 0);
GLDEBUG(glActiveTexture(GL_TEXTURE0));
GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeDepthTexture));
} else {
// Enable z-buffer test
GLDEBUG(glEnable(GL_DEPTH_TEST));
GLDEBUG(glDepthFunc(GL_LEQUAL));
GLDEBUG(glDepthRangef(0.0, 1.0));
}
KRShader *pFogShader = m_pContext->getShaderManager()->getShader(volumetric_light_downsample != 1 ? "volumetric_fog_downsampled" : "volumetric_fog", this, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_ADDITIVE_PARTICLES);
KRViewport volumetricLightingViewport = KRViewport(m_viewport.getSize() / volumetric_light_downsample, m_viewport.getViewMatrix(), m_viewport.getProjectionMatrix());
glViewport(0, 0, volumetricLightingViewport.getSize().x, volumetricLightingViewport.getSize().y);
if(pFogShader->bind(volumetricLightingViewport, m_shadowViewports, KRMat4(), lightDirection, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_ADDITIVE_PARTICLES)) {
int slice_count = 50;
@@ -472,9 +483,13 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, slice_count*6));
}
// Set render target
GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, compositeFramebuffer));
GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, compositeDepthTexture, 0));
if(volumetric_light_downsample != 1) {
// Set render target
GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, compositeFramebuffer));
GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, compositeDepthTexture, 0));
glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y);
}
}
@@ -662,8 +677,6 @@ void KRCamera::destroyBuffers()
lightAccumulationBuffer = 0;
}
if (volumetricLightAccumulationTexture) {
GLDEBUG(glDeleteTextures(1, &volumetricLightAccumulationTexture));
volumetricLightAccumulationTexture = 0;

View File

@@ -44,8 +44,8 @@
#import "KRViewport.h"
#define KRENGINE_MAX_SHADOW_BUFFERS 3
#define KRENGINE_SHADOW_MAP_WIDTH 2048
#define KRENGINE_SHADOW_MAP_HEIGHT 2048
#define KRENGINE_SHADOW_MAP_WIDTH 512
#define KRENGINE_SHADOW_MAP_HEIGHT 512
class KRInstance;
class KRScene;

View File

@@ -41,7 +41,7 @@ KRInstance::KRInstance(KRScene &scene, std::string instance_name, std::string mo
m_model_name = model_name;
m_min_lod_coverage = lod_min_coverage;
m_receivesShadow = receives_shadow;
m_receivesShadow = true;
m_receivesShadow = false;
}
KRInstance::~KRInstance() {

View File

@@ -58,7 +58,7 @@ KRShader *KRShaderManager::getShader(const std::string &shader_name, const KRCam
std::map<std::string, KRShader *>::iterator itr = m_shaders.begin();
delete (*itr).second;
m_shaders.erase(itr);
//fprintf(stderr, "Swapping shaders...\n");
fprintf(stderr, "Swapping shaders...\n");
}
stringstream stream;

View File

@@ -29,13 +29,10 @@
#extension GL_EXT_shadow_samplers : require
varying highp vec4 shadowMapCoord1;
varying mediump vec4 shadowMapCoord1;
uniform sampler2DShadow shadowTexture1;
void main()
{
gl_FragColor = vec4(0.04, 0.04, 0.04, 0.04);
gl_FragColor *= shadow2DProjEXT(shadowTexture1, shadowMapCoord1);
// gl_FragColor = vec4(shadowMapCoord1.xyz, 1.0);
gl_FragColor = vec4(shadow2DProjEXT(shadowTexture1, shadowMapCoord1) * 0.02);
}

View File

@@ -31,7 +31,7 @@ uniform highp mat4 inv_mvp_matrix;
uniform highp vec2 slice_depth_scale; // First component is the depth for the nearest plane, in view space. Second component is the distance between planes, in view space
uniform highp mat4 shadow_mvp1;
varying highp vec4 shadowMapCoord1;
varying mediump vec4 shadowMapCoord1;
uniform highp mat4 projection_matrix;

View File

@@ -0,0 +1,41 @@
// Copyright 2012 Kearwood Gilbert. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The views and conclusions contained in the software and documentation are those of the
// authors and should not be interpreted as representing official policies, either expressed
// or implied, of Kearwood Gilbert.
//
#extension GL_EXT_shadow_samplers : require
varying mediump vec4 shadowMapCoord1;
uniform sampler2DShadow shadowTexture1;
uniform lowp sampler2D depthFrame;
uniform mediump vec4 viewport;
void main()
{
if(gl_FragCoord.z > texture2D(depthFrame, vec2(gl_FragCoord.xy / viewport.zw)).r) discard;
gl_FragColor = vec4(shadow2DProjEXT(shadowTexture1, shadowMapCoord1) * 0.02);
}

View File

@@ -0,0 +1,50 @@
// Copyright 2012 Kearwood Gilbert. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The views and conclusions contained in the software and documentation are those of the
// authors and should not be interpreted as representing official policies, either expressed
// or implied, of Kearwood Gilbert.
//
attribute highp vec4 vertex_position;
uniform highp mat4 inv_mvp_matrix;
uniform highp vec2 slice_depth_scale; // First component is the depth for the nearest plane, in view space. Second component is the distance between planes, in view space
uniform highp mat4 shadow_mvp1;
varying mediump vec4 shadowMapCoord1;
uniform highp mat4 projection_matrix;
void main()
{
highp vec4 d = projection_matrix * vec4(0.0, 0.0, slice_depth_scale.x + vertex_position.z * slice_depth_scale.y, 1.0);
d /= d.w;
gl_Position = vec4(vertex_position.x, vertex_position.y, d.z, 1.0);
shadowMapCoord1 = inv_mvp_matrix * gl_Position;
shadowMapCoord1 /= shadowMapCoord1.w;
shadowMapCoord1.w = 1.0;
shadowMapCoord1 = shadow_mvp1 * shadowMapCoord1;
}