fruit-fly-simulation / src /macro-output.js
Xenova's picture
Xenova HF Staff
Upload 227 files
cc38b25 verified
Raw History Blame Contribute Delete
2.32 kB
import { OutputPass } from 'three/addons/postprocessing/OutputPass.js';
/**
* Finish the linear, premultiplied scene and composite it over an authored
* display-space backdrop. Keep this pass last, including when DOF is disabled.
*/
export class MacroOutputPass extends OutputPass {
constructor() {
super();
this.material.name = 'MacroOutputShader';
// Plain arrays deliberately retain the authored sRGB values: THREE.Color
// would convert these CSS colors to linear before the output transform.
this.uniforms.backdropEdge = { value: [16 / 255, 23 / 255, 29 / 255] };
this.uniforms.backdropCenter = { value: [32 / 255, 42 / 255, 53 / 255] };
this.uniforms.backdropAspect = { value: 1 };
const sample = 'gl_FragColor = texture2D( tDiffuse, vUv );';
if (!this.material.fragmentShader.includes(sample))
throw new Error('MacroOutputPass: unsupported OutputShader sampling statement');
this.material.fragmentShader = this.material.fragmentShader
.replace(
'uniform sampler2D tDiffuse;',
`uniform sampler2D tDiffuse;
uniform vec3 backdropEdge;
uniform vec3 backdropCenter;
uniform float backdropAspect;`,
)
.replace(
sample,
`${sample}
float sceneAlpha = clamp( gl_FragColor.a, 0.0, 1.0 );
// Normal blending into transparent black and the DOF filter both leave
// premultiplied linear RGB. Nonlinear transforms require straight RGB.
gl_FragColor.rgb = sceneAlpha > 0.000001
? gl_FragColor.rgb / sceneAlpha : vec3( 0.0 );`,
)
.replace(
/\}\s*$/,
`
// Backdrop gradient in display-space sRGB.
vec2 backdropPosition = vUv - vec2( 0.54, 0.48 );
backdropPosition.x *= mix( 1.0, clamp( backdropAspect, 0.65, 2.0 ), 0.35 );
backdropPosition.y *= 1.10;
float backdropLight = 1.0 - smoothstep( 0.04, 0.75, length( backdropPosition ) );
vec3 backdrop = mix( backdropEdge, backdropCenter, backdropLight );
#ifndef SRGB_TRANSFER
backdrop = sRGBTransferEOTF( vec4( backdrop, 1.0 ) ).rgb;
#endif
gl_FragColor = vec4( mix( backdrop, gl_FragColor.rgb, sceneAlpha ), 1.0 );
}`,
);
this.material.needsUpdate = true;
}
setSize(width, height) {
this.uniforms.backdropAspect.value = width / Math.max(height, 1);
}
}