Add custom 3D objects
Sometimes it's useful to add custom content to the 3D scene to model data Reveal doesn't
support or to customize the 3D environment. Reveal supports this by using the
Cognite3DViewer.addObject3D
-function which accepts ThreeJS objects.
There are a few restrictions to the 3D content that is to be combined with Reveal models:
- Reveal uses an "implicit lighting model", i.e. no lights are added to the scene. If you need lights this needs to be added to the viewer scene.
- Geometry is expected to use "default depth testing", meaning
THREE.Material.depthTest
must betrue
,THREE.Material.depthWrite
musttrue
andTHREE.Material.depthFunc
must beLessEqualDepth
. You might experience unexpected results if you are using materials where this doesn't hold. - Objects with opacity less than 1.0 will appear transparent regardless of if
THREE.Material.transparent
istrue
orfalse
. The final composited image is always blended as ifTHREE.Material.blendDst
isOneMinusSrcAlphaFactor
and the blending settings on the material won't have any effect on the composition.
Adding markers to the scene on clicks
The following example reacts to clicks in the scene and adds markers to the positions clicked.
Add environment
To make a model feel more natural it might be useful to add an environment. The following example adds sky and a sea effect for the example oil rig.
Below you'll find an interactive example, but first lets walk through the different parts. See the bottom of this page for an interactive example.
First, let's encapsulate the model in a large sky-textured sphere to create an illusion of skies. The sphere map is available from Free HDR - EXR SKIES-blog.
const modelCenterAtSeaLevel = model
.getModelBoundingBox()
.getCenter(new THREE.Vector3());
modelCenterAtSeaLevel.y = 0.0;
// Skybox
const skyBox = new THREE.Mesh(
new THREE.SphereGeometry(3000, 15, 15),
new THREE.MeshBasicMaterial({
side: THREE.BackSide,
// Skybox texture from http://freepanorama.blogspot.com/2010/01/sky7-spherical.html
map: new THREE.TextureLoader().load(urls.skyUrl),
})
);
skyBox.position.copy(modelCenterAtSeaLevel);
viewer.addObject3D(skyBox);
This looks a bit better, but the oil rig appears to be floating mid-air at this point. Lets add an ocean. A plane is rendered at the sea level.
// Water
const waterGeometry = new THREE.PlaneGeometry(6000, 6000, 63, 63);
const material = new THREE.MeshBasicMaterial({
map: new THREE.TextureLoader().load(
'https://threejs.org/examples/textures/water.jpg',
(texture) => {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
}),
color: { value: new THREE.Color(0x0099ff)},
side: THREE.DoubleSide
});
const water = new THREE.Mesh(waterGeometry, material);
// Make the ocean horizontal
water.rotation.x = -Math.PI / 2;
water.position.copy(modelCenterAtSeaLevel);
viewer.addObject3D(water);
Interactive example
Below is the complete code for adding a skybox and ocean to the scene.