only render 3D canvas when there are changes to render,

add performance debug logs
(3D canvas still broken though)
This commit is contained in:
HF 2024-01-20 16:25:52 +01:00
parent d7c60a9df2
commit 4bef680735
7 changed files with 225 additions and 198 deletions

View File

@ -24,9 +24,6 @@ import {
Vector2,
Vector3,
} from 'three';
import {
setViewCoordinates,
} from '../store/actions';
import {
THREE_CANVAS_HEIGHT,
} from '../core/constants';
@ -56,7 +53,6 @@ const STATE = {
const CHANGE_EVENT = { type: 'change' };
const START_EVENT = { type: 'start' };
const END_EVENT = { type: 'end' };
const EPS = 0.000001;
/*
* configuration
@ -73,10 +69,6 @@ const maxPolarAngle = Math.PI; // radians
// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].
const minAzimuthAngle = -Infinity; // radians
const maxAzimuthAngle = Infinity; // radians
// Set to true to enable damping (inertia)
// If damping is enabled, you must call controls.update() in your animation loop
const enableDamping = false;
const dampingFactor = 0.05;
// This option actually enables dollying in and out; left as "zoom" for backwards compatibility.
// Set to false to disable zooming
const enableZoom = true;
@ -103,7 +95,6 @@ class VoxelPainterControls extends EventDispatcher {
renderer;
domElement;
state;
//
// Set to false to disable this control
enabled = true;
// "target" sets the location of focus, where the object orbits around
@ -128,7 +119,6 @@ class VoxelPainterControls extends EventDispatcher {
//
scale = 1;
panOffset = new Vector3();
zoomChanged = false;
rotateStart = new Vector2();
rotateEnd = new Vector2();
rotateDelta = new Vector2();
@ -146,23 +136,22 @@ class VoxelPainterControls extends EventDispatcher {
updateTime = Date.now();
prevTime = Date.now();
offset = new Vector3();
lastPosition = new Vector3();
lastQuaternion = new Quaternion();
direction = new Vector3();
velocity = new Vector3();
vec = new Vector3();
constructor(renderer, camera, domElement, store) {
constructor(renderer, camera, target, domElement, store) {
super();
this.renderer = renderer;
this.camera = camera;
this.domElement = domElement;
this.store = store;
//
this.target = new Vector3();
this.target0 = this.target.clone();
this.position0 = this.camera.position.clone();
this.zoom0 = this.camera.zoom;
this.target = target;
//
this.target0 = target.clone();
this.position0 = camera.position.clone();
this.zoom0 = camera.zoom;
this.state = STATE.NONE;
this.onContextMenu = this.onContextMenu.bind(this);
@ -336,7 +325,7 @@ class VoxelPainterControls extends EventDispatcher {
} else if (event.deltaY > 0) {
this.dollyIn(this.getZoomScale());
}
this.update();
this.forceNextUpdate = true;
}
handleTouchStartRotate(event) {
@ -468,30 +457,24 @@ class VoxelPainterControls extends EventDispatcher {
case 87: // w
this.moveForward = true;
break;
case 37: // left
case 65: // a
this.moveLeft = true;
break;
case 40: // down
case 83: // s
this.moveBackward = true;
break;
case 39: // right
case 68: // d
this.moveRight = true;
break;
case 69: // E
this.moveUp = true;
break;
case 67: // C
this.moveDown = true;
break;
default:
break;
}
@ -513,30 +496,24 @@ class VoxelPainterControls extends EventDispatcher {
case 87: // w
this.moveForward = false;
break;
case 37: // left
case 65: // a
this.moveLeft = false;
break;
case 40: // down
case 83: // s
this.moveBackward = false;
break;
case 39: // right
case 68: // d
this.moveRight = false;
break;
case 69: // E
this.moveUp = false;
break;
case 67: // C
this.moveDown = false;
break;
default:
break;
}
@ -756,15 +733,12 @@ class VoxelPainterControls extends EventDispatcher {
case 0:
mouseAction = MOUSE_BUTTONS.LEFT;
break;
case 1:
mouseAction = MOUSE_BUTTONS.MIDDLE;
break;
case 2:
mouseAction = MOUSE_BUTTONS.RIGHT;
break;
default:
mouseAction = -1;
}
@ -774,7 +748,6 @@ class VoxelPainterControls extends EventDispatcher {
this.handleMouseDownDolly(event);
this.state = STATE.DOLLY;
break;
case MOUSE.ROTATE:
if (event.ctrlKey || event.metaKey) {
this.handleMouseDownPan(event);
@ -784,7 +757,6 @@ class VoxelPainterControls extends EventDispatcher {
this.state = STATE.ROTATE;
}
break;
case MOUSE.PAN:
if (event.ctrlKey || event.metaKey) {
this.handleMouseDownRotate(event);
@ -794,7 +766,6 @@ class VoxelPainterControls extends EventDispatcher {
this.state = STATE.PAN;
}
break;
default:
this.state = STATE.NONE;
}
@ -833,14 +804,26 @@ class VoxelPainterControls extends EventDispatcher {
this.state = STATE.NONE;
}
setView(view) {
if (view.length !== 3) {
return;
}
this.target.set(...view);
}
update() {
const {
moveRight,
moveLeft,
moveUp,
moveDown,
moveForward,
moveBackward,
} = this;
if (!(this.state !== STATE.NONE
|| this.forceNextUpdate
|| moveRight || moveLeft
|| moveUp || moveDown
|| moveForward || moveBackward
)) {
return false;
}
this.forceNextUpdate = false;
const {
camera,
target,
@ -863,15 +846,6 @@ class VoxelPainterControls extends EventDispatcher {
velocity.set(0, 0, 0);
}
const {
moveRight,
moveLeft,
moveUp,
moveDown,
moveForward,
moveBackward,
} = this;
direction.x = Number(moveRight) - Number(moveLeft);
direction.y = Number(moveUp) - Number(moveDown);
direction.z = Number(moveForward) - Number(moveBackward);
@ -898,9 +872,7 @@ class VoxelPainterControls extends EventDispatcher {
this.prevTime = time;
const { position } = camera;
offset.copy(position).sub(this.target);
offset.copy(camera.position).sub(this.target);
// rotate offset to "y-axis-is-up" space
offset.applyQuaternion(this.quat);
@ -908,13 +880,8 @@ class VoxelPainterControls extends EventDispatcher {
// angle from z-axis around y-axis
spherical.setFromVector3(offset);
if (enableDamping) {
spherical.theta += sphericalDelta.theta * dampingFactor;
spherical.phi += sphericalDelta.phi * dampingFactor;
} else {
spherical.theta += sphericalDelta.theta;
spherical.phi += sphericalDelta.phi;
}
spherical.theta += sphericalDelta.theta;
spherical.phi += sphericalDelta.phi;
// restrict theta to be between desired limits
spherical.theta = Math.max(
@ -941,11 +908,7 @@ class VoxelPainterControls extends EventDispatcher {
if (panOffset.length() > 1000) {
panOffset.set(0, 0, 0);
}
if (enableDamping) {
target.addScaledVector(panOffset, dampingFactor);
} else {
target.add(panOffset);
}
target.add(panOffset);
/*
if (scope.target.y < 10.0) {
scope.target.y = 10.0;
@ -969,58 +932,15 @@ class VoxelPainterControls extends EventDispatcher {
// rotate offset back to "camera-up-vector-is-up" space
offset.applyQuaternion(this.quatInverse);
position.copy(target).add(offset);
this.camera.position.copy(target).add(offset);
camera.lookAt(target);
if (enableDamping) {
sphericalDelta.theta *= (1 - dampingFactor);
sphericalDelta.phi *= (1 - dampingFactor);
panOffset.multiplyScalar(1 - dampingFactor);
if (panOffset.length() < 0.2 && panOffset.length() !== 0.0) {
panOffset.set(0, 0, 0);
this.store.dispatch(setViewCoordinates(target.toArray()));
this.renderer.storeViewInState();
} else if (panOffset.length() !== 0.0) {
if (time > this.updateTime + 500) {
this.updateTime = time;
this.store.dispatch(setViewCoordinates(target.toArray()));
this.renderer.storeViewInState();
}
}
/*
if (Math.abs(sphericalDelta.theta) < rotationFinishThreshold
&& sphericalDelta.theta != 0.0
&& Math.abs(sphericalDelta.phi) < rotationFinishThreshold
&& sphericalDelta.phi != 0.0) {
sphericalDelta.set(0, 0, 0);
console.log(`rotation finished`);
}
*/
} else {
sphericalDelta.set(0, 0, 0);
panOffset.set(0, 0, 0);
}
sphericalDelta.set(0, 0, 0);
panOffset.set(0, 0, 0);
this.scale = 1;
// update condition is:
// min(camera displacement, camera rotation in radians)^2 > EPS
// using small-angle approximation cos(x/2) = 1 - x^2 / 8
if (this.zoomChanged
|| this.lastPosition.distanceToSquared(camera.position) > EPS
|| 8 * (1 - this.lastQuaternion.dot(camera.quaternion)) > EPS
) {
this.dispatchEvent(CHANGE_EVENT);
this.lastPosition.copy(camera.position);
this.lastQuaternion.copy(camera.quaternion);
this.zoomChanged = false;
return true;
}
return false;
this.dispatchEvent(CHANGE_EVENT);
return true;
}
}

