make scene more beautiful
This commit is contained in:
parent
85f0054fd9
commit
bbbd5869e6
119
src/game/game.ts
119
src/game/game.ts
@ -84,7 +84,25 @@ class Game implements ThreeScene {
|
|||||||
|
|
||||||
init = (lev: LevelInitializer) => {
|
init = (lev: LevelInitializer) => {
|
||||||
this.scene = new THREE.Scene();
|
this.scene = new THREE.Scene();
|
||||||
this.scene.background = new THREE.Color(0x0a0a12); // Dark blue-gray instead of pure black
|
|
||||||
|
// Gradient background: orange → pink → purple → dark
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
canvas.width = 2;
|
||||||
|
canvas.height = 512;
|
||||||
|
const ctx = canvas.getContext('2d')!;
|
||||||
|
const gradient = ctx.createLinearGradient(0, 0, 0, 512);
|
||||||
|
gradient.addColorStop(0, '#0a0515'); // dark at top
|
||||||
|
gradient.addColorStop(0.4, '#2a1040'); // purple
|
||||||
|
gradient.addColorStop(0.7, '#ff4080'); // pink
|
||||||
|
gradient.addColorStop(1, '#ff6b35'); // orange at bottom
|
||||||
|
ctx.fillStyle = gradient;
|
||||||
|
ctx.fillRect(0, 0, 2, 512);
|
||||||
|
const bgTexture = new THREE.CanvasTexture(canvas);
|
||||||
|
bgTexture.magFilter = THREE.LinearFilter;
|
||||||
|
this.scene.background = bgTexture;
|
||||||
|
|
||||||
|
// Fog to blend distant terrain into sky
|
||||||
|
this.scene.fog = new THREE.FogExp2(0x2a1040, 0.008);
|
||||||
|
|
||||||
// Groundplane
|
// Groundplane
|
||||||
initGround(this.scene);
|
initGround(this.scene);
|
||||||
@ -97,22 +115,22 @@ class Game implements ThreeScene {
|
|||||||
this.player = new Player(this.scene, { ...level, voxels: mutableVoxels })
|
this.player = new Player(this.scene, { ...level, voxels: mutableVoxels })
|
||||||
initBoxes(this.scene, mutableVoxels, this.player);
|
initBoxes(this.scene, mutableVoxels, this.player);
|
||||||
|
|
||||||
// Lights
|
// Lights - Synthwave sunset style
|
||||||
// Subtle ambient light for base visibility
|
// Subtle ambient light for base visibility
|
||||||
this.scene.add(new THREE.AmbientLight(0x2a2a3a, 2.4));
|
this.scene.add(new THREE.AmbientLight(0x3a1a4a, 2.4));
|
||||||
|
|
||||||
// Improved hemisphere light for mood
|
// Hemisphere light: orange sky, purple ground
|
||||||
this.scene.add(new THREE.HemisphereLight(0x4a4a5a, 0x1a1a2a, 10));
|
this.scene.add(new THREE.HemisphereLight(0xff6b35, 0x2a1040, 2));
|
||||||
|
|
||||||
// Dramatic point lights with better positioning
|
// Dramatic point lights with warm pink tones
|
||||||
let pl = new THREE.PointLight(0x8090ff, 10, 0,0.3);
|
let pl = new THREE.PointLight(0xffffff, 10, 0,0.3);
|
||||||
pl.position.set(40, -40, 25);
|
pl.position.set(40, -40, 25);
|
||||||
pl.castShadow = true;
|
pl.castShadow = true;
|
||||||
pl.shadow.mapSize.width = 2048;
|
pl.shadow.mapSize.width = 2048;
|
||||||
pl.shadow.mapSize.height = 2048;
|
pl.shadow.mapSize.height = 2048;
|
||||||
pl.shadow.bias = -0.001;
|
pl.shadow.bias = -0.001;
|
||||||
this.scene.add(pl);
|
this.scene.add(pl);
|
||||||
let pl1 = new THREE.PointLight(0xff9080, 10, 0,0.3);
|
let pl1 = new THREE.PointLight(0xffffff, 10, 0,0.3);
|
||||||
pl1.position.set(-40, 40, 25);
|
pl1.position.set(-40, 40, 25);
|
||||||
pl1.castShadow = true;
|
pl1.castShadow = true;
|
||||||
pl1.shadow.mapSize.width = 2048;
|
pl1.shadow.mapSize.width = 2048;
|
||||||
@ -214,6 +232,10 @@ function initBoxes(scene: THREE.Scene, voxels: Array<Voxel>, player: Player) {
|
|||||||
mesh.castShadow = true;
|
mesh.castShadow = true;
|
||||||
mesh.receiveShadow = true;
|
mesh.receiveShadow = true;
|
||||||
mesh.position.set(x, y, z);
|
mesh.position.set(x, y, z);
|
||||||
|
|
||||||
|
const edges = new THREE.EdgesGeometry(geometry);
|
||||||
|
const line = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({ color: 0x000000, linewidth: 2 }));
|
||||||
|
mesh.add(line);
|
||||||
console.log(player.voxelStandingOn)
|
console.log(player.voxelStandingOn)
|
||||||
if (idx != player.level.playerPos.voxelIdx) {
|
if (idx != player.level.playerPos.voxelIdx) {
|
||||||
mesh.position.setZ(10)
|
mesh.position.setZ(10)
|
||||||
@ -249,69 +271,84 @@ function initGround(scene: THREE.Scene) {
|
|||||||
var data = generateHeight(128, 128);
|
var data = generateHeight(128, 128);
|
||||||
let vertices = planeGeometry.attributes.position.array;
|
let vertices = planeGeometry.attributes.position.array;
|
||||||
|
|
||||||
|
|
||||||
console.log(vertices.length)
|
|
||||||
for (var i = 0, j = 0, l = vertices.length; i < l; i++ , j += 3) {
|
for (var i = 0, j = 0, l = vertices.length; i < l; i++ , j += 3) {
|
||||||
// console.log(vertices[j + 1])
|
|
||||||
(vertices[j + 1] as number) = data[i];
|
(vertices[j + 1] as number) = data[i];
|
||||||
}
|
}
|
||||||
|
planeGeometry.computeVertexNormals();
|
||||||
|
|
||||||
var planeWire = new THREE.Mesh(planeGeometry,
|
var planeWire = new THREE.Mesh(planeGeometry,
|
||||||
|
|
||||||
new THREE.MeshPhongMaterial({
|
new THREE.MeshPhongMaterial({
|
||||||
color: 0x320032,
|
color: 0xff00ff,
|
||||||
specular: 0x0,
|
specular: 0x0,
|
||||||
// shininess: 0xffffff,
|
wireframeLinewidth: 2,
|
||||||
wireframeLinewidth: 3,
|
|
||||||
wireframe: true
|
wireframe: true
|
||||||
|
|
||||||
})
|
|
||||||
);
|
|
||||||
var planeSolid = new THREE.Mesh(planeGeometry,
|
|
||||||
|
|
||||||
new THREE.MeshPhongMaterial({
|
|
||||||
color: 0x030211,
|
|
||||||
specular: 0x0,
|
|
||||||
shininess: 0x0,
|
|
||||||
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
planeWire.position.y = 0;
|
planeWire.position.y = 0;
|
||||||
planeWire.rotateX(Math.PI * 0.5)
|
planeWire.rotateX(Math.PI * 0.5)
|
||||||
|
|
||||||
|
var planeSolid = new THREE.Mesh(planeGeometry,
|
||||||
|
new THREE.MeshPhongMaterial({
|
||||||
|
color: 0x0a0510,
|
||||||
|
specular: 0x0,
|
||||||
|
shininess: 0x0,
|
||||||
|
})
|
||||||
|
);
|
||||||
planeSolid.position.y = 0;
|
planeSolid.position.y = 0;
|
||||||
planeSolid.rotateX(Math.PI * 0.5)
|
planeSolid.rotateX(Math.PI * 0.5)
|
||||||
planeSolid.receiveShadow = true;
|
planeSolid.receiveShadow = true;
|
||||||
|
|
||||||
|
var grid = new THREE.GridHelper(200, 20, 0xff00ff, 0xff00ff);
|
||||||
var grid = new THREE.GridHelper(400, 30, 0x99bbff, 0x99bbff);
|
|
||||||
grid.rotateX(Math.PI * 0.5);
|
grid.rotateX(Math.PI * 0.5);
|
||||||
// grid.position.setZ(0.5);
|
grid.position.z = 0.05;
|
||||||
// console.log(grid.material)
|
|
||||||
(grid.material as THREE.LineBasicMaterial).opacity = 0.2;
|
(grid.material as THREE.LineBasicMaterial).opacity = 0.2;
|
||||||
(grid.material as THREE.LineBasicMaterial).transparent = true;
|
(grid.material as THREE.LineBasicMaterial).transparent = true;
|
||||||
|
|
||||||
// scene.add(planeWire);
|
var gridFar = new THREE.GridHelper(200, 40, 0xff00ff, 0xff00ff);
|
||||||
// scene.add(planeSolid);
|
gridFar.rotateX(Math.PI * 0.5);
|
||||||
scene.add(grid);
|
gridFar.position.z = 0.02;
|
||||||
|
(gridFar.material as THREE.LineBasicMaterial).opacity = 0.1;
|
||||||
|
(gridFar.material as THREE.LineBasicMaterial).transparent = true;
|
||||||
|
|
||||||
|
scene.add(planeWire);
|
||||||
|
scene.add(planeSolid);
|
||||||
|
//scene.add(gridFar);
|
||||||
|
//scene.add(grid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// used to generate terrain
|
|
||||||
function generateHeight(width, height) {
|
function generateHeight(width, height) {
|
||||||
var size = width * height, data = new Uint8Array(size),
|
var size = width * height, data = new Uint8Array(size),
|
||||||
perlin = new ImprovedNoise(), quality = 1, z = Math.random() * 200;
|
perlin = new ImprovedNoise(), quality = 1, z = Math.random() * 20;
|
||||||
|
|
||||||
for (var j = 0; j < 4; j++) {
|
for (var j = 0; j < 4; j++) {
|
||||||
for (var i = 0; i < size; i++) {
|
for (var i = 0; i < size; i++) {
|
||||||
var x = i % width, y = ~ ~(i / width);
|
var ix = i % width, iy = ~ ~(i / width);
|
||||||
data[i] += Math.abs(perlin.noise(x / quality, y / quality, z) * quality * 1.75);
|
data[i] += Math.abs(perlin.noise(ix / quality, iy / quality, z) * quality * 1.75);
|
||||||
|
|
||||||
}
|
}
|
||||||
quality *= 5;
|
quality *= 5;
|
||||||
}
|
}
|
||||||
for (var j = 0; j < size; j++) {
|
|
||||||
var x = ((j % width) - 64)
|
for (var i = 0; i < size; i++) {
|
||||||
var y = ((~ ~(j / width)) - 64)
|
var x = ((i % width) - 64);
|
||||||
data[j] *= Math.sqrt(x * x + y * y) * 0.005
|
var y = ((~ ~(i / width)) - 64);
|
||||||
|
var distFromCenter = Math.sqrt(x * x + y * y);
|
||||||
|
|
||||||
|
var flatRadius = 4;
|
||||||
|
var mountainStart = 50;
|
||||||
|
|
||||||
|
if (distFromCenter < flatRadius) {
|
||||||
|
data[i] = 0;
|
||||||
|
} else if (distFromCenter < mountainStart) {
|
||||||
|
var t = (distFromCenter - flatRadius) / (mountainStart - flatRadius);
|
||||||
|
var rise = Math.pow(t, 1.5);
|
||||||
|
data[i] = data[i] * rise * 1.5;
|
||||||
|
} else {
|
||||||
|
var valleyWidth = 25;
|
||||||
|
var valleyDepth = Math.max(0, 1 - Math.abs(x) / valleyWidth);
|
||||||
|
valleyDepth = Math.pow(valleyDepth, 2);
|
||||||
|
data[i] = data[i] * (2.5 - valleyDepth * 1.2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user