Implemented Cascaded Shadow Maps
parent
e76f5f1976
commit
e9ba7f77cc
|
@ -1,30 +1,38 @@
|
||||||
#version 150 core
|
#version 150 core
|
||||||
|
|
||||||
uniform sampler2D uColor;
|
uniform sampler2D uPosition;
|
||||||
uniform sampler2D uNormal;
|
|
||||||
uniform sampler2D uDepth;
|
uniform sampler2D uDepth;
|
||||||
|
uniform sampler2D uNormal;
|
||||||
|
uniform sampler2D uColor;
|
||||||
uniform sampler2D uAmbientOcclusion;
|
uniform sampler2D uAmbientOcclusion;
|
||||||
|
|
||||||
|
const int NUM_SPLITS = 3;
|
||||||
|
|
||||||
#define USE_SAMPLER2D_SHADOW 1
|
#define USE_SAMPLER2D_SHADOW 1
|
||||||
|
|
||||||
#ifdef USE_SAMPLER2D_SHADOW
|
#ifdef USE_SAMPLER2D_SHADOW
|
||||||
uniform sampler2DShadow uShadowMap;
|
uniform sampler2DShadow uShadowMap[NUM_SPLITS];
|
||||||
#else
|
#else
|
||||||
uniform sampler2D uShadowMap;
|
uniform sampler2D uShadowMaps[NUM_SPLITS];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uniform sampler2D uPosition;
|
uniform mat4 uViewToLightMatrix[NUM_SPLITS];
|
||||||
|
|
||||||
|
uniform float uNear;
|
||||||
|
uniform float uFar;
|
||||||
|
uniform vec4 uShadowSplits;
|
||||||
uniform vec3 uLightDirection;
|
uniform vec3 uLightDirection;
|
||||||
uniform mat4 uLightSpaceMatrix;
|
|
||||||
uniform mat4 uViewToLightSpaceMatrix;
|
|
||||||
uniform float uShadowBias;
|
uniform float uShadowBias;
|
||||||
|
|
||||||
in vec2 ioFragTexCoords;
|
in vec2 ioFragTexCoords;
|
||||||
|
|
||||||
out vec3 outColor;
|
out vec3 outColor;
|
||||||
|
|
||||||
float ShadowCalculationPCF(vec4 frag_pos_light_space, vec3 frag_normal_light_space) {
|
#ifdef USE_SAMPLER2D_SHADOW
|
||||||
|
float ShadowCalculationPCF(sampler2DShadow shadow_map, vec4 frag_pos_light_space, vec3 frag_normal_light_space) {
|
||||||
|
#else
|
||||||
|
float ShadowCalculationPCF(sampler2D shadow_map, vec4 frag_pos_light_space, vec3 frag_normal_light_space) {
|
||||||
|
#endif
|
||||||
vec3 projected_coordinates = frag_pos_light_space.xyz / frag_pos_light_space.w;
|
vec3 projected_coordinates = frag_pos_light_space.xyz / frag_pos_light_space.w;
|
||||||
projected_coordinates = projected_coordinates * 0.5 + 0.5;
|
projected_coordinates = projected_coordinates * 0.5 + 0.5;
|
||||||
|
|
||||||
|
@ -38,14 +46,14 @@ float ShadowCalculationPCF(vec4 frag_pos_light_space, vec3 frag_normal_light_spa
|
||||||
bias = max(0.001 * (1.0 - dot(frag_normal_light_space, uLightDirection)), uShadowBias);
|
bias = max(0.001 * (1.0 - dot(frag_normal_light_space, uLightDirection)), uShadowBias);
|
||||||
|
|
||||||
float shadow = 0.0;
|
float shadow = 0.0;
|
||||||
vec2 texel_size = 1.0 / textureSize(uShadowMap, 0);
|
vec2 texel_size = 1.0 / textureSize(shadow_map, 0);
|
||||||
for (int x = -1; x <= 1; ++x) {
|
for (int x = -1; x <= 1; ++x) {
|
||||||
for (int y = -1; y <= 1; ++y) {
|
for (int y = -1; y <= 1; ++y) {
|
||||||
#ifdef USE_SAMPLER2D_SHADOW
|
#ifdef USE_SAMPLER2D_SHADOW
|
||||||
vec2 coordinate = projected_coordinates.xy + vec2(x, y) * texel_size;
|
vec2 coordinate = projected_coordinates.xy + vec2(x, y) * texel_size;
|
||||||
float pcf_depth = texture(uShadowMap, vec3(coordinate, current_depth - bias));
|
float pcf_depth = texture(shadow_map, vec3(coordinate, current_depth - bias));
|
||||||
#else
|
#else
|
||||||
float pcf_depth = texture(uShadowMap, projected_coordinates.xy).r;
|
float pcf_depth = texture(shadow_map, projected_coordinates.xy).r;
|
||||||
#endif
|
#endif
|
||||||
shadow += current_depth - bias > pcf_depth ? 1.0 : 0.0;
|
shadow += current_depth - bias > pcf_depth ? 1.0 : 0.0;
|
||||||
}
|
}
|
||||||
|
@ -56,28 +64,10 @@ float ShadowCalculationPCF(vec4 frag_pos_light_space, vec3 frag_normal_light_spa
|
||||||
return shadow;
|
return shadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
float ShadowCalculation(vec4 frag_pos_light_space, vec3 frag_normal_light_space) {
|
|
||||||
vec3 projected_coordinates = frag_pos_light_space.xyz / frag_pos_light_space.w;
|
|
||||||
projected_coordinates = projected_coordinates * 0.5 + 0.5;
|
|
||||||
|
|
||||||
float current_depth = projected_coordinates.z;
|
|
||||||
|
|
||||||
float bias = 0.01;
|
|
||||||
|
|
||||||
#ifdef USE_SAMPLER2D_SHADOW
|
|
||||||
float closest_depth = texture(uShadowMap, vec3(projected_coordinates.xy, current_depth - bias));
|
|
||||||
#else
|
|
||||||
float closest_depth = texture(uShadowMap, projected_coordinates.xy).r;
|
|
||||||
bias = max(0.005 * (1.0 - dot(frag_normal_light_space, uLightDirection)), 0.003);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return current_depth - bias > closest_depth ? 1.0 : 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 get_cascade_color (float depth) {
|
vec3 get_cascade_color (float depth) {
|
||||||
if (depth < 0.97) {
|
if (depth < uShadowSplits[1]) {
|
||||||
return vec3 (1.0, 0.0, 0.0);
|
return vec3 (1.0, 0.0, 0.0);
|
||||||
} else if (depth < 0.99) {
|
} else if (depth < uShadowSplits[2]) {
|
||||||
return vec3 (0.0, 1.0, 0.0);
|
return vec3 (0.0, 1.0, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,13 +98,27 @@ void main() {
|
||||||
float spec = pow(max(dot(normal, halfway_dir), 0.0), 32);
|
float spec = pow(max(dot(normal, halfway_dir), 0.0), 32);
|
||||||
vec3 specular = spec * vec3(0.5);
|
vec3 specular = spec * vec3(0.5);
|
||||||
|
|
||||||
// shadow (need to transform position and normal to light space)
|
float shadow = 0;
|
||||||
vec4 position_light_space = uViewToLightSpaceMatrix * vec4(position, 1.0);
|
float normalized_depth = (depth - uNear) / (uFar - uNear);
|
||||||
vec3 normal_light_space = (transpose(inverse(uViewToLightSpaceMatrix)) * vec4(normal, 1.0)).xyz;
|
|
||||||
float shadow = ShadowCalculationPCF(position_light_space, normal);
|
|
||||||
|
|
||||||
// vec3 cascade = get_cascade_color(depth);
|
if (-position.z < uShadowSplits[1]) {
|
||||||
|
// shadow (need to transform position and normal to light space)
|
||||||
|
vec4 position_light_space = uViewToLightMatrix[0] * vec4(position, 1.0);
|
||||||
|
vec3 normal_light_space = (transpose(inverse(uViewToLightMatrix[0])) * vec4(normal, 1.0)).xyz;
|
||||||
|
shadow = ShadowCalculationPCF(uShadowMap[0], position_light_space, normal);
|
||||||
|
} else if (-position.z< uShadowSplits[2]) {
|
||||||
|
vec4 position_light_space = uViewToLightMatrix[1] * vec4(position, 1.0);
|
||||||
|
vec3 normal_light_space = (transpose(inverse(uViewToLightMatrix[1])) * vec4(normal, 1.0)).xyz;
|
||||||
|
shadow = ShadowCalculationPCF(uShadowMap[1], position_light_space, normal);
|
||||||
|
} else {
|
||||||
|
vec4 position_light_space = uViewToLightMatrix[2] * vec4(position, 1.0);
|
||||||
|
vec3 normal_light_space = (transpose(inverse(uViewToLightMatrix[2])) * vec4(normal, 1.0)).xyz;
|
||||||
|
shadow = ShadowCalculationPCF(uShadowMap[2], position_light_space, normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// vec3 cascade = get_cascade_color(-position.z);
|
||||||
// ambient = cascade;
|
// ambient = cascade;
|
||||||
outColor = (ambient + (1.0 - shadow) * (diffuse + specular)) * ambient_occlusion;
|
outColor = (ambient + (1.0 - shadow) * (diffuse + specular)) * ambient_occlusion;
|
||||||
|
// outColor = diffuse;
|
||||||
// outColor = (ambient + (diffuse + specular)) * ambient_occlusion;
|
// outColor = (ambient + (diffuse + specular)) * ambient_occlusion;
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,12 +210,12 @@ void Light::Initialize() {
|
||||||
| RenderTarget::EnableLinearizedDepthTexture);
|
| RenderTarget::EnableLinearizedDepthTexture);
|
||||||
|
|
||||||
for (int i = 0; i < cNumSplits; ++i) {
|
for (int i = 0; i < cNumSplits; ++i) {
|
||||||
mSplits[i].mShadowMapTarget.Initialize(mShadowMapSize, mShadowMapSize,
|
mSplitTarget[i].Initialize(mShadowMapSize, mShadowMapSize,
|
||||||
RenderTarget::EnableColor
|
RenderTarget::EnableColor
|
||||||
| RenderTarget::EnableDepthTexture
|
| RenderTarget::EnableDepthTexture
|
||||||
| RenderTarget::EnableLinearizedDepthTexture);
|
| RenderTarget::EnableLinearizedDepthTexture);
|
||||||
mSplits[i].mShadowMapTarget.mVertexArray = &gVertexArray;
|
mSplitTarget[i].mVertexArray = &gVertexArray;
|
||||||
mSplits[i].mShadowMapTarget.mQuadMesh = &gScreenQuad;
|
mSplitTarget[i].mQuadMesh = &gScreenQuad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +257,7 @@ void Light::DrawGui() {
|
||||||
if (sRendererSettings.ActiveShadowMapSplit == 3) {
|
if (sRendererSettings.ActiveShadowMapSplit == 3) {
|
||||||
shadow_split_target = &mShadowMapTarget;
|
shadow_split_target = &mShadowMapTarget;
|
||||||
} else {
|
} else {
|
||||||
shadow_split_target = &mSplits[sRendererSettings.ActiveShadowMapSplit].mShadowMapTarget;
|
shadow_split_target = &mSplitTarget[sRendererSettings.ActiveShadowMapSplit];
|
||||||
}
|
}
|
||||||
|
|
||||||
void* texture;
|
void* texture;
|
||||||
|
@ -295,14 +295,16 @@ void Light::UpdateSplits(const Camera& camera) {
|
||||||
Matrix44f light_matrix = LookAt (mPosition, mPosition + mDirection, Vector3f (0.f, 1.0f, 0.0f));
|
Matrix44f light_matrix = LookAt (mPosition, mPosition + mDirection, Vector3f (0.f, 1.0f, 0.0f));
|
||||||
Matrix44f light_matrix_inv = light_matrix.inverse();
|
Matrix44f light_matrix_inv = light_matrix.inverse();
|
||||||
|
|
||||||
|
mShadowSplits[0] = near;
|
||||||
|
mShadowSplits[1] = near + length * 0.02;
|
||||||
|
mShadowSplits[2] = near + length * 0.2;
|
||||||
|
mShadowSplits[3] = far;
|
||||||
|
|
||||||
for (int i = 0; i < cNumSplits; ++i) {
|
for (int i = 0; i < cNumSplits; ++i) {
|
||||||
ShadowSplitInfo &split = mSplits[i];
|
split_near = mShadowSplits[i];
|
||||||
|
float split_far = mShadowSplits[i + 1];
|
||||||
|
|
||||||
split_near = near + mShadowSplits[i] * length;
|
mSplitViewFrustum[i] = look_at * Perspective (camera.mFov, aspect, split_near, split_far);
|
||||||
float split_far = near + mShadowSplits[i + 1] * length;
|
|
||||||
|
|
||||||
split.mViewFrustum =
|
|
||||||
look_at * Perspective (camera.mFov, aspect, split_near, split_far);
|
|
||||||
|
|
||||||
float xn = split_near * tan_half_vfov;
|
float xn = split_near * tan_half_vfov;
|
||||||
float xf = split_far * tan_half_vfov;
|
float xf = split_far * tan_half_vfov;
|
||||||
|
@ -338,8 +340,8 @@ void Light::UpdateSplits(const Camera& camera) {
|
||||||
bbox_light.Update(v_light.block<3,1>(0,0));
|
bbox_light.Update(v_light.block<3,1>(0,0));
|
||||||
}
|
}
|
||||||
|
|
||||||
split.mBoundsWorld = bbox_world;
|
mSplitBoundsWorldSpace[i] = bbox_world;
|
||||||
split.mBoundsLight = bbox_light;
|
mSplitBoundsLightSpace[i] = bbox_light;
|
||||||
|
|
||||||
// gLog ("min/max %.3f,%.3f, %.3f,%.3f, %.3f,%.3f",
|
// gLog ("min/max %.3f,%.3f, %.3f,%.3f, %.3f,%.3f",
|
||||||
// min_x, max_x,
|
// min_x, max_x,
|
||||||
|
@ -352,11 +354,11 @@ void Light::UpdateSplits(const Camera& camera) {
|
||||||
Vector3f dimensions = (bbox_light.mMax - bbox_light.mMin) * 0.5f;
|
Vector3f dimensions = (bbox_light.mMax - bbox_light.mMin) * 0.5f;
|
||||||
Vector3f center = bbox_light.mMin + dimensions;
|
Vector3f center = bbox_light.mMin + dimensions;
|
||||||
|
|
||||||
split.mCamera.mIsOrthographic = true;
|
mSplitCamera[i].mIsOrthographic = true;
|
||||||
split.mCamera.mViewMatrix = light_matrix;
|
mSplitCamera[i].mViewMatrix = light_matrix;
|
||||||
|
|
||||||
// TODO: values for near and far planes are off
|
// TODO: values for near and far planes are off
|
||||||
split.mCamera.mProjectionMatrix = Ortho (
|
mSplitCamera[i].mProjectionMatrix = Ortho (
|
||||||
bbox_light.mMin[0], bbox_light.mMax[0],
|
bbox_light.mMin[0], bbox_light.mMax[0],
|
||||||
bbox_light.mMin[1], bbox_light.mMax[1],
|
bbox_light.mMin[1], bbox_light.mMax[1],
|
||||||
// mLight.mNear, bbox_light.mMax[2]
|
// mLight.mNear, bbox_light.mMax[2]
|
||||||
|
@ -365,9 +367,8 @@ void Light::UpdateSplits(const Camera& camera) {
|
||||||
// bbox_light.mMin[2], bbox_light.mMax[2]
|
// bbox_light.mMin[2], bbox_light.mMax[2]
|
||||||
);
|
);
|
||||||
|
|
||||||
split.mFrustum =
|
mSplitLightFrustum[i] = mSplitCamera[i].mViewMatrix
|
||||||
split.mCamera.mViewMatrix
|
* mSplitCamera[i].mProjectionMatrix;
|
||||||
* split.mCamera.mProjectionMatrix;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -643,8 +644,8 @@ void Renderer::Initialize(int width, int height) {
|
||||||
mLight.mShadowMapTarget.mLinearizeDepthProgram.RegisterFileModification();
|
mLight.mShadowMapTarget.mLinearizeDepthProgram.RegisterFileModification();
|
||||||
|
|
||||||
for (int i = 0; i < cNumSplits; ++i) {
|
for (int i = 0; i < cNumSplits; ++i) {
|
||||||
mLight.mSplits[i].mShadowMapTarget.mLinearizeDepthProgram = mRenderQuadProgramDepth;
|
mLight.mSplitTarget[i].mLinearizeDepthProgram = mRenderQuadProgramDepth;
|
||||||
mLight.mSplits[i].mShadowMapTarget.mLinearizeDepthProgram.RegisterFileModification();
|
mLight.mSplitTarget[i].mLinearizeDepthProgram.RegisterFileModification();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Model
|
// Model
|
||||||
|
@ -726,24 +727,24 @@ void Renderer::RenderGl() {
|
||||||
|
|
||||||
mCamera.UpdateMatrices();
|
mCamera.UpdateMatrices();
|
||||||
mLight.UpdateMatrices();
|
mLight.UpdateMatrices();
|
||||||
mLight.UpdateSplits(mDebugCamera);
|
mLight.UpdateSplits(mCamera);
|
||||||
|
|
||||||
// Cascaded Shadow Maps
|
// Cascaded Shadow Maps
|
||||||
for (int i = 0; i < cNumSplits; i++) {
|
for (int i = 0; i < cNumSplits; i++) {
|
||||||
ShadowSplitInfo &split = mLight.mSplits[i];
|
|
||||||
split.mShadowMapTarget.Bind();
|
mLight.mSplitTarget[i].Bind();
|
||||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
glUseProgram(mLight.mShadowMapProgram.mProgramId);
|
glUseProgram(mLight.mShadowMapProgram.mProgramId);
|
||||||
glViewport(0, 0, mLight.mShadowMapSize, mLight.mShadowMapSize);
|
glViewport(0, 0, mLight.mShadowMapSize, mLight.mShadowMapSize);
|
||||||
|
|
||||||
if (mLight.mShadowMapProgram.SetMat44("uViewProjectionMatrix", split.mFrustum) == -1) {
|
if (mLight.mShadowMapProgram.SetMat44("uViewProjectionMatrix", mLight.mSplitLightFrustum[i]) == -1) {
|
||||||
gLog ("Warning: Uniform %s not found!", "uViewProjectionMatrix");
|
gLog ("Warning: Uniform %s not found!", "uViewProjectionMatrix");
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderScene(mLight.mShadowMapProgram, split.mCamera);
|
RenderScene(mLight.mShadowMapProgram, mLight.mSplitCamera[i]);
|
||||||
split.mShadowMapTarget.RenderToLinearizedDepth(mLight.mCamera.mNear, mLight.mCamera.mFar, true);
|
mLight.mSplitTarget[i].RenderToLinearizedDepth(mLight.mCamera.mNear, mLight.mCamera.mFar, true);
|
||||||
// glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
// glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,8 +767,6 @@ void Renderer::RenderGl() {
|
||||||
|
|
||||||
glViewport(0, 0, mCamera.mWidth, mCamera.mHeight);
|
glViewport(0, 0, mCamera.mWidth, mCamera.mHeight);
|
||||||
|
|
||||||
|
|
||||||
// glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
||||||
Matrix44f model_matrix = TranslateMat44(0.0f, 0.0f, 0.0f);
|
Matrix44f model_matrix = TranslateMat44(0.0f, 0.0f, 0.0f);
|
||||||
Matrix44f model_view_projection =
|
Matrix44f model_view_projection =
|
||||||
model_matrix
|
model_matrix
|
||||||
|
@ -901,34 +900,54 @@ void Renderer::RenderGl() {
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
glUseProgram(mDeferredLighting.mProgramId);
|
glUseProgram(mDeferredLighting.mProgramId);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mColorTexture);
|
|
||||||
mDeferredLighting.SetInt("uColorTexture", 0);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mNormalTexture);
|
|
||||||
mDeferredLighting.SetInt("uNormal", 1);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE2);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mDepthTexture);
|
|
||||||
mDeferredLighting.SetInt("uDepth", 2);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE3);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, mLight.mShadowMapTarget.mDepthTexture);
|
|
||||||
mDeferredLighting.SetInt("uShadowMap", 3);
|
|
||||||
|
|
||||||
mDeferredLighting.SetMat44("uLightSpaceMatrix", mLight.mLightSpaceMatrix);
|
|
||||||
Matrix44f view_to_light_matrix = mCamera.mViewMatrix.inverse() * mLight.mLightSpaceMatrix;
|
|
||||||
mDeferredLighting.SetMat44("uViewToLightSpaceMatrix", view_to_light_matrix);
|
|
||||||
|
|
||||||
// TODO: remove and reconstruct position from depth
|
// TODO: remove and reconstruct position from depth
|
||||||
glActiveTexture(GL_TEXTURE4);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mPositionTexture);
|
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mPositionTexture);
|
||||||
mDeferredLighting.SetInt("uPosition", 4);
|
mDeferredLighting.SetInt("uPosition", 0);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE5);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mDepthTexture);
|
||||||
|
mDeferredLighting.SetInt("uDepth", 1);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mNormalTexture);
|
||||||
|
mDeferredLighting.SetInt("uNormal", 2);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE3);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mColorTexture);
|
||||||
|
mDeferredLighting.SetInt("uColor", 3);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE4);
|
||||||
glBindTexture(GL_TEXTURE_2D, mSSAOBlurTarget.mColorTexture);
|
glBindTexture(GL_TEXTURE_2D, mSSAOBlurTarget.mColorTexture);
|
||||||
mDeferredLighting.SetInt("uAmbientOcclusion", 5);
|
mDeferredLighting.SetInt("uAmbientOcclusion", 4);
|
||||||
|
|
||||||
|
// Shadow Map Cascades
|
||||||
|
glActiveTexture(GL_TEXTURE5);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mLight.mSplitTarget[0].mDepthTexture);
|
||||||
|
glActiveTexture(GL_TEXTURE6);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mLight.mSplitTarget[1].mDepthTexture);
|
||||||
|
glActiveTexture(GL_TEXTURE7);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mLight.mSplitTarget[2].mDepthTexture);
|
||||||
|
|
||||||
|
GLint shadow_maps[3];
|
||||||
|
shadow_maps[0] = 5;
|
||||||
|
shadow_maps[1] = 6;
|
||||||
|
shadow_maps[2] = 7;
|
||||||
|
mDeferredLighting.SetIntArray("uShadowMap", 3, shadow_maps);
|
||||||
|
|
||||||
|
Matrix44f light_matrices[3];
|
||||||
|
|
||||||
|
for (int i = 0; i < cNumSplits; ++i) {
|
||||||
|
light_matrices[i] = mCamera.mViewMatrix.inverse()
|
||||||
|
* mLight.mSplitLightFrustum[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
mDeferredLighting.SetMat44Array("uViewToLightMatrix", 3, light_matrices);
|
||||||
|
|
||||||
|
mDeferredLighting.SetFloat("uNear", mCamera.mNear);
|
||||||
|
mDeferredLighting.SetFloat("uFar", mCamera.mFar);
|
||||||
|
mDeferredLighting.SetVec4("uShadowSplits", mLight.mShadowSplits);
|
||||||
|
|
||||||
mDeferredLighting.SetMat44("uViewMatrix", mCamera.mViewMatrix);
|
mDeferredLighting.SetMat44("uViewMatrix", mCamera.mViewMatrix);
|
||||||
Matrix33f view_mat_rot = mCamera.mViewMatrix.block<3,3>(0,0);
|
Matrix33f view_mat_rot = mCamera.mViewMatrix.block<3,3>(0,0);
|
||||||
|
@ -963,14 +982,13 @@ void Renderer::DebugDrawShadowCascades() {
|
||||||
glUseProgram(mSimpleProgram.mProgramId);
|
glUseProgram(mSimpleProgram.mProgramId);
|
||||||
|
|
||||||
for (int i = 0; i < cNumSplits; ++i) {
|
for (int i = 0; i < cNumSplits; ++i) {
|
||||||
const ShadowSplitInfo& split = mLight.mSplits[i];
|
const BBox& bbox_light = mLight.mSplitBoundsLightSpace[i];
|
||||||
const BBox& bbox_light = split.mBoundsLight;
|
const BBox& bbox_world = mLight.mSplitBoundsWorldSpace[i];
|
||||||
const BBox& bbox_world = split.mBoundsWorld;
|
|
||||||
|
|
||||||
// Draw view split frustum
|
// Draw view split frustum
|
||||||
if (mLight.mDebugDrawSplitViewBounds) {
|
if (mLight.mDebugDrawSplitViewBounds) {
|
||||||
Matrix44f model_view_projection =
|
Matrix44f model_view_projection =
|
||||||
split.mViewFrustum.inverse()
|
mLight.mSplitViewFrustum[i].inverse()
|
||||||
* mCamera.mViewMatrix
|
* mCamera.mViewMatrix
|
||||||
* mCamera.mProjectionMatrix;
|
* mCamera.mProjectionMatrix;
|
||||||
|
|
||||||
|
@ -999,7 +1017,7 @@ void Renderer::DebugDrawShadowCascades() {
|
||||||
// Draw bounding boxes in light space
|
// Draw bounding boxes in light space
|
||||||
if (mLight.mDebugDrawSplitLightBounds) {
|
if (mLight.mDebugDrawSplitLightBounds) {
|
||||||
Matrix44f model_view_projection =
|
Matrix44f model_view_projection =
|
||||||
mLight.mSplits[i].mFrustum.inverse()
|
mLight.mSplitLightFrustum[i].inverse()
|
||||||
* mCamera.mViewMatrix
|
* mCamera.mViewMatrix
|
||||||
* mCamera.mProjectionMatrix;
|
* mCamera.mProjectionMatrix;
|
||||||
|
|
||||||
|
@ -1007,19 +1025,18 @@ void Renderer::DebugDrawShadowCascades() {
|
||||||
mSimpleProgram.SetVec4("uColor", Vector4f (0.0f, 0.0f, 1.0f, 1.0f));
|
mSimpleProgram.SetVec4("uColor", Vector4f (0.0f, 0.0f, 1.0f, 1.0f));
|
||||||
gUnitCubeLines.Draw(GL_LINES);
|
gUnitCubeLines.Draw(GL_LINES);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Draw bounding box in light space
|
// // Draw bounding box in light space
|
||||||
// if (mLight.mDebugDrawSplitLightBounds) {
|
// if (mLight.mDebugDrawSplitLightBounds) {
|
||||||
Matrix44f model_view_projection =
|
// Matrix44f model_view_projection =
|
||||||
mLight.mLightSpaceMatrix.inverse()
|
// mLight.mLightSpaceMatrix.inverse()
|
||||||
* mCamera.mViewMatrix
|
// * mCamera.mViewMatrix
|
||||||
* mCamera.mProjectionMatrix;
|
// * mCamera.mProjectionMatrix;
|
||||||
|
//
|
||||||
mSimpleProgram.SetMat44("uModelViewProj", model_view_projection);
|
// mSimpleProgram.SetMat44("uModelViewProj", model_view_projection);
|
||||||
mSimpleProgram.SetVec4("uColor", Vector4f (0.0f, 1.0f, 1.0f, 1.0f));
|
// mSimpleProgram.SetVec4("uColor", Vector4f (0.0f, 1.0f, 1.0f, 1.0f));
|
||||||
gUnitCubeLines.Draw(GL_LINES);
|
// gUnitCubeLines.Draw(GL_LINES);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// Disable wireframe
|
// Disable wireframe
|
||||||
|
@ -1043,7 +1060,6 @@ void Renderer::RenderScene(RenderProgram &program, const Camera& camera) {
|
||||||
program.SetMat33("uNormalMatrix", normal_matrix);
|
program.SetMat33("uNormalMatrix", normal_matrix);
|
||||||
|
|
||||||
program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f));
|
program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
// program.SetVec3("uLightDirection", light_dir.normalize());
|
|
||||||
program.SetVec3("uLightDirection", mLight.mDirection);
|
program.SetVec3("uLightDirection", mLight.mDirection);
|
||||||
program.SetVec3("uViewPosition", camera.mEye);
|
program.SetVec3("uViewPosition", camera.mEye);
|
||||||
|
|
||||||
|
|
|
@ -14,15 +14,6 @@
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "RenderUtils.h"
|
#include "RenderUtils.h"
|
||||||
|
|
||||||
struct ShadowSplitInfo {
|
|
||||||
BBox mBoundsLight;
|
|
||||||
BBox mBoundsWorld;
|
|
||||||
Matrix44f mViewFrustum;
|
|
||||||
Matrix44f mFrustum;
|
|
||||||
RenderTarget mShadowMapTarget;
|
|
||||||
Camera mCamera;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Light {
|
struct Light {
|
||||||
Vector3f mPosition;
|
Vector3f mPosition;
|
||||||
Vector3f mDirection;
|
Vector3f mDirection;
|
||||||
|
@ -47,7 +38,13 @@ struct Light {
|
||||||
Matrix44f mLightSpaceMatrix;
|
Matrix44f mLightSpaceMatrix;
|
||||||
|
|
||||||
Vector4f mShadowSplits = Vector4f (0.0, 0.1, 0.4, 1.0);
|
Vector4f mShadowSplits = Vector4f (0.0, 0.1, 0.4, 1.0);
|
||||||
ShadowSplitInfo mSplits[4];
|
|
||||||
|
Matrix44f mSplitViewFrustum[3];
|
||||||
|
Matrix44f mSplitLightFrustum[3];
|
||||||
|
RenderTarget mSplitTarget[3];
|
||||||
|
BBox mSplitBoundsLightSpace[3];
|
||||||
|
BBox mSplitBoundsWorldSpace[3];
|
||||||
|
Camera mSplitCamera[3];
|
||||||
|
|
||||||
Light() :
|
Light() :
|
||||||
mPosition (Vector3f(0.f, 3, 0.0f)),
|
mPosition (Vector3f(0.f, 3, 0.0f)),
|
||||||
|
|
|
@ -232,6 +232,11 @@ struct RenderProgram : AFileModificationListener {
|
||||||
glUniform1i(location, val);
|
glUniform1i(location, val);
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
GLint SetIntArray(const char* name, const int count, const int* array) {
|
||||||
|
GLint location = glGetUniformLocation(mProgramId, name);
|
||||||
|
glUniform1iv(location, count, array);
|
||||||
|
return location;
|
||||||
|
}
|
||||||
GLint SetFloat(const char* name, const float& val) {
|
GLint SetFloat(const char* name, const float& val) {
|
||||||
GLint location = glGetUniformLocation(mProgramId, name);
|
GLint location = glGetUniformLocation(mProgramId, name);
|
||||||
glUniform1f(location, val);
|
glUniform1f(location, val);
|
||||||
|
@ -242,7 +247,7 @@ struct RenderProgram : AFileModificationListener {
|
||||||
glUniform3fv(location, 1, vec.data());
|
glUniform3fv(location, 1, vec.data());
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
GLint SetVec3Array(const char* name, int count, const float* array) {
|
GLint SetVec3Array(const char* name, const int count, const float* array) {
|
||||||
GLint location = glGetUniformLocation(mProgramId, name);
|
GLint location = glGetUniformLocation(mProgramId, name);
|
||||||
glUniform3fv(location, count, array);
|
glUniform3fv(location, count, array);
|
||||||
return location;
|
return location;
|
||||||
|
@ -262,6 +267,11 @@ struct RenderProgram : AFileModificationListener {
|
||||||
glUniformMatrix4fv(location, 1, GL_FALSE, mat.data());
|
glUniformMatrix4fv(location, 1, GL_FALSE, mat.data());
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
GLint SetMat44Array (const char* name, int count, const Matrix44f* mat_array) {
|
||||||
|
GLint location = glGetUniformLocation(mProgramId, name);
|
||||||
|
glUniformMatrix4fv(location, count, GL_FALSE, mat_array[0].data());
|
||||||
|
return location;
|
||||||
|
}
|
||||||
GLint SetMat33 (const char* name, const Matrix33f& mat) {
|
GLint SetMat33 (const char* name, const Matrix33f& mat) {
|
||||||
GLint location = glGetUniformLocation(mProgramId, name);
|
GLint location = glGetUniformLocation(mProgramId, name);
|
||||||
glUniformMatrix3fv(location, 1, GL_FALSE, mat.data());
|
glUniformMatrix3fv(location, 1, GL_FALSE, mat.data());
|
||||||
|
|
Loading…
Reference in New Issue