The following playground shows the issue: https://playground.babylonjs.com/#GC63G5#50
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).
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.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.
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 (
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.