Files
2026-08-03 18:42:47 +08:00

162 lines
3.6 KiB
GLSL

uniform bool isPicking;
#ifdef ANAGLYPH
uniform mat3 matL;
uniform float gamma;
#endif
#ifdef NO_ORDER_TRANSP
#ifdef ONE_DRAW_BUFFER
uniform float which_pass; // 0. - first, 1. - second
#endif
#define gl_FragColor gl_FragData[0]
float get_weight(float depth, float alpha){
return alpha * max(1e-2, 3e3 * pow(1. - depth, 3.)); // eq #10
}
/*
* Set data for order independant transparency
*
* With multiple buffers:
* gl_FragData[0]: weighted color
* gl_FragData[1]: weight
*
* With one buffer and multi-pass:
* gl_FragData[0]: weighted color in pass 1
* gl_FragData[0]: weight in pass 2
*
*/
void setFragDataForNoOrderTransp(float depth) {
float wi = get_weight(depth, gl_FragColor.a);
gl_FragData[0] = vec4(gl_FragColor.rgb * wi, gl_FragColor.a);
#ifdef ONE_DRAW_BUFFER
// for using one draw buffer, switch on which_pass between color and weights
gl_FragData[0] = mix(gl_FragData[0], vec4(wi, wi, 0., 1.), which_pass);
#else
#ifdef ANAGLYPH
// need to set two components because anaglyph masks out colors for each eye
gl_FragData[1].rg = vec2(wi);
#else
gl_FragData[1].r = wi;
#endif // ANAGLYPH
#endif // ONE_DRAW_BUFFER
}
#endif // NO_ORDER_TRANSP
/*
* Apply post-lighting effects directly to output variables like gl_FragColor
*/
void PostLightingEffectsNoOIT() {
if (isPicking)
return;
#ifdef ray_trace_mode_3
// cel shading
gl_FragColor.rgb = floor(gl_FragColor.rgb * 3.999) / 3.0;
#endif
#ifdef ANAGLYPH
gl_FragColor.rgb = matL * pow(gl_FragColor.rgb, vec3(gamma));
#endif
}
vec3 ComputeChromadepth(float depth);
/*
* ... including OIT
*/
void PostLightingEffects(float depth) {
if (isPicking)
return;
PostLightingEffectsNoOIT();
#ifdef chromadepth_postlighting
vec3 luma_coeff = vec3(.30, .59, .11);
gl_FragColor.rgb = ComputeChromadepth(depth) * dot(luma_coeff, gl_FragColor.rgb);
#endif
#ifdef transparency_mode_3
#ifndef NO_ORDER_TRANSP
// if transparent, discard in opaque pass
if (gl_FragColor.a < .95)
discard;
#else
// if almost opaque, discard in transparent pass
if (gl_FragColor.a > .95)
discard;
setFragDataForNoOrderTransp(depth);
#endif // NO_ORDER_TRANSP
#endif // transparency_mode_3
}
/*
* Default argument overload
*/
void PostLightingEffects() {
PostLightingEffects(gl_FragCoord.z);
}
#ifdef chromadepth
#ifndef ortho
/*
* "unproject" the depth value if not in orthoscopic view, to get
* a depth gradient which is linear in eye space.
*/
uniform vec2 clippingplanes;
float orthoDepth(float depth) {
float front = clippingplanes.x;
float back = clippingplanes.y;
float front_inv = 1. / front;
float back_inv = 1. / back;
// from proj normalized dev coords to eye space
float depth_eye = 1. / (depth * (back_inv - front_inv) + front_inv);
// from eye space to ortho normalized dev coords
return (depth_eye - front) / (back - front);
}
#endif
/*
* Chromadepth - Calculates a color by depth.
* Uses a rainbow from red (near) to blue (far).
*
* http://chromatek.com/art-and-design/design-guide/
*/
vec3 ComputeChromadepth(float depth) {
#ifndef ortho
depth = orthoDepth(depth);
#endif
const float margin = 1. / 4.;
float hue6 = 6. * 240. / 360. *
clamp(depth * (1. + 2. * margin) - margin, 0., 1.);
return clamp(vec3(
abs(hue6 - 3.) - 1.,
2. - abs(hue6 - 2.),
2. - abs(hue6 - 4.)),
0., 1.);
}
#endif
/*
* Applies pre-lighting and pre-fog color alteration effects.
*/
vec4 ApplyColorEffects(vec4 color, float depth) {
#ifdef chromadepth
#ifndef chromadepth_postlighting
if (!isPicking)
color.rgb = ComputeChromadepth(depth);
#endif
#endif
return color;
}