diff options
| author | yum <yum.food.vr@gmail.com> | 2026-03-15 19:09:49 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2026-03-15 19:09:49 -0700 |
| commit | a00d67b75318d61c56446ecd90f98ce4c914ebfe (patch) | |
| tree | 031c39e19c0bb547bc0221bb7fdea9a1fede6dc6 /pbr.cginc | |
| parent | cacacf83fc033f5865703ee8680bd82a00667d21 (diff) | |
Add "kintsugi" effect - 3D voronoi boundary compositing
Diffstat (limited to 'pbr.cginc')
| -rwxr-xr-x | pbr.cginc | 68 |
1 files changed, 63 insertions, 5 deletions
@@ -126,8 +126,6 @@ void apply_marble(float3 world_pos, inout float3 albedo) { #if defined(_MARBLE) float3 uvw = world_pos * _Marble_Scale; - float3 noises[10]; - float3 noise = 0; float gain = 1; @@ -142,8 +140,7 @@ void apply_marble(float3 world_pos, inout float3 albedo) { uvw += offset; for (uint ii = 0; ii < _Marble_Octaves; ++ii) { - noises[ii] = _Marble_Noise.Sample(aniso4_trilinear_repeat_s, uvw + noise * _Marble_Strength).rgb * gain; - noise += noises[ii]; + noise += _Marble_Noise.Sample(aniso4_trilinear_repeat_s, uvw + noise * _Marble_Strength).rgb * gain; uvw *= _Marble_Lacunarity; gain *= _Marble_Gain; @@ -158,6 +155,65 @@ void apply_marble(float3 world_pos, inout float3 albedo) { #endif } +float3 kintsugi_hash33(float3 p) { + p = frac(p * float3(0.1031, 0.1030, 0.0973)); + p += dot(p, p.yxz + 33.33); + return frac((p.xxy + p.yxx) * p.zyx); +} + +float kintsugi_voronoi_edge(float3 x) { + float3 p = floor(x); + float3 f = frac(x); + float d1 = 8.0; + float d2 = 8.0; + float3 p1 = 0; + float3 p2 = 0; + + for (int k = -1; k <= 1; k++) { + for (int j = -1; j <= 1; j++) { + for (int i = -1; i <= 1; i++) { + float3 b = float3(i, j, k); + float3 r = b + kintsugi_hash33(p + b) - f; + float d = dot(r, r); + if (d < d1) { + d2 = d1; + p2 = p1; + d1 = d; + p1 = r; + } else if (d < d2) { + d2 = d; + p2 = r; + } + } + } + } + return (d2 - d1) / (2.0 * max(0.0001, length(p2 - p1))); +} + +void apply_kintsugi(float3 world_pos, inout float3 albedo, inout float smoothness, inout float metallic) { +#if defined(_KINTSUGI) + float3 uvw = world_pos * _Kintsugi_Scale; + +#if defined(_KINTSUGI_PROCEDURAL) + float mask = kintsugi_voronoi_edge(uvw) + 0.5f; +#else + float mask = _Kintsugi_Noise.Sample(aniso4_trilinear_repeat_s, uvw); +#endif + + float width = max(fwidth(mask) * 0.5f, _Kintsugi_Width); + float threshold = _Kintsugi_Threshold; + mask = smoothstep(threshold - width, threshold + width, mask); + +#if defined(_KINTSUGI_NOISE_INVERT) + mask = 1.0f - mask; +#endif // _KINTSUGI_NOISE_INVERT + + albedo = lerp(albedo, _Kintsugi_Color, mask); + smoothness = lerp(smoothness, _Kintsugi_Smoothness, mask); + metallic = lerp(metallic, _Kintsugi_Metallic, mask); +#endif // _KINTSUGI +} + Pbr getPbr(v2f i) { Pbr pbr = (Pbr) 0; @@ -183,7 +239,6 @@ Pbr getPbr(v2f i) { pbr.albedo = _MainTex.Sample(aniso4_trilinear_repeat_s, uv_parallax * _MainTex_ST.xy + _MainTex_ST.zw); pbr.albedo *= _Color; #endif - apply_marble(i.worldPos, pbr.albedo.xyz); float3 normal_tangent = UnpackNormal(_BumpMap.Sample(aniso4_trilinear_repeat_s, uv_parallax * _BumpMap_ST.xy)); normal_tangent.xy *= _BumpScale; @@ -201,6 +256,9 @@ Pbr getPbr(v2f i) { pbr.smoothness = metallic_gloss.a * _Glossiness; pbr.metallic = metallic_gloss.r * _Metallic; + apply_marble(i.worldPos, pbr.albedo.xyz); + apply_kintsugi(i.worldPos, pbr.albedo.xyz, pbr.smoothness, pbr.metallic); + applyDecals(i, pbr, normal_tangent); pbr.normal = normalize(mul(normal_tangent, pbr.tbn)); |
