Hi. How to make an image as light as in the editor?
Phisical lights was disabled in custom visualizer.
Source scene: https://drive.google.com/file/d/1fjOb2-ILJNSheJttuAcCIAS5S5tw50iC/view?usp=sharing
Source code:
import * as THREE from “three”;
import { Injectable, ElementRef, OnDestroy, NgZone } from "@angular/core";
import MathUtil from "three-math";
import { LoadingManager, ObjectLoader, TextureLoader } from "three";
import {
LoadingResource,
LoadingResources,
LOAD_TYPE,
} from "../models/loadingResource";
import { GameObject } from "../models/engine/gameObject";
@Injectable({ providedIn: "root" })
export class EngineService implements OnDestroy {
private canvas: HTMLCanvasElement;
private renderer: THREE.WebGLRenderer;
private camera: THREE.PerspectiveCamera;
private scene: THREE.Scene;
private light: THREE.AmbientLight;
private cube: THREE.Mesh;
private frameId: number = null;
private isUserInteracting = false;
private onPointerDownPointerX: number = 0;
private onPointerDownPointerY: number = 0;
private lon: number = 0;
private onPointerDownLon: number = 0;
private lat: number = 0;
private onPointerDownLat: number = 0;
private phi: number = 0;
private theta: number = 0;
private material: THREE.MeshBasicMaterial;
protected manager: LoadingManager;
protected objectLoader: ObjectLoader;
protected textureLoader: TextureLoader;
private sceneJSON: string = null;
protected gameObject: GameObject;
private publicRegx = /public/;
public constructor(private ngZone: NgZone) {
this.manager = new THREE.LoadingManager();
this.objectLoader = new THREE.ObjectLoader();
this.textureLoader = new THREE.TextureLoader(this.manager);
this.scene = new THREE.Scene();
this.scene.background = new THREE.Color(0xd3d3d3);
this.camera = new THREE.PerspectiveCamera();
}
public ngOnDestroy(): void {
if (this.frameId != null) {
cancelAnimationFrame(this.frameId);
}
}
public createRenderer(canvas: ElementRef<HTMLCanvasElement>) {
this.canvas = canvas.nativeElement;
this.renderer = new THREE.WebGLRenderer({
canvas: this.canvas,
antialias: true,
alpha: true,
});
this.renderer.physicallyCorrectLights = false;
this.renderer.toneMapping = THREE.NoToneMapping;
this.renderer.gammaFactor = 2.2;
this.renderer.setClearColor(0xffffff, 0);
this.updateRendererSize();
}
private updateRendererSize() {
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.renderer.setPixelRatio(window.devicePixelRatio);
}
public createTestScene(canvas: ElementRef<HTMLCanvasElement>): void {
// The first step is to get the reference of the canvas element from our HTML document
this.canvas = canvas.nativeElement;
// create the scene
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
this.camera.lookAt(new THREE.Vector3(-1, 0, 0));
this.scene.add(this.camera);
// soft white light
this.light = new THREE.AmbientLight(0x404040);
this.light.position.z = 10;
this.scene.add(this.light);
/*const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
this.cube = new THREE.Mesh( geometry, material );
this.scene.add(this.cube);*/
let geometry = new THREE.SphereGeometry(500, 60, 40);
geometry.scale(-1, 1, 1);
this.material = new THREE.MeshBasicMaterial({
map: new THREE.TextureLoader().load(
"https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/2294472375_24a3b8ef46_o.jpg"
),
});
let mesh = new THREE.Mesh(geometry, this.material);
this.scene.add(mesh);
}
public animate(): void {
// We have to run this outside angular zones,
// because it could trigger heavy changeDetection cycles.
this.ngZone.runOutsideAngular(() => {
if (document.readyState !== "loading") {
this.render();
} else {
window.addEventListener("DOMContentLoaded", () => {
this.render();
});
}
window.addEventListener("resize", () => {
this.resize();
});
});
}
public render(): void {
if (!this.scene || !this.camera) {
return;
}
this.frameId = requestAnimationFrame(() => {
this.render();
});
this.update();
this.renderer.render(this.scene, this.camera);
}
update() {
if (this.isUserInteracting === false) {
//auto rotation
//this.lon += 0.1;
}
this.lat = Math.max(-85, Math.min(85, this.lat));
this.phi = MathUtil.Math.degToRad(90 - this.lat);
this.theta = MathUtil.Math.degToRad(this.lon);
let vector = new THREE.Vector3();
vector.x = 500 * Math.sin(this.phi) * Math.cos(this.theta);
vector.y = 500 * Math.cos(this.phi);
vector.z = 500 * Math.sin(this.phi) * Math.sin(this.theta);
this.camera.lookAt(vector);
}
public resize(): void {
const width = window.innerWidth;
const height = window.innerHeight;
this.camera.aspect = width / height;
this.camera.updateProjectionMatrix();
this.renderer.setSize(width, height);
}
public addEventListeners() {
document.addEventListener(
"mousedown",
this.onDocumentMouseDown.bind(this),
false
);
document.addEventListener(
"mousemove",
this.onDocumentMouseMove.bind(this),
false
);
document.addEventListener(
"mouseup",
this.onDocumentMouseUp.bind(this),
false
);
document.addEventListener(
"wheel",
this.onDocumentMouseWheel.bind(this),
false
);
document.addEventListener(
"dragover",
function (event) {
event.preventDefault();
event.dataTransfer.dropEffect = "copy";
},
false
);
document.addEventListener(
"dragenter",
function (event) {
document.body.style.opacity = "0.5";
},
false
);
document.addEventListener(
"dragleave",
function (event) {
document.body.style.opacity = "1";
},
false
);
document.addEventListener(
"drop",
function (event) {
event.preventDefault();
var reader = new FileReader();
reader.addEventListener(
"load",
function (event) {
this.material.map.image.src = event.target.result;
this.material.map.needsUpdate = true;
}.bind(this),
false
);
reader.readAsDataURL(event.dataTransfer.files[0]);
document.body.style.opacity = "1";
},
false
);
}
onDocumentMouseDown(event) {
event.preventDefault();
this.isUserInteracting = true;
this.onPointerDownPointerX = event.clientX;
this.onPointerDownPointerY = event.clientY;
this.onPointerDownLon = this.lon;
this.onPointerDownLat = this.lat;
}
onDocumentMouseMove(event) {
if (this.isUserInteracting === true) {
this.lon =
(this.onPointerDownPointerX - event.clientX) * 0.1 +
this.onPointerDownLon;
this.lat =
(event.clientY - this.onPointerDownPointerY) * 0.1 +
this.onPointerDownLat;
}
}
onDocumentMouseUp(event) {
this.isUserInteracting = false;
}
onDocumentMouseWheel(event) {
this.camera.fov += event.deltaY * 0.05;
this.camera.updateProjectionMatrix();
}
public loadModel(url: string) {
this.gameObject = new GameObject("", url, this.textureLoader);
this.gameObject.url = url;
const loader = new THREE.FileLoader(this.manager);
const json = THREE.Cache.get(this.gameObject.url);
if (json) {
this.onProgress(LOAD_TYPE.LOADED, this.gameObject.url);
}
loader.load(
this.gameObject.url,
(res: any) => {
THREE.Cache.add(this.gameObject.url, res);
this.sceneJSON = res;
this.onProgress(LOAD_TYPE.LOADED, this.gameObject.url);
},
(xhr: any) =>
this.onProgress(LOAD_TYPE.LOADING, this.gameObject.url, xhr),
(err: any) => {
/*this.onError(err)*/
}
);
// preload textures feature
}
private onProgress(loadType: LOAD_TYPE, url: string, xhr?: ProgressEvent) {
//this.writeLoadedBytesToLoadedResource(loadType, url, xhr);
/*const totalLoadedSize = this.loadedSizeOfAllResources(
this.settings.loadingResources
);*/
if (loadType === LOAD_TYPE.LOADING) {
/*const progress = totalLoadedSize / this.downloadableSize;
if (progress < 1) {
this.settings.onProgress(null, progress);
}*/
} else if (loadType === LOAD_TYPE.LOADED) {
//this.countOfLoadedResources--;
//if (
// totalLoadedSize === this.downloadableSize &&
// this.countOfLoadedResources === 0
//) {
this.buildGameObject();
//this.settings.onProgress(this.gameObject, 1);
//}
} else {
throw new Error("Unknown load type");
}
}
private buildGameObject() {
try {
let json = JSON.parse(this.sceneJSON);
let project = json.project;
if (project.shadows) {
this.renderer.shadowMap.enabled = true;
}
if (json.camera) {
let camera = this.objectLoader.parse(json.camera);
camera.name = `${camera.name}-main`;
this.setCamera(camera);
}
let url = new URL(this.gameObject.url);
if (json.scene.images) {
json.scene.images = json.scene.images.map((image: any) => {
if (this.publicRegx.test(image.url)) {
image.url = `${url.origin}/${image.url}`;
}
return image;
});
}
let sceneManager = new THREE.LoadingManager();
sceneManager.onLoad = () => {
//const canvas = this.container.children[0];
//this.gameObject.Canvas = canvas;
this.gameObject.Canvas = this.canvas;
};
let objectLoaderScene = new THREE.ObjectLoader(sceneManager);
let scene = objectLoaderScene.parse(json.scene);
let children = [...scene.children];
children.forEach((child: any) => {
if (child.type === "Group") {
this.gameObject.Model = child;
}
this.scene.add(child);
});
if (this.gameObject.Model.children.length) {
let groupChildren = [...this.gameObject.Model.children];
groupChildren.forEach((child: any) => {
if (child.type === "PerspectiveCamera" && child.visible) {
child.name = `${child.name}-group`;
this.setCamera(child);
} else {
this.resetUndefinedMaps(child.material);
}
});
}
/*this.createControls();
this.updateRendererSize();
this.setSize();*/
/*const { Editor } = this.settings;
if (
Editor instanceof EditorSettings &&
Object.keys(Editor).length !== 0
) {
const surface = this.gameObject.getSurface(Editor.surfaceName || "");
if (surface) {
const gui = new dat.GUI();
const guiObject = this.gameObject.getMaterialManagerBySurface(
surface,
gui,
this.settings.Editor
);
this.loadGui(guiObject);
}
}*/
} catch (error) {
console.error(error);
//this.sendError(error);
}
}
private setCamera(camera: any) {
/*if (this.settings.isStaticCamera && this.settings.zoomMaxDistance) {
camera.position.z = this.settings.zoomMaxDistance;
} else {
this.zoomDefaultMaxDistance = camera.position.z;
}*/
this.camera = camera;
const cam = camera as any;
cam.updateProjectionMatrix();
}
private resetUndefinedMaps(material: any) {
if (!material) {
return;
}
const maps = [
"map",
"specularMap",
"bumpMap",
"normalMap",
"envMap",
"lightMap",
];
maps.forEach((mapName: string) => {
if (material[mapName] && material[mapName].image === undefined) {
material[mapName] = null;
}
});
}
private texturesLoading = (textures: LoadingResource[]) => {
const fileLoader = new THREE.FileLoader();
fileLoader.setResponseType("blob");
textures.forEach((resource) => {
fileLoader.load(
resource.url,
(object) => {
const image = new Image();
const objURL = URL.createObjectURL(object);
image.onload = () => {
let texture = new THREE.TextureLoader().load(objURL, () => {
THREE.Cache.add(resource.url, texture);
URL.revokeObjectURL(objURL);
this.onProgress(LOAD_TYPE.LOADED, resource.url);
});
};
image.src = objURL;
},
(xhr) => {
this.onProgress(LOAD_TYPE.LOADING, resource.url, xhr);
}
);
});
};
}