@@ -28,11 +28,11 @@ class SSRNode extends TempNode {
2828 * @param {Node<vec4> } colorNode - The node that represents the beauty pass.
2929 * @param {Node<float> } depthNode - A node that represents the beauty pass's depth.
3030 * @param {Node<vec3> } normalNode - A node that represents the beauty pass's normals.
31- * @param {Node<float> } metalnessRoughnessNode - A node that represents the beauty pass's metalness and roughness .
32- * @param {Camera } camera - The camera the scene is rendered with .
33- * @param {boolean } [blurred=false ] - Whether the SSR reflections should be blurred or not .
31+ * @param {Node<float> } metalnessNode - A node that represents the beauty pass's metalness.
32+ * @param {?Node<float> } [roughnessNode=null] - A node that represents the beauty pass's roughness .
33+ * @param {?Camera } [camera=null ] - The camera the scene is rendered with .
3434 */
35- constructor ( colorNode , depthNode , normalNode , metalnessRoughnessNode , camera , blurred = false ) {
35+ constructor ( colorNode , depthNode , normalNode , metalnessNode , roughnessNode = null , camera = null ) {
3636
3737 super ( 'vec4' ) ;
3838
@@ -62,14 +62,18 @@ class SSRNode extends TempNode {
6262 *
6363 * @type {Node<float> }
6464 */
65- this . metalnessRoughnessNode = metalnessRoughnessNode ;
65+ this . metalnessNode = metalnessNode ;
6666
6767 /**
68- * The camera the scene is rendered with.
68+ * Whether the SSR reflections should be blurred or not. Blurring is a costly
69+ * operation so turn it off if you encounter performance issues on certain
70+ * devices.
6971 *
70- * @type {Camera }
72+ * @private
73+ * @type {Node<float> }
74+ * @default false
7175 */
72- this . camera = camera ;
76+ this . roughnessNode = roughnessNode ;
7377
7478 /**
7579 * The resolution scale. Valid values are in the range
@@ -133,24 +137,36 @@ class SSRNode extends TempNode {
133137 */
134138 this . blurQuality = uniform ( 2 ) ;
135139
140+ //
141+
142+ if ( camera === null ) {
143+
144+ if ( this . colorNode . passNode && this . colorNode . passNode . isPassNode === true ) {
145+
146+ camera = this . colorNode . passNode . camera ;
147+
148+ } else {
149+
150+ throw new Error ( 'THREE.TSL: No camera found. ssr() requires a camera.' ) ;
151+
152+ }
153+
154+ }
155+
136156 /**
137- * The spread of the blur. Automatically set when generating mips .
157+ * The camera the scene is rendered with .
138158 *
139- * @private
140- * @type {UniformNode<int> }
159+ * @type {Camera }
141160 */
142- this . _blurSpread = uniform ( 1 ) ;
161+ this . camera = camera ;
143162
144163 /**
145- * Whether the SSR reflections should be blurred or not. Blurring is a costly
146- * operation so turn it off if you encounter performance issues on certain
147- * devices.
164+ * The spread of the blur. Automatically set when generating mips.
148165 *
149166 * @private
150- * @type {boolean }
151- * @default false
167+ * @type {UniformNode<int> }
152168 */
153- this . _blurred = blurred ;
169+ this . _blurSpread = uniform ( 1 ) ;
154170
155171 /**
156172 * Represents the projection matrix of the scene's camera.
@@ -190,7 +206,7 @@ class SSRNode extends TempNode {
190206 * @private
191207 * @type {UniformNode<bool> }
192208 */
193- this . _isPerspectiveCamera = uniform ( camera . isPerspectiveCamera ? 1 : 0 ) ;
209+ this . _isPerspectiveCamera = uniform ( camera . isPerspectiveCamera ) ;
194210
195211 /**
196212 * The resolution of the pass.
@@ -254,16 +270,24 @@ class SSRNode extends TempNode {
254270 */
255271 this . _textureNode = passTexture ( this , this . _ssrRenderTarget . texture ) ;
256272
257- const mips = this . _blurRenderTarget . texture . mipmaps . length - 1 ;
258- const lod = this . metalnessRoughnessNode . g . mul ( mips ) . clamp ( 0 , mips ) ;
273+ let blurredTextureNode = null ;
274+
275+ if ( this . roughnessNode !== null ) {
276+
277+ const mips = this . _blurRenderTarget . texture . mipmaps . length - 1 ;
278+ const lod = float ( this . roughnessNode ) . mul ( mips ) . clamp ( 0 , mips ) ;
279+
280+ blurredTextureNode = passTexture ( this , this . _blurRenderTarget . texture ) . level ( lod ) ;
281+
282+ }
259283
260284 /**
261285 * Holds the blurred SSR reflections.
262286 *
263287 * @private
264- * @type {PassTextureNode }
288+ * @type {? PassTextureNode }
265289 */
266- this . _blurredTextureNode = passTexture ( this , this . _blurRenderTarget . texture ) . level ( lod ) ;
290+ this . _blurredTextureNode = blurredTextureNode ;
267291
268292 }
269293
@@ -274,7 +298,7 @@ class SSRNode extends TempNode {
274298 */
275299 getTextureNode ( ) {
276300
277- return this . _blurred ? this . _blurredTextureNode : this . _textureNode ;
301+ return this . roughnessNode !== null ? this . _blurredTextureNode : this . _textureNode ;
278302
279303 }
280304
@@ -327,7 +351,7 @@ class SSRNode extends TempNode {
327351
328352 // blur (optional)
329353
330- if ( this . _blurred === true ) {
354+ if ( this . roughnessNode !== null ) {
331355
332356 // blur mips but leave the base mip unblurred
333357
@@ -417,7 +441,7 @@ class SSRNode extends TempNode {
417441
418442 const ssr = Fn ( ( ) => {
419443
420- const metalness = this . metalnessRoughnessNode . sample ( uvNode ) . r ;
444+ const metalness = float ( this . metalnessNode ) ;
421445
422446 // fragments with no metalness do not reflect their environment
423447 metalness . equal ( 0.0 ) . discard ( ) ;
@@ -440,7 +464,7 @@ class SSRNode extends TempNode {
440464 const d1viewPosition = viewPosition . add ( viewReflectDir . mul ( maxReflectRayLen ) ) . toVar ( ) ;
441465
442466 // check if d1viewPosition lies behind the camera near plane
443- If ( this . _isPerspectiveCamera . equal ( float ( 1 ) ) . and ( d1viewPosition . z . greaterThan ( this . _cameraNear . negate ( ) ) ) , ( ) => {
467+ If ( this . _isPerspectiveCamera . and ( d1viewPosition . z . greaterThan ( this . _cameraNear . negate ( ) ) ) , ( ) => {
444468
445469 // if so, ensure d1viewPosition is clamped on the near plane.
446470 // this prevents artifacts during the ray marching process
@@ -499,7 +523,7 @@ class SSRNode extends TempNode {
499523 const s = xy . sub ( d0 ) . length ( ) . div ( totalLen ) ;
500524
501525 // depending on the camera type, we now compute the z-coordinate of the reflected ray at the current step in view space
502- If ( this . _isPerspectiveCamera . equal ( float ( 1 ) ) , ( ) => {
526+ If ( this . _isPerspectiveCamera , ( ) => {
503527
504528 const recipVPZ = float ( 1 ) . div ( viewPosition . z ) . toVar ( ) ;
505529 viewReflectRayZ . assign ( float ( 1 ) . div ( recipVPZ . add ( s . mul ( float ( 1 ) . div ( d1viewPosition . z ) . sub ( recipVPZ ) ) ) ) ) ;
@@ -622,9 +646,9 @@ export default SSRNode;
622646 * @param {Node<vec4> } colorNode - The node that represents the beauty pass.
623647 * @param {Node<float> } depthNode - A node that represents the beauty pass's depth.
624648 * @param {Node<vec3> } normalNode - A node that represents the beauty pass's normals.
625- * @param {Node<float> } metalnessRoughnessNode - A node that represents the beauty pass's metalness and roughness .
626- * @param {Camera } camera - The camera the scene is rendered with .
627- * @param {boolean } [blurred=false ] - Whether the SSR reflections should be blurred or not .
649+ * @param {Node<float> } metalnessNode - A node that represents the beauty pass's metalness.
650+ * @param {?Node<float> } [roughnessNode=null] - A node that represents the beauty pass's roughness .
651+ * @param {?Camera } [camera=null ] - The camera the scene is rendered with .
628652 * @returns {SSRNode }
629653 */
630- export const ssr = ( colorNode , depthNode , normalNode , metalnessRoughnessNode , camera , blurred ) => nodeObject ( new SSRNode ( nodeObject ( colorNode ) , nodeObject ( depthNode ) , nodeObject ( normalNode ) , nodeObject ( metalnessRoughnessNode ) , camera , blurred ) ) ;
654+ export const ssr = ( colorNode , depthNode , normalNode , metalnessNode , roughnessNode = null , camera = null ) => nodeObject ( new SSRNode ( nodeObject ( colorNode ) , nodeObject ( depthNode ) , nodeObject ( normalNode ) , nodeObject ( metalnessNode ) , nodeObject ( roughnessNode ) , camera ) ) ;
0 commit comments