Skip to content

Alternative to .onBeforeCompile for material extension #14232

@Usnul

Description

@Usnul

Current 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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions