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
1 change: 1 addition & 0 deletions src/Three.TSL.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export const addNodeElement = TSL.addNodeElement;
export const agxToneMapping = TSL.agxToneMapping;
export const all = TSL.all;
export const alphaT = TSL.alphaT;
export const ambientOcclusion = TSL.ambientOcclusion;
export const and = TSL.and;
export const anisotropy = TSL.anisotropy;
export const anisotropyB = TSL.anisotropyB;
Expand Down
29 changes: 24 additions & 5 deletions src/materials/nodes/NodeMaterial.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Material } from '../Material.js';

import { hashArray, hashString } from '../../nodes/core/NodeUtils.js';
import { output, diffuseColor, emissive } from '../../nodes/core/PropertyNode.js';
import { output, diffuseColor, ambientOcclusion, emissive } from '../../nodes/core/PropertyNode.js';
import { materialAlphaTest, materialColor, materialOpacity, materialEmissive, materialNormal, materialLightMap, materialAO } from '../../nodes/accessors/MaterialNode.js';
import { modelViewProjection } from '../../nodes/accessors/ModelViewProjectionNode.js';
import { normalLocal } from '../../nodes/accessors/Normal.js';
Expand Down Expand Up @@ -523,6 +523,7 @@ class NodeMaterial extends Material {
if ( this.fragmentNode === null ) {

this.setupDiffuseColor( builder );
this.setupAmbientOcclusion( builder );
this.setupVariants( builder );

const outgoingLightNode = this.setupLighting( builder );
Expand Down Expand Up @@ -1015,6 +1016,24 @@ class NodeMaterial extends Material {

}

if ( builder.context.ambientOcclusion ) {

materialLightsNode.push( new AONode( builder.context.ambientOcclusion ) );

}

return materialLightsNode;

}

/**
* Setups the ambient occlusion node from the material.
*
* @param {NodeBuilder} builder - The current node builder.
* @return {Node} The ambient occlusion node.
*/
setupAmbientOcclusion( builder ) {

let aoNode = this.aoNode;

if ( aoNode === null && builder.material.aoMap ) {
Expand All @@ -1029,13 +1048,13 @@ class NodeMaterial extends Material {

}

if ( aoNode ) {
if ( aoNode !== null ) {

materialLightsNode.push( new AONode( aoNode ) );
ambientOcclusion.assign( aoNode );

}
builder.context.ambientOcclusion = ambientOcclusion;

return materialLightsNode;
}

}

Expand Down
20 changes: 18 additions & 2 deletions src/nodes/accessors/MaterialNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,11 +388,27 @@ class MaterialNode extends Node {

} else if ( scope === MaterialNode.LIGHT_MAP ) {

node = this.getTexture( scope ).rgb.mul( this.getFloat( 'lightMapIntensity' ) );
if ( material.lightMap ) {

node = this.getTexture( scope ).rgb.mul( this.getFloat( 'lightMapIntensity' ) );

} else {

node = vec3( 0.0 );

}

} else if ( scope === MaterialNode.AO ) {

node = this.getTexture( scope ).r.sub( 1.0 ).mul( this.getFloat( 'aoMapIntensity' ) ).add( 1.0 );
if ( material.aoMap ) {

node = this.getTexture( scope ).r.sub( 1.0 ).mul( this.getFloat( 'aoMapIntensity' ) ).add( 1.0 );

} else {

node = float( 1.0 );

}

} else if ( scope === MaterialNode.LINE_DASH_OFFSET ) {

Expand Down
79 changes: 76 additions & 3 deletions src/nodes/core/NodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const typeFromArray = new Map( [
[ Float32Array, 'float' ]
] );

const toFloat = ( value ) => {
const _toFloat = ( value ) => {

if ( /e/g.test( value ) ) {

Expand All @@ -65,6 +65,28 @@ const toFloat = ( value ) => {

};

const _checkWriteUsage = ( data ) => {

if ( data.writeUsageCount > 0 ) return true;

if ( data.subBuildsCache !== undefined ) {

for ( const subBuild in data.subBuildsCache ) {

if ( _checkWriteUsage( data.subBuildsCache[ subBuild ] ) ) {

return true;

}

}

}

return false;

};

/**
* Base class for builders which generate a shader program based
* on a 3D object and its node material definition.
Expand Down Expand Up @@ -1208,6 +1230,17 @@ class NodeBuilder {

}

/**
* Returns whether the builder is currently in an assignment context.
*
* @return {boolean} Whether the builder is in an assignment context.
*/
isContextAssign() {

return this.context.assign === true;

}

/**
* Calling this method increases the usage count for the given node by one.
*
Expand All @@ -1219,10 +1252,50 @@ class NodeBuilder {
const nodeData = this.getDataFromNode( node );
nodeData.usageCount = nodeData.usageCount === undefined ? 1 : nodeData.usageCount + 1;

if ( this.isContextAssign() ) {

nodeData.writeUsageCount = nodeData.writeUsageCount === undefined ? 1 : nodeData.writeUsageCount + 1;

} else {

nodeData.readUsageCount = nodeData.readUsageCount === undefined ? 1 : nodeData.readUsageCount + 1;

}

return nodeData.usageCount;

}

/**
* Returns whether the given node has been written to in any shader stage.
*
* @param {Node} node - The node to check.
* @return {boolean} Whether the node has been written to.
*/
hasWriteUsage( node ) {

const refNode = node.getShared( this );
const cache = refNode.isGlobal( this ) ? this.globalCache : this.cache;
const nodeData = cache.getData( refNode );

if ( nodeData !== undefined ) {

for ( const shaderStage in nodeData ) {

if ( _checkWriteUsage( nodeData[ shaderStage ] ) ) {

return true;

}

}

}

return false;

}

/**
* Generates a texture sample shader string for the given texture data.
*
Expand Down Expand Up @@ -1356,11 +1429,11 @@ class NodeBuilder {

}

if ( type === 'float' ) return toFloat( value );
if ( type === 'float' ) return _toFloat( value );
if ( type === 'int' ) return `${ Math.round( value ) }`;
if ( type === 'uint' ) return value >= 0 ? `${ Math.round( value ) }u` : '0u';
if ( type === 'bool' ) return value ? 'true' : 'false';
if ( type === 'color' ) return `${ this.getType( 'vec3' ) }( ${ toFloat( value.r ) }, ${ toFloat( value.g ) }, ${ toFloat( value.b ) } )`;
if ( type === 'color' ) return `${ this.getType( 'vec3' ) }( ${ _toFloat( value.r ) }, ${ _toFloat( value.g ) }, ${ _toFloat( value.b ) } )`;

const typeLength = this.getTypeLength( type );

Expand Down
40 changes: 36 additions & 4 deletions src/nodes/core/PropertyNode.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Node from './Node.js';
import { nodeImmutable } from '../tsl/TSLCore.js';
import { nodeImmutable, nodeObject } from '../tsl/TSLCore.js';
import { hashString } from './NodeUtils.js';

/**
Expand Down Expand Up @@ -28,8 +28,9 @@ class PropertyNode extends Node {
* @param {string} nodeType - The type of the node.
* @param {?string} [name=null] - The name of the property in the shader.
* @param {boolean} [varying=false] - Whether this property is a varying or not.
* @param {?Node} [placeholderNode=null] - The placeholder node if not assigned.
*/
constructor( nodeType, name = null, varying = false ) {
constructor( nodeType, name = null, varying = false, placeholderNode = null ) {

super( nodeType );

Expand All @@ -50,6 +51,14 @@ class PropertyNode extends Node {
*/
this.varying = varying;

/**
* The placeholder node of the property if it is not assigned.
*
* @type {?Node}
* @default null
*/
this.placeholderNode = nodeObject( placeholderNode );

/**
* This flag can be used for type testing.
*
Expand Down Expand Up @@ -108,6 +117,18 @@ class PropertyNode extends Node {

nodeVar = builder.getVarFromNode( this, this.name );

if ( this.placeholderNode !== null ) {

if ( builder.hasWriteUsage( this ) === false ) {

const snippet = this.placeholderNode.build( builder, this.getNodeType( builder ) );

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

}

}

}

return builder.getPropertyName( nodeVar );
Expand All @@ -125,9 +146,10 @@ export default PropertyNode;
* @function
* @param {string} type - The type of the node.
* @param {?string} [name=null] - The name of the property in the shader.
* @param {?Node} [placeholderNode=null] - The placeholder node if not assigned.
* @returns {PropertyNode}
*/
export const property = ( type, name ) => new PropertyNode( type, name );
export const property = ( type, name, placeholderNode = null ) => new PropertyNode( type, name, false, placeholderNode );

/**
* TSL function for creating a varying property node.
Expand All @@ -136,9 +158,10 @@ export const property = ( type, name ) => new PropertyNode( type, name );
* @function
* @param {string} type - The type of the node.
* @param {?string} [name=null] - The name of the varying in the shader.
* @param {?Node} [placeholderNode=null] - The placeholder node if not assigned.
* @returns {PropertyNode}
*/
export const varyingProperty = ( type, name ) => new PropertyNode( type, name, true );
export const varyingProperty = ( type, name, placeholderNode = null ) => new PropertyNode( type, name, true, placeholderNode );

/**
* TSL object that represents the shader variable `DiffuseColor`.
Expand Down Expand Up @@ -379,3 +402,12 @@ export const attenuationColor = /*@__PURE__*/ nodeImmutable( PropertyNode, 'colo
* @type {PropertyNode<float>}
*/
export const dispersion = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'Dispersion' );

/**
* TSL object that represents the shader variable `AmbientOcclusion`.
* If no value is assigned to this property, it defaults to a placeholder value of `1.0`.
*
* @tsl
* @type {PropertyNode<float>}
*/
export const ambientOcclusion = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'AmbientOcclusion', false, 1 );
2 changes: 1 addition & 1 deletion src/nodes/gpgpu/WorkgroupInfoNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class WorkgroupInfoElementNode extends ArrayElementNode {

let snippet;

const isAssignContext = builder.context.assign;
const isAssignContext = builder.isContextAssign();
snippet = super.generate( builder );

if ( isAssignContext !== true ) {
Expand Down
2 changes: 1 addition & 1 deletion src/nodes/utils/StorageArrayElementNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class StorageArrayElementNode extends ArrayElementNode {

let snippet;

const isAssignContext = builder.context.assign;
const isAssignContext = builder.isContextAssign();

//

Expand Down