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>() } { LightStage::Shadow::Shadow(model::LightPointer light) : _light{ light}, _frustum{ std::make_shared<ViewFrustum>() } {
framebuffer = gpu::FramebufferPointer(gpu::Framebuffer::createShadowmap(MAP_SIZE)); framebuffer = gpu::FramebufferPointer(gpu::Framebuffer::createShadowmap(MAP_SIZE));
map = framebuffer->getDepthStencilBuffer(); 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); _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 // Update the buffer
_schemaBuffer.edit<Schema>().projection = ortho; _schemaBuffer.edit<Schema>().projection = ortho;
_schemaBuffer.edit<Schema>().view = view.getMatrix(); _schemaBuffer.edit<Schema>().viewInverse = viewInverse.getMatrix();
} }
const glm::mat4& LightStage::Shadow::getView() const { const glm::mat4& LightStage::Shadow::getView() const {

View file

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

View file

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

View file

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