User Manual

Shader Chunk Migrations

Introduction

The PlayCanvas Engine's material shader chunk system is undergoing substantial changes in order to support a more flexible material system. Please see this page for more context.

In order to help users migrate their existing custom shader chunks, this page lists the changes made to chunks and organizes them by engine release (starting v1.51).

Chunk API Versions

The debug version of the Engine will report any API changes to the runtime console when it detects overridden chunks. For example:

Console output

Once an application's chunks have been updated to the latest API they must be flagged as such. For example, after updating a material's custom chunks to the latest engine release (say v1.55), specify this in the chunks object as follows:

material.chunks.diffusePS = '...';
material.chunks.APIVersion = pc.CHUNKAPI_1_55;

By doing this you will no longer see warning messages in the console.

Chunk changes

The following tables break down the chunk changes by Engine release.


Engine v1.57

In 1.57, almost all front-end chunks have been changed to minimize the amount of samplers used by the shader. This is an optional feature, however it's recommended to follow the same coding style to reduce the amount of samplers used by the shader. The following chunks are affected by it:

Chunk
aoPS
clearCoatPS
clearCoatGlossPS
clearCoatNormalPS
diffusePS
diffuseDetailMapPS
emissivePS
metalnessPS
normalMapPS
normalDetailMapPS
opacityPS
parallaxPS
sheenPS
sheenGlossPS
specularPS
specularityFactorPS
thicknessPS
transmissionPS

This is also supported in custom front-end chunks, given that your chunk piggybacks on the pre-existing material samplers. To support this method in your chunks, what you'd need to do is:

For example:

uniform sampler2D texture_aoMap;
void getAO() {
    dAo = 1.0;

    #ifdef MAPTEXTURE
    dAo *= texture2DBias(texture_aoMap, $UV, textureBias).$CH;
    #endif

    #ifdef MAPVERTEX
    dAo *= saturate(vVertexColor.$VC);
    #endif
}

Would be converted to:

void getAO() {
    dAo = 1.0;

    #ifdef MAPTEXTURE
    dAo *= texture2DBias($SAMPLER, $UV, textureBias).$CH;
    #endif

    #ifdef MAPVERTEX
    dAo *= saturate(vVertexColor.$VC);
    #endif
}

This allows the engine to automatically pick the sampler uniform to use, thus potentially reducing the total number of samplers. But note, this is only supported for front-end chunks.


Engine v1.56

Chunk Changes
combineXXXX
  • all combine chunks except for combinePS have been deleted.
  • instead, combinePS is controlled with a handful of preprocessor defines.
refractionPS
  • split into two new chunks, refractionCubePS and refractionDynamicPS.
refractionCubePS
  • the old refractionPS is identical to this one, uses a cube map for refractions.
refractionDynamicPS
  • new chunk which supports dynamic refractions by using the grab pass, needs requestSceneColorMap(true); to be set on the camera to work.
sheenPS
  • new chunk to provide sheen (fabric) color.
sheenGlossPS
  • new chunk to provide sheen (fabric) glossiness.
reflectionEnvHQPS
  • new chunk to provide a high quality specular environment map for reflections and refractions.
thicknessPS
  • new chunk to provide thickness which modifies attenuation color for transmissive (transparent/refractive) materials.
bakeDirLmEndPs
  • moved to chunks-lightmapper.js.
bakeLmEndPS
  • moved to chunks-lightmapper.js.

Engine v1.55

Chunk Changes
clearCoatNormalPS
  • refrain from generating world CC reflection, now done on the backend instead
  • normalize final world space normal
clusteredLightPS
  • remove dead code.
  • the CLUSTER_XXX macros have been renamed to LIT_XXX.
  • each light calculates fresnel
combinePS
  • new chunk to replace all the other combine chunks.
combineXXXX
  • combine chunk variations have been made deprecated and replaced with a single chunk.
diffusePS
  • fix gamma handling relative to albedo detail
diffuseDetailMapPS
  • gamma correct detail map before combining with base albedo
endPS
  • combine emissive with dEmissive instead of a call to getEmission()
  • CLEARCOAT macro is now LIT_CLEARCOAT.
emissivePS
  • set dEmission global instead of returning the value in order to bring it in line with the other frontend components
fresnelSchlickPS
  • fresnel effect now reacts to index of refraction.
  • no longer changes specularity global, but returns value to be used per-light and for the environment
lightmapSingleVert.js
  • removed (unused)
lightmapDirPS, lightmapSinglePS
  • renamed the lightmap function to getLightMap() instead of addLightMap()
  • changed the implementation to write dLightmap and dLightmapDir global instead of updating dDiffuseLight and dSpecularLight directly
  • backend now handles combining lightmap in lightmapAddPS and lightmapDirAddPS
lightmapAddPS, lightmapDirAddPS
  • new chunks for adding the lightmap values passed in from the backend
  • CLEARCOAT macro replaced with LIT_CLEARCOAT.
lightSpecularAnisoGGXPS
  • CLEARCOAT define replaced with LIT_CLEARCOAT
lightSpecularBlinnPS, lightSpecularPhongPS
  • added clear coat #define, removed call to antiAliasGlossiness()
ltcPS
  • CLEARCOAT macro replaced with LIT_CLEARCOAT.
normalMapFastPS
  • removed
normalMapPS
  • added MAPTEXTURE #define like the other chunks
  • normalize final normal
  • when normal texture isn't defined, calculate normal from geometry normal instead
normalDetailMapPS
  • remove two (mostly) unnecessary calls to normalise - final normal is normalized instead
normalVertexPS
  • removed chunk, moved functionality to normalMapPS frontend chunk
metalnessPS
  • now controls metalness in front end and is not exclusive of specularPS
metalnessModulatePS
  • new chunk to control how specular color is modulated based on specular color and albedo with regards to metalness
reflectionCC
  • CLEARCOAT define replaced with LIT_CLEARCOAT.
specularAaNonePS, specularAaToksvigPS, specularAaToksvigFastPS
  • removed
startPS
  • removed global declarations, generate them on demand instead
  • CLEARCOAT macro replaced with LIT_CLEARCOAT.
specularPS
  • only provides specular color, metalness modulation is now done in backend.
specularityFactorPS
  • new chunk to control specular intensity for metalness workflow.