Skip to content

Hoverer not working with Postproductionrenderer manual mode #649

@levistieber

Description

@levistieber

Describe the bug 📝

When postproductionrenderer is enabled with 'Manual mode', the Hoverer component is no longer working. Since it is not rendering when the camera is not being controlled, the Hoverer would not highlight the objects. In my application I also have a use case for camera movement (when you hover an IfcSlab object, a small circle is shown and if you click the camera moves there) which has the same problem as the Hoverer component.
To reproduce, I just copied the code from the Postproduction tutorial and the Hoverer tutorial and put them together.

Reproduction ▶️

`
import * as THREE from "three";
import * as OBC from "@thatopen/components";
import * as OBF from "@thatopen/components-front";
import * as BUI from "@thatopen/ui";

const container = document.getElementById("container")!;
const components = new OBC.Components();
const worlds = components.get(OBC.Worlds);

const world = worlds.create<OBC.ShadowedScene, OBC.OrthoPerspectiveCamera, OBF.PostproductionRenderer>();

world.scene = new OBC.ShadowedScene(components);
world.renderer = new OBF.PostproductionRenderer(components, container);
world.camera = new OBC.OrthoPerspectiveCamera(components);

await world.camera.controls.setLookAt(-7, 15, 20, -7, 0, 0);

components.init();

const grids = components.get(OBC.Grids);
const grid = grids.create(world);
grid.config.color.set(0x666666);

world.renderer.three.shadowMap.enabled = true;
world.renderer.three.shadowMap.type = THREE.PCFSoftShadowMap;

world.scene.setup({
directionalLight: {
color: new THREE.Color(1, 1, 1),
position: new THREE.Vector3(5, 10, 5),
intensity: 2,
},
shadows: {
cascade: 1,
resolution: 1024,
},
});

world.renderer.three.toneMapping = THREE.NeutralToneMapping;
world.renderer.three.toneMappingExposure = 1;
world.scene.three.background = null;

const updateIfManualMode = () => {
if (world.renderer!.mode === OBC.RendererMode.MANUAL) {
world.renderer!.needsUpdate = true;
}
};

world.camera.controls.addEventListener("update", updateIfManualMode);
world.renderer.onResize.add(updateIfManualMode);

const workerUrl = "../node_modules/@thatopen/fragments/dist/Worker/worker.mjs";

const fragments = components.get(OBC.FragmentsManager);
fragments.init(workerUrl);

world.camera.controls.addEventListener("rest", async () => {
fragments.core.update(true);
await world.scene.updateShadows();
updateIfManualMode();
});

world.onCameraChanged.add((camera) => {
for (const [, model] of fragments.list) {
model.useCamera(camera.three);
}
fragments.core.update(true);
updateIfManualMode();
});

fragments.list.onItemSet.add(({ value: model }) => {
model.useCamera(world.camera.three);
world.scene.three.add(model.object);
fragments.core.update(true);
updateIfManualMode();
});

fragments.core.models.materials.list.onItemSet.add(({ value: material }) => {
const isLod = "isLodMaterial" in material && material.isLodMaterial;

if (!isLod) {
material.polygonOffset = true;
material.polygonOffsetUnits = 1;
material.polygonOffsetFactor = Math.random();
}
});

const fetched = await fetch("/resources/frags/Fertighaus_ifc4.frag");
const buffer = await fetched.arrayBuffer();

await fragments.core.load(buffer, {
modelId: "test",
});

await fragments.core.update(true);

world.renderer.postproduction.enabled = true;
world.dynamicAnchor = false;

const hoverer = components.get(OBF.Hoverer);
hoverer.world = world;
hoverer.enabled = true;
hoverer.material = new THREE.MeshBasicMaterial({
color: 0x6528d7,
transparent: true,
opacity: 0.5,
depthTest: false,
});

BUI.Manager.init();

const { aoPass, outlinePass, edgesPass, defaultAoParameters } =
world.renderer.postproduction;

const pdParameters = {
lumaPhi: 10,
depthPhi: 2,
normalPhi: 3,
radius: 4,
radiusExponent: 1,
rings: 2,
samples: 16,
};

aoPass.updateGtaoMaterial(defaultAoParameters);
aoPass.updatePdMaterial(pdParameters);

const cube = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshLambertMaterial({ color: 0x00ff00 })
);
cube.position.set(10, 0, 0);
world.scene.three.add(cube);
world.renderer.postproduction.excludedObjectsPass.addExcludedMaterial(
cube.material
);

const panel = BUI.Component.create<BUI.PanelSection>(() => {
return BUI.html`

