SkyMaterial doesn't work with plugins

The following playground shows the issue:

Both cubes have a plugin applied that should redden them via CUSTOM_FRAGMENT_MAIN_END (set R component to 1.0). The cube on the right uses a default StandardMaterial, and correctly becomes red, while the cube on the left uses a SkyMaterial, and should also become red but doesn’t (easier to see if you tilt the camera slightly).

The SkyMaterial fragment shader source code does contain #define CUSTOM_FRAGMENT_MAIN_END, suggesting to me that it is intended to work with plugins – but whatever code is responsible for performing the injection isn’t being run. I got as far as looking at window.skyMaterial.getEffect().fragmentSourceCode and window.boringStandardMaterial.getEffect().fragmentSourceCode. The latter includes the plugin code (I looked for and found glFragColor = vec4(1.0, luma, luma, 1.0) near the end); the former doesn’t.

My high-level goal here is to make a simple plugin that lerps between the SkyMaterial and a fixed texture according to a uniform input.

Welcome aboard!

Material plugins are only supported for the standard and PBR materials (or materials that overrides them). See Using material plugins with PBRCustomMaterial - #2 by sebavan for more context.

I’m going to update the docs to make it clear.

I see @Evgeni_Popov, thanks for the quick reply!

Do you have any suggestions for the best way to make a modified version of SkyMaterial that supports blending with another textures?

What I’m currently doing is making a new class BlendedSkyMaterial that inherits from SkyMaterial, and overrides isReadyForSubMesh() to load slightly different shaders (which I have copied-and-pasted from the SkyMaterial shaders). This seems to work, but it’s fragile.

What you have done seems to me to be correct, why do you say it’s fragile? As long as you use public interfaces in your implementation code (i.e. no properties or functions starting with a “_”), everything is fine.

Thanks @Evgeni_Popov. I think it’s fragile because I’ve just copied and pasted SkyMaterial.isReadyForSubMesh() (with minor tweaks) – which does access internal properties (this._isReadyForSubMesh(), this._materialContext, defines._renderId, subMesh.effect._wasPreviouslyReady). AFAICT, these could change with any new version of BabylonJS. It also contains many accesses to public but obscure properties, like SubMesh.materialDefines.markAsMiscDirty(), that I don’t understand the details of and suspect could also change without me noticing.

I would say it’s still pretty safe, as isReadyForSubMesh is at the core of the material management, so the implementation should be stable.