diff --git a/assets/core/pbr/brdf.dds.meta b/assets/core/pbr/brdf.dds.meta deleted file mode 100644 index 6558a9b..0000000 --- a/assets/core/pbr/brdf.dds.meta +++ /dev/null @@ -1,7 +0,0 @@ -{ - "profiles": { - "default": { - "generate-probe": true - } - } -} \ No newline at end of file diff --git a/assets/core/pbr/night_sky.hdr b/assets/core/pbr/night_sky.hdr deleted file mode 100644 index bb14f82..0000000 Binary files a/assets/core/pbr/night_sky.hdr and /dev/null differ diff --git a/assets/core/pbr/night_sky.hdr.meta b/assets/core/pbr/night_sky.hdr.meta deleted file mode 100644 index 6558a9b..0000000 --- a/assets/core/pbr/night_sky.hdr.meta +++ /dev/null @@ -1,7 +0,0 @@ -{ - "profiles": { - "default": { - "generate-probe": true - } - } -} \ No newline at end of file diff --git a/assets/core/shader/a_trous_fs.sc b/assets/core/shader/a_trous_fs.sc index 1f5a1d2..ed154ad 100644 --- a/assets/core/shader/a_trous_fs.sc +++ b/assets/core/shader/a_trous_fs.sc @@ -1,3 +1,4 @@ +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include SAMPLER2D(u_color, 0); diff --git a/assets/core/shader/a_trous_vs.sc b/assets/core/shader/a_trous_vs.sc index 1b87b56..ef6ecd0 100644 --- a/assets/core/shader/a_trous_vs.sc +++ b/assets/core/shader/a_trous_vs.sc @@ -1,5 +1,6 @@ $input a_position +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() { diff --git a/assets/core/shader/aaa_downsample_fs.sc b/assets/core/shader/aaa_downsample_fs.sc index 735bc27..72b4144 100644 --- a/assets/core/shader/aaa_downsample_fs.sc +++ b/assets/core/shader/aaa_downsample_fs.sc @@ -1,3 +1,4 @@ +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include SAMPLER2D(u_color, 0); diff --git a/assets/core/shader/aaa_downsample_vs.sc b/assets/core/shader/aaa_downsample_vs.sc index 1b87b56..ef6ecd0 100644 --- a/assets/core/shader/aaa_downsample_vs.sc +++ b/assets/core/shader/aaa_downsample_vs.sc @@ -1,5 +1,6 @@ $input a_position +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() { diff --git a/assets/core/shader/aaa_upsample_fs.sc b/assets/core/shader/aaa_upsample_fs.sc index 792d52c..2567d83 100644 --- a/assets/core/shader/aaa_upsample_fs.sc +++ b/assets/core/shader/aaa_upsample_fs.sc @@ -1,3 +1,4 @@ +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include SAMPLER2D(u_input, 0); diff --git a/assets/core/shader/aaa_upsample_vs.sc b/assets/core/shader/aaa_upsample_vs.sc index 1b87b56..ef6ecd0 100644 --- a/assets/core/shader/aaa_upsample_vs.sc +++ b/assets/core/shader/aaa_upsample_vs.sc @@ -1,5 +1,6 @@ $input a_position +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() { diff --git a/assets/core/shader/aaa_utils.sh b/assets/core/shader/aaa_utils.sh index 973ed52..d0585d4 100644 --- a/assets/core/shader/aaa_utils.sh +++ b/assets/core/shader/aaa_utils.sh @@ -1,3 +1,4 @@ +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #ifndef AAA_UTILS_SH_HEADER_GUARD #define AAA_UTILS_SH_HEADER_GUARD diff --git a/assets/core/shader/bloom_combine_fs.sc b/assets/core/shader/bloom_combine_fs.sc index 9c1b80d..d6abacb 100644 --- a/assets/core/shader/bloom_combine_fs.sc +++ b/assets/core/shader/bloom_combine_fs.sc @@ -1,5 +1,6 @@ $input v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include SAMPLER2D(u_source, 0); diff --git a/assets/core/shader/bloom_combine_vs.sc b/assets/core/shader/bloom_combine_vs.sc index 0aa174c..a8521fe 100644 --- a/assets/core/shader/bloom_combine_vs.sc +++ b/assets/core/shader/bloom_combine_vs.sc @@ -1,6 +1,7 @@ $input a_position, a_texcoord0 $output v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() { diff --git a/assets/core/shader/bloom_downsample_fs.sc b/assets/core/shader/bloom_downsample_fs.sc index 8a88b93..f418d95 100644 --- a/assets/core/shader/bloom_downsample_fs.sc +++ b/assets/core/shader/bloom_downsample_fs.sc @@ -1,31 +1,41 @@ $input v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include SAMPLER2D(u_source, 0); +uniform vec4 u_source_rect; + +vec2 compute_texel(vec2 uv, vec2 center, vec4 bounds) { + vec4 w = vec4(step(bounds.xy, uv), step(uv, bounds.zw)); + return mix(center, uv, vec2(w.x*w.z, w.y*w.w)); +} void main() { vec2 uv = v_texcoord0.xy; vec4 offset = vec4(-1., 1., 1., 0.) / uResolution.xxyy; - vec4 s0 = texture2D(u_source, uv - offset.yz); - vec4 s1 = texture2D(u_source, uv - offset.wz); - vec4 s2 = texture2D(u_source, uv - offset.xz); + vec2 center = (floor(v_texcoord0.xy * uResolution.xy) + vec2_splat(0.5)) / uResolution.xy; + vec4 bounds = (floor(u_source_rect.xyzw) + vec4(1.,1.,-1.,-1.)) / uResolution.xyxy; + + vec4 s0 = texture2D(u_source, compute_texel(uv - offset.yz, center, bounds)); // -1,-1 + vec4 s1 = texture2D(u_source, compute_texel(uv - offset.wz, center, bounds)); // 0,-1 + vec4 s2 = texture2D(u_source, compute_texel(uv - offset.xz, center, bounds)); // 1,-1 - vec4 s3 = texture2D(u_source, uv + offset.xw); - vec4 s4 = texture2D(u_source, uv); - vec4 s5 = texture2D(u_source, uv + offset.yw); + vec4 s3 = texture2D(u_source, compute_texel(uv + offset.xw, center, bounds)); // -1, 0 + vec4 s4 = texture2D(u_source, compute_texel(uv, center, bounds)); // 0, 0 + vec4 s5 = texture2D(u_source, compute_texel(uv + offset.yw, center, bounds)); // 1, 0 - vec4 s6 = texture2D(u_source, uv + offset.xz); - vec4 s7 = texture2D(u_source, uv + offset.wz); - vec4 s8 = texture2D(u_source, uv + offset.yz); + vec4 s6 = texture2D(u_source, compute_texel(uv + offset.xz, center, bounds)); // -1, 1 + vec4 s7 = texture2D(u_source, compute_texel(uv + offset.wz, center, bounds)); // 0, 1 + vec4 s8 = texture2D(u_source, compute_texel(uv + offset.yz, center, bounds)); // 1, 1 offset = 0.5 * offset; - vec4 t0 = texture2D(u_source, uv - offset.yz); - vec4 t1 = texture2D(u_source, uv - offset.xz); - vec4 t2 = texture2D(u_source, uv + offset.xz); - vec4 t3 = texture2D(u_source, uv + offset.yz); + vec4 t0 = texture2D(u_source, compute_texel(uv - offset.yz, center, bounds)); // -1,-1 + vec4 t1 = texture2D(u_source, compute_texel(uv - offset.xz, center, bounds)); // 1,-1 + vec4 t2 = texture2D(u_source, compute_texel(uv + offset.xz, center, bounds)); // -1, 1 + vec4 t3 = texture2D(u_source, compute_texel(uv + offset.yz, center, bounds)); // 1, 1 vec4 v0 = s0 + s1 + s3 + s4; vec4 v1 = s1 + s2 + s4 + s5; diff --git a/assets/core/shader/bloom_downsample_vs.sc b/assets/core/shader/bloom_downsample_vs.sc index e70a81b..47acae3 100644 --- a/assets/core/shader/bloom_downsample_vs.sc +++ b/assets/core/shader/bloom_downsample_vs.sc @@ -1,6 +1,7 @@ $input a_position, a_texcoord0 $output v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include uniform vec4 u_source_rect; diff --git a/assets/core/shader/bloom_threshold_fs.sc b/assets/core/shader/bloom_threshold_fs.sc index 7ef6e64..88731d7 100644 --- a/assets/core/shader/bloom_threshold_fs.sc +++ b/assets/core/shader/bloom_threshold_fs.sc @@ -1,5 +1,6 @@ $input v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include uniform vec4 u_params; diff --git a/assets/core/shader/bloom_threshold_vs.sc b/assets/core/shader/bloom_threshold_vs.sc index 8a1f333..7519a3d 100644 --- a/assets/core/shader/bloom_threshold_vs.sc +++ b/assets/core/shader/bloom_threshold_vs.sc @@ -1,6 +1,7 @@ $input a_position, a_texcoord0 $output v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() { diff --git a/assets/core/shader/bloom_upsample_fs.sc b/assets/core/shader/bloom_upsample_fs.sc index 5f7d69d..d121004 100644 --- a/assets/core/shader/bloom_upsample_fs.sc +++ b/assets/core/shader/bloom_upsample_fs.sc @@ -1,26 +1,35 @@ $input v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include SAMPLER2D(u_source, 0); - +uniform vec4 u_source_rect; uniform vec4 u_params; +vec2 compute_texel(vec2 uv, vec2 center, vec4 bounds) { + vec4 w = vec4(step(bounds.xy, uv), step(uv, bounds.zw)); + return mix(center, uv, vec2(w.x*w.z, w.y*w.w)); +} + void main() { vec2 uv = v_texcoord0.xy; vec4 offset = vec4(-1., 1., 1., 0.) / uResolution.xxyy; - vec4 t0 = texture2D(u_source, uv - offset.yz); - vec4 t1 = texture2D(u_source, uv - offset.wz); - vec4 t2 = texture2D(u_source, uv - offset.xz); + vec2 center = (floor(v_texcoord0.xy * uResolution.xy) + vec2_splat(0.5)) / uResolution.xy; + vec4 bounds = (floor(u_source_rect.xyzw) + vec4(1.,1.,-1.,-1.)) / uResolution.xyxy; + + vec4 t0 = texture2D(u_source, compute_texel(uv - offset.yz, center, bounds)); // -1,-1 + vec4 t1 = texture2D(u_source, compute_texel(uv - offset.wz, center, bounds)); // 0,-1 + vec4 t2 = texture2D(u_source, compute_texel(uv - offset.xz, center, bounds)); // 1,-1 - vec4 t3 = texture2D(u_source, uv + offset.xw); - vec4 t4 = texture2D(u_source, uv); - vec4 t5 = texture2D(u_source, uv + offset.yw); + vec4 t3 = texture2D(u_source, compute_texel(uv + offset.xw, center, bounds)); // -1, 0 + vec4 t4 = texture2D(u_source, compute_texel(uv, center, bounds)); + vec4 t5 = texture2D(u_source, compute_texel(uv + offset.yw, center, bounds)); // 1, 0 - vec4 t6 = texture2D(u_source, uv + offset.xz); - vec4 t7 = texture2D(u_source, uv + offset.wz); - vec4 t8 = texture2D(u_source, uv + offset.yz); + vec4 t6 = texture2D(u_source, compute_texel(uv + offset.xz, center, bounds)); // -1, 1 + vec4 t7 = texture2D(u_source, compute_texel(uv + offset.wz, center, bounds)); // 0, 1 + vec4 t8 = texture2D(u_source, compute_texel(uv + offset.yz, center, bounds)); // 1, 1 gl_FragColor = u_params.z * (t0 + t2 + t6 + t8 + 2. * (t1 + t3 + t5 + t7) + 4. * t4) / 16.; } diff --git a/assets/core/shader/bloom_upsample_vs.sc b/assets/core/shader/bloom_upsample_vs.sc index 6f3cd94..df637d9 100644 --- a/assets/core/shader/bloom_upsample_vs.sc +++ b/assets/core/shader/bloom_upsample_vs.sc @@ -1,6 +1,7 @@ $input a_position, a_texcoord0 $output v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include uniform vec4 u_source_rect; diff --git a/assets/core/shader/compositing_fs.sc b/assets/core/shader/compositing_fs.sc index f94b14f..c22ffcf 100644 --- a/assets/core/shader/compositing_fs.sc +++ b/assets/core/shader/compositing_fs.sc @@ -1,5 +1,6 @@ $input v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include SAMPLER2D(u_copyColor, 0); @@ -9,49 +10,42 @@ SAMPLER2D(u_copyDepth, 1); tone-mapping operators implementation taken from https://www.shadertoy.com/view/lslGzl */ -vec3 LinearToneMapping(vec3 color, float exposure) // 1. -{ +vec3 LinearToneMapping(vec3 color, float exposure) { // 1. color = clamp(exposure * color, 0., 1.); return color; } -vec3 SimpleReinhardToneMapping(vec3 color, float exposure) // 1.5 -{ +vec3 SimpleReinhardToneMapping(vec3 color, float exposure) { // 1.5 color *= exposure / (1. + color / exposure); return color; } -vec3 LumaBasedReinhardToneMapping(vec3 color) -{ +vec3 LumaBasedReinhardToneMapping(vec3 color) { float luma = dot(color, vec3(0.2126, 0.7152, 0.0722)); float toneMappedLuma = luma / (1. + luma); color *= toneMappedLuma / luma; return color; } -vec3 WhitePreservingLumaBasedReinhardToneMapping(vec3 color, float white) // 2. -{ +vec3 WhitePreservingLumaBasedReinhardToneMapping(vec3 color, float white) { // 2. float luma = dot(color, vec3(0.2126, 0.7152, 0.0722)); float toneMappedLuma = luma * (1. + luma / (white * white)) / (1. + luma); color *= toneMappedLuma / luma; return color; } -vec3 RomBinDaHouseToneMapping(vec3 color) -{ +vec3 RomBinDaHouseToneMapping(vec3 color) { color = exp(-1. / (2.72 * color + 0.15)); return color; } -vec3 FilmicToneMapping(vec3 color) -{ +vec3 FilmicToneMapping(vec3 color) { color = max(vec3(0., 0., 0.), color - vec3(0.004, 0.004, 0.004)); color = (color * (6.2 * color + .5)) / (color * (6.2 * color + 1.7) + 0.06); return color; } -vec3 Uncharted2ToneMapping(vec3 color, float exposure) -{ +vec3 Uncharted2ToneMapping(vec3 color, float exposure) { float A = 0.15; float B = 0.50; float C = 0.10; @@ -66,8 +60,31 @@ vec3 Uncharted2ToneMapping(vec3 color, float exposure) return color; } -void main() -{ +vec4 Sharpen(vec2 uv, float strength) { + vec4 up = texture2D(u_copyColor, uv + vec2(0, 1) / uResolution.xy); + vec4 left = texture2D(u_copyColor, uv + vec2(-1, 0) / uResolution.xy); + vec4 center = texture2D(u_copyColor, uv); + vec4 right = texture2D(u_copyColor, uv + vec2(1, 0) / uResolution.xy); + vec4 down = texture2D(u_copyColor, uv + vec2(0, -1) / uResolution.xy); + + float exposure = uAAAParams[1].x; + up.xyz = SimpleReinhardToneMapping(up.xyz, exposure); + left.xyz = SimpleReinhardToneMapping(left.xyz, exposure); + center.xyz = SimpleReinhardToneMapping(center.xyz, exposure); + right.xyz = SimpleReinhardToneMapping(right.xyz, exposure); + down.xyz = SimpleReinhardToneMapping(down.xyz, exposure); + + vec4 res = (1.0 + 4.0 * strength) * center - strength * (up + left + right + down); + return vec4(res.xyz, center.w); +} + +void main() { +#if 1 + vec4 in_sample = Sharpen(v_texcoord0, uAAAParams[2].y); + + vec3 color = in_sample.xyz; + float alpha = in_sample.w; +#else vec4 in_sample = texture2D(u_copyColor, v_texcoord0); vec3 color = in_sample.xyz; @@ -78,7 +95,9 @@ void main() //color = lumaBasedReinhardToneMapping(color); //color = FilmicToneMapping(color); //color = Uncharted2ToneMapping(color, exposure); +#endif + // gamma correction float inv_gamma = uAAAParams[1].y; color = pow(color, vec3_splat(inv_gamma)); diff --git a/assets/core/shader/compositing_vs.sc b/assets/core/shader/compositing_vs.sc index 7a95b22..38cbd27 100644 --- a/assets/core/shader/compositing_vs.sc +++ b/assets/core/shader/compositing_vs.sc @@ -1,6 +1,7 @@ $input a_position, a_texcoord0 $output v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() { diff --git a/assets/core/shader/copy_fs.sc b/assets/core/shader/copy_fs.sc index 493ea49..3f7b43f 100644 --- a/assets/core/shader/copy_fs.sc +++ b/assets/core/shader/copy_fs.sc @@ -1,5 +1,6 @@ $input v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include SAMPLER2D(u_copyColor, 0); diff --git a/assets/core/shader/copy_vs.sc b/assets/core/shader/copy_vs.sc index 7a95b22..38cbd27 100644 --- a/assets/core/shader/copy_vs.sc +++ b/assets/core/shader/copy_vs.sc @@ -1,6 +1,7 @@ $input a_position, a_texcoord0 $output v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() { diff --git a/assets/core/shader/default_fs.sc b/assets/core/shader/default_fs.sc index 0789743..1197791 100644 --- a/assets/core/shader/default_fs.sc +++ b/assets/core/shader/default_fs.sc @@ -1,5 +1,6 @@ $input vWorldPos, vNormal, vTangent, vBinormal, vTexCoord0, vTexCoord1, vLinearShadowCoord0, vLinearShadowCoord1, vLinearShadowCoord2, vLinearShadowCoord3, vSpotShadowCoord, vProjPos, vPrevProjPos +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include // Surface attributes @@ -70,41 +71,54 @@ float SampleShadowPCF(sampler2DShadow map, vec4 coord, float inv_pixel_size, flo return k / 4.0; } -// Entry point of the forward pipeline default uber shader (Phong and PBR) +// Entry point of the forward pipeline default shader void main() { +#if DEPTH_ONLY != 1 #if USE_DIFFUSE_MAP +#if DIFFUSE_UV_CHANNEL == 1 + vec3 diff = texture2D(uDiffuseMap, vTexCoord1).xyz; +#else // DIFFUSE_UV_CHANNEL == 1 vec3 diff = texture2D(uDiffuseMap, vTexCoord0).xyz; -#else +#endif // DIFFUSE_UV_CHANNEL == 1 +#else // USE_DIFFUSE_MAP vec3 diff = uDiffuseColor.xyz; -#endif +#endif // USE_DIFFUSE_MAP #if USE_SPECULAR_MAP +#if SPECULAR_UV_CHANNEL == 1 + vec3 spec = texture2D(uSpecularMap, vTexCoord1).xyz; +#else // SPECULAR_UV_CHANNEL == 1 vec3 spec = texture2D(uSpecularMap, vTexCoord0).xyz; -#else +#endif // SPECULAR_UV_CHANNEL == 1 +#else // USE_SPECULAR_MAP vec3 spec = uSpecularColor.xyz; -#endif +#endif // USE_SPECULAR_MAP #if USE_SELF_MAP vec3 self = texture2D(uSelfMap, vTexCoord0).xyz; -#else +#else // USE_SELF_MAP vec3 self = uSelfColor.xyz; -#endif +#endif // USE_SELF_MAP #if USE_AMBIENT_MAP +#if AMBIENT_UV_CHANNEL == 1 vec3 ao = texture2D(uAmbientMap, vTexCoord1).xyz; -#else +#else // AMBIENT_UV_CHANNEL == 1 + vec3 ao = texture2D(uAmbientMap, vTexCoord0).xyz; +#endif // AMBIENT_UV_CHANNEL == 1 +#else // USE_AMBIENT_MAP vec3 ao = vec3_splat(1.0); -#endif +#endif // USE_AMBIENT_MAP #if USE_ADVANCED_BUFFERS ao *= texture2D(uAmbientOcclusion, gl_FragCoord.xy / uResolution.xy).x; -#endif +#endif // USE_ADVANCED_BUFFERS #if USE_LIGHT_MAP vec3 light = texture2D(uLightMap, vTexCoord1).xyz; -#else +#else // USE_LIGHT_MAP vec3 light = vec3_splat(0.0); -#endif +#endif // USE_LIGHT_MAP // vec3 view = mul(u_view, vec4(vWorldPos,1.0)).xyz; // fragment view space pos @@ -121,7 +135,7 @@ void main() { N.xy = texture2D(uNormalMap, vTexCoord0).xy * 2.0 - 1.0; N.z = sqrt(1.0 - dot(N.xy, N.xy)); N = normalize(mul(N, TBN)); -#endif +#endif // USE_NORMAL_MAP vec3 R = reflect(-V, N); // view reflection vector around normal @@ -150,7 +164,7 @@ void main() { float ramp_k = clamp((view.z - (uLinearShadowSlice.w - ramp_len)) / ramp_len, 0.0, 1.0); k *= pcf * (1.0 - ramp_k) + ramp_k; } -#endif +#endif // SLOT0_SHADOWS c_diff = uLightDiffuse[0].xyz * m.i_diff * k; c_spec = uLightSpecular[0].xyz * m.i_spec * k; } @@ -167,7 +181,7 @@ void main() { #if SLOT1_SHADOWS k *= SampleShadowPCF(uSpotShadowMap, vSpotShadowCoord, uShadowState.y, uShadowState.w); -#endif +#endif // SLOT1_SHADOWS c_diff += uLightDiffuse[1].xyz * m.i_diff * k; c_spec += uLightSpecular[1].xyz * m.i_spec * k; @@ -194,28 +208,38 @@ void main() { #if USE_REFLECTION_MAP vec4 reflection = texture2D(uReflectionMap, R.xy); color += reflection.xyz; -#endif +#endif // USE_REFLECTION_MAP color = DistanceFog(view, color); +#endif // DEPTH_ONLY != 1 #if USE_OPACITY_MAP float opacity = texture2D(uOpacityMap, vTexCoord0).x; -#else + +#if ENABLE_ALPHA_CUT + if (opacity < 0.8) + discard; +#endif // ENABLE_ALPHA_CUT +#else // USE_OPACITY_MAP float opacity = 1.0; -#endif +#endif // USE_OPACITY_MAP +#if DEPTH_ONLY + ; +#else // DEPTH_ONLY #if FORWARD_PIPELINE_AAA_PREPASS vec3 N_view = mul(u_view, vec4(N, 0)).xyz; vec2 velocity = vec2(vProjPos.xy / vProjPos.w - vPrevProjPos.xy / vPrevProjPos.w); gl_FragData[0] = vec4(N_view.xyz, vProjPos.z); gl_FragData[1] = vec4(velocity.xy, gloss, 0.); // -#else +#else // FORWARD_PIPELINE_AAA_PREPASS // incorrectly apply gamma correction at fragment shader level in the non-AAA pipeline -# if FORWARD_PIPELINE_AAA == 0 +#if FORWARD_PIPELINE_AAA != 1 float gamma = 2.2; color = pow(color, vec3_splat(1. / gamma)); -# endif +#endif // FORWARD_PIPELINE_AAA != 1 gl_FragColor = vec4(color, opacity); -#endif +#endif // FORWARD_PIPELINE_AAA_PREPASS +#endif // DEPTH_ONLY } diff --git a/assets/core/shader/default_vs.sc b/assets/core/shader/default_vs.sc index 7a46352..c54388c 100644 --- a/assets/core/shader/default_vs.sc +++ b/assets/core/shader/default_vs.sc @@ -1,6 +1,7 @@ $input a_position, a_normal, a_texcoord0, a_texcoord1, a_tangent, a_bitangent, a_indices, a_weight $output vWorldPos, vNormal, vTexCoord0, vTexCoord1, vTangent, vBinormal, vLinearShadowCoord0, vLinearShadowCoord1, vLinearShadowCoord2, vLinearShadowCoord3, vSpotShadowCoord, vProjPos, vPrevProjPos +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include mat3 normal_mat(mat4 m) { @@ -24,15 +25,16 @@ void main() { mul(uPreviousModel[int(a_indices.y * 256.0)], vtx) * a_weight.y + mul(uPreviousModel[int(a_indices.z * 256.0)], vtx) * a_weight.z + mul(uPreviousModel[int(a_indices.w * 256.0)], vtx) * a_weight.w; -#endif -#else +#endif // FORWARD_PIPELINE_AAA_PREPASS +#else // ENABLE_SKINNING vec4 world_pos = mul(u_model[0], vtx); #if FORWARD_PIPELINE_AAA_PREPASS vec4 prv_world_pos = mul(uPreviousModel[0], vtx); -#endif -#endif +#endif // FORWARD_PIPELINE_AAA_PREPASS +#endif // ENABLE_SKINNING +#if DEPTH_ONLY != 1 // normal vec4 normal = vec4(a_normal * 2. - 1., 0.); @@ -46,12 +48,12 @@ void main() { skinned_normal = normalize(skinned_normal); vNormal = skinned_normal.xyz; -#else +#else // ENABLE_SKINNING vNormal = mul(normal_mat(u_model[0]), normal.xyz); -#endif +#endif // ENABLE_SKINNING // tangent frame -#if (USE_NORMAL_MAP) // [EJ] FIXME this probably won't be the only condition to compute the tangent frame for long +#if USE_NORMAL_MAP vec4 tangent = vec4(a_tangent * 2.0 - 1.0, 0.0); vec4 binormal = vec4(a_bitangent * 2.0 - 1.0, 0.0); @@ -70,47 +72,40 @@ void main() { vTangent = skinned_tangent.xyz; vBinormal = skinned_binormal.xyz; -#else +#else // ENABLE_SKINNING vTangent = mul(u_model[0], tangent).xyz; vBinormal = mul(u_model[0], binormal).xyz; -#endif -#endif +#endif // ENABLE_SKINNING +#endif // USE_NORMAL_MAP // shadow data -#if (SLOT0_SHADOWS || SLOT1_SHADOWS) +#if SLOT0_SHADOWS || SLOT1_SHADOWS float shadowMapShrinkOffset = 0.01; vec3 shadowVertexShrinkOffset = vNormal * shadowMapShrinkOffset; -#endif +#endif // SLOT0_SHADOWS || SLOT1_SHADOWS -#if (SLOT0_SHADOWS) +#if SLOT0_SHADOWS vLinearShadowCoord0 = mul(uLinearShadowMatrix[0], vec4(world_pos.xyz + shadowVertexShrinkOffset, 1.0)); vLinearShadowCoord1 = mul(uLinearShadowMatrix[1], vec4(world_pos.xyz + shadowVertexShrinkOffset, 1.0)); vLinearShadowCoord2 = mul(uLinearShadowMatrix[2], vec4(world_pos.xyz + shadowVertexShrinkOffset, 1.0)); vLinearShadowCoord3 = mul(uLinearShadowMatrix[3], vec4(world_pos.xyz + shadowVertexShrinkOffset, 1.0)); -#endif +#endif // SLOT0_SHADOWS -#if (SLOT1_SHADOWS) +#if SLOT1_SHADOWS vSpotShadowCoord = mul(uSpotShadowMatrix, vec4(world_pos.xyz + shadowVertexShrinkOffset, 1.0)); -#endif +#endif // SLOT1_SHADOWS +#endif // DEPTH_ONLY != 1 - // vWorldPos = world_pos.xyz; -#if (USE_DIFFUSE_MAP || USE_SPECULAR_MAP|| USE_NORMAL_MAP || USE_SELF_MAP || USE_OPACITY_MAP) vTexCoord0 = a_texcoord0; -#endif - -#if (USE_LIGHT_MAP || USE_AMBIENT_MAP) vTexCoord1 = a_texcoord1; -#endif - // vec4 proj_pos = mul(uViewProjUnjittered, world_pos); #if FORWARD_PIPELINE_AAA_PREPASS vProjPos = proj_pos; vPrevProjPos = mul(uPreviousViewProjection, prv_world_pos); -#endif +#endif // FORWARD_PIPELINE_AAA_PREPASS - // gl_Position = mul(u_viewProj, world_pos); } diff --git a/assets/core/shader/denoise_vs.sc b/assets/core/shader/denoise_vs.sc index aff3c54..8a5a43d 100644 --- a/assets/core/shader/denoise_vs.sc +++ b/assets/core/shader/denoise_vs.sc @@ -1,5 +1,6 @@ $input a_position +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() { diff --git a/assets/core/shader/font_fs.sc b/assets/core/shader/font_fs.sc index e6289c2..7bfc6fa 100644 --- a/assets/core/shader/font_fs.sc +++ b/assets/core/shader/font_fs.sc @@ -1,5 +1,6 @@ $input v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include uniform vec4 u_color; diff --git a/assets/core/shader/font_vs.sc b/assets/core/shader/font_vs.sc index 0cfa264..569636a 100644 --- a/assets/core/shader/font_vs.sc +++ b/assets/core/shader/font_vs.sc @@ -1,6 +1,7 @@ $input a_position, a_texcoord0 $output v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() { diff --git a/assets/core/shader/forward_pipeline.sh b/assets/core/shader/forward_pipeline.sh index 4344696..35a8611 100644 --- a/assets/core/shader/forward_pipeline.sh +++ b/assets/core/shader/forward_pipeline.sh @@ -1,3 +1,4 @@ +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include #define PI 3.14159265359 @@ -29,19 +30,21 @@ uniform mat4 uMainInvProjection; // inverse projection for the main render (used uniform mat4 uPreviousViewProjection; uniform mat4 uPreviousModel[BGFX_CONFIG_MAX_BONES]; uniform mat4 uViewProjUnjittered; -uniform vec4 uAAAParams[2]; // [0].x: ssgi ratio, [0].y: ssr ratio, [0].z: temporal AA weight, [0].w: motion blur strength, [1].x: exposure, [1].y: 1/gamma, [1].z: sample count, [1].w: max radius +uniform vec4 uAAAParams[3]; // [0].x: ssgi ratio, [0].y: ssr ratio, [0].z: temporal AA weight, [0].w: motion blur strength, + // [1].x: exposure, [1].y: 1/gamma, [1].z: sample count, [1].w: screenspace ray max length + // [2].x: specular weight, [2].y: sharpen uniform mat4 uMainInvView; // inversion view matrix - -#if FORWARD_PIPELINE_AAA -SAMPLER2D(uIrradianceMap, 8); -SAMPLER2D(uRadianceMap, 9); -#else -SAMPLERCUBE(uIrradianceMap, 8); -SAMPLERCUBE(uRadianceMap, 9); -#endif -SAMPLER2D(uBrdfMap, 10); -SAMPLER2D(uNoiseMap, 11); +uniform mat4 uProbeMatrix; +uniform mat4 uInvProbeMatrix; +uniform vec4 uProbeData; + +SAMPLERCUBE(uIrradianceMap, 7); +SAMPLERCUBE(uRadianceMap, 8); +SAMPLER2D(uSSIrradianceMap, 9); +SAMPLER2D(uSSRadianceMap, 10); +SAMPLER2D(uBrdfMap, 11); +SAMPLER2D(uNoiseMap, 12); SAMPLER2D(uAmbientOcclusion, 13); SAMPLER2DSHADOW(uLinearShadowMap, 14); SAMPLER2DSHADOW(uSpotShadowMap, 15); @@ -79,8 +82,7 @@ vec3 Unproject(vec3 frag_coord) { return ndc.xyz / ndc.w; } -vec3 ComputeFragCoordViewRay(vec2 frag_coord) -{ +vec3 ComputeFragCoordViewRay(vec2 frag_coord) { vec2 sp = ((frag_coord - u_viewRect.xy) / u_viewRect.zw) * 2. - 1.; sp.y *= -1.; @@ -92,3 +94,65 @@ vec3 ComputeFragCoordViewRay(vec2 frag_coord) } bool isNan(float val) { return (val <= 0.0 || 0.0 <= val) ? false : true; } + +// +vec2 RaySphere(vec3 r0, vec3 rd, vec3 s0, float sr) { + float a = dot(rd, rd); + vec3 s0_r0 = r0 - s0; + + float b = 2.0 * dot(rd, s0_r0); + float c = dot(s0_r0, s0_r0) - (sr * sr); + float disc = b * b - 4.0 * a* c; + + if (disc < 0.0) + return vec2(-1.0, -1.0); + + return vec2(-b - sqrt(disc), -b + sqrt(disc)) / (2.0 * a); +} + +vec3 RayBox(vec3 ray_origin, vec3 ray_dir, vec3 minpos, vec3 maxpos) { + vec3 inverse_dir = 1.0 / ray_dir; + vec3 tbot = inverse_dir * (minpos - ray_origin); + vec3 ttop = inverse_dir * (maxpos - ray_origin); + vec3 tmin = min(ttop, tbot); + vec3 tmax = max(ttop, tbot); + vec2 traverse = max(tmin.xx, tmin.yz); + float traverselow = max(traverse.x, traverse.y); + traverse = min(tmax.xx, tmax.yz); + float traversehi = min(traverse.x, traverse.y); + return vec3(float(traversehi > max(traverselow, 0.0)), traversehi, traverselow); +} + +vec3 ReprojectProbe(vec3 O, vec3 V) { + vec3 W; + + if (uProbeData.x == 0.0) { + vec3 local_O = mul(uInvProbeMatrix, vec4(O, 1.0)).xyz; // move ray to probe volume space + vec3 local_V = mul(uInvProbeMatrix, vec4(V, 0.0)).xyz; + local_V = normalize(local_V); + + vec2 T = RaySphere(local_O, local_V, vec3(0.0, 0.0, 0.0), 0.5); + + if (T.y > -1.0) { + vec3 local_I = local_O + local_V * T.y; + W = normalize(mul(uProbeMatrix, vec4(local_I, 0.0)).xyz); + } else { + return V; + } + } else if (uProbeData.x == 1.0) { + vec3 local_O = mul(uInvProbeMatrix, vec4(O, 1.0)).xyz; // move ray to probe volume space + vec3 local_V = mul(uInvProbeMatrix, vec4(V, 0.0)).xyz; + local_V = normalize(local_V); + + vec3 T = RayBox(local_O, local_V, vec3(-0.5, -0.5, -0.5), vec3(0.5, 0.5, 0.5)); // intersect with volume + + if (T.x == 0.0) { + return V; + } else { + vec3 local_I = local_O + local_V * T.y; + W = normalize(mul(uProbeMatrix, vec4(local_I, 0.0)).xyz); // move intersection back to world space + } + } + + return normalize(mix(V, W, uProbeData.y)); +} diff --git a/assets/core/shader/hiz_compute_cs.sc b/assets/core/shader/hiz_compute_cs.sc index e9bf7fe..184e56c 100644 --- a/assets/core/shader/hiz_compute_cs.sc +++ b/assets/core/shader/hiz_compute_cs.sc @@ -5,51 +5,49 @@ IMAGE2D_RO(u_depthTexIn, rg32f, 0); // input: level i of the min depth pyramid IMAGE2D_WR(u_depthTexOut, rg32f, 1); // output: level i+1 of the min depth pyramid -uniform vec4 u_zBounds; // near(x) far(y) unused(z,w) - NUM_THREADS(16, 16, 1) void main() { - ivec2 sizeOut = imageSize(u_depthTexOut); - ivec2 coordOut = ivec2(gl_GlobalInvocationID.xy); + ivec2 sizeOut = imageSize(u_depthTexOut); + ivec2 coordOut = ivec2(gl_GlobalInvocationID.xy); - ivec2 sizeIn = imageSize(u_depthTexIn); - ivec2 coordIn = coordOut * 2; + ivec2 sizeIn = imageSize(u_depthTexIn); + ivec2 coordIn = coordOut * 2; - vec2 z = vec2(1.0, 0.0); + vec2 z = vec2(1.0, 0.0); - // The computation is applied on all the texture area. - // It's not restricted to the actual viewport so we don't need to perform any extra check. - vec2 z0 = imageLoad(u_depthTexIn, coordIn).xy; + // The computation is applied on all the texture area. + // It's not restricted to the actual viewport so we don't need to perform any extra check. + vec2 z0 = imageLoad(u_depthTexIn, coordIn).xy; vec2 z2 = imageLoad(u_depthTexIn, coordIn + ivec2(0, 1)).xy; vec2 z1 = imageLoad(u_depthTexIn, coordIn + ivec2(1, 0)).xy; - vec2 z3 = imageLoad(u_depthTexIn, coordIn + ivec2(1, 1)).xy; - - z.x = min(min(z0.x, z1.x), min(z2.x, z3.x)); - z.y = max(max(z0.y, z1.y), max(z2.y, z3.y)); - - // Here we handle the case where the size of the previous level is odd and we are on the boundaries - // of the output texture. - // In this case, we will need to sample an extra row or column. - bvec4 odd_last = bvec4(greaterThan(sizeIn.xy, 2*sizeOut.xy), equal(coordOut, sizeOut-ivec2(1,1))); - bvec2 extra_fetch = bvec2(all(odd_last.xz), all(odd_last.yw)); - if(extra_fetch.x) { - vec2 z4 = imageLoad(u_depthTexIn, coordIn + ivec2(2,0)).xy; - vec2 z5 = imageLoad(u_depthTexIn, coordIn + ivec2(2,1)).xy; + vec2 z3 = imageLoad(u_depthTexIn, coordIn + ivec2(1, 1)).xy; + + z.x = min(min(z0.x, z1.x), min(z2.x, z3.x)); + z.y = max(max(z0.y, z1.y), max(z2.y, z3.y)); + + // Here we handle the case where the size of the previous level is odd and we are on the boundaries + // of the output texture. + // In this case, we will need to sample an extra row or column. + bvec4 odd_last = bvec4(greaterThan(sizeIn.xy, 2*sizeOut.xy), equal(coordOut, sizeOut-ivec2(1,1))); + bvec2 extra_fetch = bvec2(all(odd_last.xz), all(odd_last.yw)); + if(extra_fetch.x) { + vec2 z4 = imageLoad(u_depthTexIn, coordIn + ivec2(2,0)).xy; + vec2 z5 = imageLoad(u_depthTexIn, coordIn + ivec2(2,1)).xy; z.x = min(z.x, min(z4.x, z5.x)); z.y = max(z.y, max(z4.y, z5.y)); - } - if(extra_fetch.y) { - vec2 z6 = imageLoad(u_depthTexIn, coordIn + ivec2(0,2)).xy; - vec2 z7 = imageLoad(u_depthTexIn, coordIn + ivec2(1,2)).xy; + } + if(extra_fetch.y) { + vec2 z6 = imageLoad(u_depthTexIn, coordIn + ivec2(0,2)).xy; + vec2 z7 = imageLoad(u_depthTexIn, coordIn + ivec2(1,2)).xy; z.x = min(z.x, min(z6.x, z7.x)); z.y = max(z.y, max(z6.y, z7.y)); - - if(extra_fetch.x) { - vec2 z8 = imageLoad(u_depthTexIn, coordIn + ivec2(2,2)).xy; - z.x = min(z.x, z8.x); + + if(extra_fetch.x) { + vec2 z8 = imageLoad(u_depthTexIn, coordIn + ivec2(2,2)).xy; + z.x = min(z.x, z8.x); z.y = max(z.y, z8.y); } - } + } - imageStore(u_depthTexOut, coordOut, vec4(z.x, z.y,0,1) ); + imageStore(u_depthTexOut, coordOut, vec4(z.x, z.y, 0, 1)); } \ No newline at end of file diff --git a/assets/core/shader/hiz_copy_cs.sc b/assets/core/shader/hiz_copy_cs.sc index 3083f58..4a64ae8 100644 --- a/assets/core/shader/hiz_copy_cs.sc +++ b/assets/core/shader/hiz_copy_cs.sc @@ -6,6 +6,7 @@ SAMPLER2D(u_depth, 0); IMAGE2D_WR(u_depthTexOut, rg32f, 1); // output: level 0 of the min/max depth pyramid uniform mat4 u_projection; +uniform vec4 u_zThickness; NUM_THREADS(16, 16, 1) void main() { @@ -13,13 +14,13 @@ void main() { ivec2 coord = ivec2(gl_GlobalInvocationID.xy) + ivec2(u_viewRect.xy); #if BGFX_SHADER_LANGUAGE_GLSL - ivec2 tex_coord = ivec2(coord.x, textureSize(u_depth, 0).y - 1 - coord.y); + ivec2 tex_coord = ivec2(coord.x, textureSize(u_depth, 0).y - 1 - coord.y); #else - ivec2 tex_coord = coord; + ivec2 tex_coord = coord; #endif vec2 z; - if(all(bvec4(greaterThanEqual(coord, viewport.xy), lessThan(coord, viewport.xy + viewport.zw)))) { + if (all(bvec4(greaterThanEqual(coord, viewport.xy), lessThan(coord, viewport.xy + viewport.zw)))) { z = texelFetch(u_depth, tex_coord, 0).ww; #if BGFX_SHADER_LANGUAGE_GLSL @@ -27,7 +28,7 @@ void main() { #else vec2 q = u_projection[2].zw; #endif - z.y += 0.1 * q.x; + z.y += u_zThickness.x * q.x; // Store logarithmic depth z.xy = q.x * z.xy / (z.xy - q.yy); diff --git a/assets/core/shader/hiz_trace.sh b/assets/core/shader/hiz_trace.sh index 791d45f..cf8aeb6 100644 --- a/assets/core/shader/hiz_trace.sh +++ b/assets/core/shader/hiz_trace.sh @@ -1,3 +1,4 @@ +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #ifndef HIZ_TRACE_SH_HEADER_GUARD #define HIZ_TRACE_SH_HEADER_GUARD @@ -5,44 +6,37 @@ uniform vec4 u_depthTexInfos; // width(x) heigh(y) start mipmap level(z) max mipmap level(w) -vec3 intersect_cell_boundary(vec3 pos, vec3 dir, vec2 cell, vec2 cell_count, vec4 cross_step) { - vec2 planes = (cell + cross_step.xy) / cell_count; - vec3 intersection; - if(dir.x == 0.0) { - float delta = (planes.y - pos.y) / dir.y; - intersection = pos + dir * delta; - intersection.y += cross_step.w; +// +vec3 ray_step_cell(vec3 ray, vec3 dir, float step, vec2 z_range) { + float t_ = 100000000.0; // [EJ] any large value is ok + + if (dir.x > 0.0) + t_ = min(t_, (floor(ray.x / step + 1.0) * step - ray.x) / dir.x); + else if (dir.x < 0.0) + t_ = min(t_, (ceil(ray.x / step - 1.0) * step - ray.x) / dir.x); + + if (dir.y > 0.0) + t_ = min(t_, (floor(ray.y / step + 1.0) * step - ray.y) / dir.y); + else if (dir.y < 0.0) + t_ = min(t_, (ceil(ray.y / step - 1.0) * step - ray.y) / dir.y); + + if (dir.z > 0.0) { + if (ray.z < z_range.x) + t_ = min(t_, (z_range.x - ray.z) / dir.z); + } else if (dir.z < 0.0) { + if (ray.z > z_range.y) + t_ = min(t_, (z_range.y - ray.z) / dir.z); } - else if(dir.y == 0.0) { - float delta = (planes.x - pos.x) / dir.x; - intersection = pos + dir * delta; - intersection.x += cross_step.z; - } - else { - vec2 delta = (planes - pos.xy) / dir.xy; - intersection = pos + dir * min(delta.x, delta.y); - intersection.xy += (delta.x < delta.y) ? vec2(cross_step.z, 0.0) : vec2(0.0, cross_step.w); - } - return intersection; -} -// returns the texture size in pixels for a given pyramid level. -// textureSize(sampler, level) should be used. -// Unfortunately bgfx directx implementation always returns the size of level 0. -vec2 mip_size(int level) { - return floor(u_depthTexInfos.xy / ((level != 0) ? exp2(level) : 1.0)); + return ray + dir * t_; } -bool hiz_trace(vec3 ray_o, vec3 ray_d, mat4 proj, float z_near, int max_iterations, out vec3 ray) { - vec2 viewport_scale = uv_ratio.xy / u_depthTexInfos.xy; - vec3 viewport_min = vec3(u_viewRect.xy * viewport_scale, 0.); - vec3 viewport_max = vec3((u_viewRect.xy + u_viewRect.zw) * viewport_scale, 1.); +float hiz_trace(vec3 ray_o, vec3 ray_d, mat4 proj, float z_near, int max_iterations, out vec3 ray) { + vec3 viewport_min = vec3(u_viewRect.xy, 0.); + vec3 viewport_max = vec3(u_viewRect.xy + u_viewRect.zw, 1.); - int level_max = int(u_depthTexInfos.w); int level_min = int(u_depthTexInfos.z); - ivec2 iterations = ivec2(0, level_min); - - vec2 cell_count = mip_size(level_min); + int level_max = int(u_depthTexInfos.w); // clip to the near plane float ray_len = ((ray_o.z + ray_d.z * 1000.0) < z_near) ? (z_near - ray_o.z) / ray_d.z : 1000.0; @@ -52,97 +46,108 @@ bool hiz_trace(vec3 ray_o, vec3 ray_d, mat4 proj, float z_near, int max_iteratio vec4 h0 = mul(proj, vec4(ray_o, 1.)); vec4 h1 = mul(proj, vec4(end_point, 1.)); - // screen-space endpoints + // endpoints in screen space vec3 p0 = h0.xyz / h0.w; - p0.y *= -1.; - p0.xy = NDCToViewRect(p0.xy) / cell_count.xy; + p0.y *= -1.0; + p0.xy = NDCToViewRect(p0.xy); vec3 p1 = h1.xyz / h1.w; - p1.y *= -1.; - p1.xy = NDCToViewRect(p1.xy) / cell_count.xy; + p1.y *= -1.0; + p1.xy = NDCToViewRect(p1.xy); - // compute ray start position and direction in screen space - vec3 pos = p0; + // + ray = p0; vec3 dir = normalize(p1 - p0); - if(dir.z == 0) { - ray = vec3(-1., -1., 0.); - return false; - } + vec2 uv_offset = sign(dir.xy) * 0.0001; // slight nudge to sample the correct cell - vec4 cross_step; - cross_step.xy = step(vec2_splat(0.0), dir.xy); - cross_step.zw = (2.0 * cross_step.xy - vec2_splat(1.0)) * vec2_splat(0.5) / cell_count.xy; - - vec2 cell = floor(pos.xy * cell_count); - pos.xy = cell / cell_count + vec2_splat(0.25) / cell_count.xy; - - ray = intersect_cell_boundary(pos, dir, cell, cell_count, cross_step); - - for(iterations.x = 0; (iterations.x < max_iterations) && (iterations.y >= 0); ++iterations.x, --iterations.y) { - // check if the ray goes out of the viewport. - if(any(lessThan(ray, viewport_min))) { - return false; - } - if(any(greaterThanEqual(ray, viewport_max))) { - return false; - } - cell_count = mip_size(iterations.y); - cell = floor(ray.xy * cell_count); - - vec2 z_interval = texelFetch(u_depthTex, ivec2(cell), iterations.y).xy; - - vec3 tmp = ray; - float dz = z_interval.x - ray.z; - if (dz > 0) { - tmp = ray + dz * sign(dir.z) * dir / dir.z; - } - else { - dz = ray.z - z_interval.y; - if (dz > 0) { - tmp = ray + dz * sign(dir.z) * dir / dir.z; - } - } - vec2 new_cell = floor(tmp.xy * cell_count); - if (any(notEqual(new_cell, cell))) { - tmp = intersect_cell_boundary(ray, dir, cell, cell_count, cross_step); - iterations.y = min(level_max, iterations.y + 2); +#if 1 + int level = level_min; + + int iterations = 0; + + while (level > -1) { + if (++iterations == max_iterations) + return -1.0; + + if (any(lessThan(ray, viewport_min))) + return 0.0; // TODO ramp out + if (any(greaterThanEqual(ray, viewport_max))) + return 0.0; // TODO ramp out + + float step = pow(2.0, level); + vec2 z_range = texelFetch(u_depthTex, ivec2(ray.xy / step + uv_offset), level).xy; + + if (ray.z >= z_range.x && ray.z <= z_range.y) { + --level; + } else { + ray = ray_step_cell(ray, dir, step, z_range); + if (level < level_max - 2) + ++level; } - else if ((iterations.y == (level_min+1)) && (dz > 0.00001)) { - tmp = intersect_cell_boundary(ray, dir, cell, cell_count, cross_step); - iterations.y = 2; + } + + vec2 k_fade = saturate((ray.xy - viewport_min) / (u_viewRect.zw * 0.1)); + k_fade *= saturate(vec2(1.0, 1.0) - (ray.xy - viewport_max * 0.9) / (u_viewRect.zw * 0.1)); + + ray.xy /= u_depthTexInfos.xy; + + return k_fade.x * k_fade.y; // hit +#else + int level = 0; // reference implementation (works on any mip level) + + for (int i = 0; i < 4096; ++i) { + if (any(lessThan(ray, viewport_min))) + return false; + if (any(greaterThanEqual(ray, viewport_max))) + return false; + + float step = pow(2.0, level); + vec2 z_range = texelFetch(u_depthTex, ivec2(ray.xy / step), level).xy; + + if (ray.z >= z_range.x && ray.z <= z_range.y) { + ray.xy = ray.xy / u_depthTexInfos.xy; + return true; } - ray = tmp; + ray = ray_step_cell(ray, dir, step, z_range); } - return iterations.y < 0 && iterations.x < max_iterations; + return 0.0; +#endif } -bool TraceScreenRay(vec3 ray_o, vec3 ray_d, mat4 proj, float z_near, int max_iterations, out vec2 hit_pixel, out vec3 hit_point) { +float TraceScreenRay(vec3 ray_o, vec3 ray_d, mat4 proj, float z_near, int max_iterations, out vec2 hit_pixel, out vec3 hit_point) { vec3 ray; - if (hiz_trace(ray_o, ray_d, proj, z_near, max_iterations, ray)) { + float hit = hiz_trace(ray_o, ray_d, proj, z_near, max_iterations, ray); + + if (hit > 0.0) { // compute screen position of the hit pixel #if BGFX_SHADER_LANGUAGE_GLSL hit_pixel = vec2(ray.x, 1.0 - ray.y) * floor(uResolution.xy / uv_ratio); #else hit_pixel = ray.xy * floor(uResolution.xy / uv_ratio); #endif - - // and its world space coordinates hit_point = ray; - hit_point.xy = 2. * hit_point.xy - 1.; - hit_point.y *= -1.; - - vec4 p = mul(uMainInvProjection, vec4(hit_point, 1.)); - hit_point.xyz = p.xyz / p.w; - return true; } else { hit_pixel = vec2_splat(0.); hit_point = vec3_splat(0.); - return false; } + + return hit; +} + +float ComputeRayLogDepth(in mat4 projection, in vec3 ray) { + const float z_epsilon = 0.1; // [todo] parameter? + + float za = texelFetch(u_depthTex, ivec2(floor(ray.xy * u_depthTexInfos.xy)), 0).x; + float zb = z_epsilon * (za - projection[2].z); +#if BGFX_SHADER_LANGUAGE_GLSL + return (zb + projection[3].z * za) / (zb + projection[3].z); +#else + return (zb + projection[2].w * za) / (zb + projection[2].w); +#endif } #endif // HIZ_TRACE_SH_HEADER_GUARD diff --git a/assets/core/shader/imgui_fs.sc b/assets/core/shader/imgui_fs.sc index 90483c5..9f14940 100644 --- a/assets/core/shader/imgui_fs.sc +++ b/assets/core/shader/imgui_fs.sc @@ -1,5 +1,6 @@ $input v_color0, v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include SAMPLER2D(s_tex, 0); diff --git a/assets/core/shader/imgui_vs.sc b/assets/core/shader/imgui_vs.sc index 9cc137a..f50f0d6 100644 --- a/assets/core/shader/imgui_vs.sc +++ b/assets/core/shader/imgui_vs.sc @@ -1,6 +1,7 @@ $input a_position, a_texcoord0, a_color0 $output v_color0, v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() diff --git a/assets/core/shader/missing_fs.sc b/assets/core/shader/missing_fs.sc index d740a92..0c09174 100644 --- a/assets/core/shader/missing_fs.sc +++ b/assets/core/shader/missing_fs.sc @@ -1,5 +1,6 @@ $input vWorldPos +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() { diff --git a/assets/core/shader/missing_vs.sc b/assets/core/shader/missing_vs.sc index e2b8bb5..fd9b4fc 100644 --- a/assets/core/shader/missing_vs.sc +++ b/assets/core/shader/missing_vs.sc @@ -1,6 +1,7 @@ $input a_position $output vWorldPos +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() { diff --git a/assets/core/shader/motion_blur_fs.sc b/assets/core/shader/motion_blur_fs.sc index d95f847..fea5d93 100644 --- a/assets/core/shader/motion_blur_fs.sc +++ b/assets/core/shader/motion_blur_fs.sc @@ -1,3 +1,4 @@ +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include SAMPLER2D(u_color, 0); diff --git a/assets/core/shader/motion_blur_vs.sc b/assets/core/shader/motion_blur_vs.sc index 634540d..968f4f2 100644 --- a/assets/core/shader/motion_blur_vs.sc +++ b/assets/core/shader/motion_blur_vs.sc @@ -1,5 +1,6 @@ $input a_position, a_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() { diff --git a/assets/core/shader/pbr_fs.sc b/assets/core/shader/pbr_fs.sc index e337cd3..afdf2d3 100644 --- a/assets/core/shader/pbr_fs.sc +++ b/assets/core/shader/pbr_fs.sc @@ -1,5 +1,6 @@ $input vWorldPos, vNormal, vTangent, vBinormal, vTexCoord0, vTexCoord1, vLinearShadowCoord0, vLinearShadowCoord1, vLinearShadowCoord2, vLinearShadowCoord3, vSpotShadowCoord, vProjPos, vPrevProjPos +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include // Surface attributes @@ -39,16 +40,17 @@ float SampleShadowPCF(sampler2DShadow map, vec4 coord, float inv_pixel_size, flo #if FORWARD_PIPELINE_AAA #define PCF_SAMPLE_COUNT 2.0 // 3x3 +// float weights[9] = {0.024879, 0.107973, 0.024879, 0.107973, 0.468592, 0.107973, 0.024879, 0.107973, 0.024879}; + float weights[9] = {0.011147, 0.083286, 0.011147, 0.083286, 0.622269, 0.083286, 0.011147, 0.083286, 0.011147}; + for (float j = 0.0; j <= PCF_SAMPLE_COUNT; ++j) { - float v = (j + jitter.y) / PCF_SAMPLE_COUNT * 2.0 - 1.0; + float v = 6.0 * (j + jitter.y) / PCF_SAMPLE_COUNT - 1.0; for (float i = 0.0; i <= PCF_SAMPLE_COUNT; ++i) { - float u = (i + jitter.x) / PCF_SAMPLE_COUNT * 2.0 - 1.0; - k += SampleHardShadow(map, coord + vec4(vec2(u, v) * k_pixel_size, 0.0, 0.0), bias); + float u = 6.0 * (i + jitter.x) / PCF_SAMPLE_COUNT - 1.0; + k += SampleHardShadow(map, coord + vec4(vec2(u, v) * k_pixel_size, 0.0, 0.0), bias) * weights[j * 3 + i]; } } - - k /= (PCF_SAMPLE_COUNT + 1) * (PCF_SAMPLE_COUNT + 1); -#else +#else // FORWARD_PIPELINE_AAA // 2x2 k += SampleHardShadow(map, coord + vec4(vec2(-0.5, -0.5) * k_pixel_size, 0.0, 0.0), bias); k += SampleHardShadow(map, coord + vec4(vec2( 0.5, -0.5) * k_pixel_size, 0.0, 0.0), bias); @@ -56,7 +58,7 @@ float SampleShadowPCF(sampler2DShadow map, vec4 coord, float inv_pixel_size, flo k += SampleHardShadow(map, coord + vec4(vec2( 0.5, 0.5) * k_pixel_size, 0.0, 0.0), bias); k /= 4.0; -#endif +#endif // FORWARD_PIPELINE_AAA return k; } @@ -121,39 +123,33 @@ vec3 DistanceFog(vec3 pos, vec3 color) { // Entry point of the forward pipeline default uber shader (Phong and PBR) void main() { -#if FORWARD_PIPELINE_AAA - vec4 jitter = texture2D(uNoiseMap, mod(gl_FragCoord.xy, vec2(64, 64)) / vec2(64, 64)); -#else - vec4 jitter = vec4_splat(0.); -#endif - // #if USE_BASE_COLOR_OPACITY_MAP vec4 base_opacity = texture2D(uBaseOpacityMap, vTexCoord0); base_opacity.xyz = sRGB2linear(base_opacity.xyz); -#else +#else // USE_BASE_COLOR_OPACITY_MAP vec4 base_opacity = uBaseOpacityColor; -#endif +#endif // USE_BASE_COLOR_OPACITY_MAP - // +#if DEPTH_ONLY != 1 #if USE_OCCLUSION_ROUGHNESS_METALNESS_MAP vec4 occ_rough_metal = texture2D(uOcclusionRoughnessMetalnessMap, vTexCoord0); -#else +#else // USE_OCCLUSION_ROUGHNESS_METALNESS_MAP vec4 occ_rough_metal = uOcclusionRoughnessMetalnessColor; -#endif +#endif // USE_OCCLUSION_ROUGHNESS_METALNESS_MAP // #if USE_SELF_MAP vec4 self = texture2D(uSelfMap, vTexCoord0); -#else +#else // USE_SELF_MAP vec4 self = uSelfColor; -#endif +#endif // USE_SELF_MAP // vec3 view = mul(u_view, vec4(vWorldPos, 1.0)).xyz; vec3 P = vWorldPos; // fragment world pos - vec3 V = normalize(GetT(u_invView) - P); // view vector - vec3 N = normalize(vNormal); // geometry normal + vec3 V = normalize(GetT(u_invView) - P); // world space view vector + vec3 N = sign(dot(V, vNormal)) * normalize(vNormal); // geometry normal #if USE_NORMAL_MAP vec3 T = normalize(vTangent); @@ -164,7 +160,7 @@ void main() { N.xy = texture2D(uNormalMap, vTexCoord0).xy * 2.0 - 1.0; N.z = sqrt(1.0 - dot(N.xy, N.xy)); N = normalize(mul(N, TBN)); -#endif +#endif // USE_NORMAL_MAP vec3 R = reflect(-V, N); // view reflection vector around normal @@ -175,6 +171,13 @@ void main() { vec3 color = vec3(0.0, 0.0, 0.0); + // jitter +#if FORWARD_PIPELINE_AAA + vec4 jitter = texture2D(uNoiseMap, mod(gl_FragCoord.xy, vec2(64, 64)) / vec2(64, 64)); +#else // FORWARD_PIPELINE_AAA + vec4 jitter = vec4_splat(0.); +#endif // FORWARD_PIPELINE_AAA + // SLOT 0: linear light { float k_shadow = 1.0; @@ -188,16 +191,16 @@ void main() { } else if(view.z < uLinearShadowSlice.z * k_fade_split) { k_shadow *= SampleShadowPCF(uLinearShadowMap, vLinearShadowCoord2, uShadowState.y * 0.5, uShadowState.z, jitter); } else if(view.z < uLinearShadowSlice.w * k_fade_split) { -# if FORWARD_PIPELINE_AAA +#if FORWARD_PIPELINE_AAA k_shadow *= SampleShadowPCF(uLinearShadowMap, vLinearShadowCoord3, uShadowState.y * 0.5, uShadowState.z, jitter); -# else +#else // FORWARD_PIPELINE_AAA float pcf = SampleShadowPCF(uLinearShadowMap, vLinearShadowCoord3, uShadowState.y * 0.5, uShadowState.z, jitter); float ramp_len = (uLinearShadowSlice.w - uLinearShadowSlice.z) * 0.25; float ramp_k = clamp((view.z - (uLinearShadowSlice.w - ramp_len)) / max(ramp_len, 1e-8), 0.0, 1.0); k_shadow *= pcf * (1.0 - ramp_k) + ramp_k; -# endif +#endif // FORWARD_PIPELINE_AAA } -#endif +#endif // SLOT0_SHADOWS color += GGX(V, N, NdotV, uLightDir[0].xyz, base_opacity.xyz, occ_rough_metal.g, occ_rough_metal.b, F0, uLightDiffuse[0].xyz * k_shadow, uLightSpecular[0].xyz * k_shadow); } // SLOT 1: point/spot light (with optional shadows) @@ -209,7 +212,7 @@ void main() { #if SLOT1_SHADOWS attenuation *=SampleShadowPCF(uSpotShadowMap, vSpotShadowCoord, uShadowState.y, uShadowState.w, jitter); -#endif +#endif // SLOT1_SHADOWS color += GGX(V, N, NdotV, L, base_opacity.xyz, occ_rough_metal.g, occ_rough_metal.b, F0, uLightDiffuse[1].xyz * attenuation, uLightSpecular[1].xyz * attenuation); } // SLOT 2-N: point/spot light (no shadows) [todo] @@ -225,13 +228,7 @@ void main() { } // IBL -#if FORWARD_PIPELINE_AAA - vec4 irradiance_occlusion = texture2D(uIrradianceMap, gl_FragCoord.xy / uResolution.xy); - - vec3 irradiance = irradiance_occlusion.xyz; - vec3 radiance = texture2D(uRadianceMap, gl_FragCoord.xy / uResolution.xy).xyz; -#else - float MAX_REFLECTION_LOD = 6.; + float MAX_REFLECTION_LOD = 10.; #if 0 // LOD selection vec3 Ndx = normalize(N + ddx(N)); float dx = length(Ndx.xy / Ndx.z - N.xy / N.z) * 256.0; @@ -241,14 +238,25 @@ void main() { float dd = max(dx, dy); float lod_level = log2(dd); #endif - vec3 irradiance = textureCube(uIrradianceMap, N).xyz; - vec3 radiance = textureCubeLod(uRadianceMap, R, occ_rough_metal.y * MAX_REFLECTION_LOD).xyz; + + vec3 irradiance = textureCube(uIrradianceMap, ReprojectProbe(P, N)).xyz; + vec3 radiance = textureCubeLod(uRadianceMap, ReprojectProbe(P, R), occ_rough_metal.y * MAX_REFLECTION_LOD).xyz; + +#if FORWARD_PIPELINE_AAA + vec4 ss_irradiance = texture2D(uSSIrradianceMap, gl_FragCoord.xy / uResolution.xy); + vec4 ss_radiance = texture2D(uSSRadianceMap, gl_FragCoord.xy / uResolution.xy); + + irradiance = ss_irradiance.xyz; // mix(irradiance, ss_irradiance, ss_irradiance.w); + radiance = mix(radiance, ss_radiance, ss_radiance.w); #endif vec3 diffuse = irradiance * base_opacity.xyz; vec3 F = FresnelSchlickRoughness(NdotV, F0, occ_rough_metal.y); vec2 brdf = texture2D(uBrdfMap, vec2(NdotV, occ_rough_metal.y)).xy; vec3 specular = radiance * (F * brdf.x + brdf.y); +#if FORWARD_PIPELINE_AAA + specular *= uAAAParams[2].x; // * specular weight +#endif vec3 kS = specular; vec3 kD = vec3_splat(1.) - kS; @@ -261,21 +269,29 @@ void main() { color += self.xyz; color = DistanceFog(view, color); +#endif // DEPTH_ONLY != 1 float opacity = base_opacity.w; +#if ENABLE_ALPHA_CUT + if (opacity < 0.8) + discard; +#endif // ENABLE_ALPHA_CUT + +#if DEPTH_ONLY != 1 #if FORWARD_PIPELINE_AAA_PREPASS vec3 N_view = mul(u_view, vec4(N, 0)).xyz; vec2 velocity = vec2(vProjPos.xy / vProjPos.w - vPrevProjPos.xy / vPrevProjPos.w); gl_FragData[0] = vec4(N_view.xyz, vProjPos.z); gl_FragData[1] = vec4(velocity.xy, occ_rough_metal.y, 0.); -#else +#else // FORWARD_PIPELINE_AAA_PREPASS // incorrectly apply gamma correction at fragment shader level in the non-AAA pipeline -# if FORWARD_PIPELINE_AAA == 0 +#if FORWARD_PIPELINE_AAA != 1 float gamma = 2.2; color = pow(color, vec3_splat(1. / gamma)); -# endif +#endif // FORWARD_PIPELINE_AAA != 1 gl_FragColor = vec4(color, opacity); -#endif +#endif // FORWARD_PIPELINE_AAA_PREPASS +#endif // DEPTH_ONLY } diff --git a/assets/core/shader/pbr_vs.sc b/assets/core/shader/pbr_vs.sc index 8b9ecc9..2582a33 100644 --- a/assets/core/shader/pbr_vs.sc +++ b/assets/core/shader/pbr_vs.sc @@ -1,6 +1,7 @@ $input a_position, a_normal, a_texcoord0, a_texcoord1, a_tangent, a_bitangent, a_indices, a_weight $output vWorldPos, vNormal, vTexCoord0, vTexCoord1, vTangent, vBinormal, vLinearShadowCoord0, vLinearShadowCoord1, vLinearShadowCoord2, vLinearShadowCoord3, vSpotShadowCoord, vProjPos, vPrevProjPos +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include mat3 normal_mat(mat4 m) { @@ -34,15 +35,16 @@ void main() { mul(uPreviousModel[int(a_indices.y * 256.0)], vtx) * a_weight.y + mul(uPreviousModel[int(a_indices.z * 256.0)], vtx) * a_weight.z + mul(uPreviousModel[int(a_indices.w * 256.0)], vtx) * a_weight.w; -#endif -#else +#endif // FORWARD_PIPELINE_AAA_PREPASS +#else // ENABLE_SKINNING vec4 world_pos = mul(u_model[0], vtx); #if FORWARD_PIPELINE_AAA_PREPASS vec4 prv_world_pos = mul(uPreviousModel[0], vtx); -#endif -#endif +#endif // FORWARD_PIPELINE_AAA_PREPASS +#endif // ENABLE_SKINNING +#if DEPTH_ONLY != 1 // normal vec4 normal = vec4(a_normal * 2. - 1., 0.); @@ -56,12 +58,12 @@ void main() { skinned_normal = normalize(skinned_normal); vNormal = skinned_normal.xyz; -#else +#else // ENABLE_SKINNING vNormal = mul(normal_mat(u_model[0]), normal.xyz); -#endif +#endif // ENABLE_SKINNING // tangent frame -#if (USE_NORMAL_MAP) // [EJ] FIXME this probably won't be the only condition to compute the tangent frame for long +#if USE_NORMAL_MAP // [EJ] FIXME this probably won't be the only condition to compute the tangent frame for long vec4 tangent = vec4(a_tangent * 2.0 - 1.0, 0.0); vec4 binormal = vec4(a_bitangent * 2.0 - 1.0, 0.0); @@ -80,39 +82,42 @@ void main() { vTangent = skinned_tangent.xyz; vBinormal = skinned_binormal.xyz; -#else +#else // ENABLE_SKINNING vTangent = mul(u_model[0], tangent).xyz; vBinormal = mul(u_model[0], binormal).xyz; -#endif -#endif +#endif // ENABLE_SKINNING +#endif // USE_NORMAL_MAP // shadow data -#if (SLOT0_SHADOWS || SLOT1_SHADOWS) +#if SLOT0_SHADOWS || SLOT1_SHADOWS float shadowMapShrinkOffset = 0.01; vec3 shadowVertexShrinkOffset = vNormal * shadowMapShrinkOffset; #endif -#if (SLOT0_SHADOWS) +#if SLOT0_SHADOWS vLinearShadowCoord0 = mul(uLinearShadowMatrix[0], vec4(world_pos.xyz + shadowVertexShrinkOffset, 1.0)); vLinearShadowCoord1 = mul(uLinearShadowMatrix[1], vec4(world_pos.xyz + shadowVertexShrinkOffset, 1.0)); vLinearShadowCoord2 = mul(uLinearShadowMatrix[2], vec4(world_pos.xyz + shadowVertexShrinkOffset, 1.0)); vLinearShadowCoord3 = mul(uLinearShadowMatrix[3], vec4(world_pos.xyz + shadowVertexShrinkOffset, 1.0)); #endif -#if (SLOT1_SHADOWS) +#if SLOT1_SHADOWS vSpotShadowCoord = mul(uSpotShadowMatrix, vec4(world_pos.xyz + shadowVertexShrinkOffset, 1.0)); #endif +#endif // DEPTH_ONLY // vWorldPos = world_pos.xyz; -#if (USE_BASE_COLOR_OPACITY_MAP || USE_OCCLUSION_ROUGHNESS_METALNESS_MAP || USE_DIFFUSE_MAP || USE_SPECULAR_MAP|| USE_NORMAL_MAP || USE_SELF_MAP || USE_OPACITY_MAP) +#if USE_BASE_COLOR_OPACITY_MAP || USE_OCCLUSION_ROUGHNESS_METALNESS_MAP || USE_DIFFUSE_MAP || USE_SPECULAR_MAP|| USE_NORMAL_MAP || USE_SELF_MAP || USE_OPACITY_MAP vTexCoord0 = a_texcoord0; #endif -#if (USE_LIGHT_MAP || USE_AMBIENT_MAP) +#if DEPTH_ONLY != 1 +#if USE_LIGHT_MAP || USE_AMBIENT_MAP vTexCoord1 = a_texcoord1; #endif +#endif // DEPTH_ONLY != 1 // vec4 proj_pos = mul(uViewProjUnjittered, world_pos); diff --git a/assets/core/shader/sao_blur_fs.sc b/assets/core/shader/sao_blur_fs.sc index 76d6f51..f16bde6 100644 --- a/assets/core/shader/sao_blur_fs.sc +++ b/assets/core/shader/sao_blur_fs.sc @@ -1,5 +1,6 @@ $input v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include SAMPLER2D(u_attr0, 0); diff --git a/assets/core/shader/sao_blur_vs.sc b/assets/core/shader/sao_blur_vs.sc index 8a1f333..7519a3d 100644 --- a/assets/core/shader/sao_blur_vs.sc +++ b/assets/core/shader/sao_blur_vs.sc @@ -1,6 +1,7 @@ $input a_position, a_texcoord0 $output v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() { diff --git a/assets/core/shader/sao_compute_fs.sc b/assets/core/shader/sao_compute_fs.sc index 1ca9cf0..d17d46e 100644 --- a/assets/core/shader/sao_compute_fs.sc +++ b/assets/core/shader/sao_compute_fs.sc @@ -1,5 +1,6 @@ $input v_viewRay +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include SAMPLER2D(u_attr0, 0); diff --git a/assets/core/shader/sao_compute_vs.sc b/assets/core/shader/sao_compute_vs.sc index 3076def..d02de49 100644 --- a/assets/core/shader/sao_compute_vs.sc +++ b/assets/core/shader/sao_compute_vs.sc @@ -1,6 +1,7 @@ $input a_position, a_texcoord0 $output v_viewRay +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() { diff --git a/assets/core/shader/sao_upsample_fs.sc b/assets/core/shader/sao_upsample_fs.sc index 1d0c13e..4b16028 100644 --- a/assets/core/shader/sao_upsample_fs.sc +++ b/assets/core/shader/sao_upsample_fs.sc @@ -1,5 +1,6 @@ $input v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include SAMPLER2D(u_attr0, 0); diff --git a/assets/core/shader/sao_upsample_vs.sc b/assets/core/shader/sao_upsample_vs.sc index 8a1f333..7519a3d 100644 --- a/assets/core/shader/sao_upsample_vs.sc +++ b/assets/core/shader/sao_upsample_vs.sc @@ -1,6 +1,7 @@ $input a_position, a_texcoord0 $output v_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() { diff --git a/assets/core/shader/ssgi_fs.sc b/assets/core/shader/ssgi_fs.sc index 48d4e12..efd98fa 100644 --- a/assets/core/shader/ssgi_fs.sc +++ b/assets/core/shader/ssgi_fs.sc @@ -1,5 +1,6 @@ $input vTexCoord0, v_viewRay +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include SAMPLER2D(u_color, 0); @@ -16,15 +17,17 @@ SAMPLER2D(u_depthTex, 5); // input: minimum depth pyramid #include #include - void main() { + vec4 color = vec4(0.0, 0.0, 0.0, 0.0); vec4 jitter = texture2D(u_noise, mod(gl_FragCoord.xy, vec2(64, 64)) / vec2(64, 64)); // sample normal/depth vec2 uv = GetAttributeTexCoord(vTexCoord0, textureSize(u_attr0, 0).xy); vec4 attr0 = texture2D(u_attr0, uv); - vec3 n = attr0.xyz; + vec3 n = normalize(attr0.xyz); + if (isNan(n.x) || isNan(n.y) |isNan(n.z)) + n = vec3(0, 1, 0); // compute ray origin & direction vec3 ray_o = GetRayOrigin(uMainProjection, v_viewRay, attr0.w); @@ -34,7 +37,6 @@ void main() { vec3 up = cross(n, right); // - vec4 color = vec4_splat(0.); const float z_min = 0.1; for (int i = 0; i < int(sample_count); ++i) { @@ -49,30 +51,33 @@ void main() { vec2 hit_pixel; vec3 hit_point; - if (TraceScreenRay(ray_o - v_viewRay * 0.05, ray_d_spread, uMainProjection, z_min, /*jitter.z,*/ 64, hit_pixel, hit_point)) { + float k = TraceScreenRay(ray_o - v_viewRay * 0.05, ray_d_spread, uMainProjection, z_min, 192, hit_pixel, hit_point); + + if (k > 0.0) { // use hit pixel velocity to compensate the fact that we are sampling the previous frame - vec2 uv = hit_pixel * uv_ratio / uResolution.xy; + uv = hit_pixel * uv_ratio / uResolution.xy; vec2 vel = GetVelocityVector(uv); - vec4 attr0 = texelFetch(u_attr0, ivec2(hit_pixel), 0); + attr0 = texelFetch(u_attr0, ivec2(hit_pixel), 0); + + float log_depth = ComputeRayLogDepth(uMainProjection, hit_point); - if (dot(attr0.xyz, ray_d_spread) < 0.0) { // ray facing the collision + if ((dot(attr0.xyz, ray_d_spread) < 0.0) && (hit_point.z <= log_depth)) { // ray facing the collision vec3 irradiance = texture2D(u_color, uv - vel * uv_ratio).xyz; - color += vec4(irradiance * 1.0, 0.0); + color += vec4(irradiance, 1.0); } else { color += vec4(0.0, 0.0, 0.0, 0.0); // backface hit } } else { vec3 world_ray_d_spread = mul(uMainInvView, vec4(ray_d_spread, 0.0)).xyz; - color += vec4(textureCubeLod(u_probe, world_ray_d_spread, 0).xyz, 1.); + vec3 world_ray_o = mul(uMainInvView, vec4(ray_o, 1.0)).xyz; + color += vec4(textureCubeLod(u_probe, ReprojectProbe(world_ray_o, world_ray_d_spread), 0).xyz, 0.); } } } -#if 1 - if (isNan(color.x) || isNan(color.y) || isNan(color.z)) - color = vec4(1., 0., 0., 1.); -#endif + color /= sample_count * sample_count; + color = (saturate(color) / 32.0) * 32.0; - gl_FragColor = color / (sample_count * sample_count); + gl_FragColor = color; } diff --git a/assets/core/shader/ssgi_vs.sc b/assets/core/shader/ssgi_vs.sc index af73283..6b7fbcf 100644 --- a/assets/core/shader/ssgi_vs.sc +++ b/assets/core/shader/ssgi_vs.sc @@ -1,6 +1,7 @@ $input a_position, a_texcoord0 $output vTexCoord0, v_viewRay +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include #define uv_ratio vec2_splat(uAAAParams[0].x) diff --git a/assets/core/shader/ssr_fs.sc b/assets/core/shader/ssr_fs.sc index b8b0808..9207050 100644 --- a/assets/core/shader/ssr_fs.sc +++ b/assets/core/shader/ssr_fs.sc @@ -1,5 +1,6 @@ $input vTexCoord0, v_viewRay +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include SAMPLER2D(u_color, 0); @@ -16,30 +17,49 @@ SAMPLER2D(u_depthTex, 5); // input: minimum depth pyramid #include #include - void main() { + vec4 color = vec4(0.0, 0.0, 0.0, 0.0); vec4 jitter = texture2D(u_noise, mod(gl_FragCoord.xy, vec2(64, 64)) / vec2(64, 64)); // sample normal/depth vec2 uv = GetAttributeTexCoord(vTexCoord0, textureSize(u_attr0, 0).xy); vec4 attr0 = texture2D(u_attr0, uv); - vec3 n = attr0.xyz; + vec3 n = normalize(attr0.xyz); + if (isNan(n.x) || isNan(n.y) |isNan(n.z)) + n = vec3(0, 1, 0); // compute ray origin & direction vec3 ray_o = GetRayOrigin(uMainProjection, v_viewRay, attr0.w); vec3 ray_d = reflect(normalize(ray_o), n); - // roughness + const float z_min = 0.1; + +#if 0 + vec2 hit_pixel; + vec3 hit_point; + + float k = TraceScreenRay(ray_o - v_viewRay * 0.05, ray_d, uMainProjection, z_min, 4096, hit_pixel, hit_point); + + if (k > 0.0) { + uv = hit_pixel * uv_ratio / uResolution.xy; + vec2 vel = GetVelocityVector(uv); + color = mix(color, vec4(texture2D(u_color, uv - vel * uv_ratio).xyz, 1.0), k); + } else if (k == 0.0) { + color = vec4(1.0, 0.0, 0.0, 0.0); + } else if (k == -1) { + color = vec4(0.0, 1.0, 0.0, 0.0); // max iteration reached (most likely due to a bug) + } +#else float roughness = texture2D(u_attr1, uv).z; + roughness = pow(roughness, 2.5); vec3 right = cross(ray_d, vec3(0, 0, 1)); vec3 up = cross(ray_d, right); - - const float z_min = 0.1; // - vec4 color = vec4_splat(0.); + vec3 world_ray_o = mul(uMainInvView, vec4(ray_o, 1.0)).xyz; + for (int i = 0; i < int(sample_count); ++i) { float r = roughness * (float(i) + jitter.y) / sample_count; float spread = r * 3.141592 * 0.5 * 0.99; @@ -49,31 +69,35 @@ void main() { float angle = float(j + jitter.w) / sample_count * 2. * 3.141592; vec3 ray_d_spread = (right * cos(angle) + up * sin(angle)) * sin_spread + ray_d * cos_spread; + vec3 world_ray_d = mul(uMainInvView, vec4(ray_d_spread, 0.0)).xyz; + vec4 fallback = vec4(textureCubeLod(u_probe, ReprojectProbe(world_ray_o, world_ray_d), 0).xyz, 0.); + vec2 hit_pixel; vec3 hit_point; - if (TraceScreenRay(ray_o - v_viewRay * 0.05, ray_d_spread, uMainProjection, z_min, /*jitter.z,*/ 64, hit_pixel, hit_point)) { + float k = TraceScreenRay(ray_o - v_viewRay * 0.05, ray_d_spread, uMainProjection, z_min, 192, hit_pixel, hit_point); + + if (k > 0.0) { // use hit pixel velocity to compensate the fact that we are sampling the previous frame uv = hit_pixel * uv_ratio / uResolution.xy; vec2 vel = GetVelocityVector(uv); - - vec4 attr0 = texelFetch(u_attr0, ivec2(hit_pixel), 0); - - if (dot(attr0.xyz, ray_d_spread) < 0.0) { - color += vec4(texture2D(u_color, uv - vel * uv_ratio).xyz, 0.); - } else { - color += vec4(0.0, 0.0, 0.0, 0.0); // backface hit - } + + attr0 = texelFetch(u_attr0, ivec2(hit_pixel), 0); + + float log_depth = ComputeRayLogDepth(uMainProjection, hit_point); + + vec4 output = vec4(0.0, 0.0, 0.0, 1.0); // assume backface hit + if (dot(attr0.xyz, ray_d_spread) < 0.0 && hit_point.z <= log_depth) + output = vec4(texture2D(u_color, uv - vel * uv_ratio).xyz, 1.0); // front face hit + + color += mix(fallback, output, k); } else { - vec3 world_ray_d_spread = mul(uMainInvView, vec4(ray_d_spread, 0.0)).xyz; - color += vec4(textureCubeLod(u_probe, world_ray_d_spread, 0).xyz, 1.); + color += fallback; } } } -#if 1 - if (isNan(color.x) || isNan(color.y) || isNan(color.z)) - color = vec4(1., 0., 0., 1.); + color /= sample_count * sample_count; #endif - gl_FragColor = color / (sample_count * sample_count); + gl_FragColor = color; } diff --git a/assets/core/shader/ssr_vs.sc b/assets/core/shader/ssr_vs.sc index 1636a1d..6b33b32 100644 --- a/assets/core/shader/ssr_vs.sc +++ b/assets/core/shader/ssr_vs.sc @@ -1,6 +1,7 @@ $input a_position, a_texcoord0 $output vTexCoord0, v_viewRay +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() { diff --git a/assets/core/shader/taa_fs.sc b/assets/core/shader/taa_fs.sc index 4836804..bcf820c 100644 --- a/assets/core/shader/taa_fs.sc +++ b/assets/core/shader/taa_fs.sc @@ -1,3 +1,4 @@ +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include SAMPLER2D(u_color, 0); @@ -10,6 +11,7 @@ SAMPLER2D(u_attr1, 3); #define AABB_CLAMPING 0 #define AABB_CLAMPING_FAST 1 #define VARIANCE_CLIPPING_GAMMA 0 // https://community.arm.com/developer/tools-software/graphics/b/blog/posts/temporal-anti-aliasing +#define LUMINANCE_AJDUST 1 void main() { vec2 uv = gl_FragCoord.xy / uResolution.xy; @@ -81,7 +83,20 @@ void main() { prv_color = clamp(prv_color, box_min, box_max); #endif +#if LUMINANCE_AJDUST + const vec3 luminance = vec3(0.2127, 0.7152, 0.0722); + + float l0 = dot(luminance, prv_color); + float l1 = dot(luminance, color); + + float w1 = (uAAAParams[0].z) / (1.0 + l1); + float w0 = (1.0 - uAAAParams[0].z) / (1.0 + l0); + + vec3 taa_out = (w1 * color + w0 * prv_color) / max(w0 + w1, 0.00001); + gl_FragColor = vec4(taa_out, 1.); +#else // TAA vec3 taa_out = color * uAAAParams[0].z + prv_color * (1. - uAAAParams[0].z); gl_FragColor = vec4(taa_out, 1.); +#endif } diff --git a/assets/core/shader/taa_vs.sc b/assets/core/shader/taa_vs.sc index 810238b..4747f03 100644 --- a/assets/core/shader/taa_vs.sc +++ b/assets/core/shader/taa_vs.sc @@ -1,5 +1,6 @@ $input a_position, a_texcoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() { diff --git a/assets/core/shader/temporal_accumulation_fs.sc b/assets/core/shader/temporal_accumulation_fs.sc index e850fd0..d8a3eb1 100644 --- a/assets/core/shader/temporal_accumulation_fs.sc +++ b/assets/core/shader/temporal_accumulation_fs.sc @@ -1,5 +1,6 @@ $input vTexCoord0 +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include SAMPLER2D(u_current, 0); diff --git a/assets/core/shader/temporal_accumulation_varying.def b/assets/core/shader/temporal_accumulation_varying.def index f91907c..4aad665 100644 --- a/assets/core/shader/temporal_accumulation_varying.def +++ b/assets/core/shader/temporal_accumulation_varying.def @@ -1,4 +1,4 @@ -vec2 vTexCoord0 : TEXCOORD0; - -vec3 a_position : POSITION; -vec2 a_texcoord0 : TEXCOORD0; +vec2 vTexCoord0 : TEXCOORD0; + +vec3 a_position : POSITION; +vec2 a_texcoord0 : TEXCOORD0; diff --git a/assets/core/shader/temporal_accumulation_vs.sc b/assets/core/shader/temporal_accumulation_vs.sc index 9e87523..a85563e 100644 --- a/assets/core/shader/temporal_accumulation_vs.sc +++ b/assets/core/shader/temporal_accumulation_vs.sc @@ -1,6 +1,7 @@ $input a_position, a_texcoord0 $output vTexCoord0, +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #include void main() { diff --git a/assets/shaders/aaa_utils.sh b/assets/shaders/aaa_utils.sh deleted file mode 100644 index 973ed52..0000000 --- a/assets/shaders/aaa_utils.sh +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef AAA_UTILS_SH_HEADER_GUARD -#define AAA_UTILS_SH_HEADER_GUARD - -# if !defined(uv_ratio) -# define uv_ratio vec2_splat(uAAAParams[0].x) -# endif - -vec2 NDCToViewRect(vec2 xy) { return ((xy * 0.5 + 0.5) * u_viewRect.zw + u_viewRect.xy); } - -vec2 GetVelocityVector(in vec2 uv) { -#if BGFX_SHADER_LANGUAGE_GLSL - const vec2 offset = vec2(0.5, 0.5); -#else - const vec2 offset = vec2(0.5,-0.5); -#endif - return texture2D(u_attr1, uv).xy * offset / (uResolution.xy / u_viewRect.zw); -} - -vec2 GetAttributeTexCoord(vec2 coord, vec2 size) { -#if BGFX_SHADER_LANGUAGE_GLSL - vec2 uv = vec2(coord.x, 1.0 - coord.y) * u_viewRect.zw / size; - uv.y = 1.0 - uv.y; - return uv; -#else - return coord * u_viewRect.zw / size; -#endif -} - -vec3 GetRayOrigin(mat4 projection, vec3 viewRay, float depth) { -#if BGFX_SHADER_LANGUAGE_GLSL - float z = (depth - projection[3].z) / projection[2].z; -#else - float z = (depth - projection[2].w) / projection[2].z; -#endif - return viewRay * z; -} - -#endif // AAA_UTILS_SH_HEADER_GUARD diff --git a/assets/shaders/bgfx_compute.sh b/assets/shaders/bgfx_compute.sh deleted file mode 100644 index a67103e..0000000 --- a/assets/shaders/bgfx_compute.sh +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright 2011-2021 Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause - */ - -#ifndef BGFX_COMPUTE_H_HEADER_GUARD -#define BGFX_COMPUTE_H_HEADER_GUARD - -#include "bgfx_shader.sh" - -#ifndef __cplusplus - -#if BGFX_SHADER_LANGUAGE_METAL || BGFX_SHADER_LANGUAGE_SPIRV -# define ANNOTATION(_format) [[spv::format_ ## _format]] -#else -# define ANNOTATION(_format) -#endif - -#if BGFX_SHADER_LANGUAGE_GLSL - -#define SHARED shared - -#define __IMAGE_XX(_name, _format, _reg, _image, _access) \ - layout(_format, binding=_reg) _access uniform highp _image _name - -#define readwrite -#define IMAGE2D_RO( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2D, readonly) -#define UIMAGE2D_RO(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2D, readonly) -#define IMAGE2D_WR( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2D, writeonly) -#define UIMAGE2D_WR(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2D, writeonly) -#define IMAGE2D_RW( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2D, readwrite) -#define UIMAGE2D_RW(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2D, readwrite) - -#define IMAGE2D_ARRAY_RO( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2DArray, readonly) -#define UIMAGE2D_ARRAY_RO(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2DArray, readonly) -#define IMAGE2D_ARRAY_WR( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2DArray, writeonly) -#define UIMAGE2D_ARRAY_WR(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2DArray, writeonly) -#define IMAGE2D_ARRAY_RW( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2DArray, readwrite) -#define UIMAGE2D_ARRAY_RW(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2DArray, readwrite) - -#define IMAGE3D_RO( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image3D, readonly) -#define UIMAGE3D_RO(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage3D, readonly) -#define IMAGE3D_WR( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image3D, writeonly) -#define UIMAGE3D_WR(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage3D, writeonly) -#define IMAGE3D_RW( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image3D, readwrite) -#define UIMAGE3D_RW(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage3D, readwrite) - -#define __BUFFER_XX(_name, _type, _reg, _access) \ - layout(std430, binding=_reg) _access buffer _name ## Buffer \ - { \ - _type _name[]; \ - } - -#define BUFFER_RO(_name, _type, _reg) __BUFFER_XX(_name, _type, _reg, readonly) -#define BUFFER_RW(_name, _type, _reg) __BUFFER_XX(_name, _type, _reg, readwrite) -#define BUFFER_WR(_name, _type, _reg) __BUFFER_XX(_name, _type, _reg, writeonly) - -#define NUM_THREADS(_x, _y, _z) layout (local_size_x = _x, local_size_y = _y, local_size_z = _z) in; - -#define atomicFetchAndAdd(_mem, _data, _original) _original = atomicAdd(_mem, _data) -#define atomicFetchAndAnd(_mem, _data, _original) _original = atomicAnd(_mem, _data) -#define atomicFetchAndMax(_mem, _data, _original) _original = atomicMax(_mem, _data) -#define atomicFetchAndMin(_mem, _data, _original) _original = atomicMin(_mem, _data) -#define atomicFetchAndOr(_mem, _data, _original) _original = atomicOr(_mem, _data) -#define atomicFetchAndXor(_mem, _data, _original) _original = atomicXor(_mem, _data) -#define atomicFetchAndExchange(_mem, _data, _original) _original = atomicExchange(_mem, _data) -#define atomicFetchCompareExchange(_mem, _compare, _data, _original) _original = atomicCompSwap(_mem,_compare, _data) - -#else - -#define SHARED groupshared - -#define r32ui uint -#define rg32ui uint2 -#define rgba32ui uint4 -#define r32f float -#define rg32f float2 -#define r16f float -#define rg16f float2 -#define rgba16f float4 -#if BGFX_SHADER_LANGUAGE_HLSL -# define rgba8 unorm float4 -# define rg8 unorm float2 -# define r8 unorm float -#else -# define rgba8 float4 -# define rg8 float2 -# define r8 float -#endif // BGFX_SHADER_LANGUAGE_HLSL -#define rgba32f float4 - -#define IMAGE2D_RO( _name, _format, _reg) \ - Texture2D<_format> _name ## Texture : REGISTER(t, _reg); \ - static BgfxROImage2D_ ## _format _name = { _name ## Texture } - -#define UIMAGE2D_RO(_name, _format, _reg) IMAGE2D_RO(_name, _format, _reg) - -#define IMAGE2D_RW( _name, _format, _reg) \ - ANNOTATION(_format) RWTexture2D<_format> _name ## Texture : REGISTER(u, _reg); \ - static BgfxRWImage2D_ ## _format _name = { _name ## Texture } - -#define IMAGE2D_WR( _name, _format, _reg) IMAGE2D_RW(_name, _format, _reg) -#define UIMAGE2D_WR(_name, _format, _reg) IMAGE2D_RW(_name, _format, _reg) -#define UIMAGE2D_RW(_name, _format, _reg) IMAGE2D_RW(_name, _format, _reg) - -#define IMAGE2D_ARRAY_RO(_name, _format, _reg) \ - Texture2DArray<_format> _name ## Texture : REGISTER(t, _reg); \ - static BgfxROImage2DArray_ ## _format _name = { _name ## Texture } - -#define UIMAGE2D_ARRAY_RO(_name, _format, _reg) IMAGE2D_ARRAY_RO(_name, _format, _reg) - -#define IMAGE2D_ARRAY_RW(_name, _format, _reg) \ - ANNOTATION(_format) RWTexture2DArray<_format> _name ## Texture : REGISTER(u, _reg); \ - static BgfxRWImage2DArray_ ## _format _name = { _name ## Texture } - -#define UIMAGE2D_ARRAY_RW(_name, _format, _reg) IMAGE2D_ARRAY_RW(_name, _format, _reg) -#define IMAGE2D_ARRAY_WR( _name, _format, _reg) IMAGE2D_ARRAY_RW(_name, _format, _reg) -#define UIMAGE2D_ARRAY_WR(_name, _format, _reg) IMAGE2D_ARRAY_RW(_name, _format, _reg) - -#define IMAGE3D_RO( _name, _format, _reg) \ - Texture3D<_format> _name ## Texture : REGISTER(t, _reg); \ - static BgfxROImage3D_ ## _format _name = { _name ## Texture } - -#define UIMAGE3D_RO(_name, _format, _reg) IMAGE3D_RO(_name, _format, _reg) - -#define IMAGE3D_RW( _name, _format, _reg) \ - ANNOTATION(_format) RWTexture3D<_format> _name ## Texture : REGISTER(u, _reg); \ - static BgfxRWImage3D_ ## _format _name = { _name ## Texture } - -#define UIMAGE3D_RW(_name, _format, _reg) IMAGE3D_RW(_name, _format, _reg) -#define IMAGE3D_WR( _name, _format, _reg) IMAGE3D_RW(_name, _format, _reg) -#define UIMAGE3D_WR(_name, _format, _reg) IMAGE3D_RW(_name, _format, _reg) - -#if BGFX_SHADER_LANGUAGE_METAL || BGFX_SHADER_LANGUAGE_SPIRV -#define BUFFER_RO(_name, _struct, _reg) StructuredBuffer<_struct> _name : REGISTER(t, _reg) -#define BUFFER_RW(_name, _struct, _reg) RWStructuredBuffer <_struct> _name : REGISTER(u, _reg) -#define BUFFER_WR(_name, _struct, _reg) BUFFER_RW(_name, _struct, _reg) -#else -#define BUFFER_RO(_name, _struct, _reg) Buffer<_struct> _name : REGISTER(t, _reg) -#define BUFFER_RW(_name, _struct, _reg) RWBuffer<_struct> _name : REGISTER(u, _reg) -#define BUFFER_WR(_name, _struct, _reg) BUFFER_RW(_name, _struct, _reg) -#endif - -#define NUM_THREADS(_x, _y, _z) [numthreads(_x, _y, _z)] - -#define __IMAGE_IMPL_S(_format, _storeComponents, _type, _loadComponents) \ - \ - struct BgfxROImage2D_ ## _format \ - { \ - Texture2D<_format> m_texture; \ - }; \ - \ - struct BgfxRWImage2D_ ## _format \ - { \ - ANNOTATION(_format) RWTexture2D<_format> m_texture; \ - }; \ - \ - struct BgfxROImage2DArray_ ## _format \ - { \ - Texture2DArray<_format> m_texture; \ - }; \ - \ - struct BgfxRWImage2DArray_ ## _format \ - { \ - ANNOTATION(_format) RWTexture2DArray<_format> m_texture; \ - }; \ - \ - struct BgfxROImage3D_ ## _format \ - { \ - Texture3D<_format> m_texture; \ - }; \ - \ - struct BgfxRWImage3D_ ## _format \ - { \ - ANNOTATION(_format) RWTexture3D<_format> m_texture; \ - }; \ - -#define __IMAGE_IMPL_A(_format, _storeComponents, _type, _loadComponents) \ - __IMAGE_IMPL_S(_format, _storeComponents, _type, _loadComponents) \ - \ - _type imageLoad(BgfxROImage2D_ ## _format _image, ivec2 _uv) \ - { \ - return _image.m_texture[_uv]._loadComponents; \ - } \ - \ - ivec2 imageSize(BgfxROImage2D_ ## _format _image) \ - { \ - uvec2 result; \ - _image.m_texture.GetDimensions(result.x, result.y); \ - return ivec2(result); \ - } \ - \ - _type imageLoad(BgfxRWImage2D_ ## _format _image, ivec2 _uv) \ - { \ - return _image.m_texture[_uv]._loadComponents; \ - } \ - \ - ivec2 imageSize(BgfxRWImage2D_ ## _format _image) \ - { \ - uvec2 result; \ - _image.m_texture.GetDimensions(result.x, result.y); \ - return ivec2(result); \ - } \ - \ - void imageStore(BgfxRWImage2D_ ## _format _image, ivec2 _uv, _type _value) \ - { \ - _image.m_texture[_uv] = _value._storeComponents; \ - } \ - \ - _type imageLoad(BgfxROImage2DArray_ ## _format _image, ivec3 _uvw) \ - { \ - return _image.m_texture[_uvw]._loadComponents; \ - } \ - \ - ivec3 imageSize(BgfxROImage2DArray_ ## _format _image) \ - { \ - uvec3 result; \ - _image.m_texture.GetDimensions(result.x, result.y, result.z); \ - return ivec3(result); \ - } \ - \ - _type imageLoad(BgfxRWImage2DArray_ ## _format _image, ivec3 _uvw) \ - { \ - return _image.m_texture[_uvw]._loadComponents; \ - } \ - \ - void imageStore(BgfxRWImage2DArray_ ## _format _image, ivec3 _uvw, _type _value) \ - { \ - _image.m_texture[_uvw] = _value._storeComponents; \ - } \ - \ - ivec3 imageSize(BgfxRWImage2DArray_ ## _format _image) \ - { \ - uvec3 result; \ - _image.m_texture.GetDimensions(result.x, result.y, result.z); \ - return ivec3(result); \ - } \ - \ - _type imageLoad(BgfxROImage3D_ ## _format _image, ivec3 _uvw) \ - { \ - return _image.m_texture[_uvw]._loadComponents; \ - } \ - \ - ivec3 imageSize(BgfxROImage3D_ ## _format _image) \ - { \ - uvec3 result; \ - _image.m_texture.GetDimensions(result.x, result.y, result.z); \ - return ivec3(result); \ - } \ - \ - _type imageLoad(BgfxRWImage3D_ ## _format _image, ivec3 _uvw) \ - { \ - return _image.m_texture[_uvw]._loadComponents; \ - } \ - \ - ivec3 imageSize(BgfxRWImage3D_ ## _format _image) \ - { \ - uvec3 result; \ - _image.m_texture.GetDimensions(result.x, result.y, result.z); \ - return ivec3(result); \ - } \ - \ - void imageStore(BgfxRWImage3D_ ## _format _image, ivec3 _uvw, _type _value) \ - { \ - _image.m_texture[_uvw] = _value._storeComponents; \ - } - -#define __IMAGE_IMPL_ATOMIC(_format, _storeComponents, _type, _loadComponents) \ - \ - void imageAtomicAdd(BgfxRWImage2D_ ## _format _image, ivec2 _uv, _type _value) \ - { \ - InterlockedAdd(_image.m_texture[_uv], _value._storeComponents); \ - } \ - - -__IMAGE_IMPL_A(rgba8, xyzw, vec4, xyzw) -__IMAGE_IMPL_A(rg8, xy, vec4, xyyy) -__IMAGE_IMPL_A(r8, x, vec4, xxxx) -__IMAGE_IMPL_A(rg16f, xy, vec4, xyyy) -#if BGFX_SHADER_LANGUAGE_HLSL -__IMAGE_IMPL_S(rgba16f, xyzw, vec4, xyzw) -__IMAGE_IMPL_S(r16f, x, vec4, xxxx) -__IMAGE_IMPL_S(rg32f, xy, vec4, xyyy) -#else -__IMAGE_IMPL_A(rgba16f, xyzw, vec4, xyzw) -__IMAGE_IMPL_A(r16f, x, vec4, xxxx) -__IMAGE_IMPL_A(rg32f, xy, vec4, xyyy) -#endif // BGFX_SHADER_LANGUAGE_HLSL -__IMAGE_IMPL_A(r32f, x, vec4, xxxx) -__IMAGE_IMPL_A(rgba32f, xyzw, vec4, xyzw) -__IMAGE_IMPL_A(r32ui, x, uvec4, xxxx) -__IMAGE_IMPL_A(rg32ui, xy, uvec4, xyyy) -__IMAGE_IMPL_A(rgba32ui, xyzw, uvec4, xyzw) - -__IMAGE_IMPL_ATOMIC(r32ui, x, uvec4, xxxx) - -#define atomicAdd(_mem, _data) InterlockedAdd(_mem, _data) -#define atomicAnd(_mem, _data) InterlockedAnd(_mem, _data) -#define atomicMax(_mem, _data) InterlockedMax(_mem, _data) -#define atomicMin(_mem, _data) InterlockedMin(_mem, _data) -#define atomicOr(_mem, _data) InterlockedOr(_mem, _data) -#define atomicXor(_mem, _data) InterlockedXor(_mem, _data) -#define atomicFetchAndAdd(_mem, _data, _original) InterlockedAdd(_mem, _data, _original) -#define atomicFetchAndAnd(_mem, _data, _original) InterlockedAnd(_mem, _data, _original) -#define atomicFetchAndMax(_mem, _data, _original) InterlockedMax(_mem, _data, _original) -#define atomicFetchAndMin(_mem, _data, _original) InterlockedMin(_mem, _data, _original) -#define atomicFetchAndOr(_mem, _data, _original) InterlockedOr(_mem, _data, _original) -#define atomicFetchAndXor(_mem, _data, _original) InterlockedXor(_mem, _data, _original) -#define atomicFetchAndExchange(_mem, _data, _original) InterlockedExchange(_mem, _data, _original) -#define atomicFetchCompareExchange(_mem, _compare, _data, _original) InterlockedCompareExchange(_mem,_compare, _data, _original) - -// InterlockedCompareStore - -#define barrier() GroupMemoryBarrierWithGroupSync() -#define memoryBarrier() GroupMemoryBarrierWithGroupSync() -#define memoryBarrierAtomicCounter() GroupMemoryBarrierWithGroupSync() -#define memoryBarrierBuffer() AllMemoryBarrierWithGroupSync() -#define memoryBarrierImage() GroupMemoryBarrierWithGroupSync() -#define memoryBarrierShared() GroupMemoryBarrierWithGroupSync() -#define groupMemoryBarrier() GroupMemoryBarrierWithGroupSync() - -#endif // BGFX_SHADER_LANGUAGE_GLSL - -#define dispatchIndirect( \ - _buffer \ - , _offset \ - , _numX \ - , _numY \ - , _numZ \ - ) \ - _buffer[(_offset)*2+0] = uvec4(_numX, _numY, _numZ, 0u) - -#define drawIndirect( \ - _buffer \ - , _offset \ - , _numVertices \ - , _numInstances \ - , _startVertex \ - , _startInstance \ - ) \ - _buffer[(_offset)*2+0] = uvec4(_numVertices, _numInstances, _startVertex, _startInstance) - -#define drawIndexedIndirect( \ - _buffer \ - , _offset \ - , _numIndices \ - , _numInstances \ - , _startIndex \ - , _startVertex \ - , _startInstance \ - ) \ - _buffer[(_offset)*2+0] = uvec4(_numIndices, _numInstances, _startIndex, _startVertex); \ - _buffer[(_offset)*2+1] = uvec4(_startInstance, 0u, 0u, 0u) - -#endif // __cplusplus - -#endif // BGFX_COMPUTE_H_HEADER_GUARD diff --git a/assets/shaders/forward_pipeline.sh b/assets/shaders/forward_pipeline.sh deleted file mode 100644 index 4344696..0000000 --- a/assets/shaders/forward_pipeline.sh +++ /dev/null @@ -1,94 +0,0 @@ -#include - -#define PI 3.14159265359 - -uniform vec4 uClock; // clock - -// Environment -uniform vec4 uFogColor; -uniform vec4 uFogState; // fog_near, 1.0/fog_range - -// Lighting environment -uniform vec4 uAmbientColor; - -uniform vec4 uLightPos[8]; // pos.xyz, 1.0/radius -uniform vec4 uLightDir[8]; // dir.xyz, inner_rim -uniform vec4 uLightDiffuse[8]; // diffuse.xyz, outer_rim -uniform vec4 uLightSpecular[8]; // specular.xyz, pssm_bias - -uniform mat4 uLinearShadowMatrix[4]; // slot 0: linear PSSM shadow matrices -uniform vec4 uLinearShadowSlice; // slot 0: PSSM slice distances linear light -uniform mat4 uSpotShadowMatrix; // slot 1: spot shadow matrix -uniform vec4 uShadowState; // slot 0: inverse resolution, slot1: inverse resolution, slot0: bias, slot1: bias - -uniform vec4 uResolution; // xy: backbuffer resolution -uniform vec4 uProjection; -uniform mat4 uMainProjection; // projection for the main render (used by screenspace post-processes) -uniform mat4 uMainInvProjection; // inverse projection for the main render (used by screenspace post-processes) - -uniform mat4 uPreviousViewProjection; -uniform mat4 uPreviousModel[BGFX_CONFIG_MAX_BONES]; -uniform mat4 uViewProjUnjittered; -uniform vec4 uAAAParams[2]; // [0].x: ssgi ratio, [0].y: ssr ratio, [0].z: temporal AA weight, [0].w: motion blur strength, [1].x: exposure, [1].y: 1/gamma, [1].z: sample count, [1].w: max radius - -uniform mat4 uMainInvView; // inversion view matrix - -#if FORWARD_PIPELINE_AAA -SAMPLER2D(uIrradianceMap, 8); -SAMPLER2D(uRadianceMap, 9); -#else -SAMPLERCUBE(uIrradianceMap, 8); -SAMPLERCUBE(uRadianceMap, 9); -#endif -SAMPLER2D(uBrdfMap, 10); -SAMPLER2D(uNoiseMap, 11); -SAMPLER2D(uAmbientOcclusion, 13); -SAMPLER2DSHADOW(uLinearShadowMap, 14); -SAMPLER2DSHADOW(uSpotShadowMap, 15); - -// -float sRGB2linear(float v) { - return (v < 0.04045) ? (v * 0.0773993808) : pow((v + 0.055) / 1.055, 2.4); -} - -vec3 sRGB2linear(vec3 v) { - return vec3(sRGB2linear(v.x), sRGB2linear(v.y), sRGB2linear(v.z)); -} - -// -mat3 MakeMat3(vec3 c0, vec3 c1, vec3 c2) { - return mat3(c0, c1, c2); -} - -vec3 GetT(mat4 m) { -#if BGFX_SHADER_LANGUAGE_GLSL - return vec3(m[3][0], m[3][1], m[3][2]); -#else - return vec3(m[0][3], m[1][3], m[2][3]); -#endif -} - -float LinearDepth(float z) { - return uProjection.w / (z - uProjection.z); -} - -// from screen space to view space -vec3 Unproject(vec3 frag_coord) { - vec4 clip = vec4(((frag_coord.xy - u_viewRect.xy) / u_viewRect.zw) * 2. - 1., frag_coord.z, 1.); - vec4 ndc = mul(clip, uMainInvProjection); - return ndc.xyz / ndc.w; -} - -vec3 ComputeFragCoordViewRay(vec2 frag_coord) -{ - vec2 sp = ((frag_coord - u_viewRect.xy) / u_viewRect.zw) * 2. - 1.; - sp.y *= -1.; - - vec4 ndc = mul(uMainInvProjection, vec4(sp, 1., 1.)); // far ndc frustum plane - ndc /= ndc.w; - ndc /= ndc.z; - - return ndc.xyz; -} - -bool isNan(float val) { return (val <= 0.0 || 0.0 <= val) ? false : true; } diff --git a/assets/shaders/hiz_trace.sh b/assets/shaders/hiz_trace.sh deleted file mode 100644 index 791d45f..0000000 --- a/assets/shaders/hiz_trace.sh +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef HIZ_TRACE_SH_HEADER_GUARD -#define HIZ_TRACE_SH_HEADER_GUARD - -// SAMPLER2D(u_depthTex, X); // input: minimum depth pyramid <= Must be declared by the user. - -uniform vec4 u_depthTexInfos; // width(x) heigh(y) start mipmap level(z) max mipmap level(w) - -vec3 intersect_cell_boundary(vec3 pos, vec3 dir, vec2 cell, vec2 cell_count, vec4 cross_step) { - vec2 planes = (cell + cross_step.xy) / cell_count; - vec3 intersection; - if(dir.x == 0.0) { - float delta = (planes.y - pos.y) / dir.y; - intersection = pos + dir * delta; - intersection.y += cross_step.w; - } - else if(dir.y == 0.0) { - float delta = (planes.x - pos.x) / dir.x; - intersection = pos + dir * delta; - intersection.x += cross_step.z; - } - else { - vec2 delta = (planes - pos.xy) / dir.xy; - intersection = pos + dir * min(delta.x, delta.y); - intersection.xy += (delta.x < delta.y) ? vec2(cross_step.z, 0.0) : vec2(0.0, cross_step.w); - } - return intersection; -} - -// returns the texture size in pixels for a given pyramid level. -// textureSize(sampler, level) should be used. -// Unfortunately bgfx directx implementation always returns the size of level 0. -vec2 mip_size(int level) { - return floor(u_depthTexInfos.xy / ((level != 0) ? exp2(level) : 1.0)); -} - -bool hiz_trace(vec3 ray_o, vec3 ray_d, mat4 proj, float z_near, int max_iterations, out vec3 ray) { - vec2 viewport_scale = uv_ratio.xy / u_depthTexInfos.xy; - vec3 viewport_min = vec3(u_viewRect.xy * viewport_scale, 0.); - vec3 viewport_max = vec3((u_viewRect.xy + u_viewRect.zw) * viewport_scale, 1.); - - int level_max = int(u_depthTexInfos.w); - int level_min = int(u_depthTexInfos.z); - ivec2 iterations = ivec2(0, level_min); - - vec2 cell_count = mip_size(level_min); - - // clip to the near plane - float ray_len = ((ray_o.z + ray_d.z * 1000.0) < z_near) ? (z_near - ray_o.z) / ray_d.z : 1000.0; - vec3 end_point = ray_o + ray_d * ray_len; - - // project into homogeneous clip space - vec4 h0 = mul(proj, vec4(ray_o, 1.)); - vec4 h1 = mul(proj, vec4(end_point, 1.)); - - // screen-space endpoints - vec3 p0 = h0.xyz / h0.w; - p0.y *= -1.; - p0.xy = NDCToViewRect(p0.xy) / cell_count.xy; - - vec3 p1 = h1.xyz / h1.w; - p1.y *= -1.; - p1.xy = NDCToViewRect(p1.xy) / cell_count.xy; - - // compute ray start position and direction in screen space - vec3 pos = p0; - vec3 dir = normalize(p1 - p0); - - if(dir.z == 0) { - ray = vec3(-1., -1., 0.); - return false; - } - - vec4 cross_step; - cross_step.xy = step(vec2_splat(0.0), dir.xy); - cross_step.zw = (2.0 * cross_step.xy - vec2_splat(1.0)) * vec2_splat(0.5) / cell_count.xy; - - vec2 cell = floor(pos.xy * cell_count); - pos.xy = cell / cell_count + vec2_splat(0.25) / cell_count.xy; - - ray = intersect_cell_boundary(pos, dir, cell, cell_count, cross_step); - - for(iterations.x = 0; (iterations.x < max_iterations) && (iterations.y >= 0); ++iterations.x, --iterations.y) { - // check if the ray goes out of the viewport. - if(any(lessThan(ray, viewport_min))) { - return false; - } - if(any(greaterThanEqual(ray, viewport_max))) { - return false; - } - cell_count = mip_size(iterations.y); - cell = floor(ray.xy * cell_count); - - vec2 z_interval = texelFetch(u_depthTex, ivec2(cell), iterations.y).xy; - - vec3 tmp = ray; - float dz = z_interval.x - ray.z; - if (dz > 0) { - tmp = ray + dz * sign(dir.z) * dir / dir.z; - } - else { - dz = ray.z - z_interval.y; - if (dz > 0) { - tmp = ray + dz * sign(dir.z) * dir / dir.z; - } - } - vec2 new_cell = floor(tmp.xy * cell_count); - if (any(notEqual(new_cell, cell))) { - tmp = intersect_cell_boundary(ray, dir, cell, cell_count, cross_step); - iterations.y = min(level_max, iterations.y + 2); - } - else if ((iterations.y == (level_min+1)) && (dz > 0.00001)) { - tmp = intersect_cell_boundary(ray, dir, cell, cell_count, cross_step); - iterations.y = 2; - } - - ray = tmp; - } - - return iterations.y < 0 && iterations.x < max_iterations; -} - -bool TraceScreenRay(vec3 ray_o, vec3 ray_d, mat4 proj, float z_near, int max_iterations, out vec2 hit_pixel, out vec3 hit_point) { - vec3 ray; - - if (hiz_trace(ray_o, ray_d, proj, z_near, max_iterations, ray)) { - // compute screen position of the hit pixel -#if BGFX_SHADER_LANGUAGE_GLSL - hit_pixel = vec2(ray.x, 1.0 - ray.y) * floor(uResolution.xy / uv_ratio); -#else - hit_pixel = ray.xy * floor(uResolution.xy / uv_ratio); -#endif - - // and its world space coordinates - hit_point = ray; - hit_point.xy = 2. * hit_point.xy - 1.; - hit_point.y *= -1.; - - vec4 p = mul(uMainInvProjection, vec4(hit_point, 1.)); - hit_point.xyz = p.xyz / p.w; - return true; - } else { - hit_pixel = vec2_splat(0.); - hit_point = vec3_splat(0.); - return false; - } -} - -#endif // HIZ_TRACE_SH_HEADER_GUARD