# Shadows on plane with shaderMaterial

**URL:** <https://forum.babylonjs.com/t/shadows-on-plane-with-shadermaterial/63370>\
**Category:** Questions\
**Tags:** material, shader, shadows\
**Created:** [May 11, 2026, 4:09pm UTC](https://forum.babylonjs.com/t/shadows-on-plane-with-shadermaterial/63370 "2026-05-11T16:09:44Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Censor](https://avatars.discourse-cdn.com/v4/letter/c/8e7dd6/32.png) [@Censor](https://forum.babylonjs.com/u/Censor)\
**Post date:** [May 11, 2026, 4:09pm UTC](https://forum.babylonjs.com/t/shadows-on-plane-with-shadermaterial/63370/1 "2026-05-11T16:09:44Z")

</div>

I’m trying to get shadows to work on a plane with a shaderMaterial.  
I’ve tried some different approaches but can’t really get it to work (I’m not sure how to add it to the shader).  
I tried the ShadowOnlyMaterial (and just place a plane with said material in front of the actual plane) but I can’t get it to only cast shadows that would exist on the texture (and not the transparent parts).

I’ve set up a playground here:

> **[Babylon.js Playground](https://playground.babylonjs.com/#5BQ0GN%2358)**
>
> Babylon.js playground is a live editor for Babylon.js WebGL and WebGPU 3D scenes

Is it possible to add shadows to the plane with the texture on it?

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [May 12, 2026, 10:20am UTC](https://forum.babylonjs.com/t/shadows-on-plane-with-shadermaterial/63370/2 "2026-05-12T10:20:22Z")

</div>

Hi @Censor,

The issue is that `ShaderMaterial` is intentionally a “blank slate” — its source has no built-in handling for lights or shadows. Wiring shadow reception in by hand is actually pretty complicated: it’s not just shader changes (pulling in the engine’s shadow include chain — ` __decl__ lightVxFragment`, `shadowsVertex`, ` __decl__ lightFragment`, `shadowsFragmentFunctions`, `lightFragment` — and declaring every shadow uniform/sampler), there are also JS-side changes (preparing the right shadow defines, then binding all the light + shadow uniforms per-frame the way `MaterialHelper` does it for `StandardMaterial`). A lot of boilerplate just to get the standard shadow path.

A friendlier route is to keep `StandardMaterial` (which already handles lights / shadows / fog / alpha blending correctly) and use a [`MaterialPlugin`](https://doc.babylonjs.com/features/featuresDeepDive/materials/using/materialPlugins) to inject just your pixel-perfect sampling into the diffuse step. Then `plane.receiveShadows = true` is the only extra line needed.

Working version: [https://playground.babylonjs.com/#X188AC#0](https://playground.babylonjs.com/#X188AC#0)

Two key bits:

- The pixel-perfect sampling is injected at the `CUSTOM_FRAGMENT_UPDATE_ALPHA` point, where `baseColor` (the diffuse texture sample) and `alpha` are in scope — perfect spot to overwrite both with the iq sub-pixel anti-aliased lookup.
- With `texture.hasAlpha = true` + `material.useAlphaFromDiffuseTexture = true` + `plane.receiveShadows = true`, the shadow is automatically masked by the texture’s alpha — transparent texels just don’t write to the framebuffer, so no shadow renders on them. That removes the need for the `ShadowOnlyMaterial` overlay.

Hope this helps!

---

<div class="post-metadata">

**Author:** ![Censor](https://avatars.discourse-cdn.com/v4/letter/c/8e7dd6/32.png) [@Censor](https://forum.babylonjs.com/u/Censor)\
**Post date:** [May 12, 2026, 10:47am UTC](https://forum.babylonjs.com/t/shadows-on-plane-with-shadermaterial/63370/3 "2026-05-12T10:47:24Z")

</div>

Thank you for the clear explanation and playground changes.  
Shaders/materials are something I’m still trying to understand better, and this helps a lot!
