summaryrefslogtreecommitdiffstats
path: root/pbr.cginc
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2026-03-15 19:09:49 -0700
committeryum <yum.food.vr@gmail.com>2026-03-15 19:09:49 -0700
commita00d67b75318d61c56446ecd90f98ce4c914ebfe (patch)
tree031c39e19c0bb547bc0221bb7fdea9a1fede6dc6 /pbr.cginc
parentcacacf83fc033f5865703ee8680bd82a00667d21 (diff)
Add "kintsugi" effect - 3D voronoi boundary compositing
Diffstat (limited to 'pbr.cginc')
-rwxr-xr-xpbr.cginc68
1 files changed, 63 insertions, 5 deletions
diff --git a/pbr.cginc b/pbr.cginc
index dcb94c8..cc566b4 100755
--- a/pbr.cginc
+++ b/pbr.cginc
@@ -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));