diff options
| -rw-r--r-- | Editor/tooner.cs | 17 | ||||
| -rw-r--r-- | feature_macros.cginc | 1 | ||||
| -rw-r--r-- | fog.cginc | 122 | ||||
| -rw-r--r-- | globals.cginc | 6 | ||||
| -rw-r--r-- | math.cginc | 1 | ||||
| -rw-r--r-- | oklab.cginc | 2 | ||||
| -rw-r--r-- | pbr.cginc | 32 | ||||
| -rw-r--r-- | tooner.shader | 3 |
8 files changed, 159 insertions, 25 deletions
diff --git a/Editor/tooner.cs b/Editor/tooner.cs index 0163e85..fdd81b0 100644 --- a/Editor/tooner.cs +++ b/Editor/tooner.cs @@ -2142,6 +2142,23 @@ public class ToonerGUI : ShaderGUI { EditorGUI.indentLevel -= 1; } + bc = FindProperty("_Gimmick_Fog_00_Ray_March_0_Enable_Static"); + enabled = (bc.floatValue != 0.0); + EditorGUI.BeginChangeCheck(); + enabled = Toggle("Ray march effect 0", enabled); + EditorGUI.EndChangeCheck(); + bc.floatValue = enabled ? 1.0f : 0.0f; + SetKeyword("_GIMMICK_FOG_00_RAY_MARCH_0", enabled); + + if (enabled) { + EditorGUI.indentLevel += 1; + + bc = FindProperty("_Gimmick_Fog_00_Ray_March_0_Seed"); + FloatProperty(bc, "Seed"); + + EditorGUI.indentLevel -= 1; + } + EditorGUI.indentLevel -= 1; } diff --git a/feature_macros.cginc b/feature_macros.cginc index 4724d12..6865208 100644 --- a/feature_macros.cginc +++ b/feature_macros.cginc @@ -214,6 +214,7 @@ #pragma shader_feature_local _ _GIMMICK_FOG_00_EMITTER_TEXTURE #pragma shader_feature_local _ _GIMMICK_FOG_00_EMITTER_1 #pragma shader_feature_local _ _GIMMICK_FOG_00_EMITTER_2 +#pragma shader_feature_local _ _GIMMICK_FOG_00_RAY_MARCH_0 #pragma shader_feature_local _ _UNITY_FOG #pragma shader_feature_local _ _GIMMICK_AURORA #pragma shader_feature_local _ _GIMMICK_GERSTNER_WATER @@ -4,6 +4,8 @@ #include "interpolators.cginc" #include "math.cginc" #include "noise.cginc" +#include "oklab.cginc" +#include "poi.cginc" #ifndef __FOG_INC #define __FOG_INC @@ -29,34 +31,42 @@ struct Fog00PBR { float perlin_noise_3d_tex(float3 p) { // 1/256 = 0.00390625 - float r_lo = _Gimmick_Fog_00_Noise.SampleLevel(linear_repeat_s, p.xyz * 0.00390625, 0); + float r_lo = _Gimmick_Fog_00_Noise.SampleLevel(trilinear_repeat_s, p.xyz * 0.00390625, 0); return r_lo; } float map(float3 p, float lod) { - float3 t = _Time[1] * _Gimmick_Fog_00_Noise_Scale * FOG_PERLIN_NOISE_SCALE; + float3 t = _Time[1] * FOG_PERLIN_NOISE_SCALE * .2; #define RADIUS_TRANS_WIDTH 100 #define RADIUS_TRANS_WIDTH_RCP (1.0 / RADIUS_TRANS_WIDTH) // Try to create a smooth transition without doing any length() or other // transcendental ops. float radius2 = clamp(_Gimmick_Fog_00_Radius * _Gimmick_Fog_00_Radius - dot(p, p), 0, RADIUS_TRANS_WIDTH) * RADIUS_TRANS_WIDTH_RCP; - float3 pp = p * _Gimmick_Fog_00_Noise_Scale * FOG_PERLIN_NOISE_SCALE + t; - float density = FOG_PERLIN_NOISE(pp) * radius2 * 0.7; + float3 pp = p * _Gimmick_Fog_00_Noise_Scale * FOG_PERLIN_NOISE_SCALE; + float density = FOG_PERLIN_NOISE(pp+t) * radius2 * 0.7; +#if 1 + // Add higher octaves + density += FOG_PERLIN_NOISE(pp*4+t*1.5) * radius2 * 0.3; + density += FOG_PERLIN_NOISE(pp*16+t*2.0) * radius2 * 0.15; +#endif + density *= density; + density *= 2; // Exponentiate to increase contrast. - density *= density; + //density *= density; // density had an expected value of 0.5. We just calculated pow(density, 2), // thus the new expected value is pow(0.5, ^ 2) = 1/4. Scale it to restore // the original EV. - density *= 2; - density = saturate(density); + //density *= 2; + //density = saturate(density); // This term creates large open areas. // This `if` doesn't actually create any thread divergence. Since all rays // shoot out in lock step, they all leave this mode at the same time. // Also, completely disable the term at high densities since those tend to be // slow (more computationally expensive) anyway. +#if 0 if (lod == 0 && _Gimmick_Fog_00_Noise_Scale < 2) { float tmp = FOG_PERLIN_NOISE(pp * 0.167 + t/4) * radius2 - 0.5; // Aggressively dial down this parameter as density increases. We really @@ -66,6 +76,7 @@ float map(float3 p, float lod) { tmp *= 0.5 * density_performance_fix; density += tmp; } +#endif return saturate(density); } @@ -81,7 +92,7 @@ float3 getEmitterData(float3 p, // Project onto plane const float3 p_to_emitter = p - em_loc; const float t = dot(p_to_emitter, em_normal); - const float3 p_projected = p - t * em_normal - em_loc; + float3 p_projected = p - t * em_normal - em_loc; // Add some curvature to simulate scattering. //emitter_scale *= 1 + t*t * .002; @@ -95,6 +106,13 @@ float3 getEmitterData(float3 p, float2 emitter_uv = clamp(p_projected.xy, -emitter_scale, emitter_scale) * emitter_scale_rcp; emitter_uv *= 0.5; emitter_uv += 0.5; + +#if 0 + emitter_uv.y = FOG_PERLIN_NOISE(float3(emitter_uv*100, _Time[2])); + emitter_uv.x = FOG_PERLIN_NOISE(p); + emitter_uv.y = FOG_PERLIN_NOISE(float3(emitter_uv*100, _Time[2])); +#endif + float emitter_lod = floor(abs(t) / (_Gimmick_Fog_00_Emitter_Lod_Half_Life * step_size)); float3 em_color = _Gimmick_Fog_00_Emitter_Texture.SampleLevel(linear_repeat_s, emitter_uv, emitter_lod); em_color *= _Gimmick_Fog_00_Emitter_Brightness; @@ -104,6 +122,65 @@ float3 getEmitterData(float3 p, } #endif // defined(_GIMMICK_FOG_00_EMITTER_TEXTURE) +#if defined(_GIMMICK_FOG_00_RAY_MARCH_0) +float fog00_map(float3 p, float rid_entropy) +{ + float sin_term = sin(rid_entropy*2*TAU+_Time[0]*2)+1.0; + sin_term *= sin_term; + return length(p)+1.5-rid_entropy*2.3* + sin_term*.2; +} +float fog00_map_dr( + float3 p, + float3 period, + float3 count, + float seed, + out float3 which + ) +{ + p -= float3(0, period.y * floor(count.y/2) + 1, 0); + p -= unity_ObjectToWorld._m03_m13_m23; + + which = round(p / period); + // Direction to nearest neighboring cell. + float3 min_d = p - period * which; + float3 o = sign(min_d); + + float d = 1E9; + float3 which_tmp = which; +#if 0 + for (uint xi = 0; xi < 1; xi++) + for (uint yi = 0; yi < 2; yi++) + for (uint zi = 0; zi < 1; zi++) +#else + uint xi = 0; + uint yi = 0; + uint zi = 0; +#endif + { + float3 rid = which + float3(xi, yi, zi) * o; + rid = clamp(rid, ceil(-(count)*0.5), floor((count-1)*0.5)); + float3 r = p - period * rid; + float3 rid_entropy = float3( + ign(rid.yz+seed), + ign(rid.xz+seed), + ign(rid.xy+seed)); + float3 random_dir = normalize(rid_entropy); + r += + (sin(_Time[0] * 2 + (rid_entropy.x + rid_entropy.y + rid_entropy.z) * TAU * .6666) * 2 - 1.0) * + period * 0.5 * + random_dir * + float3(.1, .1, .1) * .3; + float cur_d = fog00_map(r, rand3((rid+seed)/100)); + which_tmp = cur_d < d ? rid : which_tmp; + d = min(d, cur_d); + } + + which = which_tmp; + return d; +} +#endif + Fog00PBR getFog00(v2f i) { float3 cam_pos = _WorldSpaceCameraPos; @@ -169,7 +246,7 @@ Fog00PBR getFog00(v2f i) { dither_seed = abs(dither_seed - 1); // Shape into triangle wave ranging from 0 to 1 #endif float dither = dither_seed * step_size * _Gimmick_Fog_00_Ray_Origin_Randomization; - ro += rd * (0.1 + dither); + ro += rd * (0.03 + dither); float world_pos_depth_hit_l = length(world_pos_depth_hit - ro); @@ -204,6 +281,33 @@ Fog00PBR getFog00(v2f i) { #if defined(_GIMMICK_FOG_00_EMITTER_TEXTURE) c.rgb = getEmitterData(p, step_size, em_loc, em_normal, em_scale, em_scale_rcp) * step_size; #endif +#if defined(_GIMMICK_FOG_00_RAY_MARCH_0) + { + float3 period = 3; + float3 count = 7; + float3 which; + float seed = _Gimmick_Fog_00_Ray_March_0_Seed; + float d = fog00_map_dr(p, period, count, seed, which); + int which_flat = + which.x * count.y * count.z + + which.y * count.z + + which.z; + float d_falloff = saturate(rcp(max(pow(d, 16), 1E-6))); + float brightness = step_size * .5; +#if 1 + float3 cur_c_oklch; + cur_c_oklch[0] = 0.3 + FOG_PERLIN_NOISE(which*100 + _Time[3]*2.3) * 0.9; + cur_c_oklch[1] = .15; + cur_c_oklch[2] = 0; + //cur_c_oklch[2] = glsl_mod(ign(which_flat) * TAU + _Time[0], TAU); + c.rgb += OKLCHtoLRGB(cur_c_oklch) * d_falloff * brightness; +#else + float3 cur_c_hsv = float3(glsl_mod(ign(which_flat) + _Time[0], 1), .7, 1); + c.rgb += HSVtoRGB(cur_c_hsv) * d_falloff * brightness; +#endif + c.a *= saturate(d_falloff); + } +#endif acc += c * (1.0 - acc.a); diff --git a/globals.cginc b/globals.cginc index 8f29bc1..76f6fa0 100644 --- a/globals.cginc +++ b/globals.cginc @@ -10,6 +10,8 @@ SamplerState linear_repeat_s; SamplerState linear_clamp_s; SamplerState bilinear_repeat_s; SamplerState bilinear_clamp_s; +SamplerState trilinear_repeat_s; +SamplerState trilinear_clamp_s; float4 _Color; float _Metallic; @@ -790,5 +792,9 @@ float4 _Gimmick_Gerstner_Water_Color_Ramp_Mask1; #endif #endif +#if defined(_GIMMICK_FOG_00_RAY_MARCH_0) +float _Gimmick_Fog_00_Ray_March_0_Seed; +#endif + #endif @@ -5,6 +5,7 @@ #define PI 3.14159265 #define TAU PI * 2.0 +#define PHI 1.618033989 // Hacky parameterizable whiteout blending. Probably some big mistakes but it // passes the eyeball test. diff --git a/oklab.cginc b/oklab.cginc index f35d634..337eb94 100644 --- a/oklab.cginc +++ b/oklab.cginc @@ -29,7 +29,7 @@ #ifndef __OKLAB_INC #define __OKLAB_INC -#if defined(_OKLAB) || defined(_GIMMICK_LETTER_GRID_COLOR_WAVE) || defined(_GIMMICK_AL_CHROMA_00_HUE_SHIFT) +#if defined(_OKLAB) || defined(_GIMMICK_LETTER_GRID_COLOR_WAVE) || defined(_GIMMICK_AL_CHROMA_00_HUE_SHIFT) || defined(_GIMMICK_FOG_00_RAY_MARCH_0) // Utilities relating to the OKLAB color space, as defined here: // https://bottosson.github.io/posts/oklab/ @@ -347,21 +347,6 @@ float4 getLitColor( screenPos = float4(i.screenPos, 0, i.pos.w); #endif -// TODO optimize this -// Break up color banding by adding some dithering to direct light. -{ - float2 screen_uv; - { - float3 full_vec_eye_to_geometry = i.worldPos - _WorldSpaceCameraPos; - float3 world_dir = normalize(i.worldPos - _WorldSpaceCameraPos); - float perspective_divide = 1.0 / i.pos.w; - float perspective_factor = length(full_vec_eye_to_geometry * perspective_divide); - screen_uv = i.screenPos.xy * perspective_divide; - } - uint2 screen_uv_round = floor(screen_uv * _ScreenParams.xy); - direct_light.color += ign(screen_uv_round) * 0.00390625; -} - #if 1 float reflection_strength = _ReflectionStrength; #if defined(_REFLECTION_STRENGTH_TEX) @@ -404,6 +389,23 @@ float4 getLitColor( indirect_light).xyz; #endif + // TODO optimize this and formalize with parameters + // Break up color banding by adding some dithering to shaded color. + float screen_dither; + { + float2 screen_uv; + { + float3 full_vec_eye_to_geometry = i.worldPos - _WorldSpaceCameraPos; + float3 world_dir = normalize(i.worldPos - _WorldSpaceCameraPos); + float perspective_divide = 1.0 / i.pos.w; + float perspective_factor = length(full_vec_eye_to_geometry * perspective_divide); + screen_uv = i.screenPos.xy * perspective_divide; + } + uint2 screen_uv_round = floor(screen_uv * _ScreenParams.xy); + screen_dither = ign(screen_uv_round) * 0.00390625; + } + pbr += screen_dither; + #if defined(_CLEARCOAT) // Direct lighting // TODO add keywords to optimize away mask samples when not used diff --git a/tooner.shader b/tooner.shader index c33320f..05ea499 100644 --- a/tooner.shader +++ b/tooner.shader @@ -668,6 +668,9 @@ Shader "yum_food/tooner" _Gimmick_Fog_00_Emitter2_Scale_X("fog", Float) = 1 _Gimmick_Fog_00_Emitter2_Scale_Y("fog", Float) = 1 + _Gimmick_Fog_00_Ray_March_0_Enable_Static("enable ray march effect 0", Float) = 0 + _Gimmick_Fog_00_Ray_March_0_Seed("seed", Float) = 0 + _Gimmick_Aurora_Enable_Static("Enable aurora", Float) = 0 _Gimmick_Gerstner_Water_Enable_Static("Enable water (gerstner)", Float) = 0 |
