mirror of
https://github.com/its-ven/FrameDepth.git
synced 2026-10-17 17:00:56 +02:00
217 lines
6.6 KiB
Python
217 lines
6.6 KiB
Python
"""GLSL shaders for depth3d_vr.py (kept separate so they can be tested on their own)."""
|
|
|
|
# ---------------------------------------------------------------- the 3D screen
|
|
SCREEN_VERT = """
|
|
#version 330
|
|
uniform mat4 mvp;
|
|
in vec3 pos;
|
|
in vec2 tc;
|
|
out vec2 uv;
|
|
void main() {
|
|
uv = tc;
|
|
gl_Position = mvp * vec4(pos, 1.0);
|
|
}
|
|
"""
|
|
|
|
# For every output pixel, SEARCH along the scan line for the source pixel that lands here
|
|
# (nearest one wins, like a z-buffer). Revealed gaps are filled from the far side.
|
|
# Mip-mapped + anisotropic sampling keeps text readable; optional sharpening on top.
|
|
SCREEN_FRAG = """
|
|
#version 330
|
|
uniform sampler2D color_tex;
|
|
uniform sampler2D depth_tex;
|
|
uniform float strength; // per-eye uv shift per unit of (depth - convergence)
|
|
uniform float convergence;
|
|
uniform float eye; // -1 left, +1 right
|
|
uniform float sharpen;
|
|
uniform int samples;
|
|
uniform int show_depth;
|
|
in vec2 uv;
|
|
out vec4 fragColor;
|
|
void main() {
|
|
vec2 gx = dFdx(uv); // footprint of one output pixel -> picks the right mip level
|
|
vec2 gy = dFdy(uv);
|
|
if (show_depth == 1) {
|
|
fragColor = vec4(vec3(textureLod(depth_tex, uv, 0.0).r), 1.0);
|
|
return;
|
|
}
|
|
float sxs = uv.x;
|
|
if (strength > 1e-7) {
|
|
float R = strength * max(convergence, 1.0 - convergence);
|
|
float stp = 2.0 * R / float(samples - 1);
|
|
float tol = 0.75 * stp;
|
|
float gapmax = strength;
|
|
float best_d = -1.0, fb_score = 1e9, fb_sx = uv.x;
|
|
for (int i = 0; i < samples; i++) {
|
|
float sx = uv.x - R + stp * float(i);
|
|
float d = textureLod(depth_tex, vec2(sx, uv.y), 0.0).r;
|
|
float r = abs(sx - eye * strength * (d - convergence) - uv.x);
|
|
if (r <= tol && d > best_d) best_d = d;
|
|
float score = r / gapmax + 2.0 * d; // in a gap: nearest FAR sample
|
|
if (r <= gapmax && score < fb_score) { fb_score = score; fb_sx = sx; }
|
|
}
|
|
sxs = (best_d >= 0.0) ? uv.x + eye * strength * (best_d - convergence) : fb_sx;
|
|
}
|
|
vec2 p = vec2(sxs, uv.y);
|
|
vec3 col = textureGrad(color_tex, p, gx, gy).rgb;
|
|
if (sharpen > 0.0) {
|
|
vec3 blur = 0.25 * (textureGrad(color_tex, p + gx, gx, gy).rgb +
|
|
textureGrad(color_tex, p - gx, gx, gy).rgb +
|
|
textureGrad(color_tex, p + gy, gx, gy).rgb +
|
|
textureGrad(color_tex, p - gy, gx, gy).rgb);
|
|
col = clamp(col + sharpen * (col - blur), 0.0, 1.0);
|
|
}
|
|
fragColor = vec4(col, 1.0);
|
|
}
|
|
"""
|
|
|
|
# ---------------------------------------------------------------- depth refinement passes
|
|
FS_VERT = """
|
|
#version 330
|
|
in vec2 pos;
|
|
out vec2 uv;
|
|
void main() {
|
|
uv = pos * 0.5 + 0.5;
|
|
gl_Position = vec4(pos, 0.0, 1.0);
|
|
}
|
|
"""
|
|
|
|
# Joint-bilateral upsampling: snaps soft low-res depth edges onto the real colour edges.
|
|
REFINE_FRAG = """
|
|
#version 330
|
|
uniform sampler2D color_tex;
|
|
uniform sampler2D depth_tex;
|
|
uniform vec2 depth_texel; // 1 / raw depth size
|
|
uniform float sigma_c; // colour similarity (smaller = harder edges)
|
|
in vec2 uv;
|
|
out vec4 fragColor;
|
|
void main() {
|
|
vec3 c0 = texture(color_tex, uv).rgb;
|
|
float acc = 0.0, wsum = 0.0;
|
|
for (int j = -2; j <= 2; j++) {
|
|
for (int i = -2; i <= 2; i++) {
|
|
vec2 p = uv + vec2(float(i), float(j)) * depth_texel;
|
|
vec3 dc = texture(color_tex, p).rgb - c0;
|
|
float ws = exp(-float(i * i + j * j) / 4.5);
|
|
float wc = exp(-dot(dc, dc) / (2.0 * sigma_c * sigma_c));
|
|
float w = ws * wc;
|
|
acc += w * texture(depth_tex, p).r;
|
|
wsum += w;
|
|
}
|
|
}
|
|
fragColor = vec4(acc / max(wsum, 1e-5), 0.0, 0.0, 1.0);
|
|
}
|
|
"""
|
|
|
|
# Tiny foreground dilation so the nearest depth fully covers an object's rim.
|
|
DILATE_FRAG = """
|
|
#version 330
|
|
uniform sampler2D src;
|
|
uniform vec2 texel;
|
|
uniform float radius; // in pixels of the refined map
|
|
in vec2 uv;
|
|
out vec4 fragColor;
|
|
void main() {
|
|
float m = texture(src, uv).r;
|
|
for (int j = -1; j <= 1; j++) {
|
|
for (int i = -1; i <= 1; i++) {
|
|
m = max(m, texture(src, uv + vec2(float(i), float(j)) * texel * radius).r);
|
|
}
|
|
}
|
|
fragColor = vec4(m, 0.0, 0.0, 1.0);
|
|
}
|
|
"""
|
|
|
|
# ---------------------------------------------------------------- immersive environment
|
|
ENV_VERT = """
|
|
#version 330
|
|
uniform mat4 mvp;
|
|
in vec3 pos;
|
|
out vec3 dir;
|
|
void main() {
|
|
dir = pos;
|
|
gl_Position = mvp * vec4(pos * 80.0, 1.0);
|
|
}
|
|
"""
|
|
|
|
# Equirectangular 360 / 180 viewer, mono or stereo (side-by-side / over-under).
|
|
ENV_FRAG = """
|
|
#version 330
|
|
uniform sampler2D env_tex;
|
|
uniform int stereo; // 0 mono, 1 side-by-side, 2 over-under
|
|
uniform int fov180; // 0 = 360, 1 = 180 (front half only)
|
|
uniform float eye; // -1 left, +1 right
|
|
uniform float yaw; // radians: rotation of the environment about the vertical axis
|
|
uniform float brightness;
|
|
in vec3 dir;
|
|
out vec4 fragColor;
|
|
const float PI = 3.14159265358979;
|
|
void main() {
|
|
vec3 d = normalize(dir);
|
|
float c = cos(yaw), s = sin(yaw);
|
|
vec3 e = vec3(d.x * c - d.z * s, d.y, d.x * s + d.z * c); // world -> environment frame
|
|
float lon = atan(e.x, -e.z);
|
|
float lat = asin(clamp(e.y, -1.0, 1.0));
|
|
float v = 0.5 - lat / PI;
|
|
vec2 uvA = vec2(lon / (2.0 * PI) + 0.5, v);
|
|
vec2 uvB = vec2(fract(lon / (2.0 * PI)), v);
|
|
vec2 gx = dFdx(uvA), gy = dFdy(uvA);
|
|
vec2 gxb = dFdx(uvB), gyb = dFdy(uvB);
|
|
if (abs(gxb.x) + abs(gyb.x) < abs(gx.x) + abs(gy.x)) { gx = gxb; gy = gyb; } // hide the wrap seam
|
|
vec2 uv = uvA;
|
|
float inside = 1.0;
|
|
if (fov180 == 1) {
|
|
uv.x = lon / PI + 0.5;
|
|
gx.x *= 2.0; gy.x *= 2.0;
|
|
inside = 1.0 - smoothstep(0.5 * PI - 0.03, 0.5 * PI, abs(lon));
|
|
}
|
|
vec2 scale = vec2(1.0), off = vec2(0.0);
|
|
float right = step(0.0, eye);
|
|
if (stereo == 1) { scale.x = 0.5; off.x = 0.5 * right; }
|
|
if (stereo == 2) { scale.y = 0.5; off.y = 0.5 * right; }
|
|
vec3 col = textureGrad(env_tex, uv * scale + off, gx * scale, gy * scale).rgb;
|
|
fragColor = vec4(col * brightness * inside, 1.0);
|
|
}
|
|
"""
|
|
|
|
# ---------------------------------------------------------------- settings panel + laser pointers
|
|
PANEL_VERT = """
|
|
#version 330
|
|
uniform mat4 mvp;
|
|
in vec3 pos;
|
|
in vec2 tc;
|
|
out vec2 uv;
|
|
void main() {
|
|
uv = tc;
|
|
gl_Position = mvp * vec4(pos, 1.0);
|
|
}
|
|
"""
|
|
|
|
PANEL_FRAG = """
|
|
#version 330
|
|
uniform sampler2D ui_tex;
|
|
in vec2 uv;
|
|
out vec4 fragColor;
|
|
void main() {
|
|
fragColor = texture(ui_tex, uv);
|
|
}
|
|
"""
|
|
|
|
FLAT_VERT = """
|
|
#version 330
|
|
uniform mat4 mvp;
|
|
in vec3 pos;
|
|
void main() {
|
|
gl_Position = mvp * vec4(pos, 1.0);
|
|
}
|
|
"""
|
|
|
|
FLAT_FRAG = """
|
|
#version 330
|
|
uniform vec4 color;
|
|
out vec4 fragColor;
|
|
void main() {
|
|
fragColor = color;
|
|
}
|
|
"""
|