fuckingtech/public/assets/glsl/lygia/lighting/ssr.glsl
Elias Rhouzlane bf76c6b086 fix: code
2025-04-06 17:23:52 +02:00

138 lines
No EOL
4.4 KiB
GLSL

#include "../space/view2screenPosition.glsl"
#include "../sdf/lineSDF.glsl"
#include "../sdf/planeSDF.glsl"
#include "../sampler.glsl"
/*
contributors: Patricio Gonzalez Vivo
description: ScreenSpace Reflections
use: <float> ssao(<SAMPLER_TYPE> texPosition, <SAMPLER_TYPE> texNormal, vec2 <st> [, <float> radius, float <bias>])
options:
- SSR_MAX_STEP: number max number of raymarching steps (int)
- SSR_MAX_DISTANCE: max distance (float)
- CAMERA_PROJECTION_MATRIX: camera projection mat4 matrix
- CAMERA_NEAR_CLIP: camera near clip distance
- CAMERA_FAR_CLIP: camera far clip distance
- SSR_FRESNEL: if define scale the opacity based on the fresnel angle
license:
- Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0
- Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license
*/
// #define SSR_FRESNEL
#ifndef CAMERA_NEAR_CLIP
#define CAMERA_NEAR_CLIP u_cameraNearClip
#endif
#ifndef CAMERA_FAR_CLIP
#define CAMERA_FAR_CLIP u_cameraFarClip
#endif
#ifndef SSR_MAX_STEP
#define SSR_MAX_STEP 500
#endif
#ifndef SSR_MAX_DISTANCE
#define SSR_MAX_DISTANCE 180.0
#endif
#ifndef FNC_SSR
#define FNC_SSR
vec2 ssr(SAMPLER_TYPE texPosition, SAMPLER_TYPE texNormal, vec2 st, vec2 pixel, inout float op, inout float dist) {
vec3 viewPosition = SAMPLER_FNC(texPosition, st).xyz;
// if (-viewPosition.z >= CAMERA_FAR_CLIP)
// return st;
vec2 ssr_uv = st;
float thickness = 0.05;
float opacity = op;
op = 0.0;
dist = 0.0;
vec3 viewNormal = SAMPLER_FNC(texNormal, st).xyz;
vec3 viewIncidentDir = normalize(viewPosition);
vec3 viewReflectDir = reflect(viewIncidentDir, viewNormal);
float maxReflectRayLen = SSR_MAX_DISTANCE / dot(-viewIncidentDir, viewNormal);
vec3 d1viewPosition = viewPosition + viewReflectDir * maxReflectRayLen;
if (d1viewPosition.z > -CAMERA_NEAR_CLIP) {
//https://tutorial.math.lamar.edu/Classes/CalcIII/EqnsOfLines.aspx
float t = (-CAMERA_NEAR_CLIP - viewPosition.z)/viewReflectDir.z;
d1viewPosition = viewPosition + viewReflectDir * t;
}
vec2 resolution = 1.0 / pixel;
vec2 d0 = st * resolution;
vec2 d1 = view2screenPosition(d1viewPosition) * resolution;
float totalLen = length(d1-d0);
float xLen = d1.x-d0.x;
float yLen = d1.y-d0.y;
float totalStep = max(abs(xLen),abs(yLen));
float xSpan = (xLen/totalStep);// * pixel.x;
float ySpan = (yLen/totalStep);// * pixel.y;
for (float i = 0.0; i < float(SSR_MAX_STEP); i++) {
if ( i >= totalStep)
break;
vec2 xy = vec2(d0.x + i*xSpan, d0.y + i*ySpan);
vec2 uv = xy * pixel;
vec3 vP = SAMPLER_FNC(texPosition, uv).xyz;
// if (-vP.z >= CAMERA_FAR_CLIP)
// continue;
// https://comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf
float recipVPZ = 1.0/viewPosition.z;
float s = length(xy-d0)/totalLen;
float viewReflectRayZ = 1.0 / (recipVPZ + s * (1.0/d1viewPosition.z - recipVPZ) );
if (viewReflectRayZ <= vP.z) {
if (lineSDF(vP, viewPosition, d1viewPosition) <= max(0.0, thickness)) {
vec3 vN = SAMPLER_FNC(texNormal, uv).xyz;
if (dot(viewReflectDir, vN) >= 0.0)
continue;
dist = planeSDF(vP, viewPosition, viewNormal);
if (dist > SSR_MAX_DISTANCE)
break;
dist = s;
op = opacity;
#ifdef SSR_FRESNEL
float fresnelCoe = (dot(viewIncidentDir, viewReflectDir) + 1.0) * 0.5;
op *= fresnelCoe;
#endif
ssr_uv = uv;
break;
}
}
}
return ssr_uv;
}
vec2 ssr(SAMPLER_TYPE texPosition, SAMPLER_TYPE texNormal, vec2 st, vec2 pixel, inout float op) {
float dist = 0.0;
return ssr(texPosition, texNormal, st, pixel, op, dist);
}
vec3 ssr(SAMPLER_TYPE tex, SAMPLER_TYPE texPosition, SAMPLER_TYPE texNormal, vec2 st, vec2 pixel, float opacity) {
vec3 color = SAMPLER_FNC(tex, st).rgb;
float dist = 0.0;
vec2 uv = ssr(texPosition, texNormal, st, pixel, opacity, dist);
return mix(color, SAMPLER_FNC(tex, uv).rgb, opacity);
}
vec3 ssr(SAMPLER_TYPE tex, SAMPLER_TYPE texPosition, SAMPLER_TYPE texNormal, vec2 st, vec2 pixel) {
return ssr(tex, texPosition, texNormal, st, pixel, 0.5);
}
#endif