View File

@ -1,4 +1,19 @@
import * as THREE from 'three';
import {
MeshPhongMaterial,
TextureLoader,
Color,
Scene,
PerspectiveCamera,
WebGLRenderer,
AmbientLight,
DirectionalLight,
Mesh,
SphereGeometry,
MeshBasicMaterial,
BackSide,
Raycaster,
Vector2,
} from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import TrackballControls from 'three-trackballcontrols';
@ -50,27 +65,27 @@ document.addEventListener('DOMContentLoaded', () => {
const [canvasIdent, canvasId, canvasSize, x, y] = parseHashCoords();
const canvasTexture = new THREE.MeshPhongMaterial({
map: new THREE.TextureLoader().load(`./tiles/${canvasId}/texture.webp`),
bumpMap: new THREE.TextureLoader().load(`./assets3d/normal${canvasId}.jpg`),
const canvasTexture = new MeshPhongMaterial({
map: new TextureLoader().load(`./tiles/${canvasId}/texture.webp`),
bumpMap: new TextureLoader().load(`./assets3d/normal${canvasId}.jpg`),
bumpScale: 0.02,
specularMap: new THREE.TextureLoader()
specularMap: new TextureLoader()
.load(`./assets3d/specular${canvasId}.jpg`),
specular: new THREE.Color('grey'),
specular: new Color('grey'),
});
let width = window.innerWidth;
let height = window.innerHeight;
const scene = new THREE.Scene();
const scene = new Scene();
const camera = new THREE.PerspectiveCamera(45, width / height, 0.01, 1000);
const camera = new PerspectiveCamera(45, width / height, 0.01, 1000);
camera.position.z = 4.0;
const renderer = new THREE.WebGLRenderer();
const renderer = new WebGLRenderer();
renderer.setSize(width, height);
scene.add(new THREE.AmbientLight(0x333333));
scene.add(new AmbientLight(0x333333));
let controls = null;
let object = null;
@ -82,7 +97,7 @@ document.addEventListener('DOMContentLoaded', () => {
renderer.render(scene, camera);
}
const light = new THREE.DirectionalLight(0xffffff, 0.7);
const light = new DirectionalLight(0xffffff, 0.7);
light.position.set(10, 6, 10);
scene.add(light);
@ -129,11 +144,11 @@ document.addEventListener('DOMContentLoaded', () => {
webglEl.appendChild(renderer.domElement);
const stars = new THREE.Mesh(
new THREE.SphereGeometry(90, 64, 64),
new THREE.MeshBasicMaterial({
map: new THREE.TextureLoader().load('./assets3d/starfield.png'),
side: THREE.BackSide,
const stars = new Mesh(
new SphereGeometry(90, 64, 64),
new MeshBasicMaterial({
map: new TextureLoader().load('./assets3d/starfield.png'),
side: BackSide,
}),
);
scene.add(stars);
@ -153,8 +168,8 @@ document.addEventListener('DOMContentLoaded', () => {
/*
* update coords
*/
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
const raycaster = new Raycaster();
const mouse = new Vector2();
const coorbox = document.getElementById('coorbox');
function onDocumentMouseMove(event) {
if (!object) {

View File

@ -6,7 +6,12 @@
/* We have to look for performance here not for good looking code */
/* eslint-disable prefer-destructuring */
import * as THREE from 'three';
import {
MeshLambertMaterial,
Mesh,
BufferGeometry,
BufferAttribute,
} from 'three';
import Chunk from './Chunk';
import {
@ -69,7 +74,7 @@ const faceCorners = [
],
];
const material = new THREE.MeshLambertMaterial({
const material = new MeshLambertMaterial({
vertexColors: true,
});
@ -79,7 +84,7 @@ class Chunk3D extends Chunk {
ready = false;
palette; // Object
buffer; // Uint8Array
mesh = null; // THREE.Mesh
mesh = null; // Mesh
faceCnt; // number
lastPixel; // number
heightMap; // Array
@ -344,36 +349,36 @@ class Chunk3D extends Chunk {
const geometry = (this.mesh)
? this.mesh.geometry
: new THREE.BufferGeometry();
: new BufferGeometry();
geometry.setAttribute(
'position',
new THREE.BufferAttribute(
new BufferAttribute(
positions,
3,
),
);
geometry.setAttribute(
'normal',
new THREE.BufferAttribute(
new BufferAttribute(
normals,
3,
),
);
geometry.setAttribute(
'color',
new THREE.BufferAttribute(
new BufferAttribute(
colors,
3,
true,
),
);
geometry.setIndex(new THREE.BufferAttribute(indices, 1));
geometry.setIndex(new BufferAttribute(indices, 1));
geometry.computeBoundingSphere();
geometry.setDrawRange(0, this.faceCnt * 6);
if (!this.mesh) {
this.mesh = new THREE.Mesh(geometry, material);
this.mesh = new Mesh(geometry, material);
this.mesh.name = this.key;
}

View File

@ -7,20 +7,26 @@
/* eslint-disable max-len */
import * as THREE from 'three';
import {
Mesh,
Color,
PlaneBufferGeometry,
ShaderMaterial,
DoubleSide,
} from 'three';
export default class InfiniteGridHelper extends THREE.Mesh {
export default class InfiniteGridHelper extends Mesh {
constructor(size1, size2, color, distance, axes = 'xzy') {
color = color || new THREE.Color('white');
color = color || new Color('white');
size1 = size1 || 10;
size2 = size2 || 100;
distance = distance || 8000;
const planeAxes = axes.substring(0, 2);
const geometry = new THREE.PlaneBufferGeometry(2, 2, 1, 1);
const material = new THREE.ShaderMaterial({
const geometry = new PlaneBufferGeometry(2, 2, 1, 1);
const material = new ShaderMaterial({
side: THREE.DoubleSide,
side: DoubleSide,
uniforms: {
uSize1: { value: size1 },

View File

@ -19,8 +19,14 @@ class Renderer {
chunkLoader = null;
// needs to be known for lazy loading THREE
is3D = null;
// force renderer to rebuild whole view or
// to "subrender" known view next tick
forceNextRender = true;
forceNextSubrender = true;
// current position (subclass decies what it means),
// will be changed by controls
// TODO might be better as private and with a getter but no setter to avoid
// misconseption of it being writeable. Might have performance impact.
view = [0, 0, 0];
//
#storeViewTimeout = null;

View File

@ -3,7 +3,22 @@
*
*/
import * as THREE from 'three';
import {
Vector2,
Vector3,
PerspectiveCamera,
Scene,
AmbientLight,
DirectionalLight,
FogExp2,
BoxBufferGeometry,
MeshBasicMaterial,
Mesh,
Raycaster,
PlaneBufferGeometry,
MeshLambertMaterial,
WebGLRenderer,
} from 'three';
import Sky from './Sky';
import InfiniteGridHelper from './InfiniteGridHelper';
@ -28,6 +43,8 @@ const renderDistance = 150;
class Renderer3D extends Renderer {
scene;
camera;
// position camera is looking at
target = new Vector3();
rollOverMesh;
objects;
loadedChunks;
@ -43,8 +60,6 @@ class Renderer3D extends Renderer {
pressTime;
pressCdTime;
multitap;
//--
forceNextRender = false;
constructor(store) {
super(store);
@ -53,7 +68,7 @@ class Renderer3D extends Renderer {
this.objects = [];
// camera
const camera = new THREE.PerspectiveCamera(
const camera = new PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
@ -64,19 +79,19 @@ class Renderer3D extends Renderer {
this.camera = camera;
// scene
const scene = new THREE.Scene();
// scene.background = new THREE.Color(0xf0f0f0);
const scene = new Scene();
// scene.background = new Color(0xf0f0f0);
this.scene = scene;
// lights
const ambientLight = new THREE.AmbientLight(0x222222);
const ambientLight = new AmbientLight(0x222222);
scene.add(ambientLight);
// const directionalLight = new THREE.DirectionalLight(0xffffff);
// const directionalLight = new DirectionalLight(0xffffff);
// directionalLight.position.set(1, 1.2, 0.8).normalize();
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
const directionalLight = new DirectionalLight(0xffffff, 1);
directionalLight.position.set(80, 80, 75);
const contourLight = new THREE.DirectionalLight(0xffffff, 0.4);
const contourLight = new DirectionalLight(0xffffff, 0.4);
contourLight.position.set(-80, 80, -75);
scene.add(directionalLight);
scene.add(contourLight);
@ -85,7 +100,7 @@ class Renderer3D extends Renderer {
sky.scale.setScalar(450000);
scene.add(sky);
scene.fog = new THREE.FogExp2(0xffffff, 0.003);
scene.fog = new FogExp2(0xffffff, 0.003);
const effectController = {
turbidity: 10,
@ -104,31 +119,31 @@ class Renderer3D extends Renderer {
uniforms.sunPosition.value.set(400000, 400000, 400000);
// hover helper
const rollOverGeo = new THREE.BoxBufferGeometry(1, 1, 1);
const rollOverMaterial = new THREE.MeshBasicMaterial({
const rollOverGeo = new BoxBufferGeometry(1, 1, 1);
const rollOverMaterial = new MeshBasicMaterial({
color: 0xff0000,
opacity: 0.5,
transparent: true,
});
this.rollOverMesh = new THREE.Mesh(rollOverGeo, rollOverMaterial);
this.rollOverMesh = new Mesh(rollOverGeo, rollOverMaterial);
scene.add(this.rollOverMesh);
// grid
// const gridHelper = new THREE.GridHelper(100, 10, 0x555555, 0x555555);
// const gridHelper = new GridHelper(100, 10, 0x555555, 0x555555);
const gridHelper = new InfiniteGridHelper(1, 10);
scene.add(gridHelper);
//
this.raycaster = new THREE.Raycaster();
this.mouse = new THREE.Vector2();
this.raycaster = new Raycaster();
this.mouse = new Vector2();
this.multitap = 0;
// Plane Floor
const geometry = new THREE.PlaneBufferGeometry(1024, 1024);
const geometry = new PlaneBufferGeometry(1024, 1024);
geometry.rotateX(-Math.PI / 2);
const plane = new THREE.Mesh(
const plane = new Mesh(
geometry,
new THREE.MeshLambertMaterial({ color: 0xcae3ff }),
new MeshLambertMaterial({ color: 0xcae3ff }),
);
scene.add(plane);
this.plane = plane;
@ -136,20 +151,20 @@ class Renderer3D extends Renderer {
this.plane.position.y = -0.1;
// Out of bounds plane
const oobGeometry = new THREE.PlaneBufferGeometry(
const oobGeometry = new PlaneBufferGeometry(
THREE_TILE_SIZE,
THREE_TILE_SIZE,
);
oobGeometry.rotateX(-Math.PI / 2);
oobGeometry.translate(THREE_TILE_SIZE / 2, 0.2, THREE_TILE_SIZE / 2);
const oobMaterial = new THREE.MeshLambertMaterial({
const oobMaterial = new MeshLambertMaterial({
color: '#C4C4C4',
});
this.oobGeometry = oobGeometry;
this.oobMaterial = oobMaterial;
// renderer
const threeRenderer = new THREE.WebGLRenderer({
const threeRenderer = new WebGLRenderer({
preserveDrawingBuffer: true,
});
threeRenderer.setPixelRatio(window.devicePixelRatio);
@ -163,11 +178,11 @@ class Renderer3D extends Renderer {
const controls = new VoxelPainterControls(
this,
camera,
this.target,
domElement,
store,
);
controls.enableDamping = true;
controls.dampingFactor = 0.10;
// TODO doesn't work like this anymore
controls.maxPolarAngle = Math.PI / 2;
controls.minDistance = 10.00;
controls.maxDistance = 100.00;
@ -201,6 +216,14 @@ class Renderer3D extends Renderer {
this.updateCanvasData(state);
}
get view() {
return this.target.toArray();
}
set view(view) {
this.target.set(...view);
}
destructor() {
window.removeEventListener('resize', this.onWindowResize, false);
this.threeRenderer.dispose();
@ -211,7 +234,11 @@ class Renderer3D extends Renderer {
super.destructor();
}
updateView() {
updateView(view) {
if (view.length !== 3) {
return;
}
this.view = view;
this.forceNextRender = true;
}
@ -251,15 +278,10 @@ class Renderer3D extends Renderer {
);
}
}
this.controls.setView(view);
this.updateView(view);
this.forceNextRender = true;
}
// eslint-disable-next-line class-methods-use-this
updateScale() {
return null;
}
renderPixel(
i,
j,
@ -319,7 +341,7 @@ class Renderer3D extends Renderer {
let chunk = null;
if (xc < 0 || zc < 0 || xc >= chunkMaxXY || zc >= chunkMaxXY) {
// if out of bounds
chunk = new THREE.Mesh(this.oobGeometry, this.oobMaterial);
chunk = new Mesh(this.oobGeometry, this.oobMaterial);
} else {
chunk = chunkLoader.getChunk(xc, zc, true);
}
@ -353,12 +375,44 @@ class Renderer3D extends Renderer {
if (!this.threeRenderer) {
return;
}
super.render();
const controlUpdate = super.render();
if (this.forceNextRender) {
this.reloadChunks();
this.forceNextRender = false;
}
this.threeRenderer.render(this.scene, this.camera);
if (this.forceNextRender || this.forceNextSubRender || controlUpdate) {
if (this.forceNextRender) {
if (this.lol !== 'force') {
console.log(this.lol, this.lola);
this.lol = 'force';
this.lola = 0;
}
this.lola += 1;
} else if (this.forceNextSubRender) {
if (this.lol !== 'sub') {
console.log(this.lol, this.lola);
this.lol = 'sub';
this.lola = 0;
}
this.lola += 1;
} else if (controlUpdate) {
if (this.lol !== 'update') {
console.log(this.lol, this.lola);
this.lol = 'update';
this.lola = 0;
}
this.lola += 1;
}
this.threeRenderer.render(this.scene, this.camera);
this.forceNextRender = false;
this.forceNextSubRender = false;
} else {
if (this.lol !== 'skip') {
console.log(this.lol, this.lola);
this.lol = 'skip';
this.lola = 0;
}
this.lola += 1;
}
}
onWindowResize() {
@ -385,15 +439,17 @@ class Renderer3D extends Renderer {
rollOverMesh,
store,
} = this;
const state = store.getState();
const {
fetchingPixel,
} = store.getState().fetching;
} = state.fetching;
mouse.set(
(clientX / innerWidth) * 2 - 1,
-(clientY / innerHeight) * 2 + 1,
);
console.log('move mouse');
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(objects);
if (intersects.length > 0) {
@ -403,13 +459,25 @@ class Renderer3D extends Renderer {
.floor()
.addScalar(0.5);
if (fetchingPixel
|| target.clone().sub(camera.position).length() > 120) {
rollOverMesh.position.y = -10;
|| target.clone().sub(camera.position).length() > 120
) {
if (rollOverMesh.position.y !== -10) {
// unsetHover ?
rollOverMesh.position.y = -10;
this.forceNextSubRender = true;
}
} else {
const { hover: prevHover } = state.canvas;
rollOverMesh.position.copy(target);
const hover = target
.toArray().map((u) => Math.floor(u));
this.store.dispatch(setHover(hover));
const hover = target.toArray().map((u) => Math.floor(u));
if (!prevHover
|| prevHover[0] !== hover[0]
|| prevHover[1] !== hover[1]
|| prevHover[2] !== hover[2]
) {
this.store.dispatch(setHover(hover));
this.forceNextSubRender = true;
}
}
}
}

View File

@ -17,22 +17,29 @@
/* eslint-disable max-len */
import * as THREE from 'three';
import {
Vector3,
Mesh,
ShaderMaterial,
BackSide,
BoxGeometry,
UniformsUtils,
} from 'three';
export default class Sky extends THREE.Mesh {
export default class Sky extends Mesh {
static isSky = true;
constructor() {
const shader = Sky.SkyShader;
const material = new THREE.ShaderMaterial({
const material = new ShaderMaterial({
name: 'SkyShader',
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader,
uniforms: THREE.UniformsUtils.clone(shader.uniforms),
side: THREE.BackSide,
uniforms: UniformsUtils.clone(shader.uniforms),
side: BackSide,
depthWrite: false,
});
super(new THREE.BoxGeometry(1, 1, 1), material);
super(new BoxGeometry(1, 1, 1), material);
}
}
@ -51,10 +58,10 @@ Sky.SkyShader = {
value: 0.8,
},
sunPosition: {
value: new THREE.Vector3(),
value: new Vector3(),
},
up: {
value: new THREE.Vector3(0, 1, 0),
value: new Vector3(0, 1, 0),
},
},
vertexShader: