Visibility and dilate pass for soft shadows
This commit is contained in:
parent
d657f03cf8
commit
fbeeeac2d7
50
Shaders/blur_shadow_pass/blur_shadow_pass.frag.glsl
Normal file
50
Shaders/blur_shadow_pass/blur_shadow_pass.frag.glsl
Normal file
|
@ -0,0 +1,50 @@
|
|||
#version 450
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/gbuffer.glsl"
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform sampler2D dist;
|
||||
|
||||
uniform vec2 dirInv; // texStep
|
||||
|
||||
in vec2 texCoord;
|
||||
out float fragColor;
|
||||
|
||||
const float blurWeights[10] = float[] (0.132572, 0.125472, 0.106373, 0.08078, 0.05495, 0.033482, 0.018275, 0.008934, 0.003912, 0.001535);
|
||||
const float discardThreshold = 0.95;
|
||||
|
||||
const int penumbraScale = 1;
|
||||
|
||||
float doBlur(const float blurWeight, const int pos, const vec3 nor, const vec2 texCoord) {
|
||||
const float posadd = pos + 0.5;
|
||||
|
||||
vec3 nor2 = getNor(texture(gbuffer0, texCoord + pos * dirInv).rg);
|
||||
float influenceFactor = step(discardThreshold, dot(nor2, nor));
|
||||
float col = texture(tex, texCoord + posadd * dirInv).r;
|
||||
fragColor += col * blurWeight * influenceFactor;
|
||||
float weight = blurWeight * influenceFactor;
|
||||
|
||||
nor2 = getNor(texture(gbuffer0, texCoord - pos * dirInv).rg);
|
||||
influenceFactor = step(discardThreshold, dot(nor2, nor));
|
||||
col = texture(tex, texCoord - posadd * dirInv).r;
|
||||
fragColor += col * blurWeight * influenceFactor;
|
||||
weight += blurWeight * influenceFactor;
|
||||
|
||||
return weight;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec3 nor = getNor(texture(gbuffer0, texCoord).rg);
|
||||
|
||||
float sm = texture(tex, texCoord).r;
|
||||
fragColor = sm * blurWeights[0];
|
||||
float weight = blurWeights[0];
|
||||
float d = texture(dist, texCoord).r;
|
||||
int numTaps = min(int(d * 10 * penumbraScale), 10 * penumbraScale);
|
||||
for (int i = 1; i < numTaps; ++i) weight += doBlur(blurWeights[i - 1], i, nor, texCoord);
|
||||
// scale=2
|
||||
// for (int i = 1; i < numTaps; ++i) weight += doBlur(blurWeights[int(i / 2)], i, nor, texCoord);
|
||||
fragColor /= weight;
|
||||
}
|
82
Shaders/blur_shadow_pass/blur_shadow_pass.json
Executable file
82
Shaders/blur_shadow_pass/blur_shadow_pass.json
Executable file
|
@ -0,0 +1,82 @@
|
|||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "blur_shadow_pass_x",
|
||||
"color_write_alpha": false,
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "dirInv",
|
||||
"link": "_vec2xInv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "blur_shadow_pass.vert.glsl",
|
||||
"vertex_shader_path": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_shadow_pass.frag.glsl"
|
||||
},
|
||||
{
|
||||
"name": "blur_shadow_pass_y",
|
||||
"color_write_alpha": false,
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "dirInv",
|
||||
"link": "_vec2yInv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "blur_shadow_pass.vert.glsl",
|
||||
"vertex_shader_path": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_shadow_pass.frag.glsl"
|
||||
},
|
||||
{
|
||||
"name": "blur_shadow_pass_y_blend",
|
||||
"color_write_alpha": false,
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"blend_source": "destination_color",
|
||||
"blend_destination": "blend_zero",
|
||||
"blend_operation": "add",
|
||||
"links": [
|
||||
{
|
||||
"name": "dirInv",
|
||||
"link": "_vec2yInv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "blur_shadow_pass.vert.glsl",
|
||||
"vertex_shader_path": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_shadow_pass.frag.glsl"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "blur_shadow_pass_y_blend_add",
|
||||
"color_write_alpha": false,
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"blend_source": "blend_one",
|
||||
"blend_destination": "blend_one",
|
||||
"blend_operation": "add",
|
||||
"alpha_blend_source": "blend_one",
|
||||
"alpha_blend_destination": "blend_one",
|
||||
"alpha_blend_operation": "add",
|
||||
"links": [
|
||||
{
|
||||
"name": "dirInv",
|
||||
"link": "_vec2yInv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "blur_shadow_pass.vert.glsl",
|
||||
"vertex_shader_path": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_shadow_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -46,6 +46,9 @@ uniform sampler2D gbuffer1;
|
|||
//!uniform sampler2D shadowMap;
|
||||
//!uniform samplerCube shadowMapCube;
|
||||
#endif
|
||||
#ifdef _SoftShadows
|
||||
uniform sampler2D svisibility;
|
||||
#endif
|
||||
#ifdef _DFRS
|
||||
//!uniform sampler3D sdftex;
|
||||
#endif
|
||||
|
@ -125,7 +128,15 @@ void main() {
|
|||
float dotNL = dot(n, l);
|
||||
|
||||
float visibility = 1.0;
|
||||
|
||||
#ifndef _NoShadows
|
||||
|
||||
#ifdef _SoftShadows
|
||||
|
||||
visibility = texture(svisibility, texCoord).r;
|
||||
|
||||
#else
|
||||
|
||||
// TODO: merge..
|
||||
// float cosAngle = max(1.0 - dotNL, 0.0);
|
||||
// vec3 noff = n * shadowsBias * cosAngle;
|
||||
|
@ -139,7 +150,10 @@ void main() {
|
|||
else if (lightShadow == 2) { // Cube
|
||||
visibility = PCFCube(lp, -l, shadowsBias, lightProj, n);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _VoxelGIShadow // #else
|
||||
#ifdef _VoxelGICam
|
||||
|
|
|
@ -44,6 +44,9 @@ vec2 lightPlane;
|
|||
uniform mat4 LWVP;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _SoftShadows
|
||||
uniform sampler2D svisibility;
|
||||
#endif
|
||||
#ifdef _LampClouds
|
||||
uniform sampler2D texClouds;
|
||||
uniform float time;
|
||||
|
@ -93,6 +96,13 @@ void main() {
|
|||
|
||||
float visibility = 1.0;
|
||||
#ifndef _NoShadows
|
||||
|
||||
#ifdef _SoftShadows
|
||||
|
||||
visibility = texture(svisibility, texCoord).r;
|
||||
|
||||
#else
|
||||
|
||||
if (lightShadow == 1) {
|
||||
#ifdef _CSM
|
||||
visibility = shadowTestCascade(eye, p, shadowsBias, shadowmapSize * vec2(shadowmapCascades, 1.0));
|
||||
|
@ -101,6 +111,7 @@ void main() {
|
|||
if (lPos.w > 0.0) visibility = shadowTest(lPos.xyz / lPos.w, shadowsBias, shadowmapSize);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _VoxelGIShadow // #else
|
||||
|
|
19
Shaders/dilate_pass/dilate_pass.frag.glsl
Normal file
19
Shaders/dilate_pass/dilate_pass.frag.glsl
Normal file
|
@ -0,0 +1,19 @@
|
|||
#version 450
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/gbuffer.glsl"
|
||||
|
||||
uniform sampler2D shadowMap;
|
||||
|
||||
in vec2 texCoord;
|
||||
out float fragColor;
|
||||
|
||||
uniform vec2 step;
|
||||
|
||||
const int penumbraScale = 1;
|
||||
|
||||
void main() {
|
||||
fragColor = 1.0;
|
||||
const vec2 smStep = 1.0 / shadowmapSize;
|
||||
for (int i = -20 * penumbraScale; i < 20 * penumbraScale; i++) fragColor = min(fragColor, texture(shadowMap, texCoord.xy + step * smStep * i).r);
|
||||
}
|
36
Shaders/dilate_pass/dilate_pass.json
Executable file
36
Shaders/dilate_pass/dilate_pass.json
Executable file
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "dilate_pass_x",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "step",
|
||||
"link": "_vec2x"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "dilate_pass.vert.glsl",
|
||||
"vertex_shader_path": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "dilate_pass.frag.glsl"
|
||||
},
|
||||
{
|
||||
"name": "dilate_pass_y",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "step",
|
||||
"link": "_vec2y"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "dilate_pass.vert.glsl",
|
||||
"vertex_shader_path": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "dilate_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -99,11 +99,15 @@ mat4 getCascadeMat(const float d, out int casi, out int casIndex) {
|
|||
|
||||
// Get cascade mat
|
||||
casIndex = casi * 4;
|
||||
|
||||
return mat4(
|
||||
casData[casIndex + 0],
|
||||
casData[casIndex + 1],
|
||||
casData[casIndex + 2],
|
||||
casData[casIndex + 3]);
|
||||
|
||||
// if (casIndex == 0) return mat4(casData[0], casData[1], casData[2], casData[3]);
|
||||
// ..
|
||||
}
|
||||
|
||||
float shadowTestCascade(const vec3 eye, const vec3 p, const float shadowsBias, const vec2 smSize) {
|
||||
|
|
52
Shaders/visibility_pass/visibility_pass.frag.glsl
Normal file
52
Shaders/visibility_pass/visibility_pass.frag.glsl
Normal file
|
@ -0,0 +1,52 @@
|
|||
#version 450
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/gbuffer.glsl"
|
||||
#include "../std/math.glsl"
|
||||
|
||||
uniform sampler2D shadowMap;
|
||||
uniform sampler2D dilate;
|
||||
// uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
// uniform sampler2D gbuffer1;
|
||||
uniform vec2 cameraProj;
|
||||
uniform float shadowsBias;
|
||||
uniform vec3 eye;
|
||||
uniform vec3 eyeLook;
|
||||
uniform mat4 LWVP;
|
||||
// uniform int lightShadow;
|
||||
|
||||
in vec2 texCoord;
|
||||
in vec3 viewRay;
|
||||
|
||||
out float fragColor[2];
|
||||
|
||||
void main() {
|
||||
vec4 g0 = texture(gbuffer0, texCoord);
|
||||
// #ifdef _InvY // D3D
|
||||
// float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0;
|
||||
// #else
|
||||
float depth = (1.0 - g0.a) * 2.0 - 1.0;
|
||||
// #endif
|
||||
vec3 p = getPos(eye, eyeLook, viewRay, depth, cameraProj);
|
||||
|
||||
vec4 lampPos = LWVP * vec4(p, 1.0);
|
||||
vec3 lPos = lampPos.xyz / lampPos.w;
|
||||
|
||||
// Visibility
|
||||
// if (lightShadow == 1) {
|
||||
float sm = texture(shadowMap, lPos.xy).r;
|
||||
fragColor[0] = float(sm + shadowsBias > lPos.z);
|
||||
// }
|
||||
// else if (lightShadow == 2) { // Cube
|
||||
// visibility = PCFCube(lp, -l, shadowsBias, lightProj, n);
|
||||
// }
|
||||
|
||||
// Distance
|
||||
float d = texture(dilate, lPos.xy).r;
|
||||
fragColor[1] = max((lPos.z - d), 0.0);
|
||||
fragColor[1] *= 200;
|
||||
|
||||
// Mask non-occluded pixels
|
||||
// fragColor.b = mask;
|
||||
}
|
43
Shaders/visibility_pass/visibility_pass.json
Executable file
43
Shaders/visibility_pass/visibility_pass.json
Executable file
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "visibility_pass",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "eye",
|
||||
"link": "_cameraPosition"
|
||||
},
|
||||
{
|
||||
"name": "eyeLook",
|
||||
"link": "_cameraLook"
|
||||
},
|
||||
{
|
||||
"name": "invVP",
|
||||
"link": "_inverseViewProjectionMatrix"
|
||||
},
|
||||
{
|
||||
"name": "cameraProj",
|
||||
"link": "_cameraPlaneProj"
|
||||
},
|
||||
{
|
||||
"name": "shadowsBias",
|
||||
"link": "_lampShadowsBias"
|
||||
},
|
||||
{
|
||||
"name": "LWVP",
|
||||
"link": "_biasLampWorldViewProjectionMatrix"
|
||||
},
|
||||
{
|
||||
"name": "lightType",
|
||||
"link": "_lampType",
|
||||
"ifdef": ["_Disabled"]
|
||||
}
|
||||
],
|
||||
"vertex_shader": "visibility_pass.vert.glsl",
|
||||
"fragment_shader": "visibility_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
26
Shaders/visibility_pass/visibility_pass.vert.glsl
Executable file
26
Shaders/visibility_pass/visibility_pass.vert.glsl
Executable file
|
@ -0,0 +1,26 @@
|
|||
#version 450
|
||||
|
||||
uniform mat4 invVP;
|
||||
uniform vec3 eye;
|
||||
|
||||
in vec2 pos;
|
||||
|
||||
out vec2 texCoord;
|
||||
out vec3 viewRay;
|
||||
|
||||
void main() {
|
||||
// Scale vertex attribute to [0-1] range
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
texCoord = pos.xy * madd + madd;
|
||||
#ifdef _InvY
|
||||
texCoord.y = 1.0 - texCoord.y;
|
||||
#endif
|
||||
|
||||
gl_Position = vec4(pos.xy, 0.0, 1.0);
|
||||
|
||||
// NDC (at the back of cube)
|
||||
vec4 v = vec4(pos.x, pos.y, 1.0, 1.0);
|
||||
v = vec4(invVP * v);
|
||||
v.xyz /= v.w;
|
||||
viewRay = v.xyz - eye;
|
||||
}
|
|
@ -482,6 +482,40 @@ class RenderPathCreator {
|
|||
#end
|
||||
}
|
||||
#end
|
||||
|
||||
#if rp_soft_shadows
|
||||
{
|
||||
path.loadShader("dilate_pass/dilate_pass/dilate_pass_x");
|
||||
path.loadShader("dilate_pass/dilate_pass/dilate_pass_y");
|
||||
path.loadShader("visibility_pass/visibility_pass/visibility_pass");
|
||||
path.loadShader("blur_shadow_pass/blur_shadow_pass/blur_shadow_pass_x");
|
||||
path.loadShader("blur_shadow_pass/blur_shadow_pass/blur_shadow_pass_y");
|
||||
{
|
||||
var t = new RenderTargetRaw();
|
||||
t.name = "visa";
|
||||
t.width = 0;
|
||||
t.height = 0;
|
||||
t.format = 'R16';
|
||||
path.createRenderTarget(t);
|
||||
}
|
||||
{
|
||||
var t = new RenderTargetRaw();
|
||||
t.name = "visb";
|
||||
t.width = 0;
|
||||
t.height = 0;
|
||||
t.format = 'R16';
|
||||
path.createRenderTarget(t);
|
||||
}
|
||||
{
|
||||
var t = new RenderTargetRaw();
|
||||
t.name = "dist";
|
||||
t.width = 0;
|
||||
t.height = 0;
|
||||
t.format = 'R16';
|
||||
path.createRenderTarget(t);
|
||||
}
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
static function commands() {
|
||||
|
@ -626,13 +660,46 @@ class RenderPathCreator {
|
|||
{
|
||||
if (path.lampCastShadow()) {
|
||||
var faces = l.data.raw.shadowmap_cube ? 6 : 1;
|
||||
for (i in 0...faces) {
|
||||
if (faces > 1) path.currentFace = i;
|
||||
for (j in 0...faces) {
|
||||
if (faces > 1) path.currentFace = j;
|
||||
path.setTarget("shadowMap");
|
||||
path.clearTarget(null, 1.0);
|
||||
path.drawMeshes("shadowmap");
|
||||
}
|
||||
path.currentFace = -1;
|
||||
|
||||
// One lamp at a time for now, precompute all lamps for tiled
|
||||
#if rp_soft_shadows
|
||||
|
||||
path.setTarget("visa"); // Merge using min blend
|
||||
path.bindTarget("shadowMap", "shadowMap");
|
||||
path.drawShader("dilate_pass/dilate_pass/dilate_pass_x");
|
||||
|
||||
path.setTarget("visb");
|
||||
path.bindTarget("visa", "shadowMap");
|
||||
path.drawShader("dilate_pass/dilate_pass/dilate_pass_y");
|
||||
|
||||
path.setTarget("visa", ["dist"]);
|
||||
//if (i == 0) path.clearTarget(0x00000000);
|
||||
path.bindTarget("visb", "dilate");
|
||||
path.bindTarget("shadowMap", "shadowMap");
|
||||
//path.bindTarget("_main", "gbufferD");
|
||||
path.bindTarget("gbuffer0", "gbuffer0");
|
||||
path.drawShader("visibility_pass/visibility_pass/visibility_pass");
|
||||
|
||||
|
||||
path.setTarget("visb");
|
||||
path.bindTarget("visa", "tex");
|
||||
path.bindTarget("gbuffer0", "gbuffer0");
|
||||
path.bindTarget("dist", "dist");
|
||||
path.drawShader("blur_shadow_pass/blur_shadow_pass/blur_shadow_pass_x");
|
||||
|
||||
path.setTarget("visa");
|
||||
path.bindTarget("visb", "tex");
|
||||
path.bindTarget("gbuffer0", "gbuffer0");
|
||||
path.bindTarget("dist", "dist");
|
||||
path.drawShader("blur_shadow_pass/blur_shadow_pass/blur_shadow_pass_y");
|
||||
#end
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
@ -645,7 +712,11 @@ class RenderPathCreator {
|
|||
#if rp_shadowmap
|
||||
{
|
||||
if (path.lampCastShadow()) {
|
||||
#if rp_soft_shadows
|
||||
path.bindTarget("visa", "svisibility");
|
||||
#else
|
||||
path.bindTarget("shadowMap", "shadowMap");
|
||||
#end
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
|
|
@ -189,3 +189,10 @@ def build():
|
|||
|
||||
if rpdat.rp_dynres:
|
||||
assets.add_khafile_def('rp_dynres')
|
||||
|
||||
if rpdat.arm_soft_shadows == 'On':
|
||||
assets.add_shader2('dilate_pass', 'dilate_pass')
|
||||
assets.add_shader2('visibility_pass', 'visibility_pass')
|
||||
assets.add_shader2('blur_shadow_pass', 'blur_shadow_pass')
|
||||
assets.add_khafile_def('rp_soft_shadows')
|
||||
wrd.world_defs += '_SoftShadows'
|
||||
|
|
|
@ -419,7 +419,7 @@ class ArmRPListItem(bpy.types.PropertyGroup):
|
|||
items=[('On', 'On', 'On'),
|
||||
('Off', 'Off', 'Off'),
|
||||
('Auto', 'Auto', 'Auto')],
|
||||
name="Soft Shadows", description="Percentage Closer Soft Shadows", default='Off', update=assets.invalidate_shader_cache)
|
||||
name="Soft Shadows", description="Soft shadows with variable penumbra (spot and non-cascaded sun lamp supported)", default='Off', update=assets.invalidate_shader_cache)
|
||||
arm_ssrs = bpy.props.BoolProperty(name="SSRS", description="Screen-space ray-traced shadows", default=False, update=assets.invalidate_shader_cache)
|
||||
arm_texture_filter = EnumProperty(
|
||||
items=[('Anisotropic', 'Anisotropic', 'Anisotropic'),
|
||||
|
|
Loading…
Reference in a new issue