Breaking Change to Shader Chunks

Hello there,

We’ve had a surprise shader chunk break overnight due to the latest 1.62 engine release.

I’ve found it hard to fix this and have used the migration guide and have combed through the gitHub engine change logs, but can’t find support that includes what values to pass into the changed function interfaces to preserve existing behaviour.

The shader in question provides a transparent shadow plane under GL1 (for an A.R project) and with the below updates it seems to now be 100% opaque black (using my latest attempt / guess at arguments to provide).

I’m wondering if you could offer some help mostly about what arguments we should pass to getShadowPCF3x3(…) and combineColor(…) to simply preserve the behaviour we had had before today?

Script in question (please note //BREAKING lines for where changes were made) :

var Ground = pc.createScript('ground');
Ground.attributes.add("material", { type: 'asset' });

Ground.prototype.initialize = function () {
  // Attach a shader to a material that makes it appear transparent while still receiving shadows.
  const materialResource = this.material.resource || material;
  const shadowFragmentShader = `
      #ifdef GL2
      #define SHADOW_SAMPLERVS sampler2DShadow
      #define SHADOW_SAMPLERVS sampler2D
      vec3 dEmissive;
      //BREAKING 2023-04-18: float getShadowPCF3x3(SHADOW_SAMPLERVS shadowMap, vec3 shadowParams);
      float getShadowPCF3x3(sampler2D shadowMap, vec3 shadowCoord, vec3 shadowParams) ;
      vec3 getTransparentShadow() {
          //BREAKING 2023-04-18: float shadow = getShadowPCF3x3(light0_shadowMap, light0_shadowParams);
          float shadow = getShadowPCF3x3(light0_shadowMap, dShadowCoord, light0_shadowParams);
          dAlpha = 1. - clamp(shadow + 0.5, 0., 1.);
          return -gl_FragColor.rgb;
      void getEmission() {


  const endShader = `
      //BREAKING 2023-04-18: gl_FragColor.rgb = combineColor();
      gl_FragColor.rgb = combineColor(dAlbedo, dSpecularity, 0.);
      gl_FragColor.rgb += getTransparentShadow();
      gl_FragColor.rgb = addFog(gl_FragColor.rgb);

      #ifndef HDR
      gl_FragColor.rgb = toneMap(gl_FragColor.rgb);
      gl_FragColor.rgb = gammaCorrectOutput(gl_FragColor.rgb);

  // We use emissive because it can overwrite color to be pure black.
  materialResource.chunks.APIVersion = pc.CHUNKAPI_1_62; // Added line <-----------------------------
  materialResource.chunks.emissivePS = shadowFragmentShader;
  materialResource.chunks.endPS = endShader;
  materialResource.blendType = pc.BLEND_PREMULTIPLIED;

Many thanks & best regards,

Hi @Isaac,

The last shader chunk will be updated like this for v1.62.0:

      gl_FragColor.rgb = combineColor(litShaderArgs.albedo, litShaderArgs.sheen.specularity, litShaderArgs.clearcoat.specularity);
      gl_FragColor.rgb += getTransparentShadow();
      gl_FragColor.rgb = addFog(gl_FragColor.rgb);

      #ifndef HDR
      gl_FragColor.rgb = toneMap(gl_FragColor.rgb);
      gl_FragColor.rgb = gammaCorrectOutput(gl_FragColor.rgb);

The getTransparentShadow(), which you can include and execute in the endPS as well from what I see, I’m not so sure how to update. @mvaligursky may be able to offer some tip :innocent:

Shadow coord/params are passed locally in this bigger shader chunk, you may be able to replicate it from there:

I’ve updated shadows on transparent materials in this project

Look for ar-ground.js


As a side note, we do send advance notices on engine updates. We have the new engine in release candidate/preview option in the editor for at least a week.

PlayCanvas Ltd (see last newsletter in that list)

This is part of email options under account settings thay you may have unsubscribed/opted out of PlayCanvas | HTML5 Game Engine (disable/re-enable ‘Exciting PlayCanvas Stuff’)

1 Like

Many thanks @yaustar - that worked like a charm! :smiley:

I try to keep track of the updates, but am very grateful PlayCanvas has such a responsive support team…

I think it might be good to have a place where each breaking change is listed with an example code excerpt of how to use the new interfaces correctly / what to pass for clarity. Perhaps even the console debug message could include a reference link. Maybe I’m being a spoilt brat. :wink:

Many thanks again & best regards,

We do try to supply documentation where we can for these as it does disrupt users.

The release notes for the engine (linked from the Editor release notes) has a list of what we consider to be breaking changes Releases · playcanvas/engine · GitHub


We also link to the the Shader migrations documentation that tries to list what has changed where, why and how to migrate: Shader Chunk Migrations | Learn PlayCanvas

These are also linked in the newsletter on engine releases (PlayCanvas Engine v1.62 RC - Updates to Shader Chunks and WebGPU)

The ar-ground.js shader was a lot trickier though and took me a while to migrate it last night.