diff options
| author | yum <yum.food.vr@gmail.com> | 2024-11-02 18:10:15 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2024-11-02 18:15:00 -0700 |
| commit | 33209b34e2d6b9af2fbc3cd0886a3eb76479a9d2 (patch) | |
| tree | 4b71ad4676e16fa412b706b8563f8e8740e4d246 | |
| parent | 76af070567daeb845cabbf9a414cf487b88c12f9 (diff) | |
Fog uses interleaved gradient noise instead of white noise
This lets us use a much higher step size before noise becomes too gross
to look at.
| -rw-r--r-- | atrix256.cginc | 37 | ||||
| -rw-r--r-- | fog.cginc | 36 | ||||
| -rw-r--r-- | math.cginc | 5 | ||||
| -rw-r--r-- | pbr.cginc | 1 |
4 files changed, 68 insertions, 11 deletions
diff --git a/atrix256.cginc b/atrix256.cginc new file mode 100644 index 0000000..5236715 --- /dev/null +++ b/atrix256.cginc @@ -0,0 +1,37 @@ +#ifndef __ATRIX256_INC +#define __ATRIX256_INC +/* +MIT License + +Copyright (c) 2021 Alan Wolfe + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +// Interleaved gradient noise. +// ported from this repo: https://github.com/Atrix256/IGNLDS +// blog post: https://blog.demofox.org/2017/10/31/animating-noise-for-integration-over-time +float ign(float2 screen_px) { + return fmod(52.9829189 * + fmod(0.06711056 * screen_px.x + + 0.00583715 * screen_px.y, 1), 1); +} + +#endif // __ATRIX256_INC + @@ -1,3 +1,4 @@ +#include "atrix256.cginc" #include "cnlohr.cginc" #include "globals.cginc" #include "interpolators.cginc" @@ -126,8 +127,10 @@ Fog00PBR getFog00(v2f i) { float3 rd = normalize(obj_pos - cam_pos); float3 ro = cam_pos; + const bool inside_sphere = length(ro) < _Gimmick_Fog_00_Radius; bool no_intersection = false; - if (length(ro) > _Gimmick_Fog_00_Radius) { + float distance_to_sphere = 1E6; + { float3 l = ro; float a = 1; float b = 2 * dot(rd, l); @@ -135,25 +138,36 @@ Fog00PBR getFog00(v2f i) { float t0, t1; if (solveQuadratic(a, b, c, t0, t1)) { no_intersection = (t0 < 0) * (t1 < 0); - ro += min(max(t0, 0), max(t1, 0)) * rd; - } else { - no_intersection = true; + if (inside_sphere) { + distance_to_sphere = no_intersection ? distance_to_sphere : max(t0, t1); + distance_to_sphere = min(distance_to_sphere, length(world_pos_depth_hit - ro)); + } else { + distance_to_sphere = no_intersection ? distance_to_sphere : min(max(t0, 0), max(t1, 0)); + ro += distance_to_sphere * rd; + distance_to_sphere = max(distance_to_sphere, length(world_pos_depth_hit - ro)); + } } } - // Factor of 10 on `screen_uv*10` eliminates visible striping artifact that - // is visible with no factor. - float step_size = _Gimmick_Fog_00_Step_Size_Factor; + float density_ss_term = 1 / _Gimmick_Fog_00_Density; + density_ss_term = dmin(density_ss_term, 3.00, 5); + density_ss_term = dmax(density_ss_term, 0.33, 5); + float step_size = _Gimmick_Fog_00_Step_Size_Factor * density_ss_term; step_size = clamp(step_size, 1E-2, 10); - int2 screen_uv_round = floor(screen_uv * _ScreenParams.xy); + uint2 screen_uv_round = floor(screen_uv * _ScreenParams.xy); +#if 1 + float dither_seed = ign(screen_uv_round); +#else float dither_seed = rand2(float2(screen_uv_round.x, screen_uv_round.y)*.001); +#endif +#if 0 // Smoothly vary over time. Use a triangle wave since it distributes points // evenly. A sin wave would bunch points up at boundaries. - #if 1 + // TODO over time this integrates to white noise. Should we use blue noise? dither_seed = frac(dither_seed + _Time[0]*2); dither_seed *= 2; // Map onto [0, 2] dither_seed = abs(dither_seed - 1); // Shape into triangle wave ranging from 0 to 1 - #endif +#endif float dither = dither_seed * step_size * _Gimmick_Fog_00_Ray_Origin_Randomization; ro += rd * (0.1 + dither); @@ -164,7 +178,7 @@ Fog00PBR getFog00(v2f i) { _Gimmick_Fog_00_Max_Ray / step_size, world_pos_depth_hit_l / step_size)); step_count *= (1 - no_intersection); -#define FOG_MAX_LOOP 128 +#define FOG_MAX_LOOP (128+16) step_count = min(step_count, FOG_MAX_LOOP); #if defined(_GIMMICK_FOG_00_EMITTER_TEXTURE) @@ -13,6 +13,11 @@ // At w=1, this returns n1. #define MY_BLEND_NORMALS(n0, n1, w) normalize(float3((n0.xy * (1 - w) + n1.xy * w), lerp(1, n0.z, (1-w)) * lerp(1, n1.z, w))) +float golden_lds(uint i) +{ + return glsl_mod(1.61803398875 * float(i), 1); +} + // Complex numbers typedef float2 complex; @@ -1,3 +1,4 @@ +#include "atrix256.cginc" #include "globals.cginc" #include "filament_math.cginc" #include "globals.cginc" |
