Skip to content

Commit

Permalink
feat(RelativeSky): Relative sky to sunlight (Orillusion#237)
Browse files Browse the repository at this point in the history
Establish relative between Sky Box and other 3D object(For example sunlight) to ensure their data consistency.
  • Loading branch information
hellmor authored Jun 28, 2023
1 parent fb7aa97 commit 3664c8b
Showing 6 changed files with 146 additions and 91 deletions.
14 changes: 7 additions & 7 deletions samples/lights/Sample_DirectLight.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { GUIHelp } from "@orillusion/debug/GUIHelp";
import { Scene3D, HoverCameraController, Engine3D, AtmosphericComponent, Object3D, Camera3D, Vector3, View3D, DirectLight, KelvinUtil, LitMaterial, MeshRenderer, BoxGeometry, CameraUtil } from "@orillusion/core";
import { Scene3D, HoverCameraController, Engine3D, AtmosphericComponent, Object3D, Camera3D, Vector3, View3D, DirectLight, KelvinUtil, LitMaterial, MeshRenderer, BoxGeometry, CameraUtil, Transform } from "@orillusion/core";

//sample of direction light
class Sample_DirectLight {
@@ -12,27 +12,27 @@ class Sample_DirectLight {
GUIHelp.init();

this.scene = new Scene3D();
this.scene.addComponent(AtmosphericComponent);
let sky = this.scene.addComponent(AtmosphericComponent);

// init camera3D
let mainCamera = CameraUtil.createCamera3D(null, this.scene);
mainCamera.perspective(60, Engine3D.aspect, 1, 2000.0);
//set camera data
mainCamera.object3D.addComponent(HoverCameraController).setCamera(0, -25, 1000);

await this.initScene();

sky.relativeTransform = this.initLight();
this.initScene();

let view = new View3D();
view.scene = this.scene;
view.camera = mainCamera;

this.initLight();
Engine3D.startRenderView(view);

}

// create direction light
private initLight() {
private initLight(): Transform {
this.lightObj3D = new Object3D();
this.lightObj3D.x = 0;
this.lightObj3D.y = 30;
@@ -41,13 +41,13 @@ class Sample_DirectLight {
this.lightObj3D.rotationY = 62;
this.lightObj3D.rotationZ = 360;
let directLight = this.lightObj3D.addComponent(DirectLight);

//Convert color temperature to color object
directLight.lightColor = KelvinUtil.color_temperature_to_rgb(5355);
directLight.castShadow = false;
directLight.intensity = 20;
this.showLightGUI(directLight);
this.scene.addChild(this.lightObj3D);
return directLight.transform;
}

// show gui
131 changes: 65 additions & 66 deletions samples/lights/Sample_DirectLightShadow.ts
Original file line number Diff line number Diff line change
@@ -4,73 +4,72 @@ import { GUIUtil } from "@samples/utils/GUIUtil";

//sample of direction light
class Sample_DirectLightShadow {
scene: Scene3D;

async run() {
Engine3D.setting.shadow.autoUpdate = true;
Engine3D.setting.shadow.shadowBias = 0.0001;
Engine3D.setting.shadow.shadowBound = 100;

await Engine3D.init({});

GUIHelp.init();

this.scene = new Scene3D();
this.scene.addComponent(AtmosphericComponent);

// init camera3D
let mainCamera = CameraUtil.createCamera3D(null, this.scene);
mainCamera.perspective(60, Engine3D.aspect, 1, 5000.0);
//set camera data
mainCamera.object3D.z = -15;
mainCamera.object3D.addComponent(HoverCameraController).setCamera(-15, -35, 150);

await this.initScene();

let view = new View3D();
view.scene = this.scene;
view.camera = mainCamera;

this.initLight();
Engine3D.startRenderView(view);

}

// create direction light
private initLight() {
// add a direction light
let lightObj3D = new Object3D();
let sunLight = lightObj3D.addComponent(DirectLight);
sunLight.intensity = 15;
sunLight.lightColor = KelvinUtil.color_temperature_to_rgb(6553);
sunLight.castShadow = true;
lightObj3D.rotationX = 53.2;
lightObj3D.rotationY = 220;
lightObj3D.rotationZ = 5.58;

GUIUtil.renderDirLight(sunLight);
this.scene.addChild(lightObj3D);

let obj = new Object3D();
let mr = obj.addComponent(MeshRenderer);
mr.geometry = new BoxGeometry(20, 100, 20);
mr.material = new LitMaterial();
this.scene.addChild(obj);
scene: Scene3D;
async run() {
Engine3D.setting.shadow.autoUpdate = true;
Engine3D.setting.shadow.shadowBias = 0.0001;
Engine3D.setting.shadow.shadowBound = 100;

await Engine3D.init({});

GUIHelp.init();

this.scene = new Scene3D();
let sky = this.scene.addComponent(AtmosphericComponent);

// init camera3D
let mainCamera = CameraUtil.createCamera3D(null, this.scene);
mainCamera.perspective(60, Engine3D.aspect, 1, 5000.0);
//set camera data
mainCamera.object3D.z = -15;
mainCamera.object3D
.addComponent(HoverCameraController)
.setCamera(-15, -35, 150);

sky.relativeTransform = this.initLight();
this.initScene();

let view = new View3D();
view.scene = this.scene;
view.camera = mainCamera;

Engine3D.startRenderView(view);
}

// create direction light
private initLight() {
// add a direction light
let lightObj3D = new Object3D();
let sunLight = lightObj3D.addComponent(DirectLight);
sunLight.intensity = 15;
sunLight.lightColor = KelvinUtil.color_temperature_to_rgb(6553);
sunLight.castShadow = true;

GUIUtil.renderDirLight(sunLight);
this.scene.addChild(lightObj3D);
return sunLight.transform
}

initScene() {
{
let obj = new Object3D();
let mr = obj.addComponent(MeshRenderer);
mr.geometry = new BoxGeometry(20, 100, 20);
mr.material = new LitMaterial();
this.scene.addChild(obj);
}



initScene() {
let mat = new LitMaterial();
mat.baseMap = Engine3D.res.grayTexture;
// mat.roughness = 0.4;
// mat.metallic = 0.6;
let floor = new Object3D();
let render = floor.addComponent(MeshRenderer);
render.geometry = new BoxGeometry(200, 1, 200);
render.material = mat;
this.scene.addChild(floor);
{
let mat = new LitMaterial();
mat.baseMap = Engine3D.res.grayTexture;
// mat.roughness = 0.4;
// mat.metallic = 0.6;
let floor = new Object3D();
let mr = floor.addComponent(MeshRenderer);
mr.geometry = new BoxGeometry(200, 1, 200);
mr.material = mat;
this.scene.addChild(floor);
}
}
}

new Sample_DirectLightShadow().run();
new Sample_DirectLightShadow().run();
10 changes: 8 additions & 2 deletions samples/utils/ExampleScene.ts
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@ type ExampleSceneParam = {
exposure: number,
atmosphericSky?: any,
},

light: {
position: {
x: number,
@@ -37,7 +38,7 @@ type ExampleSceneParam = {

kelvin: number,
intensity: number,
castShadow: boolean,
castShadow: boolean
},
}

@@ -74,7 +75,7 @@ export function createSceneParam(): ExampleSceneParam {

kelvin: 5355,
intensity: 30,
castShadow: true,
castShadow: true
}
}
return param;
@@ -132,6 +133,11 @@ export function createExampleScene(param?: ExampleSceneParam) {
let light = createDirectLight(param);
scene.addChild(light.object3D);

// relative light to sky
if (atmosphericSky) {
atmosphericSky.relativeTransform = light.transform;
}

//pkg
let content = {} as ExampleSceneContent;
content.camera = camera;
4 changes: 3 additions & 1 deletion samples/utils/GUIUtil.ts
Original file line number Diff line number Diff line change
@@ -9,13 +9,15 @@ export class GUIUtil {
name ||= 'AtmosphericSky';
GUIHelp.addFolder(name);
GUIHelp.add(component, 'sunX', 0, 1, 0.01);
GUIHelp.add(component, 'sunY', 0, 1, 0.01);
GUIHelp.add(component, 'sunY', 0.4, 1.6, 0.01);
GUIHelp.add(component, 'eyePos', 0, 5000, 1);
GUIHelp.add(component, 'sunRadius', 0, 1000, 0.01);
GUIHelp.add(component, 'sunRadiance', 0, 100, 0.01);
GUIHelp.add(component, 'sunBrightness', 0, 10, 0.01);
GUIHelp.add(component, 'exposure', 0, 2, 0.01);
GUIHelp.add(component, 'displaySun', 0, 1, 0.01);
GUIHelp.add(component, 'enable');

open && GUIHelp.open();
GUIHelp.endFolder();
}
74 changes: 61 additions & 13 deletions src/components/AtmosphericComponent.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,41 @@
import { Color, View3D } from "..";
import { AtmosphericScatteringSky, AtmosphericScatteringSkySetting } from "../textures/AtmosphericScatteringSky";
import { Transform } from "./Transform";
import { SkyRenderer } from "./renderer/SkyRenderer";

class HistoryData {
public rotateX: number;
public rotateY: number;

public sunX: number;
public sunY: number;

constructor() {
this.reset();
}

public reset(): this {
this.rotateX = this.rotateY = this.sunX = this.sunY = Number.MAX_VALUE;
return this;
}

public isRotateChange(rx: number, ry: number): boolean {
return Math.abs(this.rotateX - rx) >= 0.001 || Math.abs(this.rotateY - ry) >= 0.001;
}

public isSkyChange(x: number, y: number): boolean {
return Math.abs(this.sunX - x) >= 0.001 || Math.abs(this.sunY - y) >= 0.001;
}

public save(x: number, y: number, rx: number, ry: number): this {
this.sunX = x;
this.sunY = y;
this.rotateX = rx;
this.rotateY = ry;

return this;
}
}

/**
*
* Atmospheric Sky Box Component
@@ -11,7 +45,8 @@ export class AtmosphericComponent extends SkyRenderer {

private _atmosphericScatteringSky: AtmosphericScatteringSky;
private _onChange: boolean = true;

private _relatedTransform: Transform;
private _historyData: HistoryData;
public get sunX() {
return this._atmosphericScatteringSky.setting.sunX;
}
@@ -89,17 +124,10 @@ export class AtmosphericComponent extends SkyRenderer {
}
}

// public get skyColor(): Color {
// return this._atmosphericScatteringSky.setting.skyColor;
// }

// public set skyColor(value: Color) {
// this._atmosphericScatteringSky.setting.skyColor = value;
// this._onChange = true;
// }

public init(): void {
super.init();
this._historyData = new HistoryData();
this._atmosphericScatteringSky = new AtmosphericScatteringSky(new AtmosphericScatteringSkySetting());
}

@@ -110,12 +138,32 @@ export class AtmosphericComponent extends SkyRenderer {
super.start();
}

public onUpdate(view?: View3D) {
if (this._onChange) {
// console.log("change sky");
public get relativeTransform() {
return this._relatedTransform;
}

public set relativeTransform(value: Transform) {
this._relatedTransform = value;
this._historyData.reset();
}

public onUpdate(view?: any) {
if (this._relatedTransform) {
this._relatedTransform.rotationZ = 0;
if (this._historyData.isSkyChange(this.sunX, this.sunY)) {
this._relatedTransform.rotationY = this.sunX * 360 - 90;
this._relatedTransform.rotationX = (this.sunY - 0.5) * 180;
} else if (this._historyData.isRotateChange(this._relatedTransform.rotationX, this._relatedTransform.rotationY)) {
this.sunX = (this._relatedTransform.rotationY + 90) / 360//
this.sunY = this._relatedTransform.rotationX / 180 + 0.5;
}
this._historyData.save(this.sunX, this.sunY, this._relatedTransform.rotationX, this._relatedTransform.rotationY);
}

if (this._onChange) {
this._onChange = false;
this._atmosphericScatteringSky.apply();
}

}
}
4 changes: 2 additions & 2 deletions src/math/Matrix4.ts
Original file line number Diff line number Diff line change
@@ -1477,7 +1477,7 @@ export class Matrix4 {
mr[10] /= scale.z;

let rot = vec[1];

let tr: number;
switch (orientationStyle) {
case Orientation3D.AXIS_ANGLE:
rot.w = Math.acos((mr[0] + mr[5] + mr[10] - 1) / 2);
@@ -1489,7 +1489,7 @@ export class Matrix4 {

break;
case Orientation3D.QUATERNION:
let tr = mr[0] + mr[5] + mr[10];
tr = mr[0] + mr[5] + mr[10];

if (tr > 0) {
rot.w = Math.sqrt(1 + tr) / 2;

0 comments on commit 3664c8b

Please sign in to comment.