<bim-panel-section label="General">

  <bim-checkbox checked label="Postproduction enabled"
    @change="${({ target }: { target: BUI.Checkbox }) => {
  world.renderer!.postproduction.enabled = target.value;
  updateIfManualMode();
}}">
  </bim-checkbox>

  <bim-checkbox checked label="Outlines enabled"
    ?checked=${world.renderer!.postproduction.outlinesEnabled}
    @change="${({ target }: { target: BUI.Checkbox }) => {
  world.renderer!.postproduction.outlinesEnabled = target.value;
  updateIfManualMode();
}}">
  </bim-checkbox>

  <bim-checkbox checked label="Excluded objects enabled"
    ?checked=${world.renderer!.postproduction.excludedObjectsEnabled}
    @change="${({ target }: { target: BUI.Checkbox }) => {
  world.renderer!.postproduction.excludedObjectsEnabled = target.value;
  updateIfManualMode();
}}">
  </bim-checkbox>

  <bim-checkbox checked label="SMAA enabled"
    ?checked=${world.renderer!.postproduction.smaaEnabled}
    @change="${({ target }: { target: BUI.Checkbox }) => {
  world.renderer!.postproduction.smaaEnabled = target.value;
  updateIfManualMode();
}}">
  </bim-checkbox>

  <bim-dropdown required label="Postproduction style"
    @change="${({ target }: { target: BUI.Dropdown }) => {
  const result = target.value[0] as OBF.PostproductionAspect;
  world.renderer!.postproduction.style = result;
  updateIfManualMode();
}}">

    <bim-option checked label="Basic" value="${OBF.PostproductionAspect.COLOR
}"></bim-option>
    <bim-option label="Pen" value="${OBF.PostproductionAspect.PEN
}"></bim-option>
    <bim-option label="Shadowed Pen" value="${OBF.PostproductionAspect.PEN_SHADOWS
}"></bim-option>
    <bim-option label="Color Pen" value="${OBF.PostproductionAspect.COLOR_PEN
}"></bim-option>
    <bim-option label="Color Shadows" value="${OBF.PostproductionAspect.COLOR_SHADOWS
}"></bim-option>
    <bim-option label="Color Pen Shadows" value="${OBF.PostproductionAspect.COLOR_PEN_SHADOWS
}"></bim-option>
  </bim-dropdown>

</bim-panel-section>

<bim-panel-section label="Edges">

  <bim-number-input
      slider step="0.1" label="Width"
      value="${world.renderer!.postproduction.edgesPass.width
}" min="1" max="3"
      @change="${({ target }: { target: BUI.NumberInput }) => {
  world.renderer!.postproduction.edgesPass.width = target.value;
  updateIfManualMode();
}}">
  </bim-number-input>

  <bim-color-input label="Edges color"
    color="#${edgesPass.color.getHexString()}"
    @input="${({ target }: { target: BUI.ColorInput }) => {
  edgesPass.color.set(target.value.color);
  updateIfManualMode();
}}">
  </bim-color-input>

</bim-panel-section>

