I’ve written a custom shader and applied it via a ShaderMaterial, and visually it works how I want. However, the problem is:
Once I apply my ShaderMaterial to the mesh, it completely overrides the existing PBRMaterial—so I lose all the PBR features like metallic/roughness, reflections, and environmental lighting.
Here’s PlayGround, where i have recreated the issue.
Is there any way that, I can achieve the same effect more efficient way ? or am I missing something obvious here?
Thanks in advance for any help or suggestions! I really appreciate your time.
Instead of using ShaderMaterial, use PBRCustomMaterial.
With a PBRCustomMaterial you won’t need to rewrite 100% of the code. For example, you can just insert some code such as :
const customPBR = new PBRCustomMaterial("customPBR", scene);
customPBR.Fragment_Before_FragColor(`
// some stuff
finalColor.rgb = whatever you compute as rgb color;
`);
Here is an example with custom (lower brighness) PBR
EDIT :@DarkHorse in your case, best would be to edit surfaceAlbedo using the Fragment_Custom_Albedo method :
You can also use a material plugin, for better integration with the material system (possibility to enable/disable the plugin, clone the material, etc):
You must use the observable material.onBindObservable to define the uniforms on the material effect. PBRCustomMaterial and CustomMaterial are the old way of customizing a material (but can be useful for quick prototyping); the preferred method is now to use a material plugin.
Hey folks,
Looks like I need your help a bit sooner than expected!
I’ve integrated the Material Plugin into our system, and it’s working beautifully. However, in this particular scene, we’re also using Depth of Field, which seems to be causing an issue — as you can see in the screenshot below:
When I disable Depth of Field, everything works smoothly, but I don’t think turning it off is the ideal solution here.
Any thoughts on what might be causing this?
Are you sure the depth texture is correctly passed to the shader? For debugging purpose, you should try to display (gl_FragColor) what you read from the depth texture. Also, Spector can help you find your problem. If you are able to reproduce the problem in the Playground, we can try to have a look.
Just to clarify — I’m not using a custom shader for Depth of Field. I’m relying on Babylon’s built-in DefaultRenderingPipeline.
Here’s how I’m enabling and configuring the DoF effect in code:
// Depth of Field
this.postProcess.depthOfFieldEnabled = ppp.dof.enabled;
if (ppp.dof.enabled) {
this.postProcess.depthOfField.focalLength = ppp.dof.focalLength;
this.postProcess.depthOfField.fStop = ppp.dof.fStop;
this.postProcess.depthOfField.lensSize = ppp.dof.lensSize;
this.postProcess.depthOfFieldBlurLevel = ppp.dof.blurLevel;
if (ppp.dof.dynamicDistance) {
this.adjustDynamicDoF(true);
} else {
this.postProcess.depthOfField.focusDistance = ppp.dof.distance;
}
} else {
this.adjustDynamicDoF(false);
}
Note: You can ignore the adjustDynamicDoF function — it’s just updating the focusDistance depending on the active camera.
Everything works as expected until Depth of Field is turned on. When enabled, the material plugin’s output starts misbehaving (as shown in the screenshot I shared earlier). Disabling DoF immediately resolves the issue.
I haven’t directly worked with the depth texture, so I’m wondering if there’s an internal conflict between DoF’s depth texture and the Material Plugin.