diff --git a/test/demo.srd b/test/demo.srd index f2b31dc..f16a03a 100644 --- a/test/demo.srd +++ b/test/demo.srd @@ -23,6 +23,8 @@ (set render-compute-size-y 8) (set combine-compute-size-x 8) (set combine-compute-size-y 32) + (set dof-compute-size-x 64) + (set dof-compute-size-y 16) (call scene-init) (call dof-init) @@ -34,7 +36,11 @@ (frame (profiling "Frame render" (call scene-render) - (call dof-render tx-scene-output tx-scene-depth) + (if $use-compute ( + (call dof-render tx-scene-output tx-scene-output) + )( + (call dof-render tx-scene-output tx-scene-depth) + )) (call bloom-render tx-scene-output) (call combine-render tx-dof-pass2 tx-bloom1) (call fxaa-render tx-combined) @@ -169,27 +175,41 @@ (lod 0 0) ) - # Texture & RT for pass 1 - (texture tx-dof-pass1 rgb-f16 $vp-width $vp-height) - (framebuffer rt-dof-pass1 tx-dof-pass1) + (if $use-compute ( + # Textures for both passes + (texture tx-dof-pass1 rgba-f16 $vp-width $vp-height) + (texture tx-dof-pass2 rgba-f16 $vp-width $vp-height) - # Texture & RT for pass 2 - (texture tx-dof-pass2 rgb-f16 $vp-width $vp-height) - (framebuffer rt-dof-pass2 tx-dof-pass2) - # TODO MAYBE ? (alias tx-dof-output tx-dof-pass2) + # Programs + (program prg-dof-pass1 "dof-pass1.c.glsl") + (program prg-dof-pass2 "dof-pass2.c.glsl") + + # Pipelines + (pipeline pl-dof-pass1 prg-dof-pass1) + (pipeline pl-dof-pass2 prg-dof-pass2) + )( + # Texture & RT for pass 1 + (texture tx-dof-pass1 rgb-f16 $vp-width $vp-height) + (framebuffer rt-dof-pass1 tx-dof-pass1) + + # Texture & RT for pass 2 + (texture tx-dof-pass2 rgb-f16 $vp-width $vp-height) + (framebuffer rt-dof-pass2 tx-dof-pass2) + # TODO MAYBE ? (alias tx-dof-output tx-dof-pass2) + + # Programs + (program prg-dof-pass1 "dof-pass1.f.glsl") + (program prg-dof-pass2 "dof-pass2.f.glsl") + + # Pipelines + (pipeline pl-dof-pass1 prg-fullscreen prg-dof-pass1) + (pipeline pl-dof-pass2 prg-fullscreen prg-dof-pass2) + )) # Output debugging (odbg tx-dof-pass1 hdr "DoF - First pass") (odbg tx-dof-pass2 hdr "DoF - Output") - # Programs - (program prg-dof-pass1 "dof-pass1.f.glsl") - (program prg-dof-pass2 "dof-pass2.f.glsl") - - # Pipelines - (pipeline pl-dof-pass1 prg-fullscreen prg-dof-pass1) - (pipeline pl-dof-pass2 prg-fullscreen prg-dof-pass2) - # Inputs (input dof-sharp-distance 0) (input dof-sharp-range 50) @@ -229,27 +249,44 @@ (fn dof-render (in-image in-depth) (profiling "Depth of Field" - (use-texture 1 in-depth smp-dof) - (uniforms-i prg-dof-pass1 0 0) - (uniforms-i prg-dof-pass1 1 1) (uniforms-i prg-dof-pass2 0 0) - (uniforms-i prg-dof-pass2 1 1) + + (if $use-compute ( + (locals dof-cx dof-cy) + (set dof-cx (add 1 (div $vp-width $dof-compute-size-x))) + (set dof-cy (add 1 (div $vp-height $dof-compute-size-y))) + )( + (use-texture 1 in-depth smp-dof) + (uniforms-i prg-dof-pass1 1 1) + (uniforms-i prg-dof-pass2 1 1) + )) # First pass (call dof-set-uniforms prg-dof-pass1) (use-texture 0 in-image smp-dof) (use-pipeline pl-dof-pass1) - (use-framebuffer rt-dof-pass1) - (fullscreen) + (if $use-compute ( + (image 0 tx-dof-pass1 0) + (compute $dof-cx $dof-cy 1) + )( + (use-framebuffer rt-dof-pass1) + (viewport 0 0 $vp-width $vp-height) + (fullscreen) + )) # Second pass (call dof-set-uniforms prg-dof-pass2) (use-texture 0 tx-dof-pass1 smp-dof) (use-pipeline pl-dof-pass2) - (use-framebuffer rt-dof-pass2) - (viewport 0 0 $vp-width $vp-height) - (fullscreen) + (if $use-compute ( + (image 0 tx-dof-pass2 0) + (compute $dof-cx $dof-cy 1) + )( + (use-framebuffer rt-dof-pass2) + (viewport 0 0 $vp-width $vp-height) + (fullscreen) + )) ) ) diff --git a/test/shaders/chunks/dof-cs.glsl b/test/shaders/chunks/dof-cs.glsl new file mode 100644 index 0000000..7cf03d0 --- /dev/null +++ b/test/shaders/chunks/dof-cs.glsl @@ -0,0 +1,67 @@ +//! type chunk + +layout( + local_size_x = 64 , + local_size_y = 16 +) in; + +//#define DOF_USE_RANDOM + +layout( location = 0 ) uniform sampler2D u_Input; +layout( location = 2 ) uniform vec4 u_Parameters; +layout( location = 3 ) uniform float u_Samples; +layout( location = 4 ) uniform vec3 u_ResolutionTime; + +#define uSharpDist (u_Parameters.x) +#define uSharpRange (u_Parameters.y) +#define uBlurFalloff (u_Parameters.z) +#define uMaxBlur (u_Parameters.w) + +#define uResolution (u_ResolutionTime.xy) +#define uTime (u_ResolutionTime.z) + +layout( binding = 0 , rgba16f ) writeonly uniform image2D u_Output; + +//!include lib/utils.glsl + +float DOF_CoC( + in float z ) +{ + return uMaxBlur * min( 1 , + max( 0 , abs( z - uSharpDist ) - uSharpRange ) / uBlurFalloff ); +} + +// z: z at UV +// coc: blur radius at UV +// uv: initial coordinate +// blurvec: smudge direction +vec3 DOF_Blur( + in float z , + in float coc , + in vec2 uv , + in vec2 blurvec ) +{ + vec3 sumcol = vec3( 0. ); + for ( int i = 0 ; i < u_Samples ; i++ ) { + float r = i; +#ifdef DOF_USE_RANDOM + r += M_Hash( uv + float( i + uTime ) ) - .5; +#endif + r = r / float( u_Samples - 1 ) - .5; + vec2 p = uv + r * coc * blurvec; + vec4 d = textureLod( u_Input , p , 0 ); + vec3 smpl = d.xyz; + float sz = d.w; + if ( sz < z ) { + // if sample is closer consider it's CoC + p = uv + r * min( coc , DOF_CoC( sz ) ) * blurvec; + p = uv + r * DOF_CoC( sz ) * blurvec; + smpl = textureLod( u_Input , p , 0 ).xyz; + } + sumcol += smpl; + } + sumcol /= float( u_Samples ); + sumcol = max( sumcol , 0. ); + return sumcol; +} + diff --git a/test/shaders/dof-pass1.c.glsl b/test/shaders/dof-pass1.c.glsl new file mode 100644 index 0000000..fd4142c --- /dev/null +++ b/test/shaders/dof-pass1.c.glsl @@ -0,0 +1,15 @@ +#version 450 core + +//! type compute +//! include chunks/dof-cs.glsl + +void main() +{ + ivec2 coords = ivec2( gl_GlobalInvocationID.xy ); + vec2 uv = vec2( coords ) / uResolution; + vec2 blurvec = vec2( 0 , 1 ) / uResolution; + + float z = textureLod( u_Input , uv , 0 ).w; + vec3 c = DOF_Blur( z , DOF_CoC( z ) , uv , blurvec ); + imageStore( u_Output , coords , vec4( c , z ) ); +} diff --git a/test/shaders/dof-pass2.c.glsl b/test/shaders/dof-pass2.c.glsl new file mode 100644 index 0000000..d1238b0 --- /dev/null +++ b/test/shaders/dof-pass2.c.glsl @@ -0,0 +1,21 @@ +#version 450 core + +//! type compute +//! include chunks/dof-cs.glsl + +void main() +{ + ivec2 coords = ivec2( gl_GlobalInvocationID.xy ); + vec2 uv = vec2( coords ) / uResolution; + float z = textureLod( u_Input , uv , 0 ).w; + + vec2 blurdir = vec2( 1.0 , 0.577350269189626 ); + vec2 blurvec = normalize( blurdir ) / uResolution; + vec3 color0 = DOF_Blur( z , DOF_CoC( z ) , uv , blurvec ); + + blurdir.x = -1; + blurvec = normalize( blurdir ) / uResolution; + vec3 color1 = DOF_Blur( z , DOF_CoC( z ) , uv , blurvec ); + + imageStore( u_Output , coords , vec4( min( color0 , color1 ) , 1. ) ); +}