📄 PixelationPassNode.js
¶
📊 Analysis Summary¶
Metric | Count |
---|---|
🔧 Functions | 12 |
🧱 Classes | 2 |
📦 Imports | 24 |
📊 Variables & Constants | 7 |
📚 Table of Contents¶
🛠️ File Location:¶
📂 examples/jsm/tsl/display/PixelationPassNode.js
📦 Imports¶
Name | Source |
---|---|
NearestFilter |
three/webgpu |
Vector4 |
three/webgpu |
TempNode |
three/webgpu |
NodeUpdateType |
three/webgpu |
PassNode |
three/webgpu |
nodeObject |
three/tsl |
Fn |
three/tsl |
float |
three/tsl |
uv |
three/tsl |
uniform |
three/tsl |
convertToTexture |
three/tsl |
vec2 |
three/tsl |
vec3 |
three/tsl |
clamp |
three/tsl |
floor |
three/tsl |
dot |
three/tsl |
smoothstep |
three/tsl |
If |
three/tsl |
sign |
three/tsl |
step |
three/tsl |
mrt |
three/tsl |
output |
three/tsl |
normalView |
three/tsl |
property |
three/tsl |
Variables & Constants¶
Name | Type | Kind | Value | Exported |
---|---|---|---|---|
map |
any |
let/var | this.textureNode.value |
✗ |
width |
any |
let/var | map.image.width |
✗ |
height |
any |
let/var | map.image.height |
✗ |
uvNodeTexture |
any |
let/var | textureNode.uvNode \|\| uv() |
✗ |
uvNodeDepth |
any |
let/var | depthNode.uvNode \|\| uv() |
✗ |
uvNodeNormal |
any |
let/var | normalNode.uvNode \|\| uv() |
✗ |
pixelSize |
any |
let/var | this.pixelSize.value ? this.pixelSize.value : this.pixelSize |
✗ |
Functions¶
PixelationNode.updateBefore(): void
¶
JSDoc:
/**
* This method is used to update uniforms once per frame.
*
* @param {NodeFrame} frame - The current node frame.
*/
Returns: void
Calls:
this._resolution.value.set
Code
PixelationNode.setup(): ShaderCallNodeInternal
¶
JSDoc:
/**
* This method is used to setup the effect's TSL code.
*
* @param {NodeBuilder} builder - The current node builder.
* @return {ShaderCallNodeInternal}
*/
Returns: ShaderCallNodeInternal
Calls:
uv (from three/tsl)
textureNode.sample
depthNode.sample
uvNodeDepth.add
vec2( x, y ).mul
normalNode.sample( uvNodeNormal.add( vec2( x, y ).mul( this._resolution.zw ) ) ).rgb.normalize
property (from three/tsl)
diff.addAssign
clamp (from three/tsl)
sampleDepth( 1, 0 ).sub
sampleDepth( - 1, 0 ).sub
sampleDepth( 0, 1 ).sub
sampleDepth( 0, - 1 ).sub
floor( smoothstep( 0.01, 0.02, diff ).mul( 2 ) ).div
sampleDepth( x, y ).sub
sampleNormal
vec3 (from three/tsl)
dot (from three/tsl)
normal.sub
smoothstep (from three/tsl)
sign (from three/tsl)
depthDiff.mul( .25 ).add
float( 1.0 ).sub( dot( normal, neighborNormal ) ).mul( depthIndicator ).mul
indicator.addAssign
neighborNormalEdgeIndicator
step (from three/tsl)
Fn (from three/tsl)
sampleTexture
If (from three/tsl)
this.depthEdgeStrength.greaterThan( 0.0 ).or
this.normalEdgeStrength.greaterThan
depth.assign
sampleDepth
normal.assign
this.depthEdgeStrength.greaterThan
dei.assign
depthEdgeIndicator
nei.assign
normalEdgeIndicator
dei.greaterThan( 0 ).select
float( 1.0 ).sub
dei.mul
nei.mul( this.normalEdgeStrength ).add
texel.mul
pixelation
Internal Comments:
// Edge pixels should yield to faces who's normals are closer to the bias normal. (x2)
// Only the shallower pixel should detect the normal edge. (x2)
Code
setup() {
const { textureNode, depthNode, normalNode } = this;
const uvNodeTexture = textureNode.uvNode || uv();
const uvNodeDepth = depthNode.uvNode || uv();
const uvNodeNormal = normalNode.uvNode || uv();
const sampleTexture = () => textureNode.sample( uvNodeTexture );
const sampleDepth = ( x, y ) => depthNode.sample( uvNodeDepth.add( vec2( x, y ).mul( this._resolution.zw ) ) ).r;
const sampleNormal = ( x, y ) => normalNode.sample( uvNodeNormal.add( vec2( x, y ).mul( this._resolution.zw ) ) ).rgb.normalize();
const depthEdgeIndicator = ( depth ) => {
const diff = property( 'float', 'diff' );
diff.addAssign( clamp( sampleDepth( 1, 0 ).sub( depth ) ) );
diff.addAssign( clamp( sampleDepth( - 1, 0 ).sub( depth ) ) );
diff.addAssign( clamp( sampleDepth( 0, 1 ).sub( depth ) ) );
diff.addAssign( clamp( sampleDepth( 0, - 1 ).sub( depth ) ) );
return floor( smoothstep( 0.01, 0.02, diff ).mul( 2 ) ).div( 2 );
};
const neighborNormalEdgeIndicator = ( x, y, depth, normal ) => {
const depthDiff = sampleDepth( x, y ).sub( depth );
const neighborNormal = sampleNormal( x, y );
// Edge pixels should yield to faces who's normals are closer to the bias normal.
const normalEdgeBias = vec3( 1, 1, 1 ); // This should probably be a parameter.
const normalDiff = dot( normal.sub( neighborNormal ), normalEdgeBias );
const normalIndicator = clamp( smoothstep( - 0.01, 0.01, normalDiff ), 0.0, 1.0 );
// Only the shallower pixel should detect the normal edge.
const depthIndicator = clamp( sign( depthDiff.mul( .25 ).add( .0025 ) ), 0.0, 1.0 );
return float( 1.0 ).sub( dot( normal, neighborNormal ) ).mul( depthIndicator ).mul( normalIndicator );
};
const normalEdgeIndicator = ( depth, normal ) => {
const indicator = property( 'float', 'indicator' );
indicator.addAssign( neighborNormalEdgeIndicator( 0, - 1, depth, normal ) );
indicator.addAssign( neighborNormalEdgeIndicator( 0, 1, depth, normal ) );
indicator.addAssign( neighborNormalEdgeIndicator( - 1, 0, depth, normal ) );
indicator.addAssign( neighborNormalEdgeIndicator( 1, 0, depth, normal ) );
return step( 0.1, indicator );
};
const pixelation = Fn( () => {
const texel = sampleTexture();
const depth = property( 'float', 'depth' );
const normal = property( 'vec3', 'normal' );
If( this.depthEdgeStrength.greaterThan( 0.0 ).or( this.normalEdgeStrength.greaterThan( 0.0 ) ), () => {
depth.assign( sampleDepth( 0, 0 ) );
normal.assign( sampleNormal( 0, 0 ) );
} );
const dei = property( 'float', 'dei' );
If( this.depthEdgeStrength.greaterThan( 0.0 ), () => {
dei.assign( depthEdgeIndicator( depth ) );
} );
const nei = property( 'float', 'nei' );
If( this.normalEdgeStrength.greaterThan( 0.0 ), () => {
nei.assign( normalEdgeIndicator( depth, normal ) );
} );
const strength = dei.greaterThan( 0 ).select( float( 1.0 ).sub( dei.mul( this.depthEdgeStrength ) ), nei.mul( this.normalEdgeStrength ).add( 1 ) );
return texel.mul( strength );
} );
const outputNode = pixelation();
return outputNode;
}
sampleTexture(): any
¶
Returns: any
Calls:
textureNode.sample
sampleDepth(x: any, y: any): any
¶
Parameters:
x
any
y
any
Returns: any
sampleNormal(x: any, y: any): any
¶
Parameters:
x
any
y
any
Returns: any
Calls:
normalNode.sample( uvNodeNormal.add( vec2( x, y ).mul( this._resolution.zw ) ) ).rgb.normalize
Code
depthEdgeIndicator(depth: any): any
¶
Parameters:
depth
any
Returns: any
Calls:
property (from three/tsl)
diff.addAssign
clamp (from three/tsl)
sampleDepth( 1, 0 ).sub
sampleDepth( - 1, 0 ).sub
sampleDepth( 0, 1 ).sub
sampleDepth( 0, - 1 ).sub
floor( smoothstep( 0.01, 0.02, diff ).mul( 2 ) ).div
Code
( depth ) => {
const diff = property( 'float', 'diff' );
diff.addAssign( clamp( sampleDepth( 1, 0 ).sub( depth ) ) );
diff.addAssign( clamp( sampleDepth( - 1, 0 ).sub( depth ) ) );
diff.addAssign( clamp( sampleDepth( 0, 1 ).sub( depth ) ) );
diff.addAssign( clamp( sampleDepth( 0, - 1 ).sub( depth ) ) );
return floor( smoothstep( 0.01, 0.02, diff ).mul( 2 ) ).div( 2 );
}
neighborNormalEdgeIndicator(x: any, y: any, depth: any, normal: any): any
¶
Parameters:
x
any
y
any
depth
any
normal
any
Returns: any
Calls:
sampleDepth( x, y ).sub
sampleNormal
vec3 (from three/tsl)
dot (from three/tsl)
normal.sub
clamp (from three/tsl)
smoothstep (from three/tsl)
sign (from three/tsl)
depthDiff.mul( .25 ).add
float( 1.0 ).sub( dot( normal, neighborNormal ) ).mul( depthIndicator ).mul
Internal Comments:
// Edge pixels should yield to faces who's normals are closer to the bias normal. (x2)
// Only the shallower pixel should detect the normal edge. (x2)
Code
( x, y, depth, normal ) => {
const depthDiff = sampleDepth( x, y ).sub( depth );
const neighborNormal = sampleNormal( x, y );
// Edge pixels should yield to faces who's normals are closer to the bias normal.
const normalEdgeBias = vec3( 1, 1, 1 ); // This should probably be a parameter.
const normalDiff = dot( normal.sub( neighborNormal ), normalEdgeBias );
const normalIndicator = clamp( smoothstep( - 0.01, 0.01, normalDiff ), 0.0, 1.0 );
// Only the shallower pixel should detect the normal edge.
const depthIndicator = clamp( sign( depthDiff.mul( .25 ).add( .0025 ) ), 0.0, 1.0 );
return float( 1.0 ).sub( dot( normal, neighborNormal ) ).mul( depthIndicator ).mul( normalIndicator );
}
normalEdgeIndicator(depth: any, normal: any): any
¶
Parameters:
depth
any
normal
any
Returns: any
Calls:
property (from three/tsl)
indicator.addAssign
neighborNormalEdgeIndicator
step (from three/tsl)
Code
( depth, normal ) => {
const indicator = property( 'float', 'indicator' );
indicator.addAssign( neighborNormalEdgeIndicator( 0, - 1, depth, normal ) );
indicator.addAssign( neighborNormalEdgeIndicator( 0, 1, depth, normal ) );
indicator.addAssign( neighborNormalEdgeIndicator( - 1, 0, depth, normal ) );
indicator.addAssign( neighborNormalEdgeIndicator( 1, 0, depth, normal ) );
return step( 0.1, indicator );
}
pixelation(node: any, depthNode: any, normalNode: any, pixelSize: number, normalEdgeStrength: number, depthEdgeStrength: number): any
¶
Parameters:
node
any
depthNode
any
normalNode
any
pixelSize
number
normalEdgeStrength
number
depthEdgeStrength
number
Returns: any
Calls:
nodeObject (from three/tsl)
Code
( node, depthNode, normalNode, pixelSize = 6, normalEdgeStrength = 0.3, depthEdgeStrength = 0.4 ) => nodeObject( new PixelationNode( convertToTexture( node ), convertToTexture( depthNode ), convertToTexture( normalNode ), nodeObject( pixelSize ), nodeObject( normalEdgeStrength ), nodeObject( depthEdgeStrength ) ) )
PixelationPassNode.setSize(width: number, height: number): void
¶
JSDoc:
/**
* Sets the size of the pass.
*
* @param {number} width - The width of the pass.
* @param {number} height - The height of the pass.
*/
Parameters:
width
number
height
number
Returns: void
Calls:
Math.floor
super.setSize
Code
PixelationPassNode.setup(): PixelationNode
¶
JSDoc:
/**
* This method is used to setup the effect's TSL code.
*
* @param {NodeBuilder} builder - The current node builder.
* @return {PixelationNode}
*/
Returns: PixelationNode
Calls:
super.getTextureNode
pixelation
Code
pixelationPass(scene: Scene, camera: Camera, pixelSize: any, normalEdgeStrength: any, depthEdgeStrength: any): PixelationPassNode
¶
Parameters:
scene
Scene
camera
Camera
pixelSize
any
normalEdgeStrength
any
depthEdgeStrength
any
Returns: PixelationPassNode
Calls:
nodeObject (from three/tsl)
Code
Classes¶
PixelationNode
¶
Class Code
class PixelationNode extends TempNode {
static get type() {
return 'PixelationNode';
}
/**
* Constructs a new pixelation node.
*
* @param {TextureNode} textureNode - The texture node that represents the beauty pass.
* @param {TextureNode} depthNode - The texture that represents the beauty's depth.
* @param {TextureNode} normalNode - The texture that represents the beauty's normals.
* @param {Node<float>} pixelSize - The pixel size.
* @param {Node<float>} normalEdgeStrength - The normal edge strength.
* @param {Node<float>} depthEdgeStrength - The depth edge strength.
*/
constructor( textureNode, depthNode, normalNode, pixelSize, normalEdgeStrength, depthEdgeStrength ) {
super( 'vec4' );
/**
* The texture node that represents the beauty pass.
*
* @type {TextureNode}
*/
this.textureNode = textureNode;
/**
* The texture that represents the beauty's depth.
*
* @type {TextureNode}
*/
this.depthNode = depthNode;
/**
* The texture that represents the beauty's normals.
*
* @type {TextureNode}
*/
this.normalNode = normalNode;
/**
* The pixel size.
*
* @type {Node<float>}
*/
this.pixelSize = pixelSize;
/**
* The pixel size.
*
* @type {Node<float>}
*/
this.normalEdgeStrength = normalEdgeStrength;
/**
* The depth edge strength.
*
* @type {Node<float>}
*/
this.depthEdgeStrength = depthEdgeStrength;
/**
* Uniform node that represents the resolution.
*
* @type {Node<vec4>}
*/
this._resolution = uniform( new Vector4() );
/**
* The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node updates
* its internal uniforms once per frame in `updateBefore()`.
*
* @type {string}
* @default 'frame'
*/
this.updateBeforeType = NodeUpdateType.FRAME;
}
/**
* This method is used to update uniforms once per frame.
*
* @param {NodeFrame} frame - The current node frame.
*/
updateBefore() {
const map = this.textureNode.value;
const width = map.image.width;
const height = map.image.height;
this._resolution.value.set( width, height, 1 / width, 1 / height );
}
/**
* This method is used to setup the effect's TSL code.
*
* @param {NodeBuilder} builder - The current node builder.
* @return {ShaderCallNodeInternal}
*/
setup() {
const { textureNode, depthNode, normalNode } = this;
const uvNodeTexture = textureNode.uvNode || uv();
const uvNodeDepth = depthNode.uvNode || uv();
const uvNodeNormal = normalNode.uvNode || uv();
const sampleTexture = () => textureNode.sample( uvNodeTexture );
const sampleDepth = ( x, y ) => depthNode.sample( uvNodeDepth.add( vec2( x, y ).mul( this._resolution.zw ) ) ).r;
const sampleNormal = ( x, y ) => normalNode.sample( uvNodeNormal.add( vec2( x, y ).mul( this._resolution.zw ) ) ).rgb.normalize();
const depthEdgeIndicator = ( depth ) => {
const diff = property( 'float', 'diff' );
diff.addAssign( clamp( sampleDepth( 1, 0 ).sub( depth ) ) );
diff.addAssign( clamp( sampleDepth( - 1, 0 ).sub( depth ) ) );
diff.addAssign( clamp( sampleDepth( 0, 1 ).sub( depth ) ) );
diff.addAssign( clamp( sampleDepth( 0, - 1 ).sub( depth ) ) );
return floor( smoothstep( 0.01, 0.02, diff ).mul( 2 ) ).div( 2 );
};
const neighborNormalEdgeIndicator = ( x, y, depth, normal ) => {
const depthDiff = sampleDepth( x, y ).sub( depth );
const neighborNormal = sampleNormal( x, y );
// Edge pixels should yield to faces who's normals are closer to the bias normal.
const normalEdgeBias = vec3( 1, 1, 1 ); // This should probably be a parameter.
const normalDiff = dot( normal.sub( neighborNormal ), normalEdgeBias );
const normalIndicator = clamp( smoothstep( - 0.01, 0.01, normalDiff ), 0.0, 1.0 );
// Only the shallower pixel should detect the normal edge.
const depthIndicator = clamp( sign( depthDiff.mul( .25 ).add( .0025 ) ), 0.0, 1.0 );
return float( 1.0 ).sub( dot( normal, neighborNormal ) ).mul( depthIndicator ).mul( normalIndicator );
};
const normalEdgeIndicator = ( depth, normal ) => {
const indicator = property( 'float', 'indicator' );
indicator.addAssign( neighborNormalEdgeIndicator( 0, - 1, depth, normal ) );
indicator.addAssign( neighborNormalEdgeIndicator( 0, 1, depth, normal ) );
indicator.addAssign( neighborNormalEdgeIndicator( - 1, 0, depth, normal ) );
indicator.addAssign( neighborNormalEdgeIndicator( 1, 0, depth, normal ) );
return step( 0.1, indicator );
};
const pixelation = Fn( () => {
const texel = sampleTexture();
const depth = property( 'float', 'depth' );
const normal = property( 'vec3', 'normal' );
If( this.depthEdgeStrength.greaterThan( 0.0 ).or( this.normalEdgeStrength.greaterThan( 0.0 ) ), () => {
depth.assign( sampleDepth( 0, 0 ) );
normal.assign( sampleNormal( 0, 0 ) );
} );
const dei = property( 'float', 'dei' );
If( this.depthEdgeStrength.greaterThan( 0.0 ), () => {
dei.assign( depthEdgeIndicator( depth ) );
} );
const nei = property( 'float', 'nei' );
If( this.normalEdgeStrength.greaterThan( 0.0 ), () => {
nei.assign( normalEdgeIndicator( depth, normal ) );
} );
const strength = dei.greaterThan( 0 ).select( float( 1.0 ).sub( dei.mul( this.depthEdgeStrength ) ), nei.mul( this.normalEdgeStrength ).add( 1 ) );
return texel.mul( strength );
} );
const outputNode = pixelation();
return outputNode;
}
}
Methods¶
updateBefore(): void
¶
Code
setup(): ShaderCallNodeInternal
¶
Code
setup() {
const { textureNode, depthNode, normalNode } = this;
const uvNodeTexture = textureNode.uvNode || uv();
const uvNodeDepth = depthNode.uvNode || uv();
const uvNodeNormal = normalNode.uvNode || uv();
const sampleTexture = () => textureNode.sample( uvNodeTexture );
const sampleDepth = ( x, y ) => depthNode.sample( uvNodeDepth.add( vec2( x, y ).mul( this._resolution.zw ) ) ).r;
const sampleNormal = ( x, y ) => normalNode.sample( uvNodeNormal.add( vec2( x, y ).mul( this._resolution.zw ) ) ).rgb.normalize();
const depthEdgeIndicator = ( depth ) => {
const diff = property( 'float', 'diff' );
diff.addAssign( clamp( sampleDepth( 1, 0 ).sub( depth ) ) );
diff.addAssign( clamp( sampleDepth( - 1, 0 ).sub( depth ) ) );
diff.addAssign( clamp( sampleDepth( 0, 1 ).sub( depth ) ) );
diff.addAssign( clamp( sampleDepth( 0, - 1 ).sub( depth ) ) );
return floor( smoothstep( 0.01, 0.02, diff ).mul( 2 ) ).div( 2 );
};
const neighborNormalEdgeIndicator = ( x, y, depth, normal ) => {
const depthDiff = sampleDepth( x, y ).sub( depth );
const neighborNormal = sampleNormal( x, y );
// Edge pixels should yield to faces who's normals are closer to the bias normal.
const normalEdgeBias = vec3( 1, 1, 1 ); // This should probably be a parameter.
const normalDiff = dot( normal.sub( neighborNormal ), normalEdgeBias );
const normalIndicator = clamp( smoothstep( - 0.01, 0.01, normalDiff ), 0.0, 1.0 );
// Only the shallower pixel should detect the normal edge.
const depthIndicator = clamp( sign( depthDiff.mul( .25 ).add( .0025 ) ), 0.0, 1.0 );
return float( 1.0 ).sub( dot( normal, neighborNormal ) ).mul( depthIndicator ).mul( normalIndicator );
};
const normalEdgeIndicator = ( depth, normal ) => {
const indicator = property( 'float', 'indicator' );
indicator.addAssign( neighborNormalEdgeIndicator( 0, - 1, depth, normal ) );
indicator.addAssign( neighborNormalEdgeIndicator( 0, 1, depth, normal ) );
indicator.addAssign( neighborNormalEdgeIndicator( - 1, 0, depth, normal ) );
indicator.addAssign( neighborNormalEdgeIndicator( 1, 0, depth, normal ) );
return step( 0.1, indicator );
};
const pixelation = Fn( () => {
const texel = sampleTexture();
const depth = property( 'float', 'depth' );
const normal = property( 'vec3', 'normal' );
If( this.depthEdgeStrength.greaterThan( 0.0 ).or( this.normalEdgeStrength.greaterThan( 0.0 ) ), () => {
depth.assign( sampleDepth( 0, 0 ) );
normal.assign( sampleNormal( 0, 0 ) );
} );
const dei = property( 'float', 'dei' );
If( this.depthEdgeStrength.greaterThan( 0.0 ), () => {
dei.assign( depthEdgeIndicator( depth ) );
} );
const nei = property( 'float', 'nei' );
If( this.normalEdgeStrength.greaterThan( 0.0 ), () => {
nei.assign( normalEdgeIndicator( depth, normal ) );
} );
const strength = dei.greaterThan( 0 ).select( float( 1.0 ).sub( dei.mul( this.depthEdgeStrength ) ), nei.mul( this.normalEdgeStrength ).add( 1 ) );
return texel.mul( strength );
} );
const outputNode = pixelation();
return outputNode;
}
PixelationPassNode
¶
Class Code
class PixelationPassNode extends PassNode {
static get type() {
return 'PixelationPassNode';
}
/**
* Constructs a new pixelation pass node.
*
* @param {Scene} scene - The scene to render.
* @param {Camera} camera - The camera to render the scene with.
* @param {Node<float> | number} [pixelSize=6] - The pixel size.
* @param {Node<float> | number} [normalEdgeStrength=0.3] - The normal edge strength.
* @param {Node<float> | number} [depthEdgeStrength=0.4] - The depth edge strength.
*/
constructor( scene, camera, pixelSize = 6, normalEdgeStrength = 0.3, depthEdgeStrength = 0.4 ) {
super( PassNode.COLOR, scene, camera, { minFilter: NearestFilter, magFilter: NearestFilter } );
/**
* The pixel size.
*
* @type {number}
* @default 6
*/
this.pixelSize = pixelSize;
/**
* The normal edge strength.
*
* @type {number}
* @default 0.3
*/
this.normalEdgeStrength = normalEdgeStrength;
/**
* The depth edge strength.
*
* @type {number}
* @default 0.4
*/
this.depthEdgeStrength = depthEdgeStrength;
/**
* This flag can be used for type testing.
*
* @type {boolean}
* @readonly
* @default true
*/
this.isPixelationPassNode = true;
this._mrt = mrt( {
output: output,
normal: normalView
} );
}
/**
* Sets the size of the pass.
*
* @param {number} width - The width of the pass.
* @param {number} height - The height of the pass.
*/
setSize( width, height ) {
const pixelSize = this.pixelSize.value ? this.pixelSize.value : this.pixelSize;
const adjustedWidth = Math.floor( width / pixelSize );
const adjustedHeight = Math.floor( height / pixelSize );
super.setSize( adjustedWidth, adjustedHeight );
}
/**
* This method is used to setup the effect's TSL code.
*
* @param {NodeBuilder} builder - The current node builder.
* @return {PixelationNode}
*/
setup() {
const color = super.getTextureNode( 'output' );
const depth = super.getTextureNode( 'depth' );
const normal = super.getTextureNode( 'normal' );
return pixelation( color, depth, normal, this.pixelSize, this.normalEdgeStrength, this.depthEdgeStrength );
}
}