Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TSL: Deferred function call and .once() #29121

Merged
merged 1 commit into from
Aug 14, 2024
Merged

TSL: Deferred function call and .once() #29121

merged 1 commit into from
Aug 14, 2024

Conversation

sunag
Copy link
Collaborator

@sunag sunag commented Aug 12, 2024

Description

All TSL function calls are deferred to compilation time, if this is not the desired action just create a simple JS function. The Fn.once() update allows only one function call to be made per material.

// use Fn().once() to call the function only once in compilation, 
// it will reuse the return value of the last call.

const normalViewFn = Fn( ( builder ) => {

	let node;

	if ( builder.material.flatShading === true ) {

		node = normalFlat;

	} else {

		node = varying( modelNormalMatrix.mul( normalLocal ), 'v_normalView' ).normalize();

	}

	return node;

} ).once(); 

// With deferred once functions we can have constants that can obtain 
// important data from the material, object and renderer at compile time.

export const normalView = normalViewFn().toVar( 'normalView' );

The use for the end user is the same if he would use a constant.

import { normalView } from 'three/tsl';

material.normalNode = normalView;

Optional output type has also been added to the function, this can help to optimize and avoid call overload.

const normalViewFn = Fn( function(){}, 'vec3' );

@sunag sunag added this to the r168 milestone Aug 12, 2024
Copy link

📦 Bundle size

Full ESM build, minified and gzipped.

Filesize dev Filesize PR Diff
685.1 kB (169.6 kB) 685.1 kB (169.6 kB) +0 B

🌳 Bundle size after tree-shaking

Minimal build including a renderer, camera, empty scene, and dependencies.

Filesize dev Filesize PR Diff
462 kB (111.4 kB) 462 kB (111.4 kB) +0 B

@sunag sunag marked this pull request as ready for review August 13, 2024 20:38
@sunag sunag merged commit f8b24f7 into mrdoob:dev Aug 14, 2024
12 checks passed
@sunag sunag deleted the dev-once branch August 14, 2024 01:03
@linbingquan
Copy link
Contributor

@sunag

Can we let Fn() execute itself in the setup* phase, the user should have less learning costs and write less code.

I was try to execute colorNode in NodeMaterial.setupDiffuseColor(), it can work.

Before:

material.colorNode = Fn( () => {} )()

After:

material.colorNode = Fn( () => {} )

I'm not sure it's a good idea, also I'm not sure if there are other questions.

@sunag
Copy link
Collaborator Author

sunag commented Aug 14, 2024

I think it could have other name like the example below, because Fn() will return a function and not a Node, this could make the subsequent process easier:

const Shader = ( ...params ) => Fn( ...params )();

material.colorNode = Shader( () => {} );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants