HDRI backdrop stop working after upgrade

https://playcanvas.com/editor/scene/1289712

We had been using a hdri backdrop so that the main object(product) looks more natural in the hdri background.

After it’s upgraded to 1.5x version, somehow the backdrop stopped working.

Can you kindly take a look at the test project and let me know.

@slimbuck

@sooyong_Kim For ease, would it be possible to provide the non-webpack/non minified code please?

Error message

@yaustar Unfortunately, I also can’t find the original version before it was webpacked…

!(function (modules) {
  var installedModules = {};
  function __webpack_require__(moduleId) {
    if (installedModules[moduleId]) return installedModules[moduleId].exports;
    var module = (installedModules[moduleId] = {
      i: moduleId,
      l: !1,
      exports: {},
    });
    return (
      modules[moduleId].call(
        module.exports,
        module,
        module.exports,
        __webpack_require__
      ),
      (module.l = !0),
      module.exports
    );
  }
  (__webpack_require__.m = modules),
    (__webpack_require__.c = installedModules),
    (__webpack_require__.d = function (exports, name, getter) {
      __webpack_require__.o(exports, name) ||
        Object.defineProperty(exports, name, { enumerable: !0, get: getter });
    }),
    (__webpack_require__.r = function (exports) {
      "undefined" != typeof Symbol &&
        Symbol.toStringTag &&
        Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }),
        Object.defineProperty(exports, "__esModule", { value: !0 });
    }),
    (__webpack_require__.t = function (value, mode) {
      if ((1 & mode && (value = __webpack_require__(value)), 8 & mode))
        return value;
      if (4 & mode && "object" == typeof value && value && value.__esModule)
        return value;
      var ns = Object.create(null);
      if (
        (__webpack_require__.r(ns),
        Object.defineProperty(ns, "default", { enumerable: !0, value: value }),
        2 & mode && "string" != typeof value)
      )
        for (var key in value)
          __webpack_require__.d(
            ns,
            key,
            function (key) {
              return value[key];
            }.bind(null, key)
          );
      return ns;
    }),
    (__webpack_require__.n = function (module) {
      var getter =
        module && module.__esModule
          ? function () {
              return module.default;
            }
          : function () {
              return module;
            };
      return __webpack_require__.d(getter, "a", getter), getter;
    }),
    (__webpack_require__.o = function (object, property) {
      return Object.prototype.hasOwnProperty.call(object, property);
    }),
    (__webpack_require__.p = ""),
    __webpack_require__((__webpack_require__.s = 1));
})([
  function (module, exports) {
    module.exports = pc;
  },
  function (module, exports, __webpack_require__) {
    module.exports = __webpack_require__(2);
  },
  function (module, exports, __webpack_require__) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: !0 }),
      __webpack_require__(3).HdriBackdrop.register();
  },
  function (module, exports, __webpack_require__) {
    "use strict";
    var extendStatics,
      __extends =
        (this && this.__extends) ||
        ((extendStatics = function (d, b) {
          return (extendStatics =
            Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array &&
              function (d, b) {
                d.__proto__ = b;
              }) ||
            function (d, b) {
              for (var p in b)
                Object.prototype.hasOwnProperty.call(b, p) && (d[p] = b[p]);
            })(d, b);
        }),
        function (d, b) {
          function __() {
            this.constructor = d;
          }
          extendStatics(d, b),
            (d.prototype =
              null === b
                ? Object.create(b)
                : ((__.prototype = b.prototype), new __()));
        }),
      __createBinding =
        (this && this.__createBinding) ||
        (Object.create
          ? function (o, m, k, k2) {
              void 0 === k2 && (k2 = k),
                Object.defineProperty(o, k2, {
                  enumerable: !0,
                  get: function () {
                    return m[k];
                  },
                });
            }
          : function (o, m, k, k2) {
              void 0 === k2 && (k2 = k), (o[k2] = m[k]);
            }),
      __setModuleDefault =
        (this && this.__setModuleDefault) ||
        (Object.create
          ? function (o, v) {
              Object.defineProperty(o, "default", { enumerable: !0, value: v });
            }
          : function (o, v) {
              o.default = v;
            }),
      __importStar =
        (this && this.__importStar) ||
        function (mod) {
          if (mod && mod.__esModule) return mod;
          var result = {};
          if (null != mod)
            for (var k in mod)
              "default" !== k &&
                Object.prototype.hasOwnProperty.call(mod, k) &&
                __createBinding(result, mod, k);
          return __setModuleDefault(result, mod), result;
        };
    Object.defineProperty(exports, "__esModule", { value: !0 }),
      (exports.HdriBackdrop = void 0);
    var pc = __importStar(__webpack_require__(0)),
      utilities_1 = __webpack_require__(4),
      HdriBackdrop = (function (_super) {
        function HdriBackdrop() {
          var _this =
            (null !== _super && _super.apply(this, arguments)) || this;
          return (
            (_this._material = new pc.Material()),
            (_this._worldProjectionCenter = new pc.Vec3()),
            (_this._mapRotationMatrix = new pc.Mat4()),
            _this
          );
        }
        return (
          __extends(HdriBackdrop, _super),
          (HdriBackdrop.register = function (name) {
            utilities_1.hasRegisteredScript(HdriBackdrop, name) ||
              (pc.registerScript(HdriBackdrop, name),
              HdriBackdrop.attributes.add("cubemap", {
                type: "asset",
                assetType: "cubemap",
                title: "Cubemap",
                description:
                  "Assign an imported HDR cubemap that will be projected on the ground & backdrop.",
              }),
              HdriBackdrop.attributes.add("model", {
                type: "asset",
                assetType: "model",
                title: "Model",
                description: "Specify a model to use as a backdrop.",
              }),
              HdriBackdrop.attributes.add("size", {
                type: "number",
                default: 150,
                title: "Size",
                description:
                  "The size of the model used to project the HDR cubemap (Meters). The supplied model will be scaled to match the size as closely as possible.",
              }),
              HdriBackdrop.attributes.add("angle", {
                type: "number",
                default: 0,
                title: "Angle",
                description:
                  "Absolute clockwise rotation (yaw) of the projected HDR cubemap in degrees. Note that the rotation is independent of the entity's rotation.",
              }),
              HdriBackdrop.attributes.add("intensity", {
                type: "number",
                default: 1,
                title: "Intensity",
                description:
                  "Emissivity of the backdrop. Higher values will results brighter ambient lighting sampled from the HDR cubemap (cd/m2).",
              }),
              HdriBackdrop.attributes.add("projectionCenter", {
                type: "vec3",
                default: [0, 1.7, 0],
                title: "Projection Center",
                description:
                  "Defines the projection point of the HDR cubemap. Note that the position is relative to the position of the entity this script belongs to.",
              }),
              HdriBackdrop.attributes.add("lightingDistanceFactor", {
                type: "number",
                default: 0.5,
                title: "Lighting Distance Factor",
                description:
                  "Specify the ground area that will be affected by lighting and shadows. Lit area will have slightly different shading depending on the Intensity and other lighting parameters in the scene.",
              }),
              HdriBackdrop.attributes.add("useCameraProjection", {
                type: "boolean",
                default: !1,
                title: "Use Camera Projection",
                description:
                  "Disables ground tracking, making the HDR cubemap follow the camera.",
              }));
          }),
          (HdriBackdrop.prototype.initialize = function () {
            (this._modelEntity = new pc.Entity()),
              this._modelEntity.tags.add("ignoreBoundingBox"),
              this._modelEntity.addComponent("model"),
              this.entity.addChild(this._modelEntity),
              this._initializeMaterial(),
              this._updateModel(),
              this._updateCubemapUniform(),
              this._updateIntensityUniform(),
              this._updateMapRotationUniform(),
              this._updateLightingDistanceUniform(),
              this._updateTransformRelatedUniforms(),
              this.on("attr:cubemap", this._updateCubemapUniform, this),
              this.on("attr:model", this._updateModel, this),
              this.on("attr:size", this._updateLightingDistanceUniform, this),
              this.on("attr:size", this._updateModelEntityScale, this),
              this.on("attr:angle", this._updateMapRotationUniform, this),
              this.on("attr:intensity", this._updateIntensityUniform, this),
              this.on(
                "attr:lightingDistanceFactor",
                this._updateLightingDistanceUniform,
                this
              );
          }),
          (HdriBackdrop.prototype.postUpdate = function () {
            this._restrictCurrentRotationToY(),
              this._updateTransformRelatedUniforms();
          }),
          (HdriBackdrop.prototype._updateModel = function () {
            var _this = this,
              model = this.model,
              modelComponent = this._modelEntity.model;
            modelComponent &&
              (model
                ? ((modelComponent.model = model.resource.clone()),
                  modelComponent.meshInstances.forEach(function (meshInstance) {
                    return (meshInstance.material = _this._material);
                  }))
                : (modelComponent.model = null)),
              this._updateModelEntityScale();
          }),
          (HdriBackdrop.prototype._updateCubemapUniform = function () {
            var _a,
              material = this._material,
              uHdriMap =
                null === (_a = this.cubemap) || void 0 === _a
                  ? void 0
                  : _a.resource;
            uHdriMap
              ? material.setParameter("uHdriMap", uHdriMap)
              : material.deleteParameter("uHdriMap");
          }),
          (HdriBackdrop.prototype._updateLightingDistanceUniform = function () {
            var material = this._material,
              uLightingDistance = this.size * this.lightingDistanceFactor;
            material.setParameter("uLightingDistance", uLightingDistance);
          }),
          (HdriBackdrop.prototype._updateIntensityUniform = function () {
            var material = this._material,
              uIntensity = this.intensity;
            material.setParameter("uIntensity", uIntensity);
          }),
          (HdriBackdrop.prototype._updateTransformRelatedUniforms =
            function () {
              var material = this._material,
                uProjectionCenter = this._calculateProjectionCenterUniform();
              material.setParameter("uProjectionCenter", uProjectionCenter);
            }),
          (HdriBackdrop.prototype._updateMapRotationUniform = function () {
            var material = this._material,
              matrix = this._mapRotationMatrix;
            matrix.setFromAxisAngle(pc.Vec3.UP.clone(), -this.angle);
            var uMapRotationMatrix = matrix.data;
            material.setParameter("uMapRotationMatrix", uMapRotationMatrix);
          }),
          (HdriBackdrop.prototype._updateModelEntityScale = function () {
            var _a,
              radius = this._calculateModelSphereRadius(
                null === (_a = this.model) || void 0 === _a
                  ? void 0
                  : _a.resource
              );
            if (radius > 0) {
              var scale = this.size / (2 * radius);
              this._modelEntity.setLocalScale(scale, scale, scale);
            } else this._modelEntity.setLocalScale(1, 1, 1);
          }),
          (HdriBackdrop.prototype._restrictCurrentRotationToY = function () {
            var rotation = this._modelEntity.getRotation(),
              yaw = rotation.getAxisAngle(pc.Vec3.UP.clone());
            rotation.setFromAxisAngle(pc.Vec3.UP.clone(), yaw);
          }),
          (HdriBackdrop.prototype._calculateProjectionCenterUniform =
            function () {
              var app = this.app,
                worldProjectionCenter = this._worldProjectionCenter;
              if (this.useCameraProjection) {
                var cameras = app.systems.camera.cameras,
                  camera = cameras[cameras.length - 1];
                if (!camera) throw new Error("No active camera found");
                worldProjectionCenter.copy(camera.entity.getPosition());
              } else {
                this._modelEntity
                  .getRotation()
                  .transformVector(
                    this.projectionCenter,
                    worldProjectionCenter
                  ),
                  worldProjectionCenter.add(this._modelEntity.getPosition());
              }
              return [
                worldProjectionCenter.x,
                worldProjectionCenter.y,
                worldProjectionCenter.z,
              ];
            }),
          (HdriBackdrop.prototype._initializeMaterial = function () {
            var graphicsDevice = this.app.graphicsDevice,
              precision = graphicsDevice.precision,
              vertexCode = this._getVertexShaderCode(),
              fragmentCode = this._getFragmentShaderCode(),
              shader = new pc.Shader(graphicsDevice, {
                attributes: {
                  aPosition: pc.SEMANTIC_POSITION,
                  aUv0: pc.SEMANTIC_TEXCOORD0,
                },
                vshader: vertexCode,
                fshader: "precision " + precision + " float;\n " + fragmentCode,
              });
            this._material.shader = shader;
          }),
          (HdriBackdrop.prototype._calculateModelSphereRadius = function (
            model
          ) {
            var meshInstances = null == model ? void 0 : model.meshInstances;
            if (!meshInstances || meshInstances.length < 1) return 0;
            var boundingBox = new pc.BoundingBox();
            boundingBox.copy(meshInstances[0].aabb),
              meshInstances.slice(1).forEach(function (meshInstance) {
                return boundingBox.add(meshInstance.aabb);
              });
            var positions = [],
              tmpVec1 = new pc.Vec3(),
              tmpVec2 = new pc.Vec3(),
              radiusSquared = 0;
            return (
              meshInstances.forEach(function (meshInstance) {
                for (
                  var vertexCount = meshInstance.mesh.getPositions(positions),
                    transform = meshInstance.node.getWorldTransform(),
                    idx = 0;
                  idx < vertexCount;
                  idx += 3
                )
                  transform.transformPoint(
                    tmpVec2.set(
                      positions[3 * idx + 0],
                      positions[3 * idx + 1],
                      positions[3 * idx + 2]
                    ),
                    tmpVec1
                  ),
                    tmpVec2.sub2(tmpVec1, boundingBox.center),
                    (radiusSquared = Math.max(
                      radiusSquared,
                      tmpVec2.lengthSq()
                    ));
              }),
              Math.sqrt(radiusSquared)
            );
          }),
          (HdriBackdrop.prototype._getVertexShaderCode = function () {
            return "\n      attribute vec4 aPosition;\n\n      uniform mat4 matrix_model;\n      uniform mat4 matrix_viewProjection;\n\n      varying vec3 vWorldVertexPosition;\n\n      void main(void)\n      {\n        vec4 worldVertexPosition = matrix_model * aPosition;\n        vWorldVertexPosition = worldVertexPosition.xyz;\n        gl_Position = matrix_viewProjection * worldVertexPosition;\n      }\n    ";
          }),
          (HdriBackdrop.prototype._getFragmentShaderCode = function () {
            var scene = this.app.scene,
              chunks = pc.shaderChunks,
              programlib = pc.programlib,
              shaderCode = "";
            return (
              (shaderCode += programlib.gammaCode(scene.gammaCorrection)),
              (shaderCode += programlib.tonemapCode(scene.toneMapping)),
              (shaderCode += chunks.rgbmPS),
              (shaderCode +=
                "\n      uniform samplerCube uHdriMap;\n      uniform mat4        uMapRotationMatrix;\n      uniform float       uIntensity;\n      uniform vec3        uProjectionCenter;\n      uniform float       uLightingDistance;\n      uniform vec3        view_position;\n\n      varying vec3 vWorldVertexPosition;\n\n      struct HdriAttributes\n      {\n        vec3 baseColor;\n        float specular;\n        vec3 emissiveColor;\n      };\n\n      float saturate(float source)\n      {\n        return clamp(source, 0.0, 1.0);\n      }\n\n      HdriAttributes createHdriAttributes(vec3 in_)\n      {\n        vec3 projectionDirection = normalize(vWorldVertexPosition - uProjectionCenter);\n        vec3 sampleDirection =  (vec4(projectionDirection, 1.0) * uMapRotationMatrix).xyz;\n\n        sampleDirection.x *= -1.0;  // Same flip in x is used by skybox.vert in the Playcanvas engine\n\n        vec3 hdriMapRgb = textureCubeRGBM(uHdriMap, sampleDirection).xyz;\n        vec3 poweredIn = pow(in_, vec3(4.0));\n\n        HdriAttributes result;\n\n        result.baseColor = hdriMapRgb * poweredIn * saturate(uIntensity);\n        result.specular = 0.0;\n        result.emissiveColor = hdriMapRgb * uIntensity * (vec3(1.0) - poweredIn);\n\n        return result;\n      }\n\n      void main(void)\n      {\n        vec3 in_ = vec3(saturate((uLightingDistance - length(vWorldVertexPosition - view_position)) / uLightingDistance));\n\n        HdriAttributes hdriAttributes = createHdriAttributes(in_);\n\n        vec3 color = hdriAttributes.baseColor + vec3(hdriAttributes.specular) + hdriAttributes.emissiveColor;\n\n        color = toneMap(color);\n        color = gammaCorrectOutput(color);\n\n        gl_FragColor = vec4(color, 1.0);\n      }\n    ")
            );
          }),
          HdriBackdrop
        );
      })(pc.ScriptType);
    exports.HdriBackdrop = HdriBackdrop;
  },
  function (module, exports, __webpack_require__) {
    "use strict";
    var __createBinding =
        (this && this.__createBinding) ||
        (Object.create
          ? function (o, m, k, k2) {
              void 0 === k2 && (k2 = k),
                Object.defineProperty(o, k2, {
                  enumerable: !0,
                  get: function () {
                    return m[k];
                  },
                });
            }
          : function (o, m, k, k2) {
              void 0 === k2 && (k2 = k), (o[k2] = m[k]);
            }),
      __setModuleDefault =
        (this && this.__setModuleDefault) ||
        (Object.create
          ? function (o, v) {
              Object.defineProperty(o, "default", { enumerable: !0, value: v });
            }
          : function (o, v) {
              o.default = v;
            }),
      __importStar =
        (this && this.__importStar) ||
        function (mod) {
          if (mod && mod.__esModule) return mod;
          var result = {};
          if (null != mod)
            for (var k in mod)
              "default" !== k &&
                Object.prototype.hasOwnProperty.call(mod, k) &&
                __createBinding(result, mod, k);
          return __setModuleDefault(result, mod), result;
        };
    Object.defineProperty(exports, "__esModule", { value: !0 }),
      (exports.hasRegisteredScript = void 0);
    var pc = __importStar(__webpack_require__(0));
    exports.hasRegisteredScript = function (type, name) {
      var app = pc.Application.getApplication();
      return Boolean(
        (null == app ? void 0 : app.scripts.has(type)) ||
          (name && (null == app ? void 0 : app.scripts.has(name)))
      );
    };
  },
]);

Hi @sooyong_Kim,

You need to add the following line:
(shaderCode += chunks.decodePS),
just before the line:
(shaderCode += chunks.rgbmPS),

This should fix the shader compilation error.

Please note that these chunks will likely be changing again in the near future, so you very well may to have make similar changes going forward.

Hope that helps,
Donovan

1 Like

https://playcanvas.com/editor/scene/1166854

Can you review this project? As you can see there is another issue with the current version.

I fixed this problem by modifying hdribackdrop script little bit.

https://playcanvas.com/project/1039743/

Basically what I did is change the appending order of shader chunk and added missing shader function.

 (shaderCode += chunks.decodePS),
              (shaderCode += "\n      vec3 textureCubeRGBM(samplerCube tex, vec3 uvw) {\n        return decodeRGBM(textureCube(tex, uvw)); }"),
              (shaderCode += programlib.gammaCode(scene.gammaCorrection)),
              (shaderCode += programlib.tonemapCode(scene.toneMapping)),
              (shaderCode += (chunks.rgbmPS)?chunks.rgbmPS:''),

Can you check if it’s right?

It works fine for me @sooyong_Kim, but yeah we should update the original project shader as well.