Update shadow shaders

This commit is contained in:
Zach Pomerantz 2016-01-15 15:47:01 -08:00
parent b2c9cf7452
commit 562c909ad8
4 changed files with 33 additions and 44 deletions

View file

@ -16,7 +16,7 @@
LightStage::Shadow::Shadow(model::LightPointer light) : _light{ light}, _frustum{ std::make_shared<ViewFrustum>() } {
framebuffer = gpu::FramebufferPointer(gpu::Framebuffer::createShadowmap(MAP_SIZE));
map = framebuffer->getDepthStencilBuffer();
Schema schema{glm::mat4(), glm::mat4(), 0, MAP_SIZE};
Schema schema;
_schemaBuffer = std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema);
}
@ -72,7 +72,7 @@ void LightStage::Shadow::setKeylightFrustum(ViewFrustum* viewFrustum, float near
// Update the buffer
_schemaBuffer.edit<Schema>().projection = ortho;
_schemaBuffer.edit<Schema>().view = view.getMatrix();
_schemaBuffer.edit<Schema>().viewInverse = viewInverse.getMatrix();
}
const glm::mat4& LightStage::Shadow::getView() const {

View file

@ -24,7 +24,7 @@ public:
class Shadow {
public:
using UniformBufferView = gpu::BufferView;
const int MAP_SIZE = 2048;
static const int MAP_SIZE = 2048;
Shadow(model::LightPointer light);
@ -46,10 +46,10 @@ public:
class Schema {
public:
glm::mat4 projection;
glm::mat4 view;
glm::mat4 viewInverse;
glm::float32 bias;
glm::float32 scale;
glm::float32 bias = 0.005f;
glm::float32 scale = 1 / MAP_SIZE;
};
UniformBufferView _schemaBuffer = nullptr;
};

View file

@ -113,7 +113,7 @@ void RenderShadowTask::run(const SceneContextPointer& sceneContext, const Render
ViewFrustum* viewFrustum = args->_viewFrustum;
auto nearClip = viewFrustum->getNearClip();
const int SHADOW_NEAR_DEPTH = -1;
const int SHADOW_NEAR_DEPTH = -2;
const int SHADOW_FAR_DEPTH = 20;
globalLight->shadow.setKeylightFrustum(viewFrustum, nearClip + SHADOW_NEAR_DEPTH, nearClip + SHADOW_FAR_DEPTH);

View file

@ -16,7 +16,7 @@ uniform sampler2DShadow shadowMap;
struct ShadowTransform {
mat4 projection;
mat4 view;
mat4 viewInverse;
float bias;
float scale;
@ -26,8 +26,8 @@ uniform shadowTransformBuffer {
ShadowTransform _shadowTransform;
};
mat4 getShadowView() {
return _shadowTransform.view;
mat4 getShadowViewInverse() {
return _shadowTransform.viewInverse;
}
mat4 getShadowProjection() {
@ -35,21 +35,27 @@ mat4 getShadowProjection() {
}
float getShadowScale() {
return 1.0;
//_shadowTransform.scale;
return _shadowTransform.scale;
}
float getShadowBias() {
return _shadowTransform.bias;
}
// Compute the texture coordinates from world coordinates
vec4 evalShadowTexcoord(vec4 position) {
mat4 bias = mat4(
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.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0);
return bias * getShadowProjection() * inverse(getShadowView()) * position;
float bias = -getShadowBias();
vec4 shadowCoord = biasMatrix * getShadowProjection() * getShadowViewInverse() * position;
return vec4(shadowCoord.xy, shadowCoord.z + bias, 1.0);
}
// Fetching it
// Sample the shadowMap with PCF (built-in)
float fetchShadow(vec3 shadowTexcoord) {
return texture(shadowMap, shadowTexcoord);
}
@ -65,50 +71,33 @@ vec2 samples[8] = vec2[8](
vec2(0.0, -1.0)
);
float evalShadowAttenuationPCF(vec4 shadowTexcoord) {
float radiusScale = (shadowTexcoord.w + 1.0);
float evalShadowAttenuationSampling(vec4 shadowTexcoord) {
float shadowScale = getShadowScale();
float shadowAttenuation = (0.25 * (
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[0], 0.0)) +
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[1], 0.0)) +
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[2], 0.0)) +
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[3], 0.0))
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(samples[0], 0.0)) +
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(samples[1], 0.0)) +
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(samples[2], 0.0)) +
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(samples[3], 0.0))
));
// Check for early bailing
if ((shadowAttenuation > 0) && (shadowAttenuation < 1.0)) {
radiusScale *= 0.5;
shadowAttenuation = 0.5 * shadowAttenuation + (0.125 * (
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[4], 0.0)) +
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[5], 0.0)) +
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[6], 0.0)) +
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[7], 0.0))
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(samples[4], 0.0)) +
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(samples[5], 0.0)) +
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(samples[6], 0.0)) +
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(samples[7], 0.0))
));
}
return shadowAttenuation;
}
float evalShadowAttenuationBasic(vec4 shadowTexcoord) {
float radiusScale = 0.5;
float shadowScale = getShadowScale();
float shadowAttenuation = (0.25 * (
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[0], 0.0)) +
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[1], 0.0)) +
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[2], 0.0)) +
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[3], 0.0))
));
return shadowAttenuation;
}
float evalShadowAttenuation(vec4 position) {
vec4 shadowTexcoord = evalShadowTexcoord(position);
return fetchShadow(shadowTexcoord.xyz);
// return evalShadowAttenuationBasic(shadowTexcoord);
// return evalShadowAttenuationPCF(shadowTexcoord);
return evalShadowAttenuationSampling(shadowTexcoord);
}
<@endif@>