Scene3D
Scene3D
继承自 Object3D
,拥有 Object3D
相同的属性和方法,不同的是 Scene3D
是引擎渲染根节点,是场景树的最高层级,所有想要被渲染的节点必须添加到 Scene3D
或 Scene3D
的子节点中。
Scene3D
主要功能:
Scene3D
中定义了场景的天空盒和环境光贴图。Scene3D
可以用来控制和管理场景树中的节点,例如:添加、删除、查找节点。
基础用法
ts
await Engine3D.init();
// 创建场景
let scene = new Scene3D();
// 添加一个节点
let obj = new Object3D();
scene.addChild(obj);
// 添加相机节点
let cameraObj = new Object3D();
let camera = cameraObj.addComponent(Camera3D);
scene.addChild(cameraObj);
// 开始渲染
let view = new View3D();
view.scene = scene;
view.camera = camera;
Engine3D.startRenderView(view);
// 移除一个节点
scene.removeChild(obj);
大气天空盒
可以通过 AtmosphericComponent 组件创建一个大气散射的天空盒:
ts
// 添加大气天空盒组件,自动生成背景和环境光
let sky = scene3D.addComponent(AtmosphericComponent);
详见以下示例:
ts
import { Engine3D, Scene3D, Object3D, Camera3D, AtmosphericComponent, View3D } from '@orillusion/core';
import * as dat from 'dat.gui';
// initializa engine
await Engine3D.init();
// create a Scene3D
let scene3D = new Scene3D();
// add an Atmospheric sky enviroment
let sky = scene3D.addComponent(AtmosphericComponent);
// set sun position
sky.sunX = 0.8;
sky.sunY = 0.54;
// set exposure
sky.exposure = 1;
// create a camera
let cameraObj: Object3D = new Object3D();
let camera = cameraObj.addComponent(Camera3D);
camera.perspective(60, Engine3D.aspect, 1, 5000.0);
scene3D.addChild(cameraObj);
// create a view with target scene and camera
let view = new View3D();
view.scene = scene3D;
view.camera = camera;
// start render
Engine3D.startRenderView(view);
// debug GUI
const GUIHelp = new dat.GUI({ name: 'Orillusion' });
GUIHelp.addFolder('Atmospher');
GUIHelp.add(sky, 'sunX', 0, 1, 0.01);
GUIHelp.add(sky, 'sunY', 0, 1, 0.01);
GUIHelp.add(sky, 'eyePos', 1000, 2000, 10);
GUIHelp.add(sky, 'sunRadius', 100, 1000, 10);
GUIHelp.add(sky, 'sunRadiance', 0, 20, 1);
GUIHelp.add(sky, 'sunBrightness', 0, 1, 0.1);
通过 AtmosphericComponent
组件的 sunX
, sunY
, exposure
等属性来调整环境光的的变化。
ts
let sky = scene3D.addComponent(AtmosphericComponent);
sky.sunY = 0.54 // 太阳垂直位置,可以调节环境光亮度
sky.exposure = 1.5; //调整环境光曝光度, 默认值1
sky.roughness = 0.5; // 设置天空盒背景模糊强度, 范围[0, 1], 默认值0
自动跟随灯光
除了手动设置 sunX
, sunY
的数值,引擎还支持自动跟随场景中的灯光角度调整大气环境光位置
ts
// 平行光
let lightObj3D = new Object3D();
lightObj3D.rotationX = 46;
lightObj3D.rotationY = 62;
lightObj3D.rotationZ = 0;
let directLight = lightObj3D.addComponent(DirectLight);
let sky = scene3D.addComponent(AtmosphericComponent);
// 跟随平行光自动设置 sunX sunY
sky.relativeTransform = directLight.transform
自定义天空盒
如果想要自定义天空盒材质纹理,可以通过给 Scene3D
添加 SkyRenderer
组件来显示自定义背景; 同时,可以通过 Scene3D
对象的 envMap
属性来设置环境光。
1. 单色背景和环境光
可以通过 SolidColorSky 创建一个纯色的贴图来设置背景和环境光:
ts
import {Scene3D, SolidColorSky, Color, SkyRenderer} from '@orillusion/core';
let scene = new Scene3D();
// 创建一个纯色贴图
let colorSky = new SolidColorSky(new Color(0.5, 1.0, 0.8, 1))
// 添加 SkyRenderer 组件,然后设置 map 贴图
let sky = scene.addComponent(SkyRenderer);
sky.map = colorSky;
// 同时设置单色环境光
scene.envMap = colorSky;
2. 十字天空盒
可以通过加载 十字立方贴图 设置天空盒:
ts
// 可以加载一张完整十字立方贴图
let textureCube = Engine3D.res.loadTextureCube('path/to/sky.png')
// 或加载独立的6张立方贴图
textureCube = Engine3D.res.loadTextureCube([
'path/to/px.png',
'path/to/nx.png',
'path/to/py.png',
'path/to/ny.png',
'path/to/pz.png',
'path/to/nz.png'
])
// 添加 SkyRenderer 组件,设置 map 贴图
let sky = scene.addComponent(SkyRenderer);
sky.map = textureCube;
// 设置环境光
scene.envMap = textureCube;
目前十字天空盒只支持
LDR
普通格式的图片。
3. 全景天空盒
引擎还支持设置 全景图(equirectangular) 类型的天空盒。我们可以通过内置的 res
快速加载普通 RGBA
格式的 LDR
图片, 也支持加载 RGBE
格式的 HDR
图片:
ts
// 普通全景贴图
let skyTexture = Engine3D.res.loadLDRTextureCube('path/to/sky.png');
// HDR全景贴图
skyTexture = Engine3D.res.loadHDRTextureCube('path/to/sky.hdr');
// 添加 SkyRenderer 组件,设置 map 贴图
let sky = scene.addComponent(SkyRenderer);
sky.map = skyTexture;
// 设置环境光
scene.envMap = skyTexture;
4. 透明背景
如果想显示透明背景,通过关闭天空盒组件来隐藏背景,注意一般还需要使用透明 Canvas 才能生效:
ts
// 初始化引擎
await Engine3D.init({
canvasConfig:{
alpha: true, // 使用透明的 Canvas 配置
zIndex: 1
}
});
let scene = new Scene3D();
// 可以先添加大气天空盒,获得基本环境光
let sky = scene3D.addComponent(AtmosphericComponent);
// 再隐藏大气天空盒, 环境光不会消失
sky.enable = false
当然也可以不添加大气天空盒或背景,直接设置环境光
ts
// 设置一个简单白色环境光
scene.envMap = new SolidColorSky(new Color(0.75, 0.75, 0.75));
// 或者加载环境贴图
scene.envMap = await Engine3D.res.loadHDRTextureCube('path/to/sky.hdr');
更多详细用法请参考 Scene3D