Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
13 changes: 13 additions & 0 deletions src/nodes/accessors/Texture3DNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,19 @@ class Texture3DNode extends TextureNode {

}

/**
* Generates the offset code snippet.
*
* @param {NodeBuilder} builder - The current node builder.
* @param {Node} offsetNode - The offset node to generate code for.
* @return {string} The generated code snippet.
*/
generateOffset( builder, offsetNode ) {

return offsetNode.build( builder, 'ivec3' );

}

/**
* TODO.
*
Expand Down
60 changes: 51 additions & 9 deletions src/nodes/accessors/TextureNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ class TextureNode extends UniformNode {
*/
this.gradNode = null;

/**
* Represents the optional texel offset applied to the unnormalized texture
* coordinate before sampling the texture.
*
* @type {?Node<ivec2|ivec3>}
* @default null
*/
this.offsetNode = null;

/**
* Whether texture values should be sampled or fetched.
*
Expand Down Expand Up @@ -364,6 +373,7 @@ class TextureNode extends UniformNode {
properties.compareNode = this.compareNode;
properties.gradNode = this.gradNode;
properties.depthNode = this.depthNode;
properties.offsetNode = this.offsetNode;

}

Expand All @@ -380,6 +390,19 @@ class TextureNode extends UniformNode {

}

/**
* Generates the offset code snippet.
*
* @param {NodeBuilder} builder - The current node builder.
* @param {Node} offsetNode - The offset node to generate code for.
* @return {string} The generated code snippet.
*/
generateOffset( builder, offsetNode ) {

return offsetNode.build( builder, 'ivec2' );

}

/**
* Generates the snippet for the texture sampling.
*
Expand All @@ -391,37 +414,38 @@ class TextureNode extends UniformNode {
* @param {?string} depthSnippet - The depth snippet.
* @param {?string} compareSnippet - The compare snippet.
* @param {?Array<string>} gradSnippet - The grad snippet.
* @param {?string} offsetSnippet - The offset snippet.
* @return {string} The generated code snippet.
*/
generateSnippet( builder, textureProperty, uvSnippet, levelSnippet, biasSnippet, depthSnippet, compareSnippet, gradSnippet ) {
generateSnippet( builder, textureProperty, uvSnippet, levelSnippet, biasSnippet, depthSnippet, compareSnippet, gradSnippet, offsetSnippet ) {

const texture = this.value;

let snippet;

if ( levelSnippet ) {

snippet = builder.generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet );
snippet = builder.generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet, offsetSnippet );

} else if ( biasSnippet ) {

snippet = builder.generateTextureBias( texture, textureProperty, uvSnippet, biasSnippet, depthSnippet );
snippet = builder.generateTextureBias( texture, textureProperty, uvSnippet, biasSnippet, depthSnippet, offsetSnippet );

} else if ( gradSnippet ) {

snippet = builder.generateTextureGrad( texture, textureProperty, uvSnippet, gradSnippet, depthSnippet );
snippet = builder.generateTextureGrad( texture, textureProperty, uvSnippet, gradSnippet, depthSnippet, offsetSnippet );

} else if ( compareSnippet ) {

snippet = builder.generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet );
snippet = builder.generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet, offsetSnippet );

} else if ( this.sampler === false ) {

snippet = builder.generateTextureLoad( texture, textureProperty, uvSnippet, depthSnippet );
snippet = builder.generateTextureLoad( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet );

} else {

snippet = builder.generateTexture( texture, textureProperty, uvSnippet, depthSnippet );
snippet = builder.generateTexture( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet );

}

