Alternative to .onBeforeCompile for material extension
See original GitHub issueCurrent approach of letting the user do whatever they want with the shader code from within .onBeforeCompile
is very powerful, and yet, at the same time, quite messy and fragile.
One of the biggest issues is dynamic nature of the material code, if you allow making arbitrary modification to the code - you can not assume that material code will remained the same between builds, and you have to construct that code string every time to check, this creates waste both in terms of CPU cycles and in terms of GC overhead, as that string will likely end up as garbage.
My proposal is quite simple. I propose having more restrictive transformers which can be registered onto a material. Transformers can be entirely static for most usecases, and where that’s not enough, we could offer dynamic transformers - with the main difference that the library can detect that and optimize usecases where only static transformers are being used. One fairly substantial benefit also - is the added semantic information which library can use for various optimizations and error checking.
My observation boils down to the fact that most .onBeforeCompile
functions do just 1 thing:
- find a RegEx pattern in shader code string
- replace that occurrence with a fixed string
Here is an example to illustrate current usage:
material.onBeforeCompile = function(shader){
shader.vertex = shader.vertex.replace('a','b');
}
What i propose would be:
const transform = new ShaderTransformReplace(VertexShader, 'a','b');
material.addShaderTransform(transform);
Since there is no arbitrary code being executed anymore, we know that material shader does not change as long as list of transforms hasn’t changed (in addition to other things, like defines and lighting which we already have had).
A couple of ideas on top of this proposal:
- if user adds transorms (‘a’,‘b’) and (‘a’,‘c’) - we can detect that and remove latter transform or warn the user, as we know that pattern will no longer be matched.
- If shader code is ‘aaa’ and user adds transform (‘b’,‘c’) - we can detect that such transform would be pointless and remove it or warn the user
Issue Analytics
- State:
- Created 5 years ago
- Reactions:1
- Comments:22 (19 by maintainers)
Top GitHub Comments
@donmccurdy My takeaway from this is that there is no plan to touch
onBeforeCompile
currently with the expectation thatNode
-based shaders will be ready soon (within a 2+ months)wrt
Node
-based shader in general, yes, I find the solution to be a desirable one, my issue is with how it’s done, and that’s separate from the current thread - you’re absolutely right.@mrdoob I apologize if I come off as hard. I make no demands, merely express my wishes to clarify my position. I am thankful for the work of yourself and other capable and diverse individuals who have in the past, currently are, and will in the future be contributing to making three.js great, again - I’m sorry if that was not clear.
@pailhead Thanks for the pointer. Documentation for that code will be a substantial undertaking.
@Usnul
Yeah, adding that method was a mistake on my part. But sometimes you need to experiment until finding the right solution…
We do what we can.