implement sunrise and sunset, improve sky coloring, implement alpha channel in Tessellator, update threejs
This commit is contained in:
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -2,11 +2,16 @@ export default class Tessellator {
|
|||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.material = new THREE.MeshBasicMaterial({
|
this.material = new THREE.MeshBasicMaterial({
|
||||||
vertexColors: THREE.VertexColors,
|
|
||||||
side: THREE.FrontSide,
|
side: THREE.FrontSide,
|
||||||
transparent: true,
|
transparent: true,
|
||||||
depthTest: true
|
depthTest: true,
|
||||||
|
vertexColors: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.red = 0;
|
||||||
|
this.green = 0;
|
||||||
|
this.blue = 0;
|
||||||
|
this.alpha = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bindTexture(texture) {
|
bindTexture(texture) {
|
||||||
@@ -20,13 +25,14 @@ export default class Tessellator {
|
|||||||
this.colors = [];
|
this.colors = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
setColor(red, green, blue) {
|
setColor(red, green, blue, alpha = 1) {
|
||||||
this.red = red;
|
this.red = red;
|
||||||
this.green = green;
|
this.green = green;
|
||||||
this.blue = blue;
|
this.blue = blue;
|
||||||
|
this.alpha = alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
addVertexWithUV(x, y, z, u, v) {
|
addVertex(x, y, z) {
|
||||||
this.addedVertices++;
|
this.addedVertices++;
|
||||||
|
|
||||||
// Add vertex
|
// Add vertex
|
||||||
@@ -34,27 +40,36 @@ export default class Tessellator {
|
|||||||
this.vertices.push(y);
|
this.vertices.push(y);
|
||||||
this.vertices.push(z);
|
this.vertices.push(z);
|
||||||
|
|
||||||
// Add UV
|
|
||||||
this.uv.push(u);
|
|
||||||
this.uv.push(v);
|
|
||||||
|
|
||||||
// Add colors
|
// Add colors
|
||||||
this.colors.push(this.red);
|
this.colors.push(this.red);
|
||||||
this.colors.push(this.green);
|
this.colors.push(this.green);
|
||||||
this.colors.push(this.blue);
|
this.colors.push(this.blue);
|
||||||
|
this.colors.push(this.alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
addVertexWithUV(x, y, z, u, v) {
|
||||||
|
this.addVertex(x, y, z);
|
||||||
|
|
||||||
|
// Add UV
|
||||||
|
this.uv.push(u);
|
||||||
|
this.uv.push(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
transformBrightness(brightness) {
|
transformBrightness(brightness) {
|
||||||
for (let i in this.colors) {
|
for (let i = 0; i < this.colors.length / 4; i++) {
|
||||||
this.colors[i] *= brightness;
|
this.colors[i * 4 + 0] *= brightness;
|
||||||
|
this.colors[i * 4 + 1] *= brightness;
|
||||||
|
this.colors[i * 4 + 2] *= brightness;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
draw(group) {
|
draw(group) {
|
||||||
let geometry = new THREE.BufferGeometry();
|
let geometry = new THREE.BufferGeometry();
|
||||||
geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(this.vertices), 3));
|
geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(this.vertices), 3));
|
||||||
geometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(this.colors), 3));
|
geometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(this.colors), 4));
|
||||||
geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(this.uv), 2));
|
if (this.uv.length > 0) {
|
||||||
|
geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(this.uv), 2));
|
||||||
|
}
|
||||||
|
|
||||||
// Create index array
|
// Create index array
|
||||||
let index = [];
|
let index = [];
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import BlockRenderer from "./BlockRenderer.js";
|
import BlockRenderer from "./BlockRenderer.js";
|
||||||
import EntityRenderManager from "./entity/EntityRenderManager.js";
|
import EntityRenderManager from "./entity/EntityRenderManager.js";
|
||||||
import MathHelper from "../../util/MathHelper.js";
|
import MathHelper from "../../util/MathHelper.js";
|
||||||
import ChunkSection from "../world/ChunkSection.js";
|
|
||||||
import Block from "../world/block/Block.js";
|
import Block from "../world/block/Block.js";
|
||||||
|
import Tessellator from "./Tessellator.js";
|
||||||
|
import ChunkSection from "../world/ChunkSection.js";
|
||||||
|
import Random from "../../util/Random.js";
|
||||||
|
|
||||||
export default class WorldRenderer {
|
export default class WorldRenderer {
|
||||||
|
|
||||||
@@ -14,6 +16,8 @@ export default class WorldRenderer {
|
|||||||
this.window = window;
|
this.window = window;
|
||||||
this.chunkSectionUpdateQueue = [];
|
this.chunkSectionUpdateQueue = [];
|
||||||
|
|
||||||
|
this.tessellator = new Tessellator();
|
||||||
|
|
||||||
// Load terrain texture
|
// Load terrain texture
|
||||||
this.textureTerrain = new THREE.TextureLoader().load('src/resources/terrain/terrain.png');
|
this.textureTerrain = new THREE.TextureLoader().load('src/resources/terrain/terrain.png');
|
||||||
this.textureTerrain.magFilter = THREE.NearestFilter;
|
this.textureTerrain.magFilter = THREE.NearestFilter;
|
||||||
@@ -39,6 +43,9 @@ export default class WorldRenderer {
|
|||||||
this.prevEquippedProgress = 0;
|
this.prevEquippedProgress = 0;
|
||||||
this.itemToRender = 0;
|
this.itemToRender = 0;
|
||||||
|
|
||||||
|
this.prevFogBrightness = 0;
|
||||||
|
this.fogBrightness = 0;
|
||||||
|
|
||||||
this.initialize();
|
this.initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +58,11 @@ export default class WorldRenderer {
|
|||||||
// Frustum
|
// Frustum
|
||||||
this.frustum = new THREE.Frustum();
|
this.frustum = new THREE.Frustum();
|
||||||
|
|
||||||
// Create scene
|
// Create background scene
|
||||||
|
this.background = new THREE.Scene();
|
||||||
|
this.background.matrixAutoUpdate = false;
|
||||||
|
|
||||||
|
// Create world scene
|
||||||
this.scene = new THREE.Scene();
|
this.scene = new THREE.Scene();
|
||||||
this.scene.matrixAutoUpdate = false;
|
this.scene.matrixAutoUpdate = false;
|
||||||
|
|
||||||
@@ -82,12 +93,9 @@ export default class WorldRenderer {
|
|||||||
let geometry = new THREE.BoxGeometry(1, 1, 1);
|
let geometry = new THREE.BoxGeometry(1, 1, 1);
|
||||||
let edges = new THREE.EdgesGeometry(geometry);
|
let edges = new THREE.EdgesGeometry(geometry);
|
||||||
this.blockHitBox = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({
|
this.blockHitBox = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({
|
||||||
color: 0x000000,
|
color: 0x000000
|
||||||
}));
|
}));
|
||||||
this.scene.add(this.blockHitBox);
|
this.scene.add(this.blockHitBox);
|
||||||
|
|
||||||
// Hand group
|
|
||||||
this.handGroup = new THREE.Object3D();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render(partialTicks) {
|
render(partialTicks) {
|
||||||
@@ -125,6 +133,9 @@ export default class WorldRenderer {
|
|||||||
// Render hand
|
// Render hand
|
||||||
this.renderHand(partialTicks);
|
this.renderHand(partialTicks);
|
||||||
|
|
||||||
|
// Render background scene
|
||||||
|
this.webRenderer.render(this.background, this.camera);
|
||||||
|
|
||||||
// Render actual scene
|
// Render actual scene
|
||||||
this.webRenderer.render(this.scene, this.camera);
|
this.webRenderer.render(this.scene, this.camera);
|
||||||
|
|
||||||
@@ -135,6 +146,7 @@ export default class WorldRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onTick() {
|
onTick() {
|
||||||
|
this.prevFogBrightness = this.fogBrightness;
|
||||||
this.prevEquippedProgress = this.equippedProgress;
|
this.prevEquippedProgress = this.equippedProgress;
|
||||||
|
|
||||||
let player = this.minecraft.player;
|
let player = this.minecraft.player;
|
||||||
@@ -157,6 +169,12 @@ export default class WorldRenderer {
|
|||||||
if (this.equippedProgress < 0.1) {
|
if (this.equippedProgress < 0.1) {
|
||||||
this.itemToRender = itemStack;
|
this.itemToRender = itemStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update fog brightness
|
||||||
|
let brightnessAtPosition = this.minecraft.world.getLightBrightness(player.x, player.y, player.z);
|
||||||
|
let renderDistance = WorldRenderer.RENDER_DISTANCE / 32.0;
|
||||||
|
let fogBrightness = brightnessAtPosition * (1.0 - renderDistance) + renderDistance;
|
||||||
|
this.fogBrightness += (fogBrightness - this.fogBrightness) * 0.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
orientCamera(partialTicks) {
|
orientCamera(partialTicks) {
|
||||||
@@ -208,22 +226,267 @@ export default class WorldRenderer {
|
|||||||
this.setupFog(x, z, player.isHeadInWater(), partialTicks);
|
this.setupFog(x, z, player.isHeadInWater(), partialTicks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generateSky() {
|
||||||
|
// Create cycle group
|
||||||
|
this.cycleGroup = new THREE.Object3D();
|
||||||
|
this.scene.add(this.cycleGroup);
|
||||||
|
|
||||||
|
// Create background center group
|
||||||
|
this.backgroundCenter = new THREE.Object3D();
|
||||||
|
this.background.add(this.backgroundCenter);
|
||||||
|
|
||||||
|
// Create sun
|
||||||
|
let geometry = new THREE.PlaneGeometry(1, 1);
|
||||||
|
let materialSun = new THREE.MeshBasicMaterial({
|
||||||
|
side: THREE.FrontSide,
|
||||||
|
map: this.textureSun,
|
||||||
|
alphaMap: this.textureSun,
|
||||||
|
blending: THREE.AdditiveBlending,
|
||||||
|
transparent: true
|
||||||
|
});
|
||||||
|
this.sun = new THREE.Mesh(geometry, materialSun);
|
||||||
|
this.sun.translateZ(-2);
|
||||||
|
this.sun.material.depthTest = false;
|
||||||
|
this.cycleGroup.add(this.sun);
|
||||||
|
|
||||||
|
// Create moon
|
||||||
|
let materialMoon = new THREE.MeshBasicMaterial({
|
||||||
|
side: THREE.BackSide,
|
||||||
|
map: this.textureMoon,
|
||||||
|
alphaMap: this.textureMoon,
|
||||||
|
blending: THREE.AdditiveBlending,
|
||||||
|
transparent: true
|
||||||
|
});
|
||||||
|
this.moon = new THREE.Mesh(geometry, materialMoon);
|
||||||
|
this.moon.translateZ(2);
|
||||||
|
this.moon.material.depthTest = false;
|
||||||
|
this.cycleGroup.add(this.moon);
|
||||||
|
|
||||||
|
let size = 64;
|
||||||
|
let scale = 256 / size + 2;
|
||||||
|
|
||||||
|
// Generate sky color
|
||||||
|
{
|
||||||
|
let y = 16;
|
||||||
|
this.listSky = new THREE.Object3D();
|
||||||
|
this.tessellator.startDrawing();
|
||||||
|
this.tessellator.setColor(1, 1, 1);
|
||||||
|
for (let x = -size * scale; x <= size * scale; x += size) {
|
||||||
|
for (let z = -size * scale; z <= size * scale; z += size) {
|
||||||
|
this.tessellator.addVertex(x + size, y, z);
|
||||||
|
this.tessellator.addVertex(x, y, z);
|
||||||
|
this.tessellator.addVertex(x, y, z + size);
|
||||||
|
this.tessellator.addVertex(x + size, y, z + size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mesh = this.tessellator.draw(this.listSky);
|
||||||
|
mesh.material.depthTest = false;
|
||||||
|
this.backgroundCenter.add(this.listSky);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate stars
|
||||||
|
{
|
||||||
|
this.listStars = new THREE.Object3D();
|
||||||
|
this.tessellator.startDrawing();
|
||||||
|
this.tessellator.setColor(1, 1, 1);
|
||||||
|
|
||||||
|
// Generate 1500 stars
|
||||||
|
let random = new Random(10842);
|
||||||
|
for (let i = 0; i < 1500; i++) {
|
||||||
|
// Random vector
|
||||||
|
let vectorX = random.nextFloat() * 2.0 - 1.0;
|
||||||
|
let vectorY = random.nextFloat() * 2.0 - 1.0;
|
||||||
|
let vectorZ = random.nextFloat() * 2.0 - 1.0;
|
||||||
|
|
||||||
|
// Skip invalid vectors
|
||||||
|
let distance = vectorX * vectorX + vectorY * vectorY + vectorZ * vectorZ;
|
||||||
|
if (distance >= 1.0 || distance <= 0.01) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create sphere
|
||||||
|
distance = 1.0 / Math.sqrt(distance);
|
||||||
|
vectorX *= distance;
|
||||||
|
vectorY *= distance;
|
||||||
|
vectorZ *= distance;
|
||||||
|
|
||||||
|
// Increase sphere size
|
||||||
|
let x = vectorX * 100;
|
||||||
|
let y = vectorY * 100;
|
||||||
|
let z = vectorZ * 100;
|
||||||
|
|
||||||
|
// Rotate the stars on the sphere
|
||||||
|
let rotationX = Math.atan2(vectorX, vectorZ);
|
||||||
|
let sinX = Math.sin(rotationX);
|
||||||
|
let cosX = Math.cos(rotationX);
|
||||||
|
|
||||||
|
// Face the stars to the middle of the sphere
|
||||||
|
let rotationY = Math.atan2(Math.sqrt(vectorX * vectorX + vectorZ * vectorZ), vectorY);
|
||||||
|
let sinY = Math.sin(rotationY);
|
||||||
|
let cosY = Math.cos(rotationY);
|
||||||
|
|
||||||
|
// Tilt the stars randomly
|
||||||
|
let rotationZ = random.nextFloat() * Math.PI * 2;
|
||||||
|
let sinZ = Math.sin(rotationZ);
|
||||||
|
let cosZ = Math.cos(rotationZ);
|
||||||
|
|
||||||
|
// Random size of the star
|
||||||
|
let size = 0.25 + random.nextFloat() * 0.25;
|
||||||
|
|
||||||
|
// Add vertices for each edge of the star
|
||||||
|
for (let edge = 0; edge < 4; edge++) {
|
||||||
|
// Calculate the position of the edge on a 2D plane
|
||||||
|
let tileX = ((edge & 2) - 1) * size;
|
||||||
|
let tileZ = ((edge + 1 & 2) - 1) * size;
|
||||||
|
|
||||||
|
// Project tile position onto the sphere
|
||||||
|
let sphereX = tileX * cosZ - tileZ * sinZ;
|
||||||
|
let sphereY = tileZ * cosZ + tileX * sinZ;
|
||||||
|
let sphereZ = -sphereX * cosY;
|
||||||
|
|
||||||
|
// Calculate offset of the edge on the sphere
|
||||||
|
let offsetX = sphereZ * sinX - sphereY * cosX;
|
||||||
|
let offsetY = sphereX * sinY;
|
||||||
|
let offsetZ = sphereY * sinX + sphereZ * cosX;
|
||||||
|
|
||||||
|
// Add vertex for the edge of the star
|
||||||
|
this.tessellator.addVertex(x + offsetX, y + offsetY, z + offsetZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mesh = this.tessellator.draw(this.listStars);
|
||||||
|
mesh.material = mesh.material.clone();
|
||||||
|
mesh.material.depthTest = true;
|
||||||
|
mesh.material.side = THREE.BackSide;
|
||||||
|
this.cycleGroup.add(this.listStars);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate sunrise/sunset color
|
||||||
|
{
|
||||||
|
this.listSunset = new THREE.Object3D();
|
||||||
|
this.tessellator.startDrawing();
|
||||||
|
|
||||||
|
let amount = 16;
|
||||||
|
let width = (Math.PI * 2.0) / amount;
|
||||||
|
|
||||||
|
for (let index = 0; index < amount; index++) {
|
||||||
|
let rotation = (index * Math.PI * 2.0) / amount;
|
||||||
|
|
||||||
|
let x1 = Math.sin(rotation);
|
||||||
|
let y1 = Math.cos(rotation);
|
||||||
|
|
||||||
|
let x2 = Math.sin(rotation + width);
|
||||||
|
let y2 = Math.cos(rotation + width);
|
||||||
|
|
||||||
|
this.tessellator.setColor(1, 1, 1, 1);
|
||||||
|
this.tessellator.addVertex(0.0, 100, 0.0);
|
||||||
|
this.tessellator.addVertex(0.0, 100, 0.0);
|
||||||
|
|
||||||
|
this.tessellator.setColor(1, 1, 1, 0);
|
||||||
|
this.tessellator.addVertex(x1 * 120, y1 * 120, -y1 * 40);
|
||||||
|
this.tessellator.addVertex(x2 * 120, y2 * 120, -y2 * 40);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mesh = this.tessellator.draw(this.listSunset);
|
||||||
|
mesh.material = mesh.material.clone();
|
||||||
|
mesh.material.depthTest = false;
|
||||||
|
mesh.material.opacity = 0.6;
|
||||||
|
mesh.material.side = THREE.DoubleSide;
|
||||||
|
this.backgroundCenter.add(this.listSunset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate void color
|
||||||
|
{
|
||||||
|
let y = -16;
|
||||||
|
this.listVoid = new THREE.Object3D();
|
||||||
|
this.tessellator.startDrawing();
|
||||||
|
this.tessellator.setColor(1, 1, 1);
|
||||||
|
for (let x = -size * scale; x <= size * scale; x += size) {
|
||||||
|
for (let z = -size * scale; z <= size * scale; z += size) {
|
||||||
|
this.tessellator.addVertex(x, y, z);
|
||||||
|
this.tessellator.addVertex(x + size, y, z);
|
||||||
|
this.tessellator.addVertex(x + size, y, z + size);
|
||||||
|
this.tessellator.addVertex(x, y, z + size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mesh = this.tessellator.draw(this.listVoid);
|
||||||
|
mesh.material = mesh.material.clone();
|
||||||
|
mesh.material.depthTest = false;
|
||||||
|
mesh.material.opacity = 0.75;
|
||||||
|
this.backgroundCenter.add(this.listVoid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderSky(partialTicks) {
|
||||||
|
// Center sky
|
||||||
|
this.cycleGroup.position.copy(this.camera.position);
|
||||||
|
this.backgroundCenter.position.copy(this.camera.position);
|
||||||
|
|
||||||
|
// Rotate sky cycle
|
||||||
|
let angle = this.minecraft.world.getCelestialAngle(partialTicks);
|
||||||
|
this.cycleGroup.rotation.set(angle * Math.PI * 2 + Math.PI / 2, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
setupFog(x, z, inWater, partialTicks) {
|
setupFog(x, z, inWater, partialTicks) {
|
||||||
if (inWater) {
|
if (inWater) {
|
||||||
let color = new THREE.Color(0.2, 0.2, 0.4);
|
let color = new THREE.Color(0.2, 0.2, 0.4);
|
||||||
this.scene.background = color;
|
this.background.background = color;
|
||||||
this.scene.fog = new THREE.Fog(color, 0.0025, 5);
|
this.scene.fog = new THREE.Fog(color, 0.0025, 5);
|
||||||
} else {
|
} else {
|
||||||
let viewDistance = WorldRenderer.RENDER_DISTANCE * ChunkSection.SIZE;
|
let world = this.minecraft.world;
|
||||||
|
|
||||||
let color = this.minecraft.world.getSkyColor(x, z, partialTicks);
|
let viewDistance = WorldRenderer.RENDER_DISTANCE * ChunkSection.SIZE;
|
||||||
this.scene.background = new THREE.Color(
|
let viewFactor = 1.0 - Math.pow(0.25 + 0.75 * WorldRenderer.RENDER_DISTANCE / 32.0, 0.25);
|
||||||
((color >> 16) & 0xFF) / 255,
|
|
||||||
((color >> 8) & 0xFF) / 255,
|
let angle = world.getCelestialAngle(partialTicks);
|
||||||
(color & 0xFF) / 255
|
|
||||||
);
|
let skyColor = world.getSkyColor(x, z, partialTicks);
|
||||||
this.scene.fog = new THREE.Fog(color, 0.0025, viewDistance);
|
let fogColor = world.getFogColor(partialTicks);
|
||||||
|
let sunsetColor = world.getSunriseSunsetColor(partialTicks);
|
||||||
|
|
||||||
|
let starBrightness = world.getStarBrightness(partialTicks);
|
||||||
|
let brightness = this.prevFogBrightness + (this.fogBrightness - this.prevFogBrightness) * partialTicks;
|
||||||
|
|
||||||
|
let red = (fogColor.x + (skyColor.x - fogColor.x) * viewFactor) * brightness;
|
||||||
|
let green = (fogColor.y + (skyColor.y - fogColor.y) * viewFactor) * brightness;
|
||||||
|
let blue = (fogColor.z + (skyColor.z - fogColor.z) * viewFactor) * brightness;
|
||||||
|
|
||||||
|
// Update background color
|
||||||
|
this.background.background = new THREE.Color(red, green, blue);
|
||||||
|
|
||||||
|
// Update fog color
|
||||||
|
this.scene.fog = new THREE.Fog(new THREE.Color(red, green, blue), 0.0025, viewDistance * 2);
|
||||||
|
|
||||||
|
let skyMesh = this.listSky.children[0];
|
||||||
|
let voidMesh = this.listVoid.children[0];
|
||||||
|
let starsMesh = this.listStars.children[0];
|
||||||
|
let sunsetMesh = this.listSunset.children[0];
|
||||||
|
|
||||||
|
// Update sky and void color
|
||||||
|
skyMesh.material.color.set(new THREE.Color(skyColor.x, skyColor.y, skyColor.z));
|
||||||
|
voidMesh.material.color.set(new THREE.Color(
|
||||||
|
skyColor.x * 0.2 + 0.04,
|
||||||
|
skyColor.y * 0.2 + 0.04,
|
||||||
|
skyColor.z * 0.6 + 0.1
|
||||||
|
));
|
||||||
|
|
||||||
|
// Update star brightness
|
||||||
|
if (starBrightness > 0) {
|
||||||
|
starsMesh.material.opacity = starBrightness;
|
||||||
|
starsMesh.material.color.set(new THREE.Color(starBrightness, starBrightness, starBrightness));
|
||||||
|
}
|
||||||
|
this.listStars.visible = starBrightness > 0;
|
||||||
|
|
||||||
|
// Update sunset
|
||||||
|
if (sunsetColor !== null) {
|
||||||
|
sunsetMesh.material.opacity = sunsetColor.w;
|
||||||
|
sunsetMesh.material.color.set(new THREE.Color(sunsetColor.x, sunsetColor.y, sunsetColor.z));
|
||||||
|
sunsetMesh.rotation.x = MathHelper.toRadians(angle <= 0.5 ? 90 : 135);
|
||||||
|
}
|
||||||
|
sunsetMesh.visible = sunsetColor !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.background.fog = this.scene.fog;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderChunks(cameraChunkX, cameraChunkZ) {
|
renderChunks(cameraChunkX, cameraChunkZ) {
|
||||||
@@ -300,50 +563,6 @@ export default class WorldRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generateSky() {
|
|
||||||
// Create sky group
|
|
||||||
this.skyGroup = new THREE.Scene();
|
|
||||||
this.scene.add(this.skyGroup);
|
|
||||||
|
|
||||||
// Create sun
|
|
||||||
let geometry = new THREE.PlaneGeometry(1, 1);
|
|
||||||
let materialSun = new THREE.MeshBasicMaterial({
|
|
||||||
side: THREE.FrontSide,
|
|
||||||
map: this.textureSun,
|
|
||||||
alphaMap: this.textureSun,
|
|
||||||
blending: THREE.AdditiveBlending,
|
|
||||||
transparent: true
|
|
||||||
});
|
|
||||||
this.sun = new THREE.Mesh(geometry, materialSun);
|
|
||||||
this.sun.translateZ(-2);
|
|
||||||
this.sun.renderOrder = 999;
|
|
||||||
this.sun.material.depthTest = false;
|
|
||||||
this.skyGroup.add(this.sun);
|
|
||||||
|
|
||||||
// Create moon
|
|
||||||
let materialMoon = new THREE.MeshBasicMaterial({
|
|
||||||
side: THREE.BackSide,
|
|
||||||
map: this.textureMoon,
|
|
||||||
alphaMap: this.textureMoon,
|
|
||||||
blending: THREE.AdditiveBlending,
|
|
||||||
transparent: true
|
|
||||||
});
|
|
||||||
this.moon = new THREE.Mesh(geometry, materialMoon);
|
|
||||||
this.moon.translateZ(2);
|
|
||||||
this.moon.renderOrder = 999;
|
|
||||||
this.moon.material.depthTest = false;
|
|
||||||
this.skyGroup.add(this.moon);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderSky(partialTicks) {
|
|
||||||
// Center sky
|
|
||||||
this.skyGroup.position.copy(this.camera.position);
|
|
||||||
|
|
||||||
// Rotate sky
|
|
||||||
let angle = this.minecraft.world.getCelestialAngle(partialTicks);
|
|
||||||
this.skyGroup.rotation.set(angle * Math.PI * 2 + Math.PI / 2, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderHand(partialTicks) {
|
renderHand(partialTicks) {
|
||||||
// Hide hand before rendering
|
// Hide hand before rendering
|
||||||
let player = this.minecraft.player;
|
let player = this.minecraft.player;
|
||||||
@@ -401,7 +620,7 @@ export default class WorldRenderer {
|
|||||||
stack.rotateX(MathHelper.toRadians((player.rotationPitch - pitchArm) * 0.1));
|
stack.rotateX(MathHelper.toRadians((player.rotationPitch - pitchArm) * 0.1));
|
||||||
stack.rotateY(MathHelper.toRadians((player.rotationYaw - yawArm) * 0.1));
|
stack.rotateY(MathHelper.toRadians((player.rotationYaw - yawArm) * 0.1));
|
||||||
|
|
||||||
if(hasItem) {
|
if (hasItem) {
|
||||||
// Initial offset on screen
|
// Initial offset on screen
|
||||||
this.translate(stack, -xOffset * 0.4, yOffset * 0.2, -zOffset * 0.2);
|
this.translate(stack, -xOffset * 0.4, yOffset * 0.2, -zOffset * 0.2);
|
||||||
this.translate(stack, 0.7 * factor, -0.65 * factor - (1.0 - equipProgress) * 0.6, -0.9 * factor);
|
this.translate(stack, 0.7 * factor, -0.65 * factor - (1.0 - equipProgress) * 0.6, -0.9 * factor);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import EnumSkyBlock from "../../util/EnumSkyBlock.js";
|
|||||||
import Block from "./block/Block.js";
|
import Block from "./block/Block.js";
|
||||||
import EnumBlockFace from "../../util/EnumBlockFace.js";
|
import EnumBlockFace from "../../util/EnumBlockFace.js";
|
||||||
import Vector3 from "../../util/Vector3.js";
|
import Vector3 from "../../util/Vector3.js";
|
||||||
|
import Vector4 from "../../util/Vector4.js";
|
||||||
|
|
||||||
export default class World {
|
export default class World {
|
||||||
|
|
||||||
@@ -488,7 +489,54 @@ export default class World {
|
|||||||
green *= brightness;
|
green *= brightness;
|
||||||
blue *= brightness;
|
blue *= brightness;
|
||||||
|
|
||||||
return (Math.round(red * 255) << 16) | (Math.round(green * 255) << 8) | Math.round(blue * 255);
|
return new Vector3(red, green, blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
getFogColor(partialTicks) {
|
||||||
|
let angle = this.getCelestialAngle(partialTicks);
|
||||||
|
let rotation = Math.cos(angle * Math.PI * 2.0) * 2.0 + 0.5;
|
||||||
|
rotation = MathHelper.clamp(rotation, 0.0, 1.0);
|
||||||
|
|
||||||
|
let x = 0.7529412;
|
||||||
|
let y = 0.84705883;
|
||||||
|
let z = 1.0;
|
||||||
|
|
||||||
|
x = x * (rotation * 0.94 + 0.06);
|
||||||
|
y = y * (rotation * 0.94 + 0.06);
|
||||||
|
z = z * (rotation * 0.91 + 0.09);
|
||||||
|
|
||||||
|
return new Vector3(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
getSunriseSunsetColor(partialTicks) {
|
||||||
|
let angle = this.getCelestialAngle(partialTicks);
|
||||||
|
let rotation = Math.cos(angle * Math.PI * 2.0);
|
||||||
|
|
||||||
|
let min = 0;
|
||||||
|
let max = 0.4;
|
||||||
|
|
||||||
|
// Check if rotation is inside of sunrise or sunset
|
||||||
|
if (rotation >= -max && rotation <= max) {
|
||||||
|
let factor = ((rotation - min) / max) * 0.5 + 0.5;
|
||||||
|
let strength = Math.pow(1.0 - (1.0 - Math.sin(factor * Math.PI)) * 0.99, 2);
|
||||||
|
|
||||||
|
// Calculate colors for sunrise and sunset
|
||||||
|
return new Vector4(
|
||||||
|
factor * 0.3 + 0.7,
|
||||||
|
factor * factor * 0.7 + 0.2,
|
||||||
|
0.2,
|
||||||
|
strength
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getStarBrightness(partialTicks) {
|
||||||
|
let angle = this.getCelestialAngle(partialTicks);
|
||||||
|
let rotation = 1.0 - (Math.cos(angle * 3.141593 * 2.0) * 2.0 + 0.75);
|
||||||
|
rotation = MathHelper.clamp(rotation, 0.0, 1.0);
|
||||||
|
return rotation * rotation * 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
getLightBrightness(x, y, z) {
|
getLightBrightness(x, y, z) {
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
export default class Vector4 {
|
||||||
|
|
||||||
|
constructor(x = 0, y = 0, z = 0, w = 0) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.w = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
addVector(x, y, z, w) {
|
||||||
|
return new Vector4(this.x + x, this.y + y, this.z + z, this.w + w);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user