Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions examples/jsm/effects/AnaglyphEffect.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const _forward = /*@__PURE__*/ new Vector3();
*
* This implementation uses CameraUtils.frameCorners() to align stereo
* camera frustums to a virtual screen plane, providing accurate depth
* perception with zero parallax at the screen distance.
* perception with zero parallax at the plane distance.
*
* Note that this class can only be used with {@link WebGLRenderer}.
* When using {@link WebGPURenderer}, use {@link AnaglyphPassNode}.
Expand Down Expand Up @@ -74,8 +74,8 @@ class AnaglyphEffect {
this.eyeSep = 0.064;

/**
* The distance from the viewer to the virtual screen plane
* where zero parallax (screen depth) occurs.
* The distance in world units from the viewer to the virtual
* screen plane where zero parallax (screen depth) occurs.
* Objects at this distance appear at the screen surface.
* Objects closer appear in front of the screen (negative parallax).
* Objects further appear behind the screen (positive parallax).
Expand All @@ -86,7 +86,7 @@ class AnaglyphEffect {
* @type {number}
* @default 0.5
*/
this.screenDistance = 0.5;
this.planeDistance = 0.5;

const _params = { minFilter: LinearFilter, magFilter: NearestFilter, format: RGBAFormat };

Expand Down Expand Up @@ -199,11 +199,11 @@ class AnaglyphEffect {
_eyeL.copy( camera.position ).addScaledVector( _right, - halfSep );
_eyeR.copy( camera.position ).addScaledVector( _right, halfSep );

// Calculate screen center (at screenDistance in front of the camera center)
_screenCenter.copy( camera.position ).addScaledVector( _forward, - this.screenDistance );
// Calculate screen center (at planeDistance in front of the camera center)
_screenCenter.copy( camera.position ).addScaledVector( _forward, - this.planeDistance );

// Calculate screen dimensions from camera FOV and aspect ratio
const halfHeight = this.screenDistance * Math.tan( MathUtils.DEG2RAD * camera.fov / 2 );
const halfHeight = this.planeDistance * Math.tan( MathUtils.DEG2RAD * camera.fov / 2 );
const halfWidth = halfHeight * camera.aspect;

// Calculate screen corners
Expand Down
80 changes: 40 additions & 40 deletions examples/jsm/tsl/display/AnaglyphPassNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ function createMatrixPair( leftSpec, rightSpec ) {
return [
r[ 0 ], g[ 0 ], b[ 0 ], // Column 0: coefficients for input R
r[ 1 ], g[ 1 ], b[ 1 ], // Column 1: coefficients for input G
r[ 2 ], g[ 2 ], b[ 2 ] // Column 2: coefficients for input B
r[ 2 ], g[ 2 ], b[ 2 ] // Column 2: coefficients for input B
];

}
Expand Down Expand Up @@ -117,67 +117,67 @@ const ANAGLYPH_MATRICES = {
// Paper: Left=[R,0,0], Right=[0,0,Lum]
[ AnaglyphAlgorithm.TRUE ]: {
[ AnaglyphColorMode.RED_CYAN ]: createMatrixPair(
{ r: [ 1, 0, 0 ] }, // Left: R -> outR
{ g: LUM, b: LUM } // Right: Lum -> outG, Lum -> outB
{ r: [ 1, 0, 0 ] }, // Left: R -> outR
{ g: LUM, b: LUM } // Right: Lum -> outG, Lum -> outB
),
[ AnaglyphColorMode.MAGENTA_CYAN ]: createMatrixPair(
{ r: [ 1, 0, 0 ], b: [ 0, 0, 0.5 ] }, // Left: R -> outR, partial B -> outB
{ g: LUM, b: [ 0, 0, 0.5 ] } // Right: Lum -> outG, partial B
{ r: [ 1, 0, 0 ], b: [ 0, 0, 0.5 ] }, // Left: R -> outR, partial B -> outB
{ g: LUM, b: [ 0, 0, 0.5 ] } // Right: Lum -> outG, partial B
),
[ AnaglyphColorMode.MAGENTA_GREEN ]: createMatrixPair(
{ r: [ 1, 0, 0 ], b: LUM }, // Left: R -> outR, Lum -> outB
{ g: LUM } // Right: Lum -> outG
{ r: [ 1, 0, 0 ], b: LUM }, // Left: R -> outR, Lum -> outB
{ g: LUM } // Right: Lum -> outG
)
},

// Grey Anaglyph - Luminance-based, no color, minimal ghosting
// Paper: Left=[Lum,0,0], Right=[0,0,Lum]
[ AnaglyphAlgorithm.GREY ]: {
[ AnaglyphColorMode.RED_CYAN ]: createMatrixPair(
{ r: LUM }, // Left: Lum -> outR
{ g: LUM, b: LUM } // Right: Lum -> outG, Lum -> outB
{ r: LUM }, // Left: Lum -> outR
{ g: LUM, b: LUM } // Right: Lum -> outG, Lum -> outB
),
[ AnaglyphColorMode.MAGENTA_CYAN ]: createMatrixPair(
{ r: LUM, b: [ 0.15, 0.29, 0.06 ] }, // Left: Lum -> outR, half-Lum -> outB
{ g: LUM, b: [ 0.15, 0.29, 0.06 ] } // Right: Lum -> outG, half-Lum -> outB
{ r: LUM, b: [ 0.15, 0.29, 0.06 ] }, // Left: Lum -> outR, half-Lum -> outB
{ g: LUM, b: [ 0.15, 0.29, 0.06 ] } // Right: Lum -> outG, half-Lum -> outB
),
[ AnaglyphColorMode.MAGENTA_GREEN ]: createMatrixPair(
{ r: LUM, b: LUM }, // Left: Lum -> outR, Lum -> outB
{ g: LUM } // Right: Lum -> outG
{ r: LUM, b: LUM }, // Left: Lum -> outR, Lum -> outB
{ g: LUM } // Right: Lum -> outG
)
},

// Colour Anaglyph - Full color, high retinal rivalry
// Paper: Left=[R,0,0], Right=[0,G,B]
[ AnaglyphAlgorithm.COLOUR ]: {
[ AnaglyphColorMode.RED_CYAN ]: createMatrixPair(
{ r: [ 1, 0, 0 ] }, // Left: R -> outR
{ g: [ 0, 1, 0 ], b: [ 0, 0, 1 ] } // Right: G -> outG, B -> outB
{ r: [ 1, 0, 0 ] }, // Left: R -> outR
{ g: [ 0, 1, 0 ], b: [ 0, 0, 1 ] } // Right: G -> outG, B -> outB
),
[ AnaglyphColorMode.MAGENTA_CYAN ]: createMatrixPair(
{ r: [ 1, 0, 0 ], b: [ 0, 0, 0.5 ] }, // Left: R -> outR, partial B -> outB
{ g: [ 0, 1, 0 ], b: [ 0, 0, 0.5 ] } // Right: G -> outG, partial B -> outB
{ r: [ 1, 0, 0 ], b: [ 0, 0, 0.5 ] }, // Left: R -> outR, partial B -> outB
{ g: [ 0, 1, 0 ], b: [ 0, 0, 0.5 ] } // Right: G -> outG, partial B -> outB
),
[ AnaglyphColorMode.MAGENTA_GREEN ]: createMatrixPair(
{ r: [ 1, 0, 0 ], b: [ 0, 0, 1 ] }, // Left: R -> outR, B -> outB
{ g: [ 0, 1, 0 ] } // Right: G -> outG
{ r: [ 1, 0, 0 ], b: [ 0, 0, 1 ] }, // Left: R -> outR, B -> outB
{ g: [ 0, 1, 0 ] } // Right: G -> outG
)
},

// Half-Colour Anaglyph - Luminance for left red, full color for right cyan
// Paper: Left=[Lum,0,0], Right=[0,G,B]
[ AnaglyphAlgorithm.HALF_COLOUR ]: {
[ AnaglyphColorMode.RED_CYAN ]: createMatrixPair(
{ r: LUM }, // Left: Lum -> outR
{ g: [ 0, 1, 0 ], b: [ 0, 0, 1 ] } // Right: G -> outG, B -> outB
{ r: LUM }, // Left: Lum -> outR
{ g: [ 0, 1, 0 ], b: [ 0, 0, 1 ] } // Right: G -> outG, B -> outB
),
[ AnaglyphColorMode.MAGENTA_CYAN ]: createMatrixPair(
{ r: LUM, b: [ 0.15, 0.29, 0.06 ] }, // Left: Lum -> outR, half-Lum -> outB
{ r: LUM, b: [ 0.15, 0.29, 0.06 ] }, // Left: Lum -> outR, half-Lum -> outB
{ g: [ 0, 1, 0 ], b: [ 0.15, 0.29, 0.06 ] } // Right: G -> outG, half-Lum -> outB
),
[ AnaglyphColorMode.MAGENTA_GREEN ]: createMatrixPair(
{ r: LUM, b: LUM }, // Left: Lum -> outR, Lum -> outB
{ g: [ 0, 1, 0 ] } // Right: G -> outG
{ r: LUM, b: LUM }, // Left: Lum -> outR, Lum -> outB
{ g: [ 0, 1, 0 ] } // Right: G -> outG
)
},

Expand Down Expand Up @@ -223,16 +223,16 @@ const ANAGLYPH_MATRICES = {
// Paper: Left=[0,0.7G+0.3B,0,0], Right=[0,G,B]
[ AnaglyphAlgorithm.OPTIMISED ]: {
[ AnaglyphColorMode.RED_CYAN ]: createMatrixPair(
{ r: [ 0, 0.7, 0.3 ] }, // Left: 0.7G+0.3B -> outR
{ g: [ 0, 1, 0 ], b: [ 0, 0, 1 ] } // Right: G -> outG, B -> outB
{ r: [ 0, 0.7, 0.3 ] }, // Left: 0.7G+0.3B -> outR
{ g: [ 0, 1, 0 ], b: [ 0, 0, 1 ] } // Right: G -> outG, B -> outB
),
[ AnaglyphColorMode.MAGENTA_CYAN ]: createMatrixPair(
{ r: [ 0, 0.7, 0.3 ], b: [ 0, 0, 0.5 ] }, // Left: 0.7G+0.3B -> outR, partial B
{ g: [ 0, 1, 0 ], b: [ 0, 0, 0.5 ] } // Right: G -> outG, partial B
{ g: [ 0, 1, 0 ], b: [ 0, 0, 0.5 ] } // Right: G -> outG, partial B
),
[ AnaglyphColorMode.MAGENTA_GREEN ]: createMatrixPair(
{ r: [ 0, 0.7, 0.3 ], b: [ 0, 0, 1 ] }, // Left: 0.7G+0.3B -> outR, B -> outB
{ g: [ 0, 1, 0 ] } // Right: G -> outG
{ g: [ 0, 1, 0 ] } // Right: G -> outG
)
},

Expand All @@ -241,20 +241,20 @@ const ANAGLYPH_MATRICES = {
// Paper matrix [8]: Left=[0.439R+0.447G+0.148B, 0, 0], Right=[0, 0.095R+0.934G+0.005B, 0.018R+0.028G+1.057B]
[ AnaglyphAlgorithm.COMPROMISE ]: {
[ AnaglyphColorMode.RED_CYAN ]: createMatrixPair(
{ r: [ 0.439, 0.447, 0.148 ] }, // Left: weighted RGB -> outR
{ r: [ 0.439, 0.447, 0.148 ] }, // Left: weighted RGB -> outR
{
g: [ 0.095, 0.934, 0.005 ], // Right: weighted RGB -> outG
b: [ 0.018, 0.028, 1.057 ] // Right: weighted RGB -> outB
g: [ 0.095, 0.934, 0.005 ], // Right: weighted RGB -> outG
b: [ 0.018, 0.028, 1.057 ] // Right: weighted RGB -> outB
}
),
[ AnaglyphColorMode.MAGENTA_CYAN ]: createMatrixPair(
{
r: [ 0.439, 0.447, 0.148 ],
b: [ 0.009, 0.014, 0.074 ] // Partial blue from left
b: [ 0.009, 0.014, 0.074 ] // Partial blue from left
},
{
g: [ 0.095, 0.934, 0.005 ],
b: [ 0.009, 0.014, 0.528 ] // Partial blue from right
b: [ 0.009, 0.014, 0.528 ] // Partial blue from right
}
),
[ AnaglyphColorMode.MAGENTA_GREEN ]: createMatrixPair(
Expand All @@ -275,7 +275,7 @@ const ANAGLYPH_MATRICES = {
*
* This implementation uses CameraUtils.frameCorners() to align stereo
* camera frustums to a virtual screen plane, providing accurate depth
* perception with zero parallax at the screen distance.
* perception with zero parallax at the plane distance.
*
* @augments StereoCompositePassNode
* @three_import import { anaglyphPass, AnaglyphAlgorithm, AnaglyphColorMode } from 'three/addons/tsl/display/AnaglyphPassNode.js';
Expand Down Expand Up @@ -317,8 +317,8 @@ class AnaglyphPassNode extends StereoCompositePassNode {
this.eyeSep = 0.064;

/**
* The distance from the viewer to the virtual screen plane
* where zero parallax (screen depth) occurs.
* The distance in world units from the viewer to the virtual
* screen plane where zero parallax (screen depth) occurs.
* Objects at this distance appear at the screen surface.
* Objects closer appear in front of the screen (negative parallax).
* Objects further appear behind the screen (positive parallax).
Expand All @@ -329,7 +329,7 @@ class AnaglyphPassNode extends StereoCompositePassNode {
* @type {number}
* @default 0.5
*/
this.screenDistance = 0.5;
this.planeDistance = 0.5;

/**
* The current anaglyph algorithm.
Expand Down Expand Up @@ -462,12 +462,12 @@ class AnaglyphPassNode extends StereoCompositePassNode {
_eyeL.copy( camera.position ).addScaledVector( _right, - halfSep );
_eyeR.copy( camera.position ).addScaledVector( _right, halfSep );

// Calculate screen center (at screenDistance in front of the camera center)
_screenCenter.copy( camera.position ).addScaledVector( _forward, - this.screenDistance );
// Calculate screen center (at planeDistance in front of the camera center)
_screenCenter.copy( camera.position ).addScaledVector( _forward, - this.planeDistance );

// Calculate screen dimensions from camera FOV and aspect ratio
const DEG2RAD = Math.PI / 180;
const halfHeight = this.screenDistance * Math.tan( DEG2RAD * camera.fov / 2 );
const halfHeight = this.planeDistance * Math.tan( DEG2RAD * camera.fov / 2 );
const halfWidth = halfHeight * camera.aspect;

// Calculate screen corners
Expand Down
4 changes: 2 additions & 2 deletions examples/webgl_effects_anaglyph.html
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,9 @@

// Configure stereo parameters for physically-correct rendering
// eyeSep: interpupillary distance (default 0.064m / 64mm for humans)
// screenDistance: distance to the zero-parallax plane (objects here appear at screen depth)
// planeDistance: distance to the zero-parallax plane (objects here appear at screen depth)
effect.eyeSep = 0.064;
effect.screenDistance = 3; // Match camera distance to origin for zero parallax at scene center
effect.planeDistance = 3; // Match camera distance to origin for zero parallax at scene center

//

Expand Down
8 changes: 4 additions & 4 deletions examples/webgpu_display_stereo.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
const params = {
effect: 'stereo',
eyeSep: 0.064,
screenDistance: 3,
planeDistance: 3,
anaglyphAlgorithm: 'dubois',
anaglyphColorMode: 'redCyan'
};
Expand Down Expand Up @@ -136,7 +136,7 @@

// Configure anaglyph for physically-correct stereo with zero parallax at scene center
anaglyph.eyeSep = params.eyeSep;
anaglyph.screenDistance = params.screenDistance;
anaglyph.planeDistance = params.planeDistance;

renderPipeline.outputNode = stereo;

Expand All @@ -162,9 +162,9 @@
anaglyph.colorMode = value;

} );
anaglyphFolder.add( params, 'screenDistance', 0.5, 10, 0.1 ).name( 'Screen Distance' ).onChange( function ( value ) {
anaglyphFolder.add( params, 'planeDistance', 0.5, 10, 0.1 ).name( 'Plane Distance' ).onChange( function ( value ) {

anaglyph.screenDistance = value;
anaglyph.planeDistance = value;

} );
anaglyphFolder.paramList.domElement.style.display = 'none';
Expand Down
1 change: 0 additions & 1 deletion src/Three.TSL.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export const HALF_PI = TSL.HALF_PI;
export const PointShadowFilter = TSL.PointShadowFilter;
export const Return = TSL.Return;
export const Schlick_to_F0 = TSL.Schlick_to_F0;
export const ScriptableNodeResources = TSL.ScriptableNodeResources;
export const ShaderNode = TSL.ShaderNode;
export const Stack = TSL.Stack;
export const Switch = TSL.Switch;
Expand Down
2 changes: 1 addition & 1 deletion src/loaders/FileLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class FileLoader extends Loader {

/**
* The expected mime type. Valid values can be found
* [here](hhttps://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString#mimetype)
* [here](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString#mimetype)
*
* @type {string}
*/
Expand Down