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
3 changes: 3 additions & 0 deletions src/Three.TSL.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ export const Fn = TSL.Fn;
export const HALF_PI = TSL.HALF_PI;
export const INFINITY = TSL.INFINITY;
export const If = TSL.If;
export const LTC_Evaluate = TSL.LTC_Evaluate;
export const LTC_Evaluate_Volume = TSL.LTC_Evaluate_Volume;
export const LTC_Uv = TSL.LTC_Uv;
export const Loop = TSL.Loop;
export const NodeAccess = TSL.NodeAccess;
export const NodeShaderStage = TSL.NodeShaderStage;
Expand Down
28 changes: 24 additions & 4 deletions src/materials/nodes/manager/NodeMaterialObserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -787,11 +787,15 @@ class NodeMaterialObserver {
for ( let i = 0; i < lightsData.length; i ++ ) {

const lightData = renderObjectData.lights[ i ];
const currentLightData = lightsData[ i ];

if ( lightData.map !== lightsData[ i ].map || lightData.cacheVersion !== lightsData[ i ].cacheVersion ) {
if ( lightData.map !== currentLightData.map || lightData.cacheVersion !== currentLightData.cacheVersion ||
lightData.shadowMapWidth !== currentLightData.shadowMapWidth || lightData.shadowMapHeight !== currentLightData.shadowMapHeight ) {

lightData.map = lightsData[ i ].map;
lightData.cacheVersion = lightsData[ i ].cacheVersion;
lightData.map = currentLightData.map;
lightData.cacheVersion = currentLightData.cacheVersion;
lightData.shadowMapWidth = currentLightData.shadowMapWidth;
lightData.shadowMapHeight = currentLightData.shadowMapHeight;

return false;

Expand Down Expand Up @@ -857,14 +861,30 @@ class NodeMaterialObserver {

for ( const light of materialLights ) {

let data = null;

if ( light.isSpotLight === true && light.map !== null ) {

// only add lights that have a map

lights.push( { map: light.map.version, cacheVersion: this.getTextureData( light.map )._version } );
data = { map: light.map.version, cacheVersion: this.getTextureData( light.map )._version };

}

if ( light.castShadow === true && light.shadow !== undefined ) {

// resizing a shadow map recreates its textures so the bindings
// of all related render objects must be updated

if ( data === null ) data = {};

data.shadowMapWidth = light.shadow.mapSize.width;
data.shadowMapHeight = light.shadow.mapSize.height;

}

if ( data !== null ) lights.push( data );

}

return lights;
Expand Down
1 change: 1 addition & 0 deletions src/nodes/TSL.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ export { default as F_Schlick } from './functions/BSDF/F_Schlick.js';
export { default as Schlick_to_F0 } from './functions/BSDF/Schlick_to_F0.js';
export { default as V_GGX_SmithCorrelated } from './functions/BSDF/V_GGX_SmithCorrelated.js';
export { default as V_GGX_SmithCorrelated_Anisotropic } from './functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js';
export { LTC_Evaluate, LTC_Evaluate_Volume, LTC_Uv } from './functions/BSDF/LTC.js';

export * from './lighting/LightUtils.js';

Expand Down
2 changes: 1 addition & 1 deletion src/nodes/functions/BSDF/LTC.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ const LTC_Evaluate_Volume = /*@__PURE__*/ Fn( ( { P, p0, p1, p2, p3 } ) => {
return result;

} ).setLayout( {
name: 'LTC_Evaluate',
name: 'LTC_Evaluate_Volume',
type: 'vec3',
inputs: [
{ name: 'P', type: 'vec3' },
Expand Down
6 changes: 0 additions & 6 deletions src/nodes/lighting/LightsNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,6 @@ class LightsNode extends Node {
_hashData.push( light.id );
_hashData.push( light.castShadow ? 1 : 0 );

if ( light.castShadow === true && light.shadow !== undefined ) {

_hashData.push( light.shadow.mapSize.width, light.shadow.mapSize.height );

}

if ( light.isSpotLight === true ) {

const hashMap = ( light.map !== null ) ? light.map.id : - 1;
Expand Down
2 changes: 1 addition & 1 deletion src/nodes/parsers/GLSLNodeFunction.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const parse = ( source ) => {

const pragmaMainIndex = source.indexOf( pragmaMain );

const mainCode = pragmaMainIndex !== - 1 ? source.slice( pragmaMainIndex + pragmaMain.length ) : source;
const mainCode = ( pragmaMainIndex !== - 1 ? source.slice( pragmaMainIndex + pragmaMain.length ) : source ).replace( /^(?:\s*\/\/[^\r\n]*|\s*\/\*[\s\S]*?\*\/|\s*)+/, '' );

const declaration = mainCode.match( declarationRegexp );

Expand Down
2 changes: 1 addition & 1 deletion src/renderers/webgpu/nodes/WGSLNodeFunction.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const wgslTypeLib = {

const parse = ( source ) => {

source = source.trim();
source = source.replace( /^(?:\s*\/\/[^\r\n]*|\s*\/\*[\s\S]*?\*\/|\s*)+/, '' );

const declaration = source.match( declarationRegexp );

Expand Down
2 changes: 1 addition & 1 deletion test/unit/UnitTests.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<script type="importmap">
{
"imports": {
"three": "../../build/three.module.js"
"three": "../../src/Three.js"
}
}
</script>
Expand Down
6 changes: 3 additions & 3 deletions test/unit/UnitTestsAddons.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
<script type="importmap">
{
"imports": {
"three": "../../build/three.module.js",
"three/webgpu": "../../build/three.webgpu.js",
"three/tsl": "../../build/three.tsl.js"
"three": "../../src/Three.js",
"three/webgpu": "../../src/Three.WebGPU.js",
"three/tsl": "../../src/Three.TSL.js"
}
}
</script>
Expand Down
63 changes: 63 additions & 0 deletions test/unit/addons/tsl/TSL.Irradiance.tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { SphericalHarmonics3, Vector3 } from 'three';
import { vec3, array, getShIrradianceAt } from 'three/tsl';
import { gpuTest } from './gpu-test-utils.js';

// Coverage for src/nodes/functions/material/getShIrradianceAt.js. Its 9-term
// spherical harmonics evaluation is a direct port of
// SphericalHarmonics3.getIrradianceAt() (src/math/SphericalHarmonics3.js) --
// same band constants (0.886227, 2*0.511664, 2*0.429043, 0.743125/0.247708,
// etc.) -- so the math-library method itself is used as the independent
// reference here, rather than a hand-rolled JS transliteration of the node's
// own formula.
export default QUnit.module( 'TSL', () => {

QUnit.module( 'getShIrradianceAt()', () => {

// A fixed, arbitrary-but-deterministic set of 9 SH coefficient triples
// (one per color channel) shared by every case below.
const shValues = [
[ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ],
[ 0.5, 0.5, 0 ], [ 0.2, 0, 0.3 ], [ 0, 0.4, 0 ],
[ 0.1, 0.1, 0.1 ], [ 0, 0, 0.6 ], [ 0.3, 0, 0 ]
];

const makeShArray = ( values ) => array( values.map( ( v ) => vec3( ...v ) ) );

gpuTest( 'getShIrradianceAt() matches SphericalHarmonics3.getIrradianceAt() for several normals', ( { assert } ) => {

const shArray = makeShArray( shValues );
const sh = new SphericalHarmonics3().set( shValues.map( ( v ) => new Vector3( ...v ) ) );

const cases = [
[ 0, 0, 1 ],
[ 1, 0, 0 ],
[ 1 / Math.sqrt( 3 ), 1 / Math.sqrt( 3 ), 1 / Math.sqrt( 3 ) ]
];

for ( const normal of cases ) {

const expected = sh.getIrradianceAt( new Vector3( ...normal ), new Vector3() );

assert.closeAbs(
getShIrradianceAt( vec3( ...normal ), shArray ),
vec3( expected.x, expected.y, expected.z ), 1e-4,
`getShIrradianceAt(normal=${ JSON.stringify( normal ) }) matches SphericalHarmonics3.getIrradianceAt()`
);

}

} );

gpuTest( 'getShIrradianceAt() is exactly zero for all-zero SH coefficients, regardless of normal', ( { assert } ) => {

const zeroValues = new Array( 9 ).fill( [ 0, 0, 0 ] );
const shArray = makeShArray( zeroValues );

assert.closeAbs( getShIrradianceAt( vec3( 0, 1, 0 ), shArray ), vec3( 0, 0, 0 ), 1e-6, 'getShIrradianceAt is 0 with all-zero SH coefficients (normal (0,1,0))' );
assert.closeAbs( getShIrradianceAt( vec3( 0.6, 0, 0.8 ), shArray ), vec3( 0, 0, 0 ), 1e-6, 'getShIrradianceAt is 0 with all-zero SH coefficients (normal (0.6,0,0.8))' );

} );

} );

} );
Loading