Hi everyone!
I am tying to run this script directly on PlayCanvas.
The purpose of the script is to parse Unreal Engine light map to PlayCanvas engine.
I successfully added the class NodeLightmap on my project and inserted it on an entity with render component. The class input parameters I got from the git repository web project.
But when I run the project, I got the following error:
Failed to compile fragment shader:
ERROR: 0:624: 'getLightMap' : no matching overloaded function found
619: getMetalness();
620: getIor();
621: getGlossiness();
622: getSpecularity();
623: getEmission();
624: getLightMap();
625:
626: litArgs_worldNormal = dNormalW;
627: litArgs_albedo = dAlbedo;
628: litArgs_metalness = dMetalness;
629: litArgs_ior = dIor;
[object Object]
Error compiling shader [Shader Id 9 LitShader-forward-proc] for material=MI_Trimsheet pass=0 objDefs=65548
[object Object]
Can anyone help me whit this?
PlayCanvas code:
// NodeLightmap.js
class NodeLightmap extends pc.ScriptType {
static _materialMappings = [];
static clearCachedMaterialMappings() {
this._materialMappings = [];
}
initialize() {
// ORIGINAL:
// if (!this.entity.model) {
if (!this.entity.render) {
throw new Error("The entity must have a model-component!");
}
this.applyLightmapToModel();
}
applyLightmapToModel() {
// ORIGINAL:
// if (!this.entity.model.model) {
if (!this.entity.render) {
return;
}
this.entity.render.meshInstances.forEach(instance => {
instance.material = NodeLightmap._findOrCreateExtendedMaterial(
this,
instance.material,
);
instance.setParameter("lm_coordinateScaleBias", this.coordinateScaleBias);
instance.setParameter("lm_lightmapAdd", this.lightmapAdd);
instance.setParameter("lm_lightmapScale", this.lightmapScale);
});
}
removeLightmapFromModel() {
// ORIGINAL:
// if (!this.entity.model.model) {
if (!this.entity.render) {
return;
}
// ORIGINAL:
// this.entity.model.meshInstances.forEach(instance => {
this.entity.render.meshInstances.forEach(instance => {
const originalMaterial = NodeLightmap._findOriginalMaterial(
instance.material,
);
if (originalMaterial !== null) {
instance.material = originalMaterial;
}
instance.deleteParameter("lm_coordinateScaleBias");
instance.deleteParameter("lm_lightmapAdd");
instance.deleteParameter("lm_lightmapScale");
});
}
static _findOrCreateExtendedMaterial(
nodeLightmap,
originalMaterial,
) {
let material = this._findExtendedMaterial(nodeLightmap, originalMaterial);
if (!material) {
const { texture, texCoord } = nodeLightmap;
material = originalMaterial.clone();
material.lightMap = texture.resource;
material.lightMapUv = texCoord;
material.chunks.lightmapSinglePS = this._createLightmapSinglePS();
material.update();
this._materialMappings.push({
original: originalMaterial,
extended: material,
});
}
return material;
}
static _findExtendedMaterial(
nodeLightmap,
originalMaterial,
) {
return (
this._materialMappings.find(
mapping =>
mapping.extended === originalMaterial ||
(mapping.original === originalMaterial &&
mapping.extended.lightMap === nodeLightmap.texture.resource &&
mapping.extended.lightMapUv === nodeLightmap.texCoord),
)?.extended ?? null
);
}
static _findOriginalMaterial(
extendedMaterial,
) {
return (
this._materialMappings.find(
mapping => mapping.extended === extendedMaterial,
)?.original ?? null
);
}
static _createLightmapSinglePS() {
return this._getCommonShaderCode() + this._getHighQualityShaderCode();
}
static _getCommonShaderCode() {
return `
#ifdef MAPTEXTURE
uniform sampler2D texture_lightMap;
#endif
uniform vec4 lm_coordinateScaleBias;
uniform vec4 lm_lightmapAdd;
uniform vec4 lm_lightmapScale;
vec2 getLightmapUV0(vec2 uv)
{
return (uv * lm_coordinateScaleBias.xy + lm_coordinateScaleBias.zw) * vec2(1.0, 0.5);
}
vec2 getLightmapUV1(vec2 uv)
{
return getLightmapUV0(uv) + vec2(0.0, 0.5);
}
`;
}
static _getHighQualityShaderCode() {
return `
vec2 flipY(vec2 uv)
{
return vec2(uv.x, 1.0 - uv.y);
}
vec3 getLightMapColorHQ()
{
// NOTE: Mesh Uv's are flipped in Y(V) compared to UE4, and
// we therefore need to temporarily flip them (again) while
// performing scale- and bias-calculations.
vec2 flippedUv = flipY($UV);
vec2 lightmapUv0 = flipY(getLightmapUV0(flippedUv));
vec2 lightmapUv1 = flipY(getLightmapUV1(flippedUv));
vec4 lightmap0 = texture2D(texture_lightMap, lightmapUv0).rgba;
vec4 lightmap1 = texture2D(texture_lightMap, lightmapUv1).rgba;
float logL = lightmap0.w;
// Add residual
logL += lightmap1.w * (1.0 / 255.0) - (0.5 / 255.0);
// Range scale logL
logL = logL * lm_lightmapScale.w + lm_lightmapAdd.w;
// Range scale uvw
vec3 uvw = lightmap0.rgb * lightmap0.rgb * lm_lightmapScale.rgb + lm_lightmapAdd.rgb;
// logL -> L
const float logBlackPoint = 0.01858136;
float l = exp2( logL ) - logBlackPoint;
float directionality = 0.6;
float luma = l * directionality;
vec3 color = luma * uvw;
return color;
}
void addLightMap() {
dDiffuseLight += getLightMapColorHQ();
}
`;
}
}
pc.registerScript(NodeLightmap, 'NodeLightmap');
NodeLightmap.attributes.add("texture", {
type: "asset",
assetType: "texture",
title: "Texture",
});
NodeLightmap.attributes.add("texCoord", {
type: "number",
title: "TexCoord",
});
NodeLightmap.attributes.add("lightmapAdd", {
type: "number",
array: true,
title: "Lightmap add coefficients",
});
NodeLightmap.attributes.add("lightmapScale", {
type: "number",
array: true,
title: "Lightmap scale coefficients",
});
NodeLightmap.attributes.add("coordinateScaleBias", {
type: "number",
array: true,
title: "Coordinate scale & bias",
});
Script component
Thanks a lot!