<bim-panel-section label="Outline">

  <bim-number-input
      slider step="0.1" label="Outline thickness"
      value="${outlinePass.thickness}" min="1" max="10"
      @change="${({ target }: { target: BUI.NumberInput }) => {
  outlinePass.thickness = target.value;
  updateIfManualMode();
}}">
  </bim-number-input>

  <bim-number-input
      slider step="0.01" label="Fill opacity"
      value="${outlinePass.fillOpacity}" min="0" max="1"
      @change="${({ target }: { target: BUI.NumberInput }) => {
  outlinePass.fillOpacity = target.value;
  updateIfManualMode();
}}">
  </bim-number-input>

  <bim-color-input label="Line color"
    color="#${outlinePass.outlineColor.getHexString()}"
    @input="${({ target }: { target: BUI.ColorInput }) => {
  outlinePass.outlineColor.set(target.value.color);
  updateIfManualMode();
}}">
  </bim-color-input>

  <bim-color-input label="Fill color"
    color="#${outlinePass.fillColor.getHexString()}"
    @input="${({ target }: { target: BUI.ColorInput }) => {
  outlinePass.fillColor.set(target.value.color);
  updateIfManualMode();
}}">
  </bim-color-input>

</bim-panel-section>

<bim-panel-section label="Gloss">

  <bim-checkbox label="Enabled"
    ?checked=${world.renderer!.postproduction.glossEnabled}
    @change="${({ target }: { target: BUI.Checkbox }) => {
  world.renderer!.postproduction.glossEnabled = target.value;
  updateIfManualMode();
}}">
  </bim-checkbox>

  <bim-number-input
    slider step="0.01" label="Min gloss"
    value="${world.renderer!.postproduction.glossPass.minGloss
}" min="-1" max="1"
    @change="${({ target }: { target: BUI.NumberInput }) => {
  world.renderer!.postproduction.glossPass.minGloss = target.value;
  updateIfManualMode();
}}">
  </bim-number-input>

  <bim-number-input
    slider step="0.01" label="Max gloss"
    value="${world.renderer!.postproduction.glossPass.maxGloss
}" min="-1" max="1"
    @change="${({ target }: { target: BUI.NumberInput }) => {
  world.renderer!.postproduction.glossPass.maxGloss = target.value;
  updateIfManualMode();
}}">
  </bim-number-input>

  <bim-number-input
    slider step="0.01" label="Gloss exponent"
    value="${world.renderer!.postproduction.glossPass.glossExponent
}" min="0.1" max="20"
    @change="${({ target }: { target: BUI.NumberInput }) => {
  world.renderer!.postproduction.glossPass.glossExponent = target.value;
  updateIfManualMode();
}}">
  </bim-number-input>

  <bim-number-input
    slider step="0.01" label="Fresnel exponent"
    value="${world.renderer!.postproduction.glossPass.fresnelExponent
}" min="0.1" max="50"
    @change="${({ target }: { target: BUI.NumberInput }) => {
  world.renderer!.postproduction.glossPass.fresnelExponent =
    target.value;
  updateIfManualMode();
}}">
  </bim-number-input>

  <bim-number-input
    slider step="0.01" label="Gloss factor"
    value="${world.renderer!.postproduction.glossPass.glossFactor
}" min="0" max="1"
    @change="${({ target }: { target: BUI.NumberInput }) => {
  world.renderer!.postproduction.glossPass.glossFactor = target.value;
  updateIfManualMode();
}}">
  </bim-number-input>

  <bim-number-input
    slider step="0.01" label="Fresnel factor"
    value="${world.renderer!.postproduction.glossPass.fresnelFactor
}" min="0" max="10"
    @change="${({ target }: { target: BUI.NumberInput }) => {
  world.renderer!.postproduction.glossPass.fresnelFactor = target.value;
  updateIfManualMode();
}}">
  </bim-number-input>

</bim-panel-section>

