[engine] Crossfade two materials?

Is there an example of cross fading two materials on a mesh? (With engine code)

Cross fading materials is not directly supported.

Ah ok. Basically like this demo but cross fading:

https://playcanvas.com/project/437442/overview/switching-materials-at-runtime

Requires merging the shader code into one?

It requires a new shader that samples both textures and mixes them based on some time/alpha value:

Going the path of merging shaders would be ideal, but hard, at least if you want to support many material properties. If you would only want to cross fade the diffuse texture for example, that’s a lot more doable.

Possibly x.com could help here, I think it supports PlayCanvas and shader blending.

Otherwise perhaps render the same mesh twice with alpha blending to implement fade? This would have other limitations, but might be enough in some cases.

Thanks. I understand that stuff, and I know how to patch shaders in Three.js to inject custom GLSL code. I’m just a n00b to the Playcanvas API.

Can you please provide some pointers on how to patch Playcanvas shader strings using only engine (not the editor, i.e. I am importing engine into a plain JS file and making the entire app in the JS file)?

If you could post a CodePen (or similar) showing the most minimal Playcanvas example with a shader patch that would be really helpful.

Once I know the Playcanvas-specific way to patch, I can most likely be on my way after that (f.e. merge shader codes, add extra textures/attributes/etc, fix naming conflicts, interpolate values, etc).

Thanks, I am aware of that approach, that’s the easy way. :slight_smile: I’m interested in a single shader for particular reasons.

If for engine V2, the start of documentation for shader chunks can be found here Shaders | PlayCanvas Developer Site

With some engine only examples here PlayCanvas Examples

Unless I’m missing something from what you are asking?

Cool, I see that creates a new material with a custom shader. How would I now, for example, patch an existing material? Let’s say for example you load that same example, but rather than replace the meshInstance.material with the new material, how would you patch the existing material’s shader code? For example, let’s say you want to replace gl_FragColor = ...; (or custom out variable) with gl_FragColor = vec4(1, 0, 0, 1); (or similar with a custom out)?

In v1, you assigned a shader to a chunk in the material How can I make the custom shader stop? - #12 by yaustar

Not sure in V2 it’s the same. @mvaligursky

2 Likes

yes v2 is the same.

@yaustar @mvaligursky thanks. So looks like basically we replace the official chunk with a new string, for example like this:

material.chunks.opacityPS = material.chunks.opacityPS.replace('something', 'otherthing')

Would be nice to get a plain engine example going (I’m not using the editor, but planning to make a PlayCanvas renderer to the Lume 3D HTML framework for writing 3D scenes in React/Svelte/Vue/Solid/Angular/etc) so eventually I will need to patch some shaders to introduce some features (such as cross-fading additional textures, or other things).

Something like this idea (doesn’t exist yet):

<lume-scene webgl>

  <lume-box position="1 2 3">

    <!-- override the default material -->
    <lume-physical-material diffuse-blend="30%" slot="material">

      <!-- Idea: put multipe textures into the diffuse slot, to be blended. -->
      <lume-diffuse-texture src="a.jpg" slot="diffuse"></lume-diffuse-texture>
      <lume-diffuse-texture src="b.jpg" slot="diffuse"></lume-diffuse-texture>

    </lume-physical-material>

  </lume-box>

  <lume-glft-model src="foo.glb"></lume-glft-model>

</lume-scene>

Or something.