paint: use iris for neural nodes

This commit is contained in:
luboslenco
2026-06-18 12:42:54 +02:00
parent 56e4e6116c
commit 276af1e89d
17 changed files with 322 additions and 529 deletions
+56 -66
View File
@@ -13,9 +13,14 @@ const height_map: tex2d;
#[set(everything)]
const normal_map: tex2d;
const max_steps: float = 100.0;
const ray_step: float = 0.005;
const num_dirs: float = 64.0; // cosine-weighted hemisphere directions
const num_steps: float = 24.0; // height-field march steps per direction
const max_radius: float = 0.04; // search radius
const height_scale: float = 1.0;
const ao_bias: float = 0.0015; // ignore occluders within this height of the surface
const ao_max_diff: float = 0.3; // ignore occluders taller than this
const ao_power: float = 1.6; // contrast of the final occlusion
const PI2: float = 6.28318530718;
struct vert_in {
pos: float2;
@@ -34,44 +39,8 @@ fun depth_to_ao_pass_vert(input: vert_in): vert_out {
return output;
}
fun get_delta_height(hit_xy: float2, hit_z: float, uv: float2): float {
var coord: float2 = uv + hit_xy;
if (coord.x < 0.0 || coord.x > 1.0 || coord.y < 0.0 || coord.y > 1.0) {
return 1000.0;
}
var sampled: float = sample_lod(height_map, sampler_linear, coord, 0.0).r * height_scale;
return sampled - hit_z;
}
fun ray_cast(dir: float3, uv: float2, height: float): float {
var n_dir: float3 = normalize(dir);
var step_vec: float3 = n_dir * ray_step;
var hit_xy: float2 = float2(0.0, 0.0);
var hit_z: float = height + 0.001;
var hit_coord: float3 = float3(hit_xy, hit_z);
var prev_delta: float = get_delta_height(hit_xy, hit_z, uv);
var prev_t: float = 0.0;
hit_coord += step_vec;
var t: float = ray_step;
var i: int = 1;
while (i < int(max_steps)) {
var delta: float = get_delta_height(hit_coord.xy, hit_coord.z, uv);
if (delta > 0.0 && delta < 0.2) {
var prev_sdf: float = -prev_delta;
var sdf: float = -delta;
var fraction: float = prev_sdf / (prev_sdf - sdf);
return prev_t + ray_step * fraction;
}
if (t > 0.02) { // max_radius
return 0.02; // max_radius
}
prev_delta = delta;
prev_t = t;
hit_coord += step_vec;
t += ray_step;
i += 1;
}
return 0.02; // max_radius
fun hash(p: float2): float {
return frac(sin(dot(p, float2(12.9898, 78.233))) * 43758.5453);
}
fun tangent(n: float3): float3 {
@@ -83,37 +52,58 @@ fun tangent(n: float3): float3 {
return normalize(t2);
}
fun ao_ray(dir: float3, uv: float2, h0: float): float {
var step_size: float = max_radius / num_steps;
var t: float = step_size;
var i: int = 0;
while (i < int(num_steps)) {
var coord: float2 = uv + dir.xy * t;
if (coord.x < 0.0 || coord.x > 1.0 || coord.y < 0.0 || coord.y > 1.0) {
return 0.0; // walked off the map
}
var ray_z: float = h0 + dir.z * t;
var surf: float = sample_lod(height_map, sampler_linear, coord, 0.0).r * height_scale;
var delta: float = surf - ray_z;
if (delta > ao_bias && delta < ao_max_diff) {
return 1.0 - t / max_radius; // linear distance falloff
}
t += step_size;
i += 1;
}
return 0.0;
}
fun depth_to_ao_pass_frag(input: vert_out): float4 {
var height: float = sample_lod(height_map, sampler_linear, input.tex, 0.0).r * height_scale;
var normal: float3 = sample_lod(normal_map, sampler_linear, input.tex, 0.0).rgb * 2.0 - 1.0;
var n: float3 = normalize(normal);
var o1: float3 = tangent(n);
var o2: float3 = cross(o1, n);
var c1: float3 = 0.5 * (o1 + o2);
var c2: float3 = 0.5 * (o1 - o2);
var col: float = ray_cast(lerp3(n, o1, 0.5), input.tex, height);
col += ray_cast(lerp3(n, -o1, 0.5), input.tex, height);
col += ray_cast(lerp3(n, o2, 0.5), input.tex, height);
col += ray_cast(lerp3(n, -o2, 0.5), input.tex, height);
col += ray_cast(lerp3(n, c1, 0.5), input.tex, height);
col += ray_cast(lerp3(n, -c1, 0.5), input.tex, height);
col += ray_cast(lerp3(n, c2, 0.5), input.tex, height);
col += ray_cast(lerp3(n, -c2, 0.5), input.tex, height);
var d1: float3 = normalize(o1 + 0.5 * o2);
var d2: float3 = normalize(o1 - 0.5 * o2);
var d3: float3 = normalize(o2 + 0.5 * o1);
var d4: float3 = normalize(o2 - 0.5 * o1);
col += ray_cast(lerp3(n, d1, 0.5), input.tex, height);
col += ray_cast(lerp3(n, -d1, 0.5), input.tex, height);
col += ray_cast(lerp3(n, d2, 0.5), input.tex, height);
col += ray_cast(lerp3(n, -d2, 0.5), input.tex, height);
col += ray_cast(lerp3(n, d3, 0.5), input.tex, height);
col += ray_cast(lerp3(n, -d3, 0.5), input.tex, height);
col += ray_cast(lerp3(n, d4, 0.5), input.tex, height);
col += ray_cast(lerp3(n, -d4, 0.5), input.tex, height);
var f: float = (col / (16.0 * 0.02)); // max_radius
return float4(f, f, f, 1.0);
var t1: float3 = tangent(n);
var t2: float3 = cross(n, t1);
var jitter: float = hash(input.tex);
var h0: float = height + ao_bias;
var occ: float = 0.0;
var i: int = 0;
while (i < int(num_dirs)) {
// Cosine-weighted hemisphere sample
var u1: float = (float(i) + 0.5) / num_dirs;
var u2: float = frac(float(i) * 0.61803398875 + jitter);
var r: float = sqrt(u1);
var phi: float = PI2 * u2;
var lx: float = r * cos(phi);
var ly: float = r * sin(phi);
var lz: float = sqrt(max(0.0, 1.0 - u1));
var dir: float3 = lx * t1 + ly * t2 + lz * n;
occ += ao_ray(dir, input.tex, h0);
i += 1;
}
var ao: float = 1.0 - occ / num_dirs;
ao = pow(max(0.0, ao), ao_power);
return float4(ao, ao, ao, 1.0);
}
#[pipe]
+26 -26
View File
@@ -1,7 +1,7 @@
#[set(everything)]
const constants: {
empty: float4;
texel_size: float2;
};
#[set(everything)]
@@ -28,31 +28,31 @@ fun depth_to_normal_pass_vert(input: vert_in): vert_out {
}
fun depth_to_normal_pass_frag(input: vert_out): float4 {
var ts: float = 1.0 / 768.0;
var h00: float = sample_lod(height_map, sampler_linear, input.tex + float2(-2.0 * ts, -2.0 * ts), 0.0).r;
var h01: float = sample_lod(height_map, sampler_linear, input.tex + float2(-ts, -2.0 * ts), 0.0).r;
var h02: float = sample_lod(height_map, sampler_linear, input.tex + float2(0.0, -2.0 * ts), 0.0).r;
var h03: float = sample_lod(height_map, sampler_linear, input.tex + float2( ts, -2.0 * ts), 0.0).r;
var h04: float = sample_lod(height_map, sampler_linear, input.tex + float2( 2.0 * ts, -2.0 * ts), 0.0).r;
var h10: float = sample_lod(height_map, sampler_linear, input.tex + float2(-2.0 * ts, -ts), 0.0).r;
var h11: float = sample_lod(height_map, sampler_linear, input.tex + float2(-ts, -ts), 0.0).r;
var h12: float = sample_lod(height_map, sampler_linear, input.tex + float2(0.0, -ts), 0.0).r;
var h13: float = sample_lod(height_map, sampler_linear, input.tex + float2( ts, -ts), 0.0).r;
var h14: float = sample_lod(height_map, sampler_linear, input.tex + float2( 2.0 * ts, -ts), 0.0).r;
var h20: float = sample_lod(height_map, sampler_linear, input.tex + float2(-2.0 * ts, 0.0), 0.0).r;
var h21: float = sample_lod(height_map, sampler_linear, input.tex + float2(-ts, 0.0), 0.0).r;
var h23: float = sample_lod(height_map, sampler_linear, input.tex + float2( ts, 0.0), 0.0).r;
var h24: float = sample_lod(height_map, sampler_linear, input.tex + float2( 2.0 * ts, 0.0), 0.0).r;
var h30: float = sample_lod(height_map, sampler_linear, input.tex + float2(-2.0 * ts, ts), 0.0).r;
var h31: float = sample_lod(height_map, sampler_linear, input.tex + float2(-ts, ts), 0.0).r;
var h32: float = sample_lod(height_map, sampler_linear, input.tex + float2(0.0, ts), 0.0).r;
var h33: float = sample_lod(height_map, sampler_linear, input.tex + float2( ts, ts), 0.0).r;
var h34: float = sample_lod(height_map, sampler_linear, input.tex + float2( 2.0 * ts, ts), 0.0).r;
var h40: float = sample_lod(height_map, sampler_linear, input.tex + float2(-2.0 * ts, 2.0 * ts), 0.0).r;
var h41: float = sample_lod(height_map, sampler_linear, input.tex + float2(-ts, 2.0 * ts), 0.0).r;
var h42: float = sample_lod(height_map, sampler_linear, input.tex + float2(0.0, 2.0 * ts), 0.0).r;
var h43: float = sample_lod(height_map, sampler_linear, input.tex + float2( ts, 2.0 * ts), 0.0).r;
var h44: float = sample_lod(height_map, sampler_linear, input.tex + float2( 2.0 * ts, 2.0 * ts), 0.0).r;
var ts: float2 = constants.texel_size;
var h00: float = sample_lod(height_map, sampler_linear, input.tex + float2(-2.0, -2.0) * ts, 0.0).r;
var h01: float = sample_lod(height_map, sampler_linear, input.tex + float2(-1.0, -2.0) * ts, 0.0).r;
var h02: float = sample_lod(height_map, sampler_linear, input.tex + float2( 0.0, -2.0) * ts, 0.0).r;
var h03: float = sample_lod(height_map, sampler_linear, input.tex + float2( 1.0, -2.0) * ts, 0.0).r;
var h04: float = sample_lod(height_map, sampler_linear, input.tex + float2( 2.0, -2.0) * ts, 0.0).r;
var h10: float = sample_lod(height_map, sampler_linear, input.tex + float2(-2.0, -1.0) * ts, 0.0).r;
var h11: float = sample_lod(height_map, sampler_linear, input.tex + float2(-1.0, -1.0) * ts, 0.0).r;
var h12: float = sample_lod(height_map, sampler_linear, input.tex + float2( 0.0, -1.0) * ts, 0.0).r;
var h13: float = sample_lod(height_map, sampler_linear, input.tex + float2( 1.0, -1.0) * ts, 0.0).r;
var h14: float = sample_lod(height_map, sampler_linear, input.tex + float2( 2.0, -1.0) * ts, 0.0).r;
var h20: float = sample_lod(height_map, sampler_linear, input.tex + float2(-2.0, 0.0) * ts, 0.0).r;
var h21: float = sample_lod(height_map, sampler_linear, input.tex + float2(-1.0, 0.0) * ts, 0.0).r;
var h23: float = sample_lod(height_map, sampler_linear, input.tex + float2( 1.0, 0.0) * ts, 0.0).r;
var h24: float = sample_lod(height_map, sampler_linear, input.tex + float2( 2.0, 0.0) * ts, 0.0).r;
var h30: float = sample_lod(height_map, sampler_linear, input.tex + float2(-2.0, 1.0) * ts, 0.0).r;
var h31: float = sample_lod(height_map, sampler_linear, input.tex + float2(-1.0, 1.0) * ts, 0.0).r;
var h32: float = sample_lod(height_map, sampler_linear, input.tex + float2( 0.0, 1.0) * ts, 0.0).r;
var h33: float = sample_lod(height_map, sampler_linear, input.tex + float2( 1.0, 1.0) * ts, 0.0).r;
var h34: float = sample_lod(height_map, sampler_linear, input.tex + float2( 2.0, 1.0) * ts, 0.0).r;
var h40: float = sample_lod(height_map, sampler_linear, input.tex + float2(-2.0, 2.0) * ts, 0.0).r;
var h41: float = sample_lod(height_map, sampler_linear, input.tex + float2(-1.0, 2.0) * ts, 0.0).r;
var h42: float = sample_lod(height_map, sampler_linear, input.tex + float2( 0.0, 2.0) * ts, 0.0).r;
var h43: float = sample_lod(height_map, sampler_linear, input.tex + float2( 1.0, 2.0) * ts, 0.0).r;
var h44: float = sample_lod(height_map, sampler_linear, input.tex + float2( 2.0, 2.0) * ts, 0.0).r;
var dx: float = 2.0 * (h00 - h04) + 1.0 * (h01 - h03)
+ 3.0 * (h10 - h14) + 2.0 * (h11 - h13)
+ 4.0 * (h20 - h24) + 3.0 * (h21 - h23)