Lighting
Lighting can make the scene more layered, using lighting, you can build a more realistic three-dimensional scene. The lighting system of the Orillusion
engine is mainly composed of the following parts:
Light Source | Description |
---|---|
Light Component | Basic light source components: direct light, point light and spotlight |
Ambient Reflection | Skybox environment light, global exposure |
Global Illumination | Indirect light sources reflected or refracted in the scene |
Light Component
There are currently three types of classic light sources built into the engine:
Direct Light
Direct Light represents the light that is emitted uniformly from a certain direction and lights between them are parallel. The lights from the sun to the earth can be considered as the parallel light, because the distance between the sun and the earth is far greater than the radius of the earth, so the lights from the sun to the earth can be seen as lights from the same direction, that is, the parallel light. The direct light
has 4
main features:
Attribute | Type | Description |
---|---|---|
lightColor | Color | The color of the light, the default is white rgb(1.0,1.0,1.0) |
intensity | Number | The intensity of the light, the default value is 1 |
direction | Vector3 | Read-only property, get the direction vector of the parallel light |
castShadow | Boolean | Whether to enable projection, the default false is disabled |
Normally, the rotation
of the Object3D
, where the direct light
is located, is used to control the direction of the light.
let lightObj = new Object3D();
scene.addChild(lightObj);
// Add direct light
let dl = lightObj.addComponent(DirectLight);
// Set color
dl.lightColor = new Color(1.0, 0.95, 0.84, 1.0);
// Set intensity
dl.intensity = 20;
// Set the direction of the light source through Object3D
lightObj.rotateX = 45;
lightObj.rotateY = 45;
// You can get the direction vector through direction
let target = dl.direction
import { BoxGeometry, Camera3D, Engine3D, AtmosphericComponent, LitMaterial, HoverCameraController, MeshRenderer, Object3D, Scene3D, DirectLight, Vector3, webGPUContext, View3D } from '@orillusion/core';
import * as dat from 'dat.gui';
class Sample_Light {
scene: Scene3D;
hoverCameraController: HoverCameraController;
lightObj: any;
constructor() {}
async run() {
await Engine3D.init({
canvasConfig: { devicePixelRatio: 1 }
});
this.scene = new Scene3D();
let cameraObj = new Object3D();
let mainCamera = cameraObj.addComponent(Camera3D);
mainCamera.perspective(37, webGPUContext.aspect, 1, 10000.0);
this.hoverCameraController = mainCamera.object3D.addComponent(HoverCameraController);
this.scene.addChild(cameraObj);
//set camera data
this.hoverCameraController.setCamera(0, -45, 2000);
this.initScene(this.scene);
// add an Atmospheric sky enviroment
this.scene.addComponent(AtmosphericComponent).sunY = 0.6;
// create a view with target scene and camera
let view = new View3D();
view.scene = this.scene;
view.camera = mainCamera;
// start render
Engine3D.startRenderView(view);
}
initScene(scene: Scene3D) {
{
let dirLight = new Object3D();
dirLight.rotationX = 30;
dirLight.rotationZ = 30;
let light = dirLight.addComponent(DirectLight);
light.intensity = 20;
light.lightColor.r = 255 / 255;
light.lightColor.g = 157 / 255;
light.lightColor.b = 5 / 255;
scene.addChild(dirLight);
let GUIHelp = new dat.GUI();
GUIHelp.addFolder('Direct Light');
GUIHelp.add(dirLight, 'rotationX', -180, 180, 1);
GUIHelp.add(dirLight, 'rotationY', -180, 180, 1);
GUIHelp.add(dirLight, 'rotationZ', -180, 180, 1);
GUIHelp.addColor({ color: Object.values(light.lightColor).map((v) => v * 255) }, 'color').onChange((v) => {
light.lightColor.copyFromArray(v);
});
GUIHelp.add(light, 'intensity', 0, 100, 1);
}
let mat = new LitMaterial();
mat.baseMap = Engine3D.res.grayTexture;
let floor = new Object3D();
let mr = floor.addComponent(MeshRenderer);
mr.geometry = new BoxGeometry(2000, 1, 2000);
mr.material = mat;
this.scene.addChild(floor);
let box = new BoxGeometry(1, 1, 1);
let wall_w = new Object3D();
wall_w.localScale = new Vector3(500, 100, 10);
wall_w.localPosition = new Vector3(0, 50, 0);
let mrw = wall_w.addComponent(MeshRenderer);
mrw.geometry = box;
mrw.material = mat;
this.scene.addChild(wall_w);
let wall_a = new Object3D();
wall_a.localScale = new Vector3(10, 100, 500);
wall_a.localPosition = new Vector3(250, 50, 0);
let mra = wall_a.addComponent(MeshRenderer);
mra.geometry = box;
mra.material = mat;
this.scene.addChild(wall_a);
let wall_d = new Object3D();
wall_d.localScale = new Vector3(10, 100, 500);
wall_d.localPosition = new Vector3(-250, 50, 0);
let mrd = wall_d.addComponent(MeshRenderer);
mrd.geometry = box;
mrd.material = mat;
this.scene.addChild(wall_d);
}
}
new Sample_Light().run();
Point Light
Point Light is a point that exists in space, and light is emitted from that point in all directions. The light beyond the effective distance cannot receive the light from the point light, and the intensity of the light will gradually decrease as the light source moves away. It is usually used to simulate the common bulbs in life. The point light has the following main attributes:
Attribute | Type | Description |
---|---|---|
lightColor | Color | The color of the light, the default is white rgb(1.0,1.0,1.0) |
intensity | Number | The intensity of the light, the default value is 1 |
range | Number | The farthest distance of the light |
let pointLightObj = new Object3D();
// Set the position of the light source Object3D
pointLightObj.x = -10;
pointLightObj.y = 10;
pointLightObj.z = 10;
scene.addChild(pointLightObj);
// Set the radius, intensity, and color of the point light component
let pointLight = pointLightObj.addComponent(PointLight);
pointLight.range = 20;
pointLight.intensity = 10;
pointLight.lightColor = new Color(1.0, 0.95, 0.84, 1.0);
import { BoxGeometry, Camera3D, Engine3D, AtmosphericComponent, LitMaterial, HoverCameraController, MeshRenderer, Object3D, Scene3D, SphereGeometry, PointLight, Vector3, webGPUContext, View3D } from '@orillusion/core';
import * as dat from 'dat.gui';
class Sample_Light {
scene: Scene3D;
hoverCameraController: HoverCameraController;
lightObj: any;
constructor() {}
async run() {
await Engine3D.init({
canvasConfig: { devicePixelRatio: 1 }
});
this.scene = new Scene3D();
let cameraObj = new Object3D();
let mainCamera = cameraObj.addComponent(Camera3D);
mainCamera.perspective(37, webGPUContext.aspect, 1, 5000.0);
this.hoverCameraController = mainCamera.object3D.addComponent(HoverCameraController);
this.scene.addChild(cameraObj);
//set camera data
this.hoverCameraController.setCamera(0, -45, 1200);
await this.initScene(this.scene);
// add an Atmospheric sky enviroment
this.scene.addComponent(AtmosphericComponent).sunY = 0.6;
// create a view with target scene and camera
let view = new View3D();
view.scene = this.scene;
view.camera = mainCamera;
// start render
Engine3D.startRenderView(view);
}
initScene(scene: Scene3D) {
{
let sp = new SphereGeometry(5, 30, 30);
let pointLight = new Object3D();
pointLight.y = 200;
let mr = pointLight.addComponent(MeshRenderer);
mr.geometry = sp;
mr.material = new LitMaterial();
let light = pointLight.addComponent(PointLight);
light.intensity = 100;
light.range = 300;
light.lightColor.r = 255 / 255;
light.lightColor.g = 157 / 255;
light.lightColor.b = 5 / 255;
scene.addChild(pointLight);
let GUIHelp = new dat.GUI();
GUIHelp.addFolder('Direct Light');
GUIHelp.add(pointLight, 'x', -180, 180, 1);
GUIHelp.add(pointLight, 'y', -180, 180, 1);
GUIHelp.add(pointLight, 'z', -180, 180, 1);
GUIHelp.addColor({ color: Object.values(light.lightColor).map((v) => v * 255) }, 'color').onChange((v) => {
light.lightColor.copyFromArray(v);
});
GUIHelp.add(light, 'intensity', 0, 200, 1);
GUIHelp.add(light, 'range', 100, 500, 1);
}
let mat = new LitMaterial();
mat.baseMap = Engine3D.res.grayTexture;
let floor = new Object3D();
let mr = floor.addComponent(MeshRenderer);
mr.geometry = new BoxGeometry(2000, 1, 2000);
mr.material = mat;
this.scene.addChild(floor);
let box = new BoxGeometry(1, 1, 1);
let wall_w = new Object3D();
wall_w.localScale = new Vector3(500, 100, 10);
wall_w.localPosition = new Vector3(0, 50, 0);
let mrw = wall_w.addComponent(MeshRenderer);
mrw.geometry = box;
mrw.material = mat;
this.scene.addChild(wall_w);
let wall_a = new Object3D();
wall_a.localScale = new Vector3(10, 100, 500);
wall_a.localPosition = new Vector3(250, 50, 0);
let mra = wall_a.addComponent(MeshRenderer);
mra.geometry = box;
mra.material = mat;
this.scene.addChild(wall_a);
let wall_d = new Object3D();
wall_d.localScale = new Vector3(10, 100, 500);
wall_d.localPosition = new Vector3(-250, 50, 0);
let mrd = wall_d.addComponent(MeshRenderer);
mrd.geometry = box;
mrd.material = mat;
this.scene.addChild(wall_d);
}
}
new Sample_Light().run();
Spot Light
Spot Light is similar to the point light
, but its light is not emitted in all directions, but in a certain direction range, just like the light emitted by the flashlight in real life. The spotlight has several main features:
Attribute | Type | Description |
---|---|---|
lightColor | Color | The color of the light, the default is white rgb(1.0,1.0,1.0) |
intensity | Number | The intensity of the light, the default value is 1 |
direction | Vector3 | Read-only property, get the direction vector of the spotlight |
range | Number | The farthest distance of the light |
innerAngle | Number | The inner angle of the spotlight, the light has light in the range of less than this angle |
outerAngle | Number | The outer angle of the spotlight, the light will gradually decrease to 0 in the range from the inner angle to the outer angle |
let spotLightObj = new Object3D();
// Set the position of the light source Object3D
spotLightObj.y = 100;
spotLightObj.rotationX = 90;
scene.addChild(spotLightObj);
// Set the attributes of the spotlight component
let spotLight = spotLightObj.addComponent(SpotLight);
spotLight.lightColor = new Color(1.0, 0.95, 0.84, 1.0);
spotLight.intensity = 20;
spotLight.range = 200;
spotLight.innerAngle = 20;
spotLight.outerAngle = 35;
import { BoxGeometry, Camera3D, Engine3D, AtmosphericComponent, LitMaterial, HoverCameraController, MeshRenderer, Object3D, Scene3D, SphereGeometry, SpotLight, Vector3, webGPUContext, View3D } from '@orillusion/core';
import * as dat from 'dat.gui';
class Sample_Light {
scene: Scene3D;
hoverCameraController: HoverCameraController;
lightObj: any;
constructor() {}
async run() {
await Engine3D.init({
canvasConfig: { devicePixelRatio: 1 }
});
this.scene = new Scene3D();
let cameraObj = new Object3D();
let mainCamera = cameraObj.addComponent(Camera3D);
mainCamera.perspective(37, webGPUContext.aspect, 1, 5000.0);
this.hoverCameraController = mainCamera.object3D.addComponent(HoverCameraController);
this.scene.addChild(cameraObj);
//set camera data
this.hoverCameraController.setCamera(0, -45, 1000);
this.initScene(this.scene);
// add an Atmospheric sky enviroment
this.scene.addComponent(AtmosphericComponent).sunY = 0.6;
// create a view with target scene and camera
let view = new View3D();
view.scene = this.scene;
view.camera = mainCamera;
// start render
Engine3D.startRenderView(view);
}
initScene(scene: Scene3D) {
{
let sp = new SphereGeometry(5, 30, 30);
let spotLight = new Object3D();
let mr = spotLight.addComponent(MeshRenderer);
mr.geometry = sp;
mr.material = new LitMaterial();
let light = spotLight.addComponent(SpotLight);
spotLight.y = 200;
spotLight.z = 50;
spotLight.rotationX = 120;
light.lightColor.r = 255 / 255;
light.lightColor.g = 157 / 255;
light.lightColor.b = 5 / 255;
light.intensity = 100;
light.range = 500;
light.outerAngle = 110;
light.innerAngle = 30;
scene.addChild(spotLight);
let GUIHelp = new dat.GUI();
GUIHelp.addFolder('Direct Light');
GUIHelp.add(spotLight, 'x', -180, 180, 1);
GUIHelp.add(spotLight, 'y', -180, 180, 1);
GUIHelp.add(spotLight, 'z', -180, 180, 1);
GUIHelp.add(spotLight, 'rotationX', -180, 180, 1);
GUIHelp.add(spotLight, 'rotationY', -180, 180, 1);
GUIHelp.add(spotLight, 'rotationZ', -180, 180, 1);
GUIHelp.addColor({ color: Object.values(light.lightColor).map((v) => v * 255) }, 'color').onChange((v) => {
light.lightColor.copyFromArray(v);
});
GUIHelp.add(light, 'intensity', 0, 200, 1);
GUIHelp.add(light, 'range', 100, 1000, 1);
GUIHelp.add(light, 'outerAngle', 0, 180, 1);
GUIHelp.add(light, 'innerAngle', 0, 100, 1);
}
let mat = new LitMaterial();
mat.baseMap = Engine3D.res.grayTexture;
let floor = new Object3D();
let mr = floor.addComponent(MeshRenderer);
mr.geometry = new BoxGeometry(2000, 1, 2000);
mr.material = mat;
this.scene.addChild(floor);
let box = new BoxGeometry(1, 1, 1);
let wall_w = new Object3D();
wall_w.localScale = new Vector3(500, 100, 10);
wall_w.localPosition = new Vector3(0, 50, 0);
let mrw = wall_w.addComponent(MeshRenderer);
mrw.geometry = box;
mrw.material = mat;
this.scene.addChild(wall_w);
let wall_a = new Object3D();
wall_a.localScale = new Vector3(10, 100, 500);
wall_a.localPosition = new Vector3(250, 50, 0);
let mra = wall_a.addComponent(MeshRenderer);
mra.geometry = box;
mra.material = mat;
this.scene.addChild(wall_a);
let wall_d = new Object3D();
wall_d.localScale = new Vector3(10, 100, 500);
wall_d.localPosition = new Vector3(-250, 50, 0);
let mrd = wall_d.addComponent(MeshRenderer);
mrd.geometry = box;
mrd.material = mat;
this.scene.addChild(wall_d);
}
}
new Sample_Light().run();
IES Light Information
The Illuminating Engineering Society(IES) defines a file format that can describe the light intensity distribution of real light in the real world. The IES file describes the light intensity of various types of lamps, attenuation curves, simulating the transmission and refraction of the lamp beads, and finally decoding into a specified 2D data map for 3D space lighting mapping.
IES Light Example
Load IES Texture
Besides the common light source type settings, the engine also supports setting complex light distribution by loading preset IES
textures:
// Load IES texture
let iesTexture = await Engine3D.res.loadTexture("https://cdn.orillusion.com/ies/ies_2.png");
// Create IES object
let iesPofiles = new IESProfiles();
iesPofiles.IESTexture = iesTexture;
let light = new Object3d()
let pointLight = light.addComponent(PointLight);
// Set light IES distribution
pointLight.iesPofile = iesPofiles;
import { BoxGeometry, Camera3D, Engine3D, View3D, LitMaterial, HoverCameraController, BitmapTexture2D, MeshRenderer, Object3D, Scene3D, SphereGeometry, PointLight, Vector3, webGPUContext, IESProfiles, AtmosphericComponent } from '@orillusion/core';
class Sample_LightIES {
scene: Scene3D;
hoverCameraController: HoverCameraController;
lightObj: any;
constructor() {}
async run() {
Engine3D.setting.shadow.pointShadowBias = 0.0001;
Engine3D.setting.shadow.type = `HARD`;
await Engine3D.init({
canvasConfig: { devicePixelRatio: 1 }
});
this.scene = new Scene3D();
let cameraObj = new Object3D();
let mainCamera = cameraObj.addComponent(Camera3D);
mainCamera.perspective(37, webGPUContext.aspect, 1, 5000.0);
this.hoverCameraController = mainCamera.object3D.addComponent(HoverCameraController);
this.scene.addChild(cameraObj);
//set camera data
this.hoverCameraController.setCamera(0, -45, 200);
await this.initScene(this.scene);
// add an Atmospheric sky enviroment
this.scene.addComponent(AtmosphericComponent).sunY = 0.6;
// create a view with target scene and camera
let view = new View3D();
view.scene = this.scene;
view.camera = mainCamera;
// start render
Engine3D.startRenderView(view);
}
async initScene(scene: Scene3D) {
// load ies texture
let iesTexture = await Engine3D.res.loadTexture('https://cdn.orillusion.com/ies/ies_2.png');
var iesPofiles = new IESProfiles();
iesPofiles.IESTexture = iesTexture;
{
let po = new Object3D();
let pl = po.addComponent(PointLight);
pl.intensity = 10;
pl.range = 100;
pl.castShadow = true;
pl.realTimeShadow = true;
pl.iesProfiles = iesPofiles;
po.x = 0;
po.y = 22;
po.z = 15;
this.scene.addChild(po);
}
let ball: Object3D;
{
let mat = new LitMaterial();
mat.roughness = 0.5;
mat.metallic = 0.2;
ball = new Object3D();
let mr = ball.addComponent(MeshRenderer);
mr.geometry = new SphereGeometry(6, 20, 20);
mr.material = mat;
this.scene.addChild(ball);
ball.transform.x = -17;
ball.transform.y = 10;
ball.transform.z = 10;
//wall
let back_wall = new Object3D();
let mr2 = back_wall.addComponent(MeshRenderer);
mr2.geometry = new BoxGeometry(500, 500, 10);
mr2.material = mat;
this.scene.addChild(back_wall);
}
}
}
new Sample_LightIES().run();
Get IES Texture
The community has a lot of high-quality IES
resources, some lighting equipment manufacturers will also share professional IES
files, they are generally free, such as:
The community also has a lot of professional IES
preview/conversion software, such as IESviewer, you can also use professional 3D modeling software to convert the IES
file to a normal png
texture file, and then load it into the engine.
Environment Light
Besides the direct light source, the engine can also render basic environment lighting by setting the Scene3D.evnMap
skybox texture, see Skybox for related settings.
Global Illumination
Normal lighting system only considers the effect of light source directly irradiating the surface of the object, and does not calculate the light reflected or refracted by the light source through the surface of the object, that is, indirect lighting. Global illumination system can model indirect lighting to achieve more realistic lighting effects. See Advanced GI for details.