<bim-panel-section label="Manual mode">
  <bim-checkbox label="Enabled"
    ?checked=${world.renderer!.mode === OBC.RendererMode.MANUAL}
    @change="${({ target }: { target: BUI.Checkbox }) => {
  world.renderer!.mode = target.value
    ? OBC.RendererMode.MANUAL
    : OBC.RendererMode.AUTO;
  updateIfManualMode();
}}">
  </bim-checkbox>

  <bim-number-input label="Delay"
    value="${world.renderer!.manualModeDelay}" min="10" max="1000"
    @change="${({ target }: { target: BUI.NumberInput }) => {
  world.renderer!.manualModeDelay = target.value;
  updateIfManualMode();
}}">
  </bim-number-input>

  <bim-checkbox label="Turn off on manual mode"
    ?checked=${world.renderer!.turnOffOnManualMode}
    @change="${({ target }: { target: BUI.Checkbox }) => {
  world.renderer!.turnOffOnManualMode = target.value;
  updateIfManualMode();
}}">
  </bim-checkbox>

  <bim-dropdown label="Default style"
    @change="${({ target }: { target: BUI.Dropdown }) => {
  const result = target.value[0] as OBF.PostproductionAspect;
  world.renderer!.manualDefaultStyle = result;
  updateIfManualMode();
}}">
    <bim-option label="Basic" value="${OBF.PostproductionAspect.COLOR
}"></bim-option>
    <bim-option label="Pen" value="${OBF.PostproductionAspect.PEN
}"></bim-option>
    <bim-option label="Pen Shadows" value="${OBF.PostproductionAspect.PEN_SHADOWS
}"></bim-option>
    <bim-option label="Color Pen" value="${OBF.PostproductionAspect.COLOR_PEN
}"></bim-option>
    <bim-option label="Color Shadows" value="${OBF.PostproductionAspect.COLOR_SHADOWS
}"></bim-option>
    <bim-option label="Color Pen Shadows" value="${OBF.PostproductionAspect.COLOR_PEN_SHADOWS
}"></bim-option>
  </bim-dropdown>

</bim-panel-section>

