mirror of
https://github.com/Nexoniarz/Fry3DX.git
synced 2026-11-03 20:44:26 +00:00
Shapes with live settings, shape editing, knife and hole tools, drawing shapes onto other objects, combining objects (add / subtract / overlap), copies, thickness, painting with stickers and layers, a Layout tab, a Print tab with checks, packed .fry files with autosave, export to GLB, glTF, FBX, OBJ, 3MF, STL and PLY, folders in Layers, its own crash screen, and a website for GitHub Pages in docs/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NMSrd5oe1GpUD7E6d825KP
82 lines
3.7 KiB
GLSL
82 lines
3.7 KiB
GLSL
#version 460
|
|
// Screen-space reflections (half resolution): from each pixel, the view ray mirrored about its
|
|
// normal (the mesh pass's G-buffer) is marched through view space against the depth buffer;
|
|
// on a hit (refined by bisection) it takes this frame's lit scene there. Fades with roughness,
|
|
// distance, the screen's edges and rays towards the camera, so it blends into the sky and
|
|
// probe reflections the mesh pass already gave. TAA (or the tonemap) adds it to the scene.
|
|
// Rows are the targets' own (uv from gl_FragCoord), on both backends.
|
|
#define KEEL_POST // screen-space: render targets, sampled clamped
|
|
#include "backend.glsl"
|
|
PUSH_BLOCK {
|
|
uint depth, gbuf, scene;
|
|
uint w, h; // full size
|
|
uint outW, outH; // this target's
|
|
float strength;
|
|
vec4 proj; // tan(half fov x), tan(half fov y), near, far
|
|
} pc;
|
|
layout(location = 0) out vec4 o_ssr;
|
|
|
|
float viewZ(vec2 uv) {
|
|
ivec2 p = clamp(ivec2(uv * vec2(pc.w, pc.h)), ivec2(0), ivec2(pc.w - 1, pc.h - 1));
|
|
float d = fetchTex(pc.depth, p).r;
|
|
return d >= 1.0 ? 1e9 : pc.proj.z * pc.proj.w / (pc.proj.w - d * (pc.proj.w - pc.proj.z));
|
|
}
|
|
vec3 viewPos(vec2 uv) { // across the screen from the centre of the pixel its depth came from (as ssao.frag)
|
|
float z = viewZ(uv);
|
|
ivec2 p = clamp(ivec2(uv * vec2(pc.w, pc.h)), ivec2(0), ivec2(pc.w - 1, pc.h - 1));
|
|
vec2 at = (vec2(p) + 0.5) / vec2(pc.w, pc.h);
|
|
return vec3((at * 2.0 - 1.0) * pc.proj.xy * z, z);
|
|
}
|
|
vec2 toUv(vec3 v) { return v.xy / (v.z * pc.proj.xy) * 0.5 + 0.5; }
|
|
vec3 octDecode(vec2 e) {
|
|
e = e * 2.0 - 1.0;
|
|
vec3 n = vec3(e, 1.0 - abs(e.x) - abs(e.y));
|
|
if (n.z < 0.0) n.xy = (1.0 - abs(n.yx)) * vec2(n.x >= 0.0 ? 1.0 : -1.0, n.y >= 0.0 ? 1.0 : -1.0);
|
|
return normalize(n);
|
|
}
|
|
|
|
void main() {
|
|
vec2 uv = gl_FragCoord.xy / vec2(pc.outW, pc.outH);
|
|
o_ssr = vec4(0.0);
|
|
vec4 g = fetchTex(pc.gbuf, clamp(ivec2(uv * vec2(pc.w, pc.h)), ivec2(0), ivec2(pc.w - 1, pc.h - 1)));
|
|
float rough = g.z, weight = g.w;
|
|
if (weight <= 0.01 || rough > 0.65) return;
|
|
vec3 p = viewPos(uv);
|
|
if (p.z > 1e8) return;
|
|
vec3 n = octDecode(g.xy);
|
|
vec3 v = normalize(p);
|
|
vec3 r = reflect(v, n);
|
|
if (r.z < -0.2) return; // back at the camera: nothing on screen to see there
|
|
// March: steps grow with distance; thickness grows with them.
|
|
float jitter = fract(52.9829189 * fract(dot(gl_FragCoord.xy, vec2(0.06711056, 0.00583715))));
|
|
float t = 4.0 + 6.0 * jitter, stepLen = 6.0;
|
|
const int STEPS = 40;
|
|
vec2 hit = vec2(-1.0);
|
|
float hitT = 0.0;
|
|
for (int i = 0; i < STEPS; ++i) {
|
|
vec3 q = p + r * t;
|
|
if (q.z <= pc.proj.z) break;
|
|
vec2 quv = toUv(q);
|
|
if (any(lessThan(quv, vec2(0.0))) || any(greaterThan(quv, vec2(1.0)))) break;
|
|
float sceneZ = viewZ(quv);
|
|
float behind = q.z - sceneZ;
|
|
if (behind > 0.0 && behind < stepLen * 2.0 + 8.0) {
|
|
float lo = t - stepLen, hi = t; // refine between the last two steps
|
|
for (int k = 0; k < 5; ++k) {
|
|
float mid = (lo + hi) * 0.5;
|
|
vec3 m = p + r * mid;
|
|
if (m.z - viewZ(toUv(m)) > 0.0) hi = mid; else lo = mid;
|
|
}
|
|
hitT = hi;
|
|
hit = toUv(p + r * hi);
|
|
break;
|
|
}
|
|
t += stepLen;
|
|
stepLen *= 1.12;
|
|
}
|
|
if (hit.x < 0.0) return;
|
|
vec2 edge = smoothstep(vec2(0.0), vec2(0.12), hit) * smoothstep(vec2(0.0), vec2(0.12), 1.0 - hit);
|
|
float fade = edge.x * edge.y * (1.0 - smoothstep(0.3, 0.65, rough)) * (1.0 - smoothstep(1500.0, 3000.0, hitT)) * smoothstep(-0.2, 0.1, r.z + 0.1);
|
|
vec3 c = min(sampleTexLod(pc.scene, hit, 0.0).rgb, vec3(16.0));
|
|
o_ssr = vec4(c * weight * fade * pc.strength, fade);
|
|
}
|