Volumetric lighting in progress

--HG--
extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40152
This commit is contained in:
kearwood
2012-11-09 09:18:38 +00:00
parent 19a6689245
commit 602425dd51
36 changed files with 886 additions and 211 deletions

View File

@@ -35,18 +35,10 @@
E43B0AD715DDCA0F00A5CB9F /* KRContextObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43B0AD415DDCA0C00A5CB9F /* KRContextObject.cpp */; };
E43B0AD815DDCA0F00A5CB9F /* KRContextObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */; };
E43B0AD915DDCA0F00A5CB9F /* KRContextObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
E45AC0301641D66300DC3C3B /* simple_blit.vsh in Sources */ = {isa = PBXBuildFile; fileRef = E45AC02F1641D66300DC3C3B /* simple_blit.vsh */; };
E45AC0311641D66300DC3C3B /* simple_blit.vsh in Sources */ = {isa = PBXBuildFile; fileRef = E45AC02F1641D66300DC3C3B /* simple_blit.vsh */; };
E45AC0341641D67300DC3C3B /* simple_blit.fsh in Sources */ = {isa = PBXBuildFile; fileRef = E45AC0331641D67300DC3C3B /* simple_blit.fsh */; };
E45AC0351641D67300DC3C3B /* simple_blit.fsh in Sources */ = {isa = PBXBuildFile; fileRef = E45AC0331641D67300DC3C3B /* simple_blit.fsh */; };
E45AC03F1641DE5D00DC3C3B /* debug_font.vsh in Sources */ = {isa = PBXBuildFile; fileRef = E45AC03E1641DE5D00DC3C3B /* debug_font.vsh */; };
E45AC0401641DE5D00DC3C3B /* debug_font.vsh in Sources */ = {isa = PBXBuildFile; fileRef = E45AC03E1641DE5D00DC3C3B /* debug_font.vsh */; };
E45AC0421641DE6D00DC3C3B /* debug_font.fsh in Sources */ = {isa = PBXBuildFile; fileRef = E45AC0411641DE6D00DC3C3B /* debug_font.fsh */; };
E45AC0431641DE6D00DC3C3B /* debug_font.fsh in Sources */ = {isa = PBXBuildFile; fileRef = E45AC0411641DE6D00DC3C3B /* debug_font.fsh */; };
E45AC0471643451300DC3C3B /* particle.fsh in Sources */ = {isa = PBXBuildFile; fileRef = E45AC0461643451200DC3C3B /* particle.fsh */; };
E45AC0481643451300DC3C3B /* particle.fsh in Sources */ = {isa = PBXBuildFile; fileRef = E45AC0461643451200DC3C3B /* particle.fsh */; };
E45AC04A1643452100DC3C3B /* particle.vsh in Sources */ = {isa = PBXBuildFile; fileRef = E45AC0491643452000DC3C3B /* particle.vsh */; };
E45AC04B1643452100DC3C3B /* particle.vsh in Sources */ = {isa = PBXBuildFile; fileRef = E45AC0491643452000DC3C3B /* particle.vsh */; };
E443C5FE164B120A00FC4FD8 /* KRVolumetricFog.h in Headers */ = {isa = PBXBuildFile; fileRef = E443C5FD164B120900FC4FD8 /* KRVolumetricFog.h */; };
E443C5FF164B120A00FC4FD8 /* KRVolumetricFog.h in Headers */ = {isa = PBXBuildFile; fileRef = E443C5FD164B120900FC4FD8 /* KRVolumetricFog.h */; };
E443C602164B122C00FC4FD8 /* KRVolumetricFog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E443C601164B122C00FC4FD8 /* KRVolumetricFog.cpp */; };
E443C603164B122C00FC4FD8 /* KRVolumetricFog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E443C601164B122C00FC4FD8 /* KRVolumetricFog.cpp */; };
E461A152152E54B500F2044A /* KRLight.h in Headers */ = {isa = PBXBuildFile; fileRef = E461A151152E54B500F2044A /* KRLight.h */; };
E461A153152E54B500F2044A /* KRLight.h in Headers */ = {isa = PBXBuildFile; fileRef = E461A151152E54B500F2044A /* KRLight.h */; settings = {ATTRIBUTES = (Public, ); }; };
E461A156152E54F800F2044A /* KRLight.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E461A155152E54F700F2044A /* KRLight.cpp */; };
@@ -239,6 +231,12 @@
E4324BAD16444E120043185B /* KRParticleSystemBrownian.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KRParticleSystemBrownian.cpp; path = Classes/KRParticleSystemBrownian.cpp; sourceTree = "<group>"; };
E43B0AD415DDCA0C00A5CB9F /* KRContextObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KRContextObject.cpp; path = Classes/KRContextObject.cpp; sourceTree = "<group>"; };
E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KRContextObject.h; path = Classes/KRContextObject.h; sourceTree = "<group>"; };
E443C5FD164B120900FC4FD8 /* KRVolumetricFog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KRVolumetricFog.h; path = Classes/KRVolumetricFog.h; sourceTree = "<group>"; };
E443C601164B122C00FC4FD8 /* KRVolumetricFog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KRVolumetricFog.cpp; path = Classes/KRVolumetricFog.cpp; sourceTree = "<group>"; };
E443C606164B27B400FC4FD8 /* volumetric_fog.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = volumetric_fog.fsh; path = Shaders/volumetric_fog.fsh; sourceTree = "<group>"; };
E443C609164B27C500FC4FD8 /* volumetric_fog.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = volumetric_fog.vsh; path = Shaders/volumetric_fog.vsh; sourceTree = "<group>"; };
E443C612164B5BE500FC4FD8 /* volumetric_fog_inside.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = volumetric_fog_inside.fsh; path = Shaders/volumetric_fog_inside.fsh; sourceTree = "<group>"; };
E443C615164B5BFB00FC4FD8 /* volumetric_fog_inside.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = volumetric_fog_inside.vsh; path = Shaders/volumetric_fog_inside.vsh; sourceTree = "<group>"; };
E45772F113C9A13C0037BEEA /* ShadowShader.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; lineEnding = 0; name = ShadowShader.vsh; path = Shaders/ShadowShader.vsh; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.glsl; };
E45772F213C9A13C0037BEEA /* ShadowShader.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = ShadowShader.fsh; path = Shaders/ShadowShader.fsh; sourceTree = "<group>"; };
E45772F313C9A13C0037BEEA /* PostShader.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = PostShader.fsh; path = Shaders/PostShader.fsh; sourceTree = "<group>"; };
@@ -426,6 +424,10 @@
E45AC0411641DE6D00DC3C3B /* debug_font.fsh */,
E45AC0461643451200DC3C3B /* particle.fsh */,
E45AC0491643452000DC3C3B /* particle.vsh */,
E443C606164B27B400FC4FD8 /* volumetric_fog.fsh */,
E443C609164B27C500FC4FD8 /* volumetric_fog.vsh */,
E443C612164B5BE500FC4FD8 /* volumetric_fog_inside.fsh */,
E443C615164B5BFB00FC4FD8 /* volumetric_fog_inside.vsh */,
);
name = Shaders;
sourceTree = "<group>";
@@ -584,6 +586,8 @@
E461A171152E599E00F2044A /* Lights */,
E4F975311536220900FD60B2 /* KRNode.h */,
E4F975351536221C00FD60B2 /* KRNode.cpp */,
E443C5FD164B120900FC4FD8 /* KRVolumetricFog.h */,
E443C601164B122C00FC4FD8 /* KRVolumetricFog.cpp */,
);
name = "Scene Graph Nodes";
sourceTree = "<group>";
@@ -767,6 +771,7 @@
E4CA11741639CBD6005D9400 /* KRViewport.h in Headers */,
E4324BA416444C0D0043185B /* KRParticleSystem.h in Headers */,
E4324BAB16444DEF0043185B /* KRParticleSystemBrownian.h in Headers */,
E443C5FE164B120A00FC4FD8 /* KRVolumetricFog.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -821,6 +826,7 @@
E461A169152E570700F2044A /* KRSpotLight.h in Headers */,
E4324BA516444C0D0043185B /* KRParticleSystem.h in Headers */,
E4324BAC16444DEF0043185B /* KRParticleSystemBrownian.h in Headers */,
E443C5FF164B120A00FC4FD8 /* KRVolumetricFog.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -946,14 +952,9 @@
E4CA10E91637BD2B005D9400 /* KRTexturePVR.cpp in Sources */,
E4CA10EF1637BD58005D9400 /* KRTextureTGA.cpp in Sources */,
E4CA11781639CC90005D9400 /* KRViewport.cpp in Sources */,
E45AC0301641D66300DC3C3B /* simple_blit.vsh in Sources */,
E45AC0341641D67300DC3C3B /* simple_blit.fsh in Sources */,
E45AC03F1641DE5D00DC3C3B /* debug_font.vsh in Sources */,
E45AC0421641DE6D00DC3C3B /* debug_font.fsh in Sources */,
E45AC0471643451300DC3C3B /* particle.fsh in Sources */,
E45AC04A1643452100DC3C3B /* particle.vsh in Sources */,
E4324BA816444C230043185B /* KRParticleSystem.cpp in Sources */,
E4324BAE16444E120043185B /* KRParticleSystemBrownian.cpp in Sources */,
E443C602164B122C00FC4FD8 /* KRVolumetricFog.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1002,14 +1003,9 @@
E4CA10EA1637BD2B005D9400 /* KRTexturePVR.cpp in Sources */,
E4CA10F01637BD58005D9400 /* KRTextureTGA.cpp in Sources */,
E4CA11791639CC90005D9400 /* KRViewport.cpp in Sources */,
E45AC0311641D66300DC3C3B /* simple_blit.vsh in Sources */,
E45AC0351641D67300DC3C3B /* simple_blit.fsh in Sources */,
E45AC0401641DE5D00DC3C3B /* debug_font.vsh in Sources */,
E45AC0431641DE6D00DC3C3B /* debug_font.fsh in Sources */,
E45AC0481643451300DC3C3B /* particle.fsh in Sources */,
E45AC04B1643452100DC3C3B /* particle.vsh in Sources */,
E4324BAF16444E120043185B /* KRParticleSystemBrownian.cpp in Sources */,
E4324BB0164458930043185B /* KRParticleSystem.cpp in Sources */,
E443C603164B122C00FC4FD8 /* KRVolumetricFog.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@@ -20,7 +20,7 @@ KRAABB::KRAABB(const KRVector3 &minPoint, const KRVector3 &maxPoint)
KRAABB::KRAABB(const KRVector3 &corner1, const KRVector3 &corner2, const KRMat4 &modelMatrix)
{
for(int iCorner=0; iCorner<8; iCorner++) {
KRVector3 sourceCornerVertex = KRMat4::Dot(modelMatrix, KRVector3(
KRVector3 sourceCornerVertex = KRMat4::DotWDiv(modelMatrix, KRVector3(
(iCorner & 1) == 0 ? corner1.x : corner2.x,
(iCorner & 2) == 0 ? corner1.y : corner2.y,
(iCorner & 4) == 0 ? corner1.z : corner2.z));

View File

@@ -39,6 +39,7 @@
#import "KRCamera.h"
#import "KRBoundingVolume.h"
#import "KRStockGeometry.h"
#import "KRDirectionalLight.h"
KRCamera::KRCamera(KRContext &context) : KRContextObject(context) {
m_particlesAbsoluteTime = 0.0f;
@@ -149,27 +150,49 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, float deltaTime)
m_pContext->rotateBuffers(true);
KRVector3 lightDirection(0.0, 0.0, 1.0);
// ----- Render Model -----
KRMat4 shadowvp;
shadowvp.rotate(scene.sun_pitch, X_AXIS);
shadowvp.rotate(scene.sun_yaw, Y_AXIS);
lightDirection = KRMat4::Dot(shadowvp, lightDirection);
lightDirection.normalize();
shadowvp.invert();
KRDirectionalLight *firstDirectionalLight = scene.getFirstDirectionalLight();
KRVector3 lightDirection = KRVector3::Normalize(KRVector3(0.90, 0.70, 0.25));
if(firstDirectionalLight) {
lightDirection = firstDirectionalLight->getWorldLightDirection();
}
allocateShadowBuffers(m_cShadowBuffers);
int iOffset=m_iFrame % m_cShadowBuffers;
for(int iShadow2=iOffset; iShadow2 < m_cShadowBuffers + iOffset; iShadow2++) {
int iShadow = iShadow2 % m_cShadowBuffers;
for(int iShadow=0; iShadow < m_cShadowBuffers; iShadow++) {
GLfloat shadowMinDepths[3][3] = {{0.0, 0.0, 0.0},{0.0, 0.0, 0.0},{0.0, 0.05, 0.3}};
GLfloat shadowMaxDepths[3][3] = {{0.0, 0.0, 1.0},{0.1, 0.0, 0.0},{0.1, 0.3, 1.0}};
KRMat4 newShadowMVP;
KRVector3 shadowLook = -KRVector3::Normalize(lightDirection);
KRVector3 shadowUp(0.0, 1.0, 0.0);
if(KRVector3::Dot(shadowUp, shadowLook) > 0.99f) shadowUp = KRVector3(0.0, 0.0, 1.0); // Ensure shadow look direction is not parallel with the shadowUp direction
KRMat4 matShadowView = KRMat4::LookAt(m_viewport.getCameraPosition() - shadowLook, m_viewport.getCameraPosition(), shadowUp);
KRMat4 matShadowProjection = KRMat4();
matShadowProjection.scale(0.001, 0.001, 0.001);
KRMat4 matBias;
matBias.bias();
matShadowProjection *= matBias;
// KRAABB frustrumWorldBounds = KRAABB(KRVector3(-1.0, -1.0, 0.0), KRVector3(1.0, 1.0, 1.0), m_viewport.getInverseProjectionMatrix() * m_viewport.getInverseViewMatrix());
// matShadowProjection.translate(KRVector3(0.0, 0.0, -frustrumWorldBounds.size().z));
// matShadowProjection.scale(2.0 / frustrumWorldBounds.size().x, 2.0 / frustrumWorldBounds.size().y, 2.0 / frustrumWorldBounds.size().z);
// matShadowView.translate(-m_viewport.getCameraPosition());
//matShadowProjection *= matBias;
m_shadowViewports[iShadow] = KRViewport(KRVector2(KRENGINE_SHADOW_MAP_WIDTH, KRENGINE_SHADOW_MAP_HEIGHT), matShadowView, matShadowProjection);
// KRMat4 newShadowMVP;
// if(shadowMaxDepths[m_cShadowBuffers - 1][iShadow] == 0.0) {
// KRBoundingVolume ext = KRBoundingVolume(-KRVector3::One(), KRVector3::One(), KRMat4()); // HACK - Temporary workaround to compile until this logic is updated to use information from the Octree
//
@@ -179,22 +202,13 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, float deltaTime)
// newShadowMVP = frustrumSliceVolume.calcShadowProj(&scene, m_pContext, scene.sun_yaw, scene.sun_pitch);
// }
KRBoundingVolume frustrumSliceVolume = KRBoundingVolume(viewMatrix, perspective_fov, getViewportSize().x / getViewportSize().y, perspective_nearz + (perspective_farz - perspective_nearz) * shadowMinDepths[m_cShadowBuffers - 1][iShadow], perspective_nearz + (perspective_farz - perspective_nearz) * shadowMaxDepths[m_cShadowBuffers - 1][iShadow]);
newShadowMVP = frustrumSliceVolume.calcShadowProj(&scene, m_pContext, scene.sun_yaw, scene.sun_pitch);
// KRBoundingVolume frustrumSliceVolume = KRBoundingVolume(viewMatrix, perspective_fov, getViewportSize().x / getViewportSize().y, perspective_nearz + (perspective_farz - perspective_nearz) * shadowMinDepths[m_cShadowBuffers - 1][iShadow], perspective_nearz + (perspective_farz - perspective_nearz) * shadowMaxDepths[m_cShadowBuffers - 1][iShadow]);
// newShadowMVP = frustrumSliceVolume.calcShadowProj(&scene, m_pContext, scene.sun_yaw, scene.sun_pitch);
//
// m_shadowViewports[iShadow] = KRViewport(KRVector2(KRENGINE_SHADOW_MAP_WIDTH, KRENGINE_SHADOW_MAP_HEIGHT), KRMat4(), newShadowMVP);
//
renderShadowBuffer(scene, iShadow);
if(!(shadowmvpmatrix[iShadow] == newShadowMVP)) {
shadowValid[iShadow] = false;
}
if(!shadowValid[iShadow]) {
shadowValid[iShadow] = true;
shadowmvpmatrix[iShadow] = newShadowMVP;
renderShadowBuffer(scene, iShadow);
break;
}
}
renderFrame(scene, lightDirection, deltaTime);
@@ -237,7 +251,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
GLDEBUG(glDisable(GL_BLEND));
// Render the geometry
scene.render(this, m_visibleBounds, m_pContext, m_viewport, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_GBUFFER, newVisibleBounds);
scene.render(this, m_viewport.getVisibleBounds(), m_pContext, m_viewport, m_shadowViewports, lightDirection, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_GBUFFER, newVisibleBounds);
// ----====---- Opaque Geometry, Deferred rendering Pass 2 ----====----
// Set render target
@@ -263,7 +277,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
// Render the geometry
scene.render(this, m_visibleBounds, m_pContext, m_viewport, lightDirection, shadowmvpmatrix, shadowDepthTexture, 0, KRNode::RENDER_PASS_DEFERRED_LIGHTS, newVisibleBounds);
scene.render(this, m_viewport.getVisibleBounds(), m_pContext, m_viewport, m_shadowViewports, lightDirection, shadowDepthTexture, 0, KRNode::RENDER_PASS_DEFERRED_LIGHTS, newVisibleBounds);
// ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====----
// Set render target
@@ -295,7 +309,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
// Render the geometry
std::set<KRAABB> emptyBoundsSet; // At this point, we only render octree nodes that produced fragments during the 1st pass into the GBuffer
scene.render(this, emptyBoundsSet, m_pContext, m_viewport, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_OPAQUE, newVisibleBounds);
scene.render(this, emptyBoundsSet, m_pContext, m_viewport, m_shadowViewports, lightDirection, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_OPAQUE, newVisibleBounds);
// Deactivate source buffer texture units
m_pContext->getTextureManager()->selectTexture(6, NULL, 0);
@@ -333,7 +347,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
// Render the geometry
scene.render(this, m_visibleBounds, m_pContext, m_viewport, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_OPAQUE, newVisibleBounds);
scene.render(this, m_viewport.getVisibleBounds(), m_pContext, m_viewport, m_shadowViewports, lightDirection, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_OPAQUE, newVisibleBounds);
}
// ----====---- Sky Box ----====----
@@ -359,7 +373,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
if(m_pSkyBoxTexture) {
KRShader *pShader = getContext().getShaderManager()->getShader("sky_box", this, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_OPAQUE);
pShader->bind(m_viewport, KRMat4(), lightDirection, NULL, NULL, 0, KRNode::RENDER_PASS_FORWARD_OPAQUE);
pShader->bind(m_viewport, m_shadowViewports, KRMat4(), lightDirection, NULL, 0, KRNode::RENDER_PASS_FORWARD_OPAQUE);
getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture, 2048);
@@ -393,7 +407,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
GLDEBUG(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
// Render all transparent geometry
scene.render(this, m_visibleBounds, m_pContext, m_viewport, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, newVisibleBounds);
scene.render(this, m_viewport.getVisibleBounds(), m_pContext, m_viewport, m_shadowViewports, lightDirection, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, newVisibleBounds);
// ----====---- Flares ----====----
@@ -417,7 +431,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
// Render all flares
scene.render(this, m_visibleBounds, m_pContext, m_viewport, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_ADDITIVE_PARTICLES, newVisibleBounds);
scene.render(this, m_viewport.getVisibleBounds(), m_pContext, m_viewport, m_shadowViewports, lightDirection, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_ADDITIVE_PARTICLES, newVisibleBounds);
// ----====---- Debug Overlay ----====----
@@ -442,17 +456,17 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
KRMat4 projectionMatrix = getProjectionMatrix();
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, true, false, false, false, false);
for(std::set<KRAABB>::iterator itr=m_visibleBounds.begin(); itr != m_visibleBounds.end(); itr++) {
for(std::set<KRAABB>::iterator itr=m_viewport.getVisibleBounds().begin(); itr != m_viewport.getVisibleBounds().end(); itr++) {
KRMat4 matModel = KRMat4();
matModel.scale((*itr).size() / 2.0f);
matModel.translate((*itr).center());
if(pVisShader->bind(m_viewport, matModel, lightDirection, shadowmvpmatrix, shadowDepthTexture, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
if(pVisShader->bind(m_viewport, m_shadowViewports, matModel, lightDirection, shadowDepthTexture, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 14));
}
}
}
m_visibleBounds = newVisibleBounds;
m_viewport.setVisibleBounds(newVisibleBounds);
// Re-enable z-buffer write
GLDEBUG(glDepthMask(GL_TRUE));
@@ -548,6 +562,10 @@ void KRCamera::allocateShadowBuffers(int cBuffers) {
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
#if GL_EXT_shadow_samplers
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_EXT, GL_COMPARE_REF_TO_TEXTURE_EXT)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_EXT, GL_LEQUAL)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available
#endif
GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, KRENGINE_SHADOW_MAP_WIDTH, KRENGINE_SHADOW_MAP_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL));
GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadowDepthTexture[iShadow], 0));
@@ -589,11 +607,13 @@ void KRCamera::destroyBuffers()
void KRCamera::renderShadowBuffer(KRScene &scene, int iShadow)
{
glViewport(0, 0, m_shadowViewports[iShadow].getSize().x, m_shadowViewports[iShadow].getSize().y);
GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, shadowFramebuffer[iShadow]));
GLDEBUG(glClearDepthf(1.0f));
GLDEBUG(glClear(GL_DEPTH_BUFFER_BIT));
//glViewport(1, 1, 2046, 2046);
glViewport(1, 1, m_shadowViewports[iShadow].getSize().x - 2, m_shadowViewports[iShadow].getSize().y - 2);
GLDEBUG(glDisable(GL_DITHER));
@@ -611,40 +631,40 @@ void KRCamera::renderShadowBuffer(KRScene &scene, int iShadow)
// Use shader program
KRShader *shadowShader = m_pContext->getShaderManager()->getShader("ShadowShader", this, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
KRViewport viewport = KRViewport(getViewportSize(), KRMat4(), KRMat4());
shadowShader->bind(viewport, KRMat4(), KRVector3(), NULL, NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
shadowShader->bind(m_shadowViewports[iShadow], m_shadowViewports, KRMat4(), KRVector3(), NULL, 0, KRNode::RENDER_PASS_SHADOWMAP);
// Bind our modelmatrix variable to be a uniform called mvpmatrix in our shaderprogram
shadowmvpmatrix[iShadow].setUniform(shadowShader->m_uniforms[KRShader::KRENGINE_UNIFORM_SHADOWMVP1]);
// // Bind our modelmatrix variable to be a uniform called mvpmatrix in our shaderprogram
// shadowmvpmatrix[iShadow].setUniform(shadowShader->m_uniforms[KRShader::KRENGINE_UNIFORM_SHADOWMVP1]);
// Calculate the bounding volume of the light map
KRMat4 matInvShadow = shadowmvpmatrix[iShadow];
matInvShadow.invert();
// // Calculate the bounding volume of the light map
// KRMat4 matInvShadow = shadowmvpmatrix[iShadow];
// matInvShadow.invert();
//
// KRVector3 vertices[8];
// vertices[0] = KRVector3(-1.0, -1.0, 0.0);
// vertices[1] = KRVector3(1.0, -1.0, 0.0);
// vertices[2] = KRVector3(1.0, 1.0, 0.0);
// vertices[3] = KRVector3(-1.0, 1.0, 0.0);
// vertices[4] = KRVector3(-1.0, -1.0, 1.0);
// vertices[5] = KRVector3(1.0, -1.0, 1.0);
// vertices[6] = KRVector3(1.0, 1.0, 1.0);
// vertices[7] = KRVector3(-1.0, 1.0, 1.0);
//
// for(int iVertex=0; iVertex < 8; iVertex++) {
// vertices[iVertex] = KRMat4::Dot(matInvShadow, vertices[iVertex]);
// }
//
// KRVector3 cameraPosition;
// KRVector3 lightDirection;
// KRBoundingVolume shadowVolume = KRBoundingVolume(vertices);
KRVector3 vertices[8];
vertices[0] = KRVector3(-1.0, -1.0, 0.0);
vertices[1] = KRVector3(1.0, -1.0, 0.0);
vertices[2] = KRVector3(1.0, 1.0, 0.0);
vertices[3] = KRVector3(-1.0, 1.0, 0.0);
vertices[4] = KRVector3(-1.0, -1.0, 1.0);
vertices[5] = KRVector3(1.0, -1.0, 1.0);
vertices[6] = KRVector3(1.0, 1.0, 1.0);
vertices[7] = KRVector3(-1.0, 1.0, 1.0);
for(int iVertex=0; iVertex < 8; iVertex++) {
vertices[iVertex] = KRMat4::Dot(matInvShadow, vertices[iVertex]);
}
KRVector3 cameraPosition;
KRVector3 lightDirection;
KRBoundingVolume shadowVolume = KRBoundingVolume(vertices);
KRVector3 temp = KRVector3();
std::set<KRAABB> newVisibleBounds;
viewport = KRViewport(m_viewport.getSize(), KRMat4(), shadowmvpmatrix[iShadow]);
scene.render(this, m_shadowVisibleBounds[iShadow], m_pContext, viewport, lightDirection, shadowmvpmatrix, NULL, m_cShadowBuffers, KRNode::RENDER_PASS_SHADOWMAP, newVisibleBounds);
scene.render(this, m_shadowViewports[iShadow].getVisibleBounds(), m_pContext, m_shadowViewports[iShadow], m_shadowViewports, temp, NULL, m_cShadowBuffers, KRNode::RENDER_PASS_SHADOWMAP, newVisibleBounds);
m_shadowVisibleBounds[iShadow] = newVisibleBounds;
GLDEBUG(glViewport(0, 0, backingWidth, backingHeight));
m_shadowViewports[iShadow].setVisibleBounds(newVisibleBounds);
GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y));
}
void KRCamera::renderPost()
@@ -675,7 +695,7 @@ void KRCamera::renderPost()
GLDEBUG(glDisable(GL_DEPTH_TEST));
KRShader *postShader = m_pContext->getShaderManager()->getShader("PostShader", this, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
postShader->bind(KRViewport(getViewportSize(), KRMat4(), KRMat4()), KRMat4(), KRVector3(), NULL, NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
postShader->bind(m_viewport, m_shadowViewports, KRMat4(), KRVector3(), NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
m_pContext->getTextureManager()->selectTexture(0, NULL, 0);
GLDEBUG(glActiveTexture(GL_TEXTURE0));
@@ -706,12 +726,18 @@ void KRCamera::renderPost()
KRMat4 viewMatrix = KRMat4();
viewMatrix.scale(0.20, 0.20, 0.20);
viewMatrix.translate(-0.70, 0.70 - 0.45 * iShadow, 0.0);
blitShader->bind(KRViewport(getViewportSize(), viewMatrix, KRMat4()), KRMat4(), KRVector3(), NULL, NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
blitShader->bind(KRViewport(getViewportSize(), viewMatrix, KRMat4()), m_shadowViewports, KRMat4(), KRVector3(), NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
m_pContext->getTextureManager()->selectTexture(1, NULL, 0);
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, true, false, false, true, false);
GLDEBUG(glActiveTexture(GL_TEXTURE0));
GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow]));
#if GL_EXT_shadow_samplers
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_EXT, GL_NONE)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available
#endif
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
#if GL_EXT_shadow_samplers
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_EXT, GL_COMPARE_REF_TO_TEXTURE_EXT)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available
#endif
}
m_pContext->getTextureManager()->selectTexture(0, NULL, 0);

View File

@@ -137,7 +137,6 @@ private:
GLuint shadowFramebuffer[KRENGINE_MAX_SHADOW_BUFFERS], shadowDepthTexture[KRENGINE_MAX_SHADOW_BUFFERS];
bool shadowValid[KRENGINE_MAX_SHADOW_BUFFERS];
KRMat4 shadowmvpmatrix[KRENGINE_MAX_SHADOW_BUFFERS]; /* MVP Matrix for view from light source */
KRViewport m_shadowViewports[KRENGINE_MAX_SHADOW_BUFFERS];
@@ -172,9 +171,6 @@ private:
float m_distance;
};
std::set<KRAABB> m_visibleBounds; // AABB's that output fragments in the last frame
std::set<KRAABB> m_shadowVisibleBounds[KRENGINE_MAX_SHADOW_BUFFERS]; // AABB's that output fragments in the last frame for each shadow map
std::string m_skyBoxName;
KRTexture *m_pSkyBoxTexture;

