Warning, /firebird/packages/firebird-ng/display/src/lib/services/three-clipping-patch.ts is written in an unsupported language. File is not indexed.
0001 /**
0002 * Selects three's fragment-shader path for union clipping planes.
0003 *
0004 * Union planes (a `ClippingGroup` with `clipIntersection = false`: the wedge
0005 * at 180 degrees or more, and the Z plane) can clip in two places:
0006 * - hardware clip distances, when the device offers them (WebGPU
0007 * `clip-distances`, WebGL `ANGLE_clip_cull_distance`);
0008 * - a discard in the fragment shader, otherwise.
0009 *
0010 * Through three r185 the hardware decision was stored on a temporary node
0011 * material and lost before draw time, so union planes silently stopped
0012 * clipping on hardware that offers clip distances. three r186 carries the
0013 * decision on the node builder state, which fixes that. This patch remains
0014 * so that every backend and device clips through the same fragment-shader
0015 * path, which keeps clip edges identical between the WebGPU renderer and the
0016 * WebGL2 fallback and keeps the pixel baselines device-independent.
0017 *
0018 * The patch replaces `NodeMaterial.prototype.setupHardwareClipping` with a
0019 * version that never selects hardware clipping. `NodeBuilder` starts with
0020 * `hardwareClipping = false`, and `ClippingNode` emits the fragment-shader
0021 * union loop only for an explicit `false`, so union planes then clip in the
0022 * fragment shader. three-clipping-patch.spec.ts pins those three facts;
0023 * when it fails after a three upgrade, re-check the patch against the new
0024 * `setupHardwareClipping`.
0025 *
0026 * Removing the patch is a deliberate rendering change: union-plane edges
0027 * then come from hardware clipping where available, so re-capture the pixel
0028 * baselines of every view that clips with union planes.
0029 */
0030
0031 import { NodeMaterial } from 'three/webgpu';
0032
0033 type HardwareClippingBuilder = { hardwareClipping: boolean };
0034
0035 let patched = false;
0036
0037 /** Applies the patch once per page; later calls do nothing. */
0038 export function useFragmentShaderClipping(): void {
0039 if (patched) return;
0040 patched = true;
0041 (NodeMaterial.prototype as unknown as { setupHardwareClipping: (builder: HardwareClippingBuilder) => void })
0042 .setupHardwareClipping = function (builder: HardwareClippingBuilder): void {
0043 builder.hardwareClipping = false;
0044 };
0045 }