Expand Down Expand Up @@ -459,20 +483,21 @@ class TextureNode extends UniformNode {

if ( propertyName === undefined ) {

const { uvNode, levelNode, biasNode, compareNode, depthNode, gradNode } = properties;
const { uvNode, levelNode, biasNode, compareNode, depthNode, gradNode, offsetNode } = properties;

const uvSnippet = this.generateUV( builder, uvNode );
const levelSnippet = levelNode ? levelNode.build( builder, 'float' ) : null;
const biasSnippet = biasNode ? biasNode.build( builder, 'float' ) : null;
const depthSnippet = depthNode ? depthNode.build( builder, 'int' ) : null;
const compareSnippet = compareNode ? compareNode.build( builder, 'float' ) : null;
const gradSnippet = gradNode ? [ gradNode[ 0 ].build( builder, 'vec2' ), gradNode[ 1 ].build( builder, 'vec2' ) ] : null;
const offsetSnippet = offsetNode ? this.generateOffset( builder, offsetNode ) : null;

const nodeVar = builder.getVarFromNode( this );

propertyName = builder.getPropertyName( nodeVar );

const snippet = this.generateSnippet( builder, textureProperty, uvSnippet, levelSnippet, biasSnippet, depthSnippet, compareSnippet, gradSnippet );
const snippet = this.generateSnippet( builder, textureProperty, uvSnippet, levelSnippet, biasSnippet, depthSnippet, compareSnippet, gradSnippet, offsetSnippet );

builder.addLineFlowCode( `${propertyName} = ${snippet}`, this );

Expand Down Expand Up @@ -695,6 +720,22 @@ class TextureNode extends UniformNode {

}

/**
* Samples the texture by defining an offset node.
*
* @param {Node<ivec2>} offsetNode - The offset node.
* @return {TextureNode} A texture node representing the texture sample.
*/
offset( offsetNode ) {

const textureNode = this.clone();
textureNode.offsetNode = nodeObject( offsetNode );
textureNode.referenceNode = this.getBase();

return nodeObject( textureNode );

}

// --

serialize( data ) {
Expand Down Expand Up @@ -749,6 +790,7 @@ class TextureNode extends UniformNode {
newNode.depthNode = this.depthNode;
newNode.compareNode = this.compareNode;
newNode.gradNode = this.gradNode;
newNode.offsetNode = this.offsetNode;

return newNode;

Expand Down
74 changes: 67 additions & 7 deletions src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ ${ flowData.code }
const channel = '.' + vectorComponents.join( '' ).slice( 0, itemSize );
const uvSnippet = `ivec2(${indexSnippet} % ${ propertySizeName }, ${indexSnippet} / ${ propertySizeName })`;

const snippet = this.generateTextureLoad( null, textureName, uvSnippet, null, '0' );
const snippet = this.generateTextureLoad( null, textureName, uvSnippet, null, null, '0' );

//

Expand Down Expand Up @@ -384,17 +384,30 @@ ${ flowData.code }
* @param {string} textureProperty - The name of the texture uniform in the shader.
* @param {string} uvIndexSnippet - A GLSL snippet that represents texture coordinates used for sampling.
* @param {?string} depthSnippet - A GLSL snippet that represents the 0-based texture array index to sample.
* @param {?string} offsetSnippet - A GLSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
* @param {string} [levelSnippet='0u'] - A GLSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
* @return {string} The GLSL snippet.
*/
generateTextureLoad( texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0' ) {
generateTextureLoad( texture, textureProperty, uvIndexSnippet, depthSnippet, offsetSnippet, levelSnippet = '0' ) {

if ( depthSnippet ) {

if ( offsetSnippet ) {

return `texelFetchOffset( ${ textureProperty }, ivec3( ${ uvIndexSnippet }, ${ depthSnippet } ), ${ levelSnippet }, ${ offsetSnippet } )`;

}

return `texelFetch( ${ textureProperty }, ivec3( ${ uvIndexSnippet }, ${ depthSnippet } ), ${ levelSnippet } )`;

} else {

if ( offsetSnippet ) {

return `texelFetchOffset( ${ textureProperty }, ${ uvIndexSnippet }, ${ levelSnippet }, ${ offsetSnippet } )`;

}

return `texelFetch( ${ textureProperty }, ${ uvIndexSnippet }, ${ levelSnippet } )`;

}
Expand All @@ -408,20 +421,33 @@ ${ flowData.code }
* @param {string} textureProperty - The name of the texture uniform in the shader.
* @param {string} uvSnippet - A GLSL snippet that represents texture coordinates used for sampling.
* @param {?string} depthSnippet - A GLSL snippet that represents the 0-based texture array index to sample.
* @param {?string} offsetSnippet - A GLSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
* @return {string} The GLSL snippet.
*/
generateTexture( texture, textureProperty, uvSnippet, depthSnippet ) {
generateTexture( texture, textureProperty, uvSnippet, depthSnippet, offsetSnippet ) {

if ( texture.isDepthTexture ) {

if ( depthSnippet ) uvSnippet = `vec4( ${ uvSnippet }, ${ depthSnippet } )`;

if ( offsetSnippet ) {

return `textureOffset( ${ textureProperty }, ${ uvSnippet }, ${ offsetSnippet } ).x`;

}

return `texture( ${ textureProperty }, ${ uvSnippet } ).x`;

} else {

if ( depthSnippet ) uvSnippet = `vec3( ${ uvSnippet }, ${ depthSnippet } )`;

if ( offsetSnippet ) {

return `textureOffset( ${ textureProperty }, ${ uvSnippet }, ${ offsetSnippet } )`;

}

return `texture( ${ textureProperty }, ${ uvSnippet } )`;

}
Expand All @@ -435,9 +461,16 @@ ${ flowData.code }
* @param {string} textureProperty - The name of the texture uniform in the shader.
* @param {string} uvSnippet - A GLSL snippet that represents texture coordinates used for sampling.
* @param {string} levelSnippet - A GLSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
* @param {?string} offsetSnippet - A GLSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
* @return {string} The GLSL snippet.
*/
generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet ) {
generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet, offsetSnippet ) {

if ( offsetSnippet ) {

return `textureLodOffset( ${ textureProperty }, ${ uvSnippet }, ${ levelSnippet }, ${ offsetSnippet } )`;

}

return `textureLod( ${ textureProperty }, ${ uvSnippet }, ${ levelSnippet } )`;

Expand All @@ -450,9 +483,16 @@ ${ flowData.code }
* @param {string} textureProperty - The name of the texture uniform in the shader.
* @param {string} uvSnippet - A GLSL snippet that represents texture coordinates used for sampling.
* @param {string} biasSnippet - A GLSL snippet that represents the bias to apply to the mip level before sampling.
* @param {?string} offsetSnippet - A GLSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
* @return {string} The GLSL snippet.
*/
generateTextureBias( texture, textureProperty, uvSnippet, biasSnippet ) {
generateTextureBias( texture, textureProperty, uvSnippet, biasSnippet, offsetSnippet ) {

if ( offsetSnippet ) {

return `textureOffset( ${ textureProperty }, ${ uvSnippet }, ${ offsetSnippet }, ${ biasSnippet } )`;

}

return `texture( ${ textureProperty }, ${ uvSnippet }, ${ biasSnippet } )`;

Expand All @@ -465,9 +505,16 @@ ${ flowData.code }
* @param {string} textureProperty - The name of the texture uniform in the shader.
* @param {string} uvSnippet - A GLSL snippet that represents texture coordinates used for sampling.
* @param {Array<string>} gradSnippet - An array holding both gradient GLSL snippets.
* @param {?string} offsetSnippet - A GLSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
* @return {string} The GLSL snippet.
*/
generateTextureGrad( texture, textureProperty, uvSnippet, gradSnippet ) {
generateTextureGrad( texture, textureProperty, uvSnippet, gradSnippet, offsetSnippet ) {

if ( offsetSnippet ) {

return `textureGradOffset( ${ textureProperty }, ${ uvSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] }, ${ offsetSnippet } )`;

}

return `textureGrad( ${ textureProperty }, ${ uvSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] } )`;

Expand All @@ -482,19 +529,32 @@ ${ flowData.code }
* @param {string} uvSnippet - A GLSL snippet that represents texture coordinates used for sampling.
* @param {string} compareSnippet - A GLSL snippet that represents the reference value.
* @param {?string} depthSnippet - A GLSL snippet that represents 0-based texture array index to sample.
* @param {?string} offsetSnippet - A GLSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
* @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
* @return {string} The GLSL snippet.
*/
generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet, shaderStage = this.shaderStage ) {
generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet, offsetSnippet, shaderStage = this.shaderStage ) {

if ( shaderStage === 'fragment' ) {

if ( depthSnippet ) {

if ( offsetSnippet ) {

return `textureOffset( ${ textureProperty }, vec4( ${ uvSnippet }, ${ depthSnippet }, ${ compareSnippet } ), ${ offsetSnippet } )`;

}

return `texture( ${ textureProperty }, vec4( ${ uvSnippet }, ${ depthSnippet }, ${ compareSnippet } ) )`;

}

if ( offsetSnippet ) {

return `textureOffset( ${ textureProperty }, vec3( ${ uvSnippet }, ${ compareSnippet } ), ${ offsetSnippet } )`;

}

return `texture( ${ textureProperty }, vec3( ${ uvSnippet }, ${ compareSnippet } ) )`;

} else {
Expand Down
Loading
Loading