<bim-panel-section label="Ambient Occlusion">

    <bim-checkbox checked label="Screen Space Radius"
      ?checked=${defaultAoParameters.screenSpaceRadius}
      @change="${({ target }: { target: BUI.Checkbox }) => {
  defaultAoParameters.screenSpaceRadius = target.value;
  aoPass.updateGtaoMaterial(defaultAoParameters);
  updateIfManualMode();
}}">
    </bim-checkbox>

    <bim-number-input
      slider step="0.01" label="Blend intensity"
      value="${aoPass.blendIntensity}" min="0" max="1"
      @change="${({ target }: { target: BUI.NumberInput }) => {
  aoPass.blendIntensity = target.value;
  updateIfManualMode();
}}">
    </bim-number-input>

    <bim-number-input
      slider step="0.01" label="Radius"
      value="${defaultAoParameters.radius}" min="0.01" max="1"
      @change="${({ target }: { target: BUI.NumberInput }) => {
  defaultAoParameters.radius = target.value;
  aoPass.updateGtaoMaterial(defaultAoParameters);
  updateIfManualMode();
}}">
    </bim-number-input>

    <bim-number-input
      slider step="0.01" label="Distance exponent"
      value="${defaultAoParameters.distanceExponent}" min="1" max="10"
      @change="${({ target }: { target: BUI.NumberInput }) => {
  defaultAoParameters.distanceExponent = target.value;
  aoPass.updateGtaoMaterial(defaultAoParameters);
  updateIfManualMode();
}}">
    </bim-number-input>

    <bim-number-input
      slider step="0.01" label="Thickness"
      value="${defaultAoParameters.thickness}" min="0.01" max="10"
      @change="${({ target }: { target: BUI.NumberInput }) => {
  defaultAoParameters.thickness = target.value;
  aoPass.updateGtaoMaterial(defaultAoParameters);
  updateIfManualMode();
}}">
    </bim-number-input>

    <bim-number-input
      slider step="0.01" label="Distance falloff"
      value="${defaultAoParameters.distanceFallOff}" min="0" max="1"
      @change="${({ target }: { target: BUI.NumberInput }) => {
  defaultAoParameters.distanceFallOff = target.value;
  aoPass.updateGtaoMaterial(defaultAoParameters);
  updateIfManualMode();
}}">
    </bim-number-input>

    <bim-number-input
      slider step="0.01" label="Scale"
      value="${defaultAoParameters.scale}" min="0.01" max="10"
      @change="${({ target }: { target: BUI.NumberInput }) => {
  defaultAoParameters.scale = target.value;
  aoPass.updateGtaoMaterial(defaultAoParameters);
  updateIfManualMode();
}}">
    </bim-number-input>

    <bim-number-input
      slider step="1" label="Samples"
      value="${defaultAoParameters.samples}" min="2" max="32"
      @change="${({ target }: { target: BUI.NumberInput }) => {
  defaultAoParameters.samples = target.value;
  aoPass.updateGtaoMaterial(defaultAoParameters);
  updateIfManualMode();
}}">
    </bim-number-input>

    <bim-number-input
      slider step="0.1" label="PD Luma Phi"
      value="${pdParameters.lumaPhi}" min="0" max="20"
      @change="${({ target }: { target: BUI.NumberInput }) => {
  pdParameters.lumaPhi = target.value;
  aoPass.updatePdMaterial(pdParameters);
  updateIfManualMode();
}}">
    </bim-number-input>

    <bim-number-input
      slider step="0.1" label="PD Depth Phi"
      value="${pdParameters.depthPhi}" min="0.01" max="20"
      @change="${({ target }: { target: BUI.NumberInput }) => {
  pdParameters.depthPhi = target.value;
  aoPass.updatePdMaterial(pdParameters);
  updateIfManualMode();
}}">
    </bim-number-input>

    <bim-number-input
      slider step="0.1" label="PD Normal Phi"
      value="${pdParameters.normalPhi}" min="0.01" max="20"
      @change="${({ target }: { target: BUI.NumberInput }) => {
  pdParameters.normalPhi = target.value;
  aoPass.updatePdMaterial(pdParameters);
  updateIfManualMode();
}}">
    </bim-number-input>

    <bim-number-input
      slider step="1" label="PD Radius"
      value="${pdParameters.radius}" min="0" max="32"
      @change="${({ target }: { target: BUI.NumberInput }) => {
  pdParameters.radius = target.value;
  aoPass.updatePdMaterial(pdParameters);
  updateIfManualMode();
}}">
    </bim-number-input>

    <bim-number-input
      slider step="0.1" label="PD Radius Exponent"
      value="${pdParameters.radiusExponent}" min="0.1" max="4"
      @change="${({ target }: { target: BUI.NumberInput }) => {
  pdParameters.radiusExponent = target.value;
  aoPass.updatePdMaterial(pdParameters);
  updateIfManualMode();
}}">
    </bim-number-input>

    <bim-number-input
      slider step="1" label="PD Rings"
      value="${pdParameters.rings}" min="1" max="16"
      @change="${({ target }: { target: BUI.NumberInput }) => {
  pdParameters.rings = target.value;
  aoPass.updatePdMaterial(pdParameters);
  updateIfManualMode();
}}">
    </bim-number-input>

    <bim-number-input
      slider step="1" label="PD Samples"
      value="${pdParameters.samples}" min="2" max="32"
      @change="${({ target }: { target: BUI.NumberInput }) => {
  pdParameters.samples = target.value;
  aoPass.updatePdMaterial(pdParameters);
  updateIfManualMode();
}}">
    </bim-number-input>

  </bim-panel-section>

</bim-panel>
`;

});

document.body.append(panel);

const style = document.createElement("style");
style.textContent = .options-menu { position: fixed; top: 1rem; max-height: calc(100vh - 2rem); overflow: auto; z-index: 1000; };
document.head.appendChild(style);
`

System Info 💻

System:
    OS: Linux 5.15 Ubuntu 22.04.5 LTS 22.04.5 LTS (Jammy Jellyfish)
    CPU: (16) x64 AMD Ryzen 7 7735HS with Radeon Graphics
    Memory: 8.05 GB / 15.02 GB
    Container: Yes
    Shell: 5.1.16 - /bin/bash
  Binaries:
    Node: 20.19.5 - /home/stieberl/.nvm/versions/node/v20.19.5/bin/node
    npm: 10.8.2 - /home/stieberl/.nvm/versions/node/v20.19.5/bin/npm

Used Package Manager 📦

npm

Error Trace/Logs 📃

No response

Validations ✅

  • Read the docs.
  • Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
  • Make sure this is a repository issue and not a framework-specific issue. For example, if it's a THREE.js related bug, it should likely be reported to mrdoob/threejs instead.
  • Check that this is a concrete bug. For Q&A join our Community.
  • The provided reproduction is a minimal reproducible example of the bug.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions