Volumetric lighting in progress
--HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40152
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
@@ -146,30 +147,52 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, float deltaTime)
|
||||
|
||||
setViewportSize(KRVector2(backingWidth, backingHeight));
|
||||
m_viewport = KRViewport(getViewportSize(), viewMatrix, getProjectionMatrix());
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
||||
if(!(shadowmvpmatrix[iShadow] == newShadowMVP)) {
|
||||
shadowValid[iShadow] = false;
|
||||
}
|
||||
|
||||
if(!shadowValid[iShadow]) {
|
||||
shadowValid[iShadow] = true;
|
||||
|
||||
shadowmvpmatrix[iShadow] = newShadowMVP;
|
||||
renderShadowBuffer(scene, iShadow);
|
||||
|
||||
break;
|
||||
}
|
||||
// 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);
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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
|
||||
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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, ¶ms));
|
||||
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,13 +360,17 @@ 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)) {
|
||||
// m_nodeTree.remove(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
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
174
KREngine/KREngine/Classes/KRVolumetricFog.cpp
Normal file
174
KREngine/KREngine/Classes/KRVolumetricFog.cpp
Normal 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();
|
||||
}
|
||||
}
|
||||
|
||||
79
KREngine/KREngine/Classes/KRVolumetricFog.h
Normal file
79
KREngine/KREngine/Classes/KRVolumetricFog.h
Normal 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
|
||||
@@ -5,7 +5,7 @@
|
||||
//
|
||||
// 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.
|
||||
@@ -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 == 1
|
||||
|
||||
#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 + 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) {
|
||||
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.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 >= 2
|
||||
|
||||
highp float shadowMapDepth = 1.0;
|
||||
highp float vertexShadowDepth = 1.0;
|
||||
|
||||
#if SHADOW_QUALITY >= 1
|
||||
if(vertexShadowDepth >= shadowMapDepth && shadowMapDepth < 1.0) {
|
||||
#if GBUFFER_PASS == 3
|
||||
lamberFactor = vec3(0.0);
|
||||
#else
|
||||
lamberFactor = 0.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
|
||||
|
||||
|
||||
33
KREngine/KREngine/Shaders/volumetric_fog.fsh
Normal file
33
KREngine/KREngine/Shaders/volumetric_fog.fsh
Normal 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);
|
||||
}
|
||||
62
KREngine/KREngine/Shaders/volumetric_fog.vsh
Normal file
62
KREngine/KREngine/Shaders/volumetric_fog.vsh
Normal 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;
|
||||
}
|
||||
41
KREngine/KREngine/Shaders/volumetric_fog_inside.fsh
Normal file
41
KREngine/KREngine/Shaders/volumetric_fog_inside.fsh
Normal 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);
|
||||
}
|
||||
54
KREngine/KREngine/Shaders/volumetric_fog_inside.vsh
Normal file
54
KREngine/KREngine/Shaders/volumetric_fog_inside.vsh
Normal 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;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user