View File

@@ -50,9 +50,9 @@ KRVector3 KRDirectionalLight::getLocalLightDirection() {
#if TARGET_OS_IPHONE
void KRDirectionalLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) {
void KRDirectionalLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) {
KRLight::render(pCamera, pContext, viewport, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
KRLight::render(pCamera, pContext, viewport, pShadowViewports, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass);
if(renderPass == KRNode::RENDER_PASS_DEFERRED_LIGHTS) {
// Lights are rendered on the second pass of the deferred renderer
@@ -66,7 +66,7 @@ void KRDirectionalLight::render(KRCamera *pCamera, KRContext *pContext, const KR
light_direction_view_space.normalize();
KRShader *pShader = pContext->getShaderManager()->getShader("light_directional", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
if(pShader->bind(viewport, getModelMatrix(), lightDirection, pShadowMatrices, shadowDepthTextures, 0, renderPass)) {
if(pShader->bind(viewport, pShadowViewports, getModelMatrix(), lightDirection, shadowDepthTextures, 0, renderPass)) {
light_direction_view_space.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE]);
m_color.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR]);

View File

@@ -25,7 +25,7 @@ public:
#if TARGET_OS_IPHONE
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
#endif
};

View File

@@ -35,11 +35,13 @@
#import "KRModel.h"
#include <assert.h>
KRInstance::KRInstance(KRScene &scene, std::string instance_name, std::string model_name, std::string light_map, float lod_min_coverage) : KRNode(scene, instance_name) {
KRInstance::KRInstance(KRScene &scene, std::string instance_name, std::string model_name, std::string light_map, float lod_min_coverage, bool receives_shadow) : KRNode(scene, instance_name) {
m_lightMap = light_map;
m_pLightMap = NULL;
m_model_name = model_name;
m_min_lod_coverage = lod_min_coverage;
m_receivesShadow = receives_shadow;
m_receivesShadow = true;
}
KRInstance::~KRInstance() {
@@ -56,6 +58,7 @@ tinyxml2::XMLElement *KRInstance::saveXML( tinyxml2::XMLNode *parent)
e->SetAttribute("mesh_name", m_model_name.c_str());
e->SetAttribute("light_map", m_lightMap.c_str());
e->SetAttribute("lod_min_coverage", m_min_lod_coverage);
e->SetAttribute("receives_shadow", m_receivesShadow ? "true" : "false");
return e;
}
@@ -73,10 +76,10 @@ void KRInstance::loadModel() {
#if TARGET_OS_IPHONE
void KRInstance::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) {
void KRInstance::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) {
KRNode::render(pCamera, pContext, viewport, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
KRNode::render(pCamera, pContext, viewport, pShadowViewports, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass);
if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && (renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT || this->hasTransparency()) && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES) {
// Don't render meshes on second pass of the deferred lighting renderer, as only lights will be applied
@@ -104,11 +107,11 @@ void KRInstance::render(KRCamera *pCamera, KRContext *pContext, const KRViewport
m_pLightMap = pContext->getTextureManager()->getTexture(m_lightMap.c_str());
}
if(cShadowBuffers == 0 && m_pLightMap && pCamera->bEnableLightMap && renderPass != RENDER_PASS_SHADOWMAP) {
if(m_pLightMap && pCamera->bEnableLightMap && renderPass != RENDER_PASS_SHADOWMAP) {
m_pContext->getTextureManager()->selectTexture(5, m_pLightMap, 2048);
}
pModel->render(pCamera, pContext, viewport, getModelMatrix(), lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, m_pLightMap, renderPass);
pModel->render(pCamera, pContext, viewport, pShadowViewports, getModelMatrix(), lightDirection, shadowDepthTextures, m_receivesShadow ? cShadowBuffers : 0, m_pLightMap, renderPass);
}
}
}

View File

@@ -50,7 +50,7 @@
class KRInstance : public KRNode {
public:
KRInstance(KRScene &scene, std::string instance_name, std::string model_name, std::string light_map, float lod_min_coverage);
KRInstance(KRScene &scene, std::string instance_name, std::string model_name, std::string light_map, float lod_min_coverage, bool receives_shadow);
virtual ~KRInstance();
virtual std::string getElementName();
@@ -58,7 +58,7 @@ public:
#if TARGET_OS_IPHONE
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
#endif
bool hasTransparency();
@@ -75,6 +75,8 @@ private:
float m_min_lod_coverage;
void loadModel();
bool m_receivesShadow;
};

View File

@@ -118,9 +118,9 @@ float KRLight::getDecayStart() {
#if TARGET_OS_IPHONE
void KRLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) {
void KRLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) {
KRNode::render(pCamera, pContext, viewport, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
KRNode::render(pCamera, pContext, viewport, pShadowViewports, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass);
if(renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES) {
if(m_flareTexture.size() && m_flareSize > 0.0f) {
@@ -135,7 +135,7 @@ void KRLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &v
// Render light flare on transparency pass
KRShader *pShader = pContext->getShaderManager()->getShader("flare", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
if(pShader->bind(viewport, getModelMatrix(), lightDirection, pShadowMatrices, shadowDepthTextures, 0, renderPass)) {
if(pShader->bind(viewport, pShadowViewports, getModelMatrix(), lightDirection, shadowDepthTextures, 0, renderPass)) {
GLDEBUG(glUniform1f(
pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE],
m_flareSize

View File

@@ -36,7 +36,7 @@ public:
#if TARGET_OS_IPHONE
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
#endif

View File

@@ -201,7 +201,7 @@ bool KRMaterial::isTransparent() {
}
#if TARGET_OS_IPHONE
bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, const KRCamera *pCamera, const KRViewport &viewport, const KRMat4 &matModel, const KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRContext *pContext, KRTexture *pLightMap, KRNode::RenderPass renderPass) {
bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, const KRCamera *pCamera, const KRViewport &viewport, const KRViewport *pShadowViewports, const KRMat4 &matModel, const KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRContext *pContext, KRTexture *pLightMap, KRNode::RenderPass renderPass) {
bool bSameMaterial = *prevBoundMaterial == this;
bool bLightMap = pLightMap && pCamera->bEnableLightMap;
@@ -242,7 +242,7 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, con
bool bSameShader = strcmp(pShader->getKey(), szPrevShaderKey) == 0;
if(!bSameShader) {
if(!pShader->bind(viewport, matModel, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass)) {
if(!pShader->bind(viewport, pShadowViewports, matModel, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass)) {
return false;
}

View File

@@ -89,7 +89,7 @@ public:
char *getName();
#if TARGET_OS_IPHONE
bool bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, const KRCamera *pCamera, const KRViewport &viewport, const KRMat4 &matModel, const KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRContext *pContext, KRTexture *pLightMap, KRNode::RenderPass renderPass);
bool bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, const KRCamera *pCamera, const KRViewport &viewport, const KRViewport *pShadowViewports, const KRMat4 &matModel, const KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRContext *pContext, KRTexture *pLightMap, KRNode::RenderPass renderPass);
#endif

View File

@@ -111,7 +111,7 @@ void KRModel::loadPack(KRDataBlock *data) {
#if TARGET_OS_IPHONE
void KRModel::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRMat4 &matModel, const KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRTexture *pLightMap, KRNode::RenderPass renderPass) {
void KRModel::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, const KRMat4 &matModel, const KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRTexture *pLightMap, KRNode::RenderPass renderPass) {
//fprintf(stderr, "Rendering model: %s\n", m_name.c_str());
if(renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES) {
@@ -164,7 +164,7 @@ void KRModel::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &v
if(pMaterial != NULL && pMaterial == (*mat_itr)) {
if((!pMaterial->isTransparent() && renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT) || (pMaterial->isTransparent() && renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
if(pMaterial->bind(&pPrevBoundMaterial, szPrevShaderKey, pCamera, viewport, matModel, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, pContext, pLightMap, renderPass)) {
if(pMaterial->bind(&pPrevBoundMaterial, szPrevShaderKey, pCamera, viewport, pShadowViewports, matModel, lightDirection, shadowDepthTextures, cShadowBuffers, pContext, pLightMap, renderPass)) {
switch(pMaterial->getAlphaMode()) {
case KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE: // Non-transparent materials

View File

@@ -69,7 +69,7 @@ public:
#if TARGET_OS_IPHONE
void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRMat4 &matModel, const KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRTexture *pLightMap, KRNode::RenderPass renderPass);
void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, const KRMat4 &matModel, const KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRTexture *pLightMap, KRNode::RenderPass renderPass);
#endif

View File

@@ -40,6 +40,7 @@ KRModelManager::KRModelManager(KRContext &context) : KRContextObject(context) {
m_currentVBO.data = NULL;
m_vboMemUsed = 0;
m_randomParticleVertexData = NULL;
m_volumetricLightingVertexData = NULL;
}
KRModelManager::~KRModelManager() {
@@ -48,6 +49,7 @@ KRModelManager::~KRModelManager() {
}
m_models.empty();
if(m_randomParticleVertexData != NULL) delete m_randomParticleVertexData;
if(m_volumetricLightingVertexData != NULL) delete m_volumetricLightingVertexData;
}
KRModel *KRModelManager::loadModel(const char *szName, KRDataBlock *pData) {
@@ -249,6 +251,53 @@ void KRModelManager::rotateBuffers(bool new_frame)
}
KRModelManager::VolumetricLightingVertexData *KRModelManager::getVolumetricLightingVertexes()
{
const int MAX_PLANES=500;
if(m_volumetricLightingVertexData == NULL) {
m_volumetricLightingVertexData = (VolumetricLightingVertexData *)malloc(sizeof(VolumetricLightingVertexData) * MAX_PLANES * 6);
int iVertex=0;
for(int iPlane=0; iPlane < MAX_PLANES; iPlane++) {
m_volumetricLightingVertexData[iVertex].vertex.x = -1.0f;
m_volumetricLightingVertexData[iVertex].vertex.y = -1.0f;
m_volumetricLightingVertexData[iVertex].vertex.z = iPlane;
iVertex++;
m_volumetricLightingVertexData[iVertex].vertex.x = 1.0f;
m_volumetricLightingVertexData[iVertex].vertex.y = -1.0f;
m_volumetricLightingVertexData[iVertex].vertex.z = iPlane;
iVertex++;
m_volumetricLightingVertexData[iVertex].vertex.x = -1.0f;
m_volumetricLightingVertexData[iVertex].vertex.y = 1.0f;
m_volumetricLightingVertexData[iVertex].vertex.z = iPlane;
iVertex++;
m_volumetricLightingVertexData[iVertex].vertex.x = -1.0f;
m_volumetricLightingVertexData[iVertex].vertex.y = 1.0f;
m_volumetricLightingVertexData[iVertex].vertex.z = iPlane;
iVertex++;
m_volumetricLightingVertexData[iVertex].vertex.x = 1.0f;
m_volumetricLightingVertexData[iVertex].vertex.y = -1.0f;
m_volumetricLightingVertexData[iVertex].vertex.z = iPlane;
iVertex++;
m_volumetricLightingVertexData[iVertex].vertex.x = 1.0f;
m_volumetricLightingVertexData[iVertex].vertex.y = 1.0f;
m_volumetricLightingVertexData[iVertex].vertex.z = iPlane;
iVertex++;
// -1.0f, -1.0f,
// 1.0f, -1.0f,
// -1.0f, 1.0f,
// 1.0f, 1.0f,
}
}
return m_volumetricLightingVertexData;
}
KRModelManager::RandomParticleVertexData *KRModelManager::getRandomParticles()
{
const int MAX_PARTICLES=500000;

View File

@@ -80,7 +80,12 @@ public:
TexCoord uva;
} RandomParticleVertexData;
typedef struct {
KRVector3D vertex;
} VolumetricLightingVertexData;
RandomParticleVertexData *getRandomParticles();
VolumetricLightingVertexData *getVolumetricLightingVertexes();
private:
std::multimap<std::string, KRModel *> m_models; // Multiple models with the same name/key may be inserted, representing multiple LOD levels of the model
@@ -99,6 +104,8 @@ private:
std::map<GLvoid *, vbo_info_type> m_vbosPool;
RandomParticleVertexData *m_randomParticleVertexData;
VolumetricLightingVertexData *m_volumetricLightingVertexData;
};
#endif

View File

@@ -17,6 +17,7 @@
#import "KRInstance.h"
#import "KRParticleSystem.h"
#import "KRParticleSystemBrownian.h"
#import "KRVolumetricFog.h"
#import "KRAABB.h"
#import "KRQuaternion.h"
@@ -147,12 +148,22 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) {
new_node = new KRSpotLight(scene, szName);
} else if(strcmp(szElementName, "brownian_particles") == 0) {
new_node = new KRParticleSystemBrownian(scene, szName);
} else if(strcmp(szElementName, "volumetric_fog") == 0) {
float lod_min_coverage = 0.0f;
if(e->QueryFloatAttribute("lod_min_coverage", &lod_min_coverage) != tinyxml2::XML_SUCCESS) {
lod_min_coverage = 0.0f; //1.0f / 1024.0f / 768.0f; // FINDME - HACK - Need to dynamically select the absolute minimum based on the render buffer size
}
new_node = new KRVolumetricFog(scene, szName, szName, lod_min_coverage);
} else if(strcmp(szElementName, "mesh") == 0) {
float lod_min_coverage = 0.0f;
if(e->QueryFloatAttribute("lod_min_coverage", &lod_min_coverage) != tinyxml2::XML_SUCCESS) {
lod_min_coverage = 0.0f; //1.0f / 1024.0f / 768.0f; // FINDME - HACK - Need to dynamically select the absolute minimum based on the render buffer size
}
new_node = new KRInstance(scene, szName, szName, e->Attribute("light_map"), lod_min_coverage);
bool receives_shadow = true;
if(e->QueryBoolAttribute("receives_shadow", &receives_shadow) != tinyxml2::XML_SUCCESS) {
receives_shadow = true;
}
new_node = new KRInstance(scene, szName, szName, e->Attribute("light_map"), lod_min_coverage, receives_shadow);
}
if(new_node) {
@@ -164,7 +175,7 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) {
#if TARGET_OS_IPHONE
void KRNode::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, RenderPass renderPass) {
void KRNode::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, RenderPass renderPass) {
}
#endif
@@ -211,3 +222,14 @@ const KRMat4 &KRNode::getModelMatrix()
}
return m_modelMatrix;
}
void KRNode::physicsUpdate(float deltaTime)
{
}
bool KRNode::hasPhysics()
{
return false;
}

View File

@@ -68,10 +68,13 @@ public:
KRScene &getScene();
#if TARGET_OS_IPHONE
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, RenderPass renderPass);
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, RenderPass renderPass);
#endif
virtual void physicsUpdate(float deltaTime);
virtual bool hasPhysics();
protected:
KRVector3 m_localTranslation;
KRVector3 m_localScale;

View File

@@ -19,6 +19,13 @@ public:
virtual void loadXML(tinyxml2::XMLElement *e);
virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent);
virtual KRAABB getBounds() = 0;
#if TARGET_OS_IPHONE
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) = 0;
#endif
protected:
KRParticleSystem(KRScene &scene, std::string name);
private:

View File

@@ -7,10 +7,13 @@
//
#include "KRParticleSystemBrownian.h"
#include "KRAABB.h"
#include "KRTexture.h"
#include "KRContext.h"
KRParticleSystemBrownian::KRParticleSystemBrownian(KRScene &scene, std::string name) : KRParticleSystem(scene, name)
{
m_particlesAbsoluteTime = 0.0f;
}
KRParticleSystemBrownian::~KRParticleSystemBrownian()
@@ -35,17 +38,60 @@ tinyxml2::XMLElement *KRParticleSystemBrownian::saveXML( tinyxml2::XMLNode *pare
}
KRAABB KRParticleSystemBrownian::getBounds()
{
return KRAABB(-KRVector3::One(), KRVector3::One(), getModelMatrix());
}
void KRParticleSystemBrownian::physicsUpdate(float deltaTime)
{
KRParticleSystem::physicsUpdate(deltaTime);
m_particlesAbsoluteTime += deltaTime;
}
#if TARGET_OS_IPHONE
void KRParticleSystemBrownian::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) {
KRNode::render(pCamera, pContext, viewport, pShadowViewports, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass);
if(renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES) {
float lod_coverage = getBounds().coverage(viewport.getViewProjectionMatrix(), viewport.getSize()); // This also checks the view frustrum culling
if(lod_coverage > 0.0f) {
// Enable z-buffer test
GLDEBUG(glEnable(GL_DEPTH_TEST));
GLDEBUG(glDepthRangef(0.0, 1.0));
KRTexture *pParticleTexture = m_pContext->getTextureManager()->getTexture("flare");
m_pContext->getTextureManager()->selectTexture(0, pParticleTexture, 2048);
KRShader *pParticleShader = m_pContext->getShaderManager()->getShader("particle", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_ADDITIVE_PARTICLES);
int particle_count = 10000;
if(pParticleShader->bind(viewport, pShadowViewports, getModelMatrix(), lightDirection, shadowDepthTextures, cShadowBuffers, KRNode::RENDER_PASS_ADDITIVE_PARTICLES)) {
GLDEBUG(glUniform1f(
pParticleShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE],
1.0f
));
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRModelManager::RandomParticleVertexData), true, false, false, true, false);
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3));
}
}
}
}
#endif
//
// m_particlesAbsoluteTime += deltaTime;
//
// // Enable z-buffer test
// GLDEBUG(glEnable(GL_DEPTH_TEST));
// GLDEBUG(glDepthRangef(0.0, 1.0));
//
// KRTexture *pParticleTexture = m_pContext->getTextureManager()->getTexture("flare");
// m_pContext->getTextureManager()->selectTexture(0, pParticleTexture, 2048);
//
// KRShader *pParticleShader = m_pContext->getShaderManager()->getShader("particle", this, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_ADDITIVE_PARTICLES);
//
// KRMat4 particleModelMatrix = KRMat4();
//// particleModelMatrix.scale(particleBlockScale);

View File

@@ -19,8 +19,20 @@ public:
virtual std::string getElementName();
virtual void loadXML(tinyxml2::XMLElement *e);
virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent);
private:
virtual KRAABB getBounds();
#if TARGET_OS_IPHONE
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
#endif
virtual void physicsUpdate(float deltaTime);
private:
float m_particlesAbsoluteTime;
};
#endif

View File

@@ -43,9 +43,9 @@ KRAABB KRPointLight::getBounds() {
#if TARGET_OS_IPHONE
void KRPointLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) {
void KRPointLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) {
KRLight::render(pCamera, pContext, viewport, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
KRLight::render(pCamera, pContext, viewport, pShadowViewports, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass);
bool bVisualize = renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && pCamera->bShowDeferred;
@@ -69,7 +69,7 @@ void KRPointLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewpo
bool bInsideLight = view_light_position.sqrMagnitude() <= (influence_radius + pCamera->getPerspectiveNearZ()) * (influence_radius + pCamera->getPerspectiveNearZ());
KRShader *pShader = pContext->getShaderManager()->getShader(bVisualize ? "visualize_overlay" : (bInsideLight ? "light_point_inside" : "light_point"), pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
if(pShader->bind(viewport, sphereModelMatrix, lightDirection, pShadowMatrices, shadowDepthTextures, 0, renderPass)) {
if(pShader->bind(viewport, pShadowViewports, sphereModelMatrix, lightDirection, shadowDepthTextures, 0, renderPass)) {

View File

@@ -24,7 +24,7 @@ public:
#if TARGET_OS_IPHONE
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
#endif
private:

View File

@@ -57,7 +57,7 @@ KRScene::~KRScene() {
#if TARGET_OS_IPHONE
void KRScene::render(KRCamera *pCamera, std::set<KRAABB> &visibleBounds, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds) {
void KRScene::render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds) {
updateOctree();
pCamera->setSkyBox(m_skyBoxName); // This is temporary until the camera is moved into the scene graph
@@ -118,10 +118,10 @@ void KRScene::render(KRCamera *pCamera, std::set<KRAABB> &visibleBounds, KRConte
newRemainingOctrees.clear();
newRemainingOctreesTestResults.clear();
for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctrees.begin(); octree_itr != remainingOctrees.end(); octree_itr++) {
render(*octree_itr, visibleBounds, pCamera, pContext, viewport, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false);
render(*octree_itr, visibleBounds, pCamera, pContext, viewport, pShadowViewports, forward_render_light_direction, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false);
}
for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctreesTestResults.begin(); octree_itr != remainingOctreesTestResults.end(); octree_itr++) {
render(*octree_itr, visibleBounds, pCamera, pContext, viewport, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, false);
render(*octree_itr, visibleBounds, pCamera, pContext, viewport, pShadowViewports, forward_render_light_direction, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, false);
}
remainingOctrees = newRemainingOctrees;
remainingOctreesTestResults = newRemainingOctreesTestResults;
@@ -130,16 +130,16 @@ void KRScene::render(KRCamera *pCamera, std::set<KRAABB> &visibleBounds, KRConte
newRemainingOctrees.clear();
newRemainingOctreesTestResults.clear();
for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctreesTestResultsOnly.begin(); octree_itr != remainingOctreesTestResultsOnly.end(); octree_itr++) {
render(*octree_itr, visibleBounds, pCamera, pContext, viewport, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, true);
render(*octree_itr, visibleBounds, pCamera, pContext, viewport, pShadowViewports, forward_render_light_direction, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, true);
}
std::set<KRNode *> outerNodes = std::set<KRNode *>(m_nodeTree.getOuterSceneNodes()); // HACK - Copying the std::set as it is potentially modified as KRNode's update their bounds during the iteration. This is very expensive and will be eliminated in the future.
for(std::set<KRNode *>::iterator itr=outerNodes.begin(); itr != outerNodes.end(); itr++) {
(*itr)->render(pCamera, pContext, viewport, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
(*itr)->render(pCamera, pContext, viewport, pShadowViewports, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass);
}
}
void KRScene::render(KROctreeNode *pOctreeNode, std::set<KRAABB> &visibleBounds, KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, std::set<KRAABB> &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly)
void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleBounds, KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, std::set<KRAABB> &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly)
{
if(pOctreeNode) {
@@ -152,7 +152,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, std::set<KRAABB> &visibleBounds,
GLDEBUG(glGetQueryObjectuivEXT(pOctreeNode->m_occlusionQuery, GL_QUERY_RESULT_EXT, &params));
if(params) {
newVisibleBounds.insert(octreeBounds); // Record the actual tests that succeeded during this frame
visibleBounds.insert(octreeBounds); // Update the list of tests that we won't repeat for subsequent passes during this frame
// visibleBounds.insert(octreeBounds); // Update the list of tests that we won't repeat for subsequent passes during this frame
if(!bOcclusionTestResultsOnly) {
// Schedule a pass to perform the rendering
remainingOctrees.push_back(pOctreeNode);
@@ -181,7 +181,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, std::set<KRAABB> &visibleBounds,
bVisible = octreeBounds.intersects(cameraExtents);
if(bVisible) {
newVisibleBounds.insert(octreeBounds); // Record the actual tests that succeeded during this frame
visibleBounds.insert(octreeBounds); // Update the list of tests that we won't repeat for subsequent passes during this frame
// visibleBounds.insert(octreeBounds); // Update the list of tests that we won't repeat for subsequent passes during this frame
bNeedOcclusionTest = false;
}
}
@@ -239,7 +239,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, std::set<KRAABB> &visibleBounds,
GLDEBUG(glDepthMask(GL_FALSE));
}
if(pVisShader->bind(viewport, matModel, lightDirection, pShadowMatrices, shadowDepthTextures, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
if(pVisShader->bind(viewport, pShadowViewports, matModel, lightDirection, shadowDepthTextures, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 14));
}
@@ -276,13 +276,13 @@ void KRScene::render(KROctreeNode *pOctreeNode, std::set<KRAABB> &visibleBounds,
for(std::set<KRNode *>::iterator itr=pOctreeNode->getSceneNodes().begin(); itr != pOctreeNode->getSceneNodes().end(); itr++) {
//assert(pOctreeNode->getBounds().contains((*itr)->getBounds())); // Sanity check
(*itr)->render(pCamera, pContext, viewport, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
(*itr)->render(pCamera, pContext, viewport, pShadowViewports, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass);
}
const int *childOctreeOrder = renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT || renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES ? viewport.getBackToFrontOrder() : viewport.getFrontToBackOrder();
for(int i=0; i<8; i++) {
render(pOctreeNode->getChildren()[childOctreeOrder[i]], visibleBounds, pCamera, pContext, viewport, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, remainingOctrees, remainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false);
render(pOctreeNode->getChildren()[childOctreeOrder[i]], visibleBounds, pCamera, pContext, viewport, pShadowViewports, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass, remainingOctrees, remainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false);
}
}
}
@@ -360,12 +360,16 @@ KRDirectionalLight *KRScene::getFirstDirectionalLight()
void KRScene::notify_sceneGraphCreate(KRNode *pNode)
{
m_nodeTree.add(pNode);
if(pNode->hasPhysics()) {
m_physicsNodes.erase(pNode);
}
// m_newNodes.insert(pNode);
}
void KRScene::notify_sceneGraphDelete(KRNode *pNode)
{
m_nodeTree.remove(pNode);
m_physicsNodes.erase(pNode);
//
// m_modifiedNodes.erase(pNode);
// if(!m_newNodes.erase(pNode)) {
@@ -390,6 +394,14 @@ void KRScene::updateOctree()
// m_newNodes.clear();
// m_modifiedNodes.clear();
}
void KRScene::physicsUpdate(float deltaTime)
{
for(std::set<KRNode *>::iterator itr=m_physicsNodes.begin(); itr != m_physicsNodes.end(); itr++) {
(*itr)->physicsUpdate(deltaTime);
}
}
#if TARGET_OS_IPHONE
#endif

View File

@@ -62,9 +62,9 @@ public:
#if TARGET_OS_IPHONE
void render(KRCamera *pCamera, std::set<KRAABB> &visibleBounds, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds);
void render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds);
void render(KROctreeNode *pOctreeNode, std::set<KRAABB> &visibleBounds, KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, std::set<KRAABB> &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly);
void render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleBounds, KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, std::set<KRAABB> &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly);
#endif
@@ -75,6 +75,8 @@ public:
void notify_sceneGraphDelete(KRNode *pNode);
void notify_sceneGraphModify(KRNode *pNode);
void physicsUpdate(float deltaTime);
private:
KRContext *m_pContext;
KRDirectionalLight *findFirstDirectionalLight(KRNode &node);
@@ -85,6 +87,10 @@ private:
std::set<KRNode *> m_newNodes;
std::set<KRNode *> m_modifiedNodes;
std::set<KRNode *> m_physicsNodes;
KROctree m_nodeTree;
void updateOctree();

View File

@@ -136,6 +136,7 @@ KRShader::KRShader(char *szKey, std::string options, std::string vertShaderSourc
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_MODEL_INVERSE_TRANSPOSE] = glGetUniformLocation(m_iProgram, "model_inverse_transpose_matrix"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_MODEL_VIEW] = glGetUniformLocation(m_iProgram, "model_view_matrix"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_MODEL_MATRIX] = glGetUniformLocation(m_iProgram, "model_matrix"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_PROJECTION_MATRIX] = glGetUniformLocation(m_iProgram, "projection_matrix"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_SHADOWMVP1] = glGetUniformLocation(m_iProgram, "shadow_mvp1"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_SHADOWMVP2] = glGetUniformLocation(m_iProgram, "shadow_mvp2"));
@@ -167,6 +168,7 @@ KRShader::KRShader(char *szKey, std::string options, std::string vertShaderSourc
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_GBUFFER_DEPTH] = glGetUniformLocation(m_iProgram, "gbuffer_depth"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_DEPTH_FRAME] = glGetUniformLocation(m_iProgram, "depthFrame"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_RENDER_FRAME] = glGetUniformLocation(m_iProgram, "renderFrame"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_SLICE_DEPTH_SCALE] = glGetUniformLocation(m_iProgram, "slice_depth_scale"));
}
} catch(...) {
@@ -201,7 +203,7 @@ KRShader::~KRShader() {
#if TARGET_OS_IPHONE
bool KRShader::bind(const KRViewport &viewport, const KRMat4 &matModel, const KRVector3 &lightDirection, const KRMat4 *pShadowMatrices, const GLuint *shadowDepthTextures, const int &cShadowBuffers, const KRNode::RenderPass &renderPass) {
bool KRShader::bind(const KRViewport &viewport, const KRViewport *pShadowViewports, const KRMat4 &matModel, const KRVector3 &lightDirection, const GLuint *shadowDepthTextures, const int &cShadowBuffers, const KRNode::RenderPass &renderPass) {
if(m_iProgram == 0) {
return false;
}
@@ -235,7 +237,7 @@ bool KRShader::bind(const KRViewport &viewport, const KRMat4 &matModel, const KR
}
}
if(m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_POSITION_VIEW_SPACE] != -1 || m_uniforms[KRENGINE_UNIFORM_MODEL_VIEW_INVERSE_TRANSPOSE] != -1) {
if(m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_POSITION_VIEW_SPACE] != -1 || m_uniforms[KRENGINE_UNIFORM_MODEL_VIEW_INVERSE_TRANSPOSE] != -1 || m_uniforms[KRShader::KRENGINE_UNIFORM_MODEL_VIEW] != -1) {
KRMat4 matModelView = matModel * viewport.getViewMatrix();
matModelView.setUniform(m_uniforms[KRShader::KRENGINE_UNIFORM_MODEL_VIEW]);
@@ -280,6 +282,9 @@ bool KRShader::bind(const KRViewport &viewport, const KRMat4 &matModel, const KR
}
matModel.setUniform(m_uniforms[KRShader::KRENGINE_UNIFORM_MODEL_MATRIX]);
if(m_uniforms[KRENGINE_UNIFORM_PROJECTION_MATRIX] != -1) {
viewport.getProjectionMatrix().setUniform(m_uniforms[KRENGINE_UNIFORM_PROJECTION_MATRIX]);
}
if(m_uniforms[KRENGINE_UNIFORM_VIEWPORT] != -1) {
GLDEBUG(glUniform4f(
@@ -293,7 +298,10 @@ bool KRShader::bind(const KRViewport &viewport, const KRMat4 &matModel, const KR
// Bind the shadowmap space matrices
for(int iShadow=0; iShadow < cShadowBuffers; iShadow++) {
pShadowMatrices[iShadow].setUniform(m_uniforms[KRENGINE_UNIFORM_SHADOWMVP1 + iShadow]);
KRMat4 matBias;
matBias.translate(1.0, 1.0, 1.0);
matBias.scale(0.5);
(matModel * pShadowViewports[iShadow].getViewProjectionMatrix() * matBias).setUniform(m_uniforms[KRENGINE_UNIFORM_SHADOWMVP1 + iShadow]);
}
// Sets the diffuseTexture variable to the first texture unit

View File

@@ -56,7 +56,7 @@ public:
#if TARGET_OS_IPHONE
bool bind(const KRViewport &viewport, const KRMat4 &matModel, const KRVector3 &lightDirection, const KRMat4 *pShadowMatrices, const GLuint *shadowDepthTextures, const int &cShadowBuffers, const KRNode::RenderPass &renderPass);
bool bind(const KRViewport &viewport, const KRViewport *pShadowViewports, const KRMat4 &matModel, const KRVector3 &lightDirection, const GLuint *shadowDepthTextures, const int &cShadowBuffers, const KRNode::RenderPass &renderPass);
#endif
@@ -96,6 +96,7 @@ public:
KRENGINE_UNIFORM_MODEL_INVERSE_TRANSPOSE,
KRENGINE_UNIFORM_MODEL_VIEW,
KRENGINE_UNIFORM_MODEL_MATRIX,
KRENGINE_UNIFORM_PROJECTION_MATRIX,
KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE,
KRENGINE_UNIFORM_VIEWPORT,
@@ -126,6 +127,8 @@ public:
KRENGINE_UNIFORM_DEPTH_FRAME,
KRENGINE_UNIFORM_RENDER_FRAME,
KRENGINE_UNIFORM_SLICE_DEPTH_SCALE,
KRENGINE_NUM_UNIFORMS
};
GLint m_uniforms[KRENGINE_NUM_UNIFORMS];

View File

@@ -151,3 +151,15 @@ void KRViewport::calculateDerivedValues()
m_backToFrontOrder[i] = m_frontToBackOrder[7-i];
}
}
const std::set<KRAABB> &KRViewport::getVisibleBounds()
{
return m_visibleBounds;
}
void KRViewport::setVisibleBounds(const std::set<KRAABB> visibleBounds)
{
m_visibleBounds = visibleBounds;
}

View File

@@ -11,6 +11,7 @@
#include "KRVector2.h"
#include "KRMat4.h"
#include "KRAABB.h"
class KRViewport {
public:
@@ -35,6 +36,9 @@ public:
// Overload assignment operator
KRViewport& operator=(const KRViewport &v);
const std::set<KRAABB> &getVisibleBounds();
void setVisibleBounds(const std::set<KRAABB> visibleBounds);
private:
KRVector2 m_size;
KRMat4 m_matView;
@@ -52,6 +56,8 @@ private:
int m_backToFrontOrder[8];
void calculateDerivedValues();
std::set<KRAABB> m_visibleBounds; // AABB's that output fragments in the last frame
};
#endif

View File

@@ -0,0 +1,174 @@
//
// KRVolumetricFog.cpp
// KREngine
//
// 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.
//
#include <iostream>
#import "KRVolumetricFog.h"
#import "KRContext.h"
#import "KRModel.h"
#import "KRShader.h"
#include <assert.h>
KRVolumetricFog::KRVolumetricFog(KRScene &scene, std::string instance_name, std::string model_name, float lod_min_coverage) : KRNode(scene, instance_name) {
m_model_name = model_name;
m_min_lod_coverage = lod_min_coverage;
}
KRVolumetricFog::~KRVolumetricFog() {
}
std::string KRVolumetricFog::getElementName() {
return "volumetric_fog";
}
tinyxml2::XMLElement *KRVolumetricFog::saveXML( tinyxml2::XMLNode *parent)
{
tinyxml2::XMLElement *e = KRNode::saveXML(parent);
e->SetAttribute("mesh_name", m_model_name.c_str());
e->SetAttribute("lod_min_coverage", m_min_lod_coverage);
return e;
}
void KRVolumetricFog::loadModel() {
if(m_models.size() == 0) {
m_models = m_pContext->getModelManager()->getModel(m_model_name.c_str()); // The model manager returns the LOD levels in sorted order, with the highest detail first
if(m_models.size() > 0) {
getScene().notify_sceneGraphModify(this);
}
// if(m_pModel == NULL) {
// fprintf(stderr, "KREngine - Model not found: %s\n", m_model_name.c_str());
// }
}
}
#if TARGET_OS_IPHONE
void KRVolumetricFog::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) {
KRNode::render(pCamera, pContext, viewport, pShadowViewports, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass);
if(renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES) {
// Don't render meshes on second pass of the deferred lighting renderer, as only lights will be applied
loadModel();
KRAABB bounds = getBounds();
if(m_models.size() > 0 && cShadowBuffers > 0) {
float lod_coverage = bounds.coverage(viewport.getViewProjectionMatrix(), viewport.getSize()); // This also checks the view frustrum culling
if(lod_coverage > m_min_lod_coverage) {
// ---===--- Select the best LOD model based on screen coverage ---===---
std::vector<KRModel *>::iterator itr=m_models.begin();
KRModel *pModel = *itr++;
while(itr != m_models.end()) {
KRModel *pLODModel = *itr++;
if((float)pLODModel->getLODCoverage() / 100.0f > lod_coverage && pLODModel->getLODCoverage() < pModel->getLODCoverage()) {
pModel = pLODModel;
} else {
break;
}
}
KRShader *pFogShader = m_pContext->getShaderManager()->getShader("volumetric_fog_inside", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
if(pFogShader->bind(viewport, pShadowViewports, getModelMatrix(), lightDirection, shadowDepthTextures, cShadowBuffers, KRNode::RENDER_PASS_ADDITIVE_PARTICLES)) {
KRAABB viewSpaceBounds = KRAABB(bounds.min, bounds.max, viewport.getViewProjectionMatrix());
// Enable z-buffer test
GLDEBUG(glEnable(GL_DEPTH_TEST));
GLDEBUG(glDepthFunc(GL_LEQUAL));
GLDEBUG(glDepthRangef(0.0, 1.0));
// Enable backface culling
GLDEBUG(glCullFace(GL_BACK));
GLDEBUG(glEnable(GL_CULL_FACE));
int slice_count = 50;
float slice_near = -100.0;
float slice_far = -1000.0;
float slice_spacing = (slice_far - slice_near) / slice_count;
KRVector2(slice_near, slice_spacing).setUniform(pFogShader->m_uniforms[KRShader::KRENGINE_UNIFORM_SLICE_DEPTH_SCALE]);
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getVolumetricLightingVertexes(), slice_count * 6 * sizeof(KRModelManager::VolumetricLightingVertexData), true, false, false, false, false);
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, slice_count*6));
/*
float slice_near = viewSpaceBounds.max.z;
float slice_far = viewSpaceBounds.min.z;
slice_near = -1.0;
slice_far = 1.0;
float slice_spacing = (slice_far - slice_near) / slice_count;
// slice_spacing = 1.0f / slice_count;
// slice_near = 0.0f;
for(int slice=0; slice < slice_count; slice++) {
KRVector2(slice_near + slice * slice_spacing, slice_spacing).setUniform(pFogShader->m_uniforms[KRShader::KRENGINE_UNIFORM_SLICE_DEPTH_SCALE]);
int mesh_count = pModel->getSubmeshes().size();
for(int iMesh=0; iMesh < mesh_count; iMesh++) {
pModel->renderSubmesh(iMesh);
}
}
*/
}
}
}
}
}
#endif
bool KRVolumetricFog::hasTransparency() {
if(m_models.size() > 0) {
return m_models[0]->hasTransparency();
} else {
return false;
}
}
KRAABB KRVolumetricFog::getBounds() {
loadModel();
if(m_models.size() > 0) {
return KRAABB(m_models[0]->getMinPoint(), m_models[0]->getMaxPoint(), getModelMatrix());
} else {
return KRAABB::Infinite();
}
}

View File

@@ -0,0 +1,79 @@
//
// KRVolumetricFog.h
// KREngine
//
// 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.
//
#import "KREngine-common.h"
#ifndef KRVOLUMETRICFOG_H
#define KRVOLUMETRICFOG_H
#import "KRModel.h"
#import "KRMat4.h"
#import "KRVector3.h"
#import "KRVolumetricFog.h"
#import "KRCamera.h"
#import "KRModelManager.h"
#import "KRNode.h"
#import "KRContext.h"
#import "KRModel.h"
#import "KRTexture.h"
class KRVolumetricFog : public KRNode {
public:
KRVolumetricFog(KRScene &scene, std::string instance_name, std::string model_name, float lod_min_coverage);
virtual ~KRVolumetricFog();
virtual std::string getElementName();
virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent);
#if TARGET_OS_IPHONE
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
#endif
bool hasTransparency();
virtual KRAABB getBounds();
private:
std::vector<KRModel *> m_models;
std::string m_model_name;
float m_min_lod_coverage;
void loadModel();
};
#endif

View File

@@ -25,6 +25,8 @@
// or implied, of Kearwood Gilbert.
//
#extension GL_EXT_shadow_samplers : require
#if ENABLE_PER_PIXEL == 1 || GBUFFER_PASS == 1
uniform mediump float material_shininess;
#if HAS_NORMAL_MAP == 1
@@ -99,7 +101,11 @@
#if SHADOW_QUALITY >= 1
uniform sampler2D shadowTexture1;
#ifdef GL_EXT_shadow_samplers
uniform sampler2DShadow shadowTexture1;
#else
uniform sampler2D shadowTexture1;
#endif
varying highp vec4 shadowMapCoord1;
#endif
@@ -212,62 +218,72 @@ void main()
#endif
}
#if SHADOW_QUALITY == 1
highp float shadowMapDepth = 1.0;
highp float vertexShadowDepth = 1.0;
highp vec2 shadowMapPos = ((shadowMapCoord1 / shadowMapCoord1.w + 1.0) / 2.0).st;
if(shadowMapCoord1.x >= -1.0 && shadowMapCoord1.x <= 1.0 && shadowMapCoord1.y >= -1.0 && shadowMapCoord1.y <= 1.0 && shadowMapCoord1.z >= 0.0 && shadowMapCoord1.z <= 1.0) {
#if DEBUG_PSSM == 1
diffuseMaterial = diffuseMaterial * vec4(0.75, 0.75, 0.5, 1.0) + vec4(0.0, 0.0, 0.5, 0.0);
#ifdef GL_EXT_shadow_samplers
#if SHADOW_QUALITY == 1
lowp float shadow = shadow2DProjEXT(shadowTexture1, shadowMapCoord1);
lamberFactor *= shadow;
specularFactor *= shadow;
#endif
shadowMapDepth = texture2D(shadowTexture1, shadowMapPos).z;
vertexShadowDepth = ((shadowMapCoord1 / shadowMapCoord1.w + 1.0) / 2.0).z;
}
#endif
#else
#if SHADOW_QUALITY >= 2
#if SHADOW_QUALITY == 1
highp float shadowMapDepth = 1.0;
highp float vertexShadowDepth = 1.0;
highp float shadowMapDepth = 1.0;
highp float vertexShadowDepth = 1.0;
highp vec2 shadowMapPos = (shadowMapCoord1 / shadowMapCoord1.w).st;
if(shadowMapCoord1.x >= -1.0 && shadowMapCoord1.x <= 1.0 && shadowMapCoord1.y >= -1.0 && shadowMapCoord1.y <= 1.0 && shadowMapCoord1.z >= 0.0 && shadowMapCoord1.z <= 1.0) {
#if DEBUG_PSSM == 1
diffuseMaterial = diffuseMaterial * vec4(0.75, 0.75, 0.5, 1.0) + vec4(0.0, 0.0, 0.5, 0.0);
#endif
highp vec2 shadowMapPos = ((shadowMapCoord1 / shadowMapCoord1.w + 1.0) / 2.0).st;
shadowMapDepth = texture2D(shadowTexture1, shadowMapPos).z;
vertexShadowDepth = ((shadowMapCoord1 / shadowMapCoord1.w + 1.0) / 2.0).z;
} else if(shadowMapCoord2.s >= -1.0 && shadowMapCoord2.s <= 1.0 && shadowMapCoord2.t >= -1.0 && shadowMapCoord2.t <= 1.0 && shadowMapCoord2.z >= 0.0 && shadowMapCoord2.z <= 1.0) {
#if DEBUG_PSSM == 1
diffuseMaterial = diffuseMaterial * vec4(0.75, 0.50, 0.75, 1.0) + vec4(0.0, 0.5, 0.0, 0.0);
#endif
highp vec2 shadowMapPos = ((shadowMapCoord2 / shadowMapCoord2.w + 1.0) / 2.0).st;
shadowMapDepth = texture2D(shadowTexture2, shadowMapPos).z;
vertexShadowDepth = ((shadowMapCoord2 / shadowMapCoord2.w + 1.0) / 2.0).z;
}
#if SHADOW_QUALITY >= 3
else if(shadowMapCoord3.s >= -1.0 && shadowMapCoord3.s <= 1.0 && shadowMapCoord3.t >= -1.0 && shadowMapCoord3.t <= 1.0 && shadowMapCoord3.z >= 0.0 && shadowMapCoord3.z <= 1.0) {
if(shadowMapCoord1.x >= -1.0 && shadowMapCoord1.x <= 1.0 && shadowMapCoord1.y >= -1.0 && shadowMapCoord1.y <= 1.0 && shadowMapCoord1.z >= 0.0 && shadowMapCoord1.z <= 1.0) {
#if DEBUG_PSSM == 1
diffuseMaterial = diffuseMaterial * vec4(0.50, 0.75, 0.75, 1.0) + vec4(0.5, 0.0, 0.0, 0.0);
diffuseMaterial = diffuseMaterial * vec4(0.75, 0.75, 0.5, 1.0) + vec4(0.0, 0.0, 0.5, 0.0);
#endif
highp vec2 shadowMapPos = ((shadowMapCoord3 / shadowMapCoord3.w + 1.0) / 2.0).st;
shadowMapDepth = texture2D(shadowTexture3, shadowMapPos).z;
vertexShadowDepth = ((shadowMapCoord3 / shadowMapCoord3.w + 1.0) / 2.0).z;
}
shadowMapDepth = texture2D(shadowTexture1, shadowMapPos).z;
vertexShadowDepth = (shadowMapCoord1 / shadowMapCoord1.w).z;
}
#endif
#endif
#if SHADOW_QUALITY >= 1
if(vertexShadowDepth >= shadowMapDepth && shadowMapDepth < 1.0) {
#if GBUFFER_PASS == 3
lamberFactor = vec3(0.0);
#else
lamberFactor = 0.0;
#if SHADOW_QUALITY >= 2
highp float shadowMapDepth = 1.0;
highp float vertexShadowDepth = 1.0;
if(shadowMapCoord1.x >= -1.0 && shadowMapCoord1.x <= 1.0 && shadowMapCoord1.y >= -1.0 && shadowMapCoord1.y <= 1.0 && shadowMapCoord1.z >= 0.0 && shadowMapCoord1.z <= 1.0) {
#if DEBUG_PSSM == 1
diffuseMaterial = diffuseMaterial * vec4(0.75, 0.75, 0.5, 1.0) + vec4(0.0, 0.0, 0.5, 0.0);
#endif
highp vec2 shadowMapPos = (shadowMapCoord1 / shadowMapCoord1.w).st;
shadowMapDepth = texture2D(shadowTexture1, shadowMapPos).z;
vertexShadowDepth = (shadowMapCoord1 / shadowMapCoord1.w).z;
} else if(shadowMapCoord2.s >= -1.0 && shadowMapCoord2.s <= 1.0 && shadowMapCoord2.t >= -1.0 && shadowMapCoord2.t <= 1.0 && shadowMapCoord2.z >= 0.0 && shadowMapCoord2.z <= 1.0) {
#if DEBUG_PSSM == 1
diffuseMaterial = diffuseMaterial * vec4(0.75, 0.50, 0.75, 1.0) + vec4(0.0, 0.5, 0.0, 0.0);
#endif
highp vec2 shadowMapPos = (shadowMapCoord2 / shadowMapCoord2.w).st;
shadowMapDepth = texture2D(shadowTexture2, shadowMapPos).z;
vertexShadowDepth = (shadowMapCoord2 / shadowMapCoord2.w).z;
}
#if SHADOW_QUALITY >= 3
else if(shadowMapCoord3.s >= -1.0 && shadowMapCoord3.s <= 1.0 && shadowMapCoord3.t >= -1.0 && shadowMapCoord3.t <= 1.0 && shadowMapCoord3.z >= 0.0 && shadowMapCoord3.z <= 1.0) {
#if DEBUG_PSSM == 1
diffuseMaterial = diffuseMaterial * vec4(0.50, 0.75, 0.75, 1.0) + vec4(0.5, 0.0, 0.0, 0.0);
#endif
highp vec2 shadowMapPos = (shadowMapCoord3 / shadowMapCoord3.w).st;
shadowMapDepth = texture2D(shadowTexture3, shadowMapPos).z;
vertexShadowDepth = (shadowMapCoord3 / shadowMapCoord3.w).z;
}
#endif
specularFactor = 0.0;
}
#endif
#if SHADOW_QUALITY >= 1
if(vertexShadowDepth >= shadowMapDepth && shadowMapDepth < 1.0) {
#if GBUFFER_PASS == 3
lamberFactor = vec3(0.0);
#else
lamberFactor = 0.0;
#endif
specularFactor = 0.0;
}
#endif
#endif
#endif

View File

@@ -0,0 +1,33 @@
// 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.
//
//varying mediump vec2 texCoord;
void main()
{
gl_FragColor = vec4(0.0, 0.02, 0.02, 0.02);
}

View File

@@ -0,0 +1,62 @@
// 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 mvp_matrix; // mvp_matrix is the result of multiplying the model, view, and projection matrices
//uniform highp mat4 model_view_matrix;
//uniform highp mat4 projection_matrix;
//uniform highp mat4 inv_projection_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
void main()
{
// Transform position
/*
position = shadow_mvp1 * vec4(vertex_position,1.0);
*/
// gl_Position = mvp_matrix * vertex_position;
/*
// Pass UV co-ordinates
texCoord = vertex_uv.st;
*/
// highp vec4 p = model_view_matrix * vertex_position;
// p.z = slice_depth_scale.x;
// gl_Position = projection_matrix * p;
// highp vec4 p = mvp_matrix * vertex_position;
// p = inv_projection_matrix * p;
// p = projection_matrix * p;
// gl_Position = p;
highp vec4 p = mvp_matrix * vertex_position;
p.z = slice_depth_scale.x * p.w;
gl_Position = p;
}

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.
//
//varying mediump vec2 texCoord;
#extension GL_EXT_shadow_samplers : require
varying highp 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);
}

View File

@@ -0,0 +1,54 @@
// 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 highp vec4 shadowMapCoord1;
uniform highp mat4 projection_matrix;
void main()
{
// gl_Position = vec4(vertex_position.x, vertex_position.y, slice_depth_scale.x + vertex_position.z * slice_depth_scale.y, 1.0);
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;
}