Optimized shadow shader evaluation by computing concatenated shadow reprojection matrix on CPU

This commit is contained in:
Olivier Prat 2017-11-10 11:26:20 +01:00
parent 6cd4da877e
commit cbd2877524
3 changed files with 15 additions and 20 deletions

View file

@ -14,6 +14,11 @@
#include "LightStage.h" #include "LightStage.h"
std::string LightStage::_stageName { "LIGHT_STAGE"}; std::string LightStage::_stageName { "LIGHT_STAGE"};
const glm::mat4 LightStage::Shadow::_biasMatrix{
0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0 };
LightStage::LightStage() { LightStage::LightStage() {
} }
@ -92,8 +97,7 @@ void LightStage::Shadow::setKeylightFrustum(const ViewFrustum& viewFrustum,
_frustum->calculate(); _frustum->calculate();
// Update the buffer // Update the buffer
_schemaBuffer.edit<Schema>().projection = ortho; _schemaBuffer.edit<Schema>().reprojection = _biasMatrix * ortho * viewInverse.getMatrix();
_schemaBuffer.edit<Schema>().viewInverse = viewInverse.getMatrix();
} }
void LightStage::Shadow::setFrustum(const ViewFrustum& shadowFrustum) { void LightStage::Shadow::setFrustum(const ViewFrustum& shadowFrustum) {
@ -102,8 +106,7 @@ void LightStage::Shadow::setFrustum(const ViewFrustum& shadowFrustum) {
*_frustum = shadowFrustum; *_frustum = shadowFrustum;
// Update the buffer // Update the buffer
_schemaBuffer.edit<Schema>().projection = shadowFrustum.getProjection(); _schemaBuffer.edit<Schema>().reprojection = _biasMatrix * shadowFrustum.getProjection() * viewInverse.getMatrix();
_schemaBuffer.edit<Schema>().viewInverse = viewInverse.getMatrix();
} }
const glm::mat4& LightStage::Shadow::getView() const { const glm::mat4& LightStage::Shadow::getView() const {

View file

@ -62,6 +62,9 @@ public:
gpu::TexturePointer map; gpu::TexturePointer map;
protected: protected:
static const glm::mat4 _biasMatrix;
model::LightPointer _light; model::LightPointer _light;
std::shared_ptr<ViewFrustum> _frustum; std::shared_ptr<ViewFrustum> _frustum;
@ -70,8 +73,7 @@ public:
Schema(); Schema();
glm::mat4 projection; glm::mat4 reprojection;
glm::mat4 viewInverse;
glm::float32 bias; glm::float32 bias;
glm::float32 scale; glm::float32 scale;

View file

@ -15,8 +15,7 @@
uniform sampler2DShadow shadowMap; uniform sampler2DShadow shadowMap;
struct ShadowTransform { struct ShadowTransform {
mat4 projection; mat4 reprojection;
mat4 viewInverse;
float bias; float bias;
float scale; float scale;
@ -26,12 +25,8 @@ uniform shadowTransformBuffer {
ShadowTransform _shadowTransform; ShadowTransform _shadowTransform;
}; };
mat4 getShadowViewInverse() { mat4 getShadowReprojection() {
return _shadowTransform.viewInverse; return _shadowTransform.reprojection;
}
mat4 getShadowProjection() {
return _shadowTransform.projection;
} }
float getShadowScale() { float getShadowScale() {
@ -44,14 +39,9 @@ float getShadowBias() {
// Compute the texture coordinates from world coordinates // Compute the texture coordinates from world coordinates
vec4 evalShadowTexcoord(vec4 position) { vec4 evalShadowTexcoord(vec4 position) {
mat4 biasMatrix = mat4(
0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0);
float bias = -getShadowBias(); float bias = -getShadowBias();
vec4 shadowCoord = biasMatrix * getShadowProjection() * getShadowViewInverse() * position; vec4 shadowCoord = getShadowReprojection() * position;
return vec4(shadowCoord.xy, shadowCoord.z + bias, 1.0); return vec4(shadowCoord.xy, shadowCoord.z + bias, 1.0);
} }