# Screenshots using custom #ifdef block within a PBRCustomMaterial

**URL:** <https://forum.babylonjs.com/t/screenshots-using-custom-ifdef-block-within-a-pbrcustommaterial/42144>\
**Category:** Questions\
**Tags:** shader, pbr, screenshot\
**Created:** [July 4, 2023, 1:52pm UTC](https://forum.babylonjs.com/t/screenshots-using-custom-ifdef-block-within-a-pbrcustommaterial/42144 "2023-07-04T13:52:45Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Marian\_Becher](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/marian_becher/32/24613_2.png) [@Marian\_Becher](https://forum.babylonjs.com/u/Marian_Becher)\
**Post date:** [July 4, 2023, 1:52pm UTC](https://forum.babylonjs.com/t/screenshots-using-custom-ifdef-block-within-a-pbrcustommaterial/42144/1 "2023-07-04T13:52:45Z")

</div>

Hi together,

this may be a bit specific but I try my best to generalize my issue/question.

# Qustion / Issue

I ran into a problem with `CreateScreenshotUsingRenderTargetAsync()` using a custom PBR shader that has its own `#ifdef` block.

If I update the material (custom defines habe to be updated) shortly before taking the screenshot the target object is invisible within the screenshot. If I repeat the action it works as intended.

I event tried calling `CreateScreenshotUsingRenderTargetAsync` within `scene.onAfterRenderObservable` without any luck. Another idea was to wait until `material.isReady()` is set to `true`. However as far as I can tell it is never set to `true`.

Is there a way to ensure the shader is fully rebuild before the screenshot is taken? Or did I handle the implementation of custom `#ifdev` blocks wrong and should use another approach?

# Playground

[https://playground.babylonjs.com/#VMKSIU#12](https://playground.babylonjs.com/#VMKSIU#12)

- Basic custom material / shader with a `useCustomDefine` property
- Shader code contains a custom `#ifdef` block that changes the color if set
- Material overrides the Builder() function to update the shader defines depending on the state of `useCustomDefine` property
- If `useCustomDefine` is enabled the shader will draw each pixel in green
- The button updates the `useCustomDefine` and takes a screenshot

**Desired Behavior** : On the press of a button the material is updated and the screenshot contains the image of the updated sphere.

**Observed Behavior** : After pressing the button for the first time the screenshot does not contain any sphere. On the next clicks the screenshot works as expected.

**Video:**

**Sadly this is not reproducible 100% of the time!** Sometimes it will happen on every first click after I recompile the playground solution. Sometimes it works perfectly fine…

---

<div class="post-metadata">

**Author:** ![sebavan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/sebavan/32/57_2.png) [@sebavan](https://forum.babylonjs.com/u/sebavan)\
**Post date:** [July 4, 2023, 3:05pm UTC](https://forum.babylonjs.com/t/screenshots-using-custom-ifdef-block-within-a-pbrcustommaterial/42144/2 "2023-07-04T15:05:26Z")

</div>

It looks like you would need for the shader to be compiled before using it as it is async.

You could force it to be synchronous with `scene.getEngine().getCaps().parallelShaderCompile = undefined;`

> **[Babylon.js Playground](https://playground.babylonjs.com/#VMKSIU%2314)**
>
> Babylon.js playground is a live editor for Babylon.js WebGL 3D scenes

---

<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:** [July 4, 2023, 3:12pm UTC](https://forum.babylonjs.com/t/screenshots-using-custom-ifdef-block-within-a-pbrcustommaterial/42144/3 "2023-07-04T15:12:12Z")

</div>

Also, you can trigger a recompilation of the shader by calling `sphere.resetDrawCache()`, then use `scene.executeWhenReady` to call the screenshot function only when the shader compilation is finished:

> **[Babylon.js Playground](https://playground.babylonjs.com/#VMKSIU%2316)**
>
> Babylon.js playground is a live editor for Babylon.js WebGL 3D scenes

---

<div class="post-metadata">

**Author:** ![Marian\_Becher](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/marian_becher/32/24613_2.png) [@Marian\_Becher](https://forum.babylonjs.com/u/Marian_Becher)\
**Post date:** [July 4, 2023, 3:46pm UTC](https://forum.babylonjs.com/t/screenshots-using-custom-ifdef-block-within-a-pbrcustommaterial/42144/4 "2023-07-04T15:46:10Z")

</div>

You are awesome thanks!

I went with the `resetDrawCache()` option and it seems to be working great in my situation. 👍. Only have to hide the flickering of my objects but that should not be a problem.

Setting `paralellShaderCompile` to undefined did work as well. But in my application I had to do as a global setting not right before the screenshot was taken because the structure is not as simplistic as in the playground. But nevertheless great suggestion.
