mirror of
https://github.com/godotengine/godot.git
synced 2025-12-07 22:00:10 +00:00
51 lines
1.6 KiB
GLSL
51 lines
1.6 KiB
GLSL
|
|
vec3 oct_to_vec3(vec2 e) {
|
|
vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));
|
|
float t = max(-v.z, 0.0);
|
|
v.xy += t * -sign(v.xy);
|
|
return normalize(v);
|
|
}
|
|
|
|
// border_size: 1.0 - padding_in_uv_space * 2.0.
|
|
vec3 oct_to_vec3_with_border(vec2 uv, float border_size) {
|
|
// Convert into [-1,1] space and add border which extends beyond [-1,1].
|
|
uv = (uv - 0.5) * (2.0 / border_size);
|
|
// Calculate octahedral mirroring for values outside of [-1,1].
|
|
// Inspired by Timothy Lottes' code here: https://gpuopen.com/learn/fetching-from-cubes-and-octahedrons/
|
|
vec2 mask = step(vec2(1.0), abs(uv));
|
|
uv = 2.0 * clamp(uv, -1.0, 1.0) - uv;
|
|
uv = mix(uv, -uv, mask.yx);
|
|
return oct_to_vec3(uv);
|
|
}
|
|
|
|
vec2 oct_wrap(vec2 v) {
|
|
vec2 signVal;
|
|
signVal.x = v.x >= 0.0 ? 1.0 : -1.0;
|
|
signVal.y = v.y >= 0.0 ? 1.0 : -1.0;
|
|
return (1.0 - abs(v.yx)) * signVal;
|
|
}
|
|
|
|
vec2 vec3_to_oct(vec3 n) {
|
|
// Reference: https://twitter.com/Stubbesaurus/status/937994790553227264
|
|
n /= (abs(n.x) + abs(n.y) + abs(n.z));
|
|
n.xy = (n.z >= 0.0) ? n.xy : oct_wrap(n.xy);
|
|
n.xy = n.xy * 0.5 + 0.5;
|
|
return n.xy;
|
|
}
|
|
|
|
// border_size.x: padding_in_uv_space
|
|
// border_size.y: 1.0 - padding_in_uv_space * 2.0
|
|
vec2 vec3_to_oct_with_border(vec3 n, vec2 border_size) {
|
|
vec2 uv = vec3_to_oct(n);
|
|
return uv * border_size.y + border_size.x;
|
|
}
|
|
|
|
float vec3_to_oct_lod(vec3 n_ddx, vec3 n_ddy, float pixel_size) {
|
|
// Approximate UV space derivatives by a factor of 0.5 because
|
|
// vec3_to_oct maps from [-1,1] to [0,1].
|
|
float pixel_size_sqr = 4.0 * pixel_size * pixel_size;
|
|
float ddx = dot(n_ddx, n_ddx) / pixel_size_sqr;
|
|
float ddy = dot(n_ddy, n_ddy) / pixel_size_sqr;
|
|
float dd_sqr = max(ddx, ddy);
|
|
return 0.25 * log2(dd_sqr + 1e-6f);
|
|
}
|