调整雾
This commit is contained in:
@@ -762,20 +762,22 @@ export class OceanScene {
|
|||||||
|
|
||||||
initFog() {
|
initFog() {
|
||||||
const fogTexture = this.createFogTexture();
|
const fogTexture = this.createFogTexture();
|
||||||
|
const lowFogTexture = this.createLowFogTexture();
|
||||||
this.fogGroup = new THREE.Group();
|
this.fogGroup = new THREE.Group();
|
||||||
this.fogLayers = [];
|
this.fogLayers = [];
|
||||||
|
|
||||||
const layerConfigs = [
|
const layerConfigs = [
|
||||||
{ width: 4600, height: 2400, y: 8, opacity: 0.26, speedX: 0.00055, speedY: 0.0001, rotation: 0.08 },
|
{ width: 5200, height: 1800, y: 5, opacity: 0.18, speedX: 0.00022, speedY: 0.00004, rotation: 0.03, scale: 3.2, texture: lowFogTexture, low: true },
|
||||||
{ width: 3900, height: 1900, y: 22, opacity: 0.2, speedX: -0.00032, speedY: 0.00014, rotation: -0.05 },
|
{ width: 4300, height: 1500, y: 11, opacity: 0.14, speedX: -0.00018, speedY: 0.00005, rotation: -0.04, scale: 2.8, texture: lowFogTexture, low: true },
|
||||||
{ width: 3200, height: 1500, y: 42, opacity: 0.13, speedX: 0.00024, speedY: -0.00008, rotation: 0.12 }
|
{ width: 4600, height: 2400, y: 22, opacity: 0.2, speedX: 0.00045, speedY: 0.0001, rotation: 0.08, scale: 2.4, texture: fogTexture, low: false },
|
||||||
|
{ width: 3900, height: 1900, y: 52, opacity: 0.14, speedX: -0.00028, speedY: 0.00014, rotation: -0.05, scale: 2.1, texture: fogTexture, low: false }
|
||||||
];
|
];
|
||||||
|
|
||||||
layerConfigs.forEach((config) => {
|
layerConfigs.forEach((config) => {
|
||||||
const texture = fogTexture.clone();
|
const texture = config.texture.clone();
|
||||||
texture.wrapS = THREE.RepeatWrapping;
|
texture.wrapS = THREE.RepeatWrapping;
|
||||||
texture.wrapT = THREE.RepeatWrapping;
|
texture.wrapT = THREE.RepeatWrapping;
|
||||||
texture.repeat.set(2.4, 1.4);
|
texture.repeat.set(config.scale, config.low ? 1.1 : 1.4);
|
||||||
texture.needsUpdate = true;
|
texture.needsUpdate = true;
|
||||||
|
|
||||||
const material = new THREE.MeshBasicMaterial({
|
const material = new THREE.MeshBasicMaterial({
|
||||||
@@ -801,6 +803,7 @@ export class OceanScene {
|
|||||||
texture,
|
texture,
|
||||||
baseY: config.y,
|
baseY: config.y,
|
||||||
baseOpacity: config.opacity,
|
baseOpacity: config.opacity,
|
||||||
|
isLowLayer: config.low,
|
||||||
speedX: config.speedX,
|
speedX: config.speedX,
|
||||||
speedY: config.speedY
|
speedY: config.speedY
|
||||||
});
|
});
|
||||||
@@ -867,6 +870,52 @@ export class OceanScene {
|
|||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createLowFogTexture() {
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
canvas.width = 512;
|
||||||
|
canvas.height = 256;
|
||||||
|
|
||||||
|
const context = canvas.getContext('2d');
|
||||||
|
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
for (let i = 0; i < 30; i++) {
|
||||||
|
const x = Math.random() * canvas.width;
|
||||||
|
const y = 30 + Math.random() * 150;
|
||||||
|
const radiusX = 80 + Math.random() * 140;
|
||||||
|
const radiusY = 14 + Math.random() * 28;
|
||||||
|
const gradient = context.createRadialGradient(x, y, 0, x, y, radiusX);
|
||||||
|
|
||||||
|
gradient.addColorStop(0, 'rgba(255,255,255,0.58)');
|
||||||
|
gradient.addColorStop(0.22, 'rgba(255,255,255,0.36)');
|
||||||
|
gradient.addColorStop(0.6, 'rgba(255,255,255,0.12)');
|
||||||
|
gradient.addColorStop(1, 'rgba(255,255,255,0)');
|
||||||
|
|
||||||
|
context.save();
|
||||||
|
context.translate(x, y);
|
||||||
|
context.scale(1.0, radiusY / radiusX);
|
||||||
|
context.translate(-x, -y);
|
||||||
|
context.fillStyle = gradient;
|
||||||
|
context.fillRect(x - radiusX, y - radiusX, radiusX * 2, radiusX * 2);
|
||||||
|
context.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
const verticalFade = context.createLinearGradient(0, 0, 0, canvas.height);
|
||||||
|
verticalFade.addColorStop(0, 'rgba(255,255,255,0)');
|
||||||
|
verticalFade.addColorStop(0.18, 'rgba(255,255,255,0.55)');
|
||||||
|
verticalFade.addColorStop(0.52, 'rgba(255,255,255,1)');
|
||||||
|
verticalFade.addColorStop(0.86, 'rgba(255,255,255,0.42)');
|
||||||
|
verticalFade.addColorStop(1, 'rgba(255,255,255,0)');
|
||||||
|
context.globalCompositeOperation = 'destination-in';
|
||||||
|
context.fillStyle = verticalFade;
|
||||||
|
context.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
context.globalCompositeOperation = 'source-over';
|
||||||
|
|
||||||
|
const texture = new THREE.CanvasTexture(canvas);
|
||||||
|
texture.colorSpace = THREE.SRGBColorSpace;
|
||||||
|
texture.needsUpdate = true;
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
createHorizonFogTexture() {
|
createHorizonFogTexture() {
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
canvas.width = 64;
|
canvas.width = 64;
|
||||||
@@ -1656,25 +1705,37 @@ export class OceanScene {
|
|||||||
const heightBase = THREE.MathUtils.lerp(-20, 95, this.params.fogHeight);
|
const heightBase = THREE.MathUtils.lerp(-20, 95, this.params.fogHeight);
|
||||||
const verticalSpread = THREE.MathUtils.lerp(20, 110, this.params.fogHeight);
|
const verticalSpread = THREE.MathUtils.lerp(20, 110, this.params.fogHeight);
|
||||||
const rangeOpacity = THREE.MathUtils.lerp(0.55, 1.35, this.params.fogRange);
|
const rangeOpacity = THREE.MathUtils.lerp(0.55, 1.35, this.params.fogRange);
|
||||||
|
const nearSeaMist = THREE.MathUtils.lerp(0.12, 0.9, this.params.fogDensity) * THREE.MathUtils.lerp(0.8, 1.22, this.params.fogRange);
|
||||||
|
|
||||||
this.fogLayers.forEach((layer, index) => {
|
this.fogLayers.forEach((layer, index) => {
|
||||||
layer.mesh.position.y = heightBase + index * verticalSpread * 0.36;
|
if (layer.isLowLayer) {
|
||||||
|
layer.mesh.position.y = THREE.MathUtils.lerp(1.5, 18.0, this.params.fogHeight) + index * 2.8;
|
||||||
|
layer.mesh.scale.set(
|
||||||
|
THREE.MathUtils.lerp(0.92, 1.28, this.params.fogRange),
|
||||||
|
1,
|
||||||
|
THREE.MathUtils.lerp(0.92, 1.24, this.params.fogRange)
|
||||||
|
);
|
||||||
|
layer.mesh.material.opacity = layer.baseOpacity * nearSeaMist;
|
||||||
|
layer.mesh.material.color.copy(horizonColor.clone().lerp(fogColor, 0.72));
|
||||||
|
} else {
|
||||||
|
layer.mesh.position.y = heightBase + (index - 2) * verticalSpread * 0.42;
|
||||||
layer.mesh.scale.setScalar(THREE.MathUtils.lerp(0.82, 1.2, this.params.fogRange));
|
layer.mesh.scale.setScalar(THREE.MathUtils.lerp(0.82, 1.2, this.params.fogRange));
|
||||||
layer.mesh.material.opacity = layer.baseOpacity * THREE.MathUtils.lerp(0.18, 1.35, this.params.fogDensity) * rangeOpacity;
|
layer.mesh.material.opacity = layer.baseOpacity * THREE.MathUtils.lerp(0.16, 1.18, this.params.fogDensity) * rangeOpacity;
|
||||||
layer.mesh.material.color.copy(fogLayerColor);
|
layer.mesh.material.color.copy(fogLayerColor);
|
||||||
|
}
|
||||||
layer.mesh.visible = layer.mesh.material.opacity > 0.01;
|
layer.mesh.visible = layer.mesh.material.opacity > 0.01;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.horizonFog) {
|
if (this.horizonFog) {
|
||||||
this.horizonFog.material.color.copy(horizonColor);
|
this.horizonFog.material.color.copy(horizonColor.clone().lerp(fogColor, 0.18));
|
||||||
this.horizonFog.material.opacity =
|
this.horizonFog.material.opacity =
|
||||||
THREE.MathUtils.lerp(0.16, 0.5, this.params.fogDensity) *
|
THREE.MathUtils.lerp(0.12, 0.42, this.params.fogDensity) *
|
||||||
THREE.MathUtils.lerp(0.7, 1.28, this.params.fogRange);
|
THREE.MathUtils.lerp(0.82, 1.34, this.params.fogRange);
|
||||||
this.horizonFog.position.y = THREE.MathUtils.lerp(70, 190, this.params.fogHeight);
|
this.horizonFog.position.y = THREE.MathUtils.lerp(52, 168, this.params.fogHeight);
|
||||||
this.horizonFog.scale.set(
|
this.horizonFog.scale.set(
|
||||||
THREE.MathUtils.lerp(0.88, 1.28, this.params.fogRange),
|
THREE.MathUtils.lerp(0.92, 1.34, this.params.fogRange),
|
||||||
THREE.MathUtils.lerp(0.8, 1.18, this.params.fogHeight),
|
THREE.MathUtils.lerp(0.72, 1.12, this.params.fogHeight),
|
||||||
THREE.MathUtils.lerp(0.88, 1.28, this.params.fogRange)
|
THREE.MathUtils.lerp(0.92, 1.34, this.params.fogRange)
|
||||||
);
|
);
|
||||||
this.horizonFog.visible = this.horizonFog.material.opacity > 0.01;
|
this.horizonFog.visible = this.horizonFog.material.opacity > 0.01;
|
||||||
}
|
}
|
||||||
@@ -1682,13 +1743,13 @@ export class OceanScene {
|
|||||||
if (this.skyHazeBand) {
|
if (this.skyHazeBand) {
|
||||||
this.skyHazeBand.material.color.copy(skyBlendColor);
|
this.skyHazeBand.material.color.copy(skyBlendColor);
|
||||||
this.skyHazeBand.material.opacity =
|
this.skyHazeBand.material.opacity =
|
||||||
THREE.MathUtils.lerp(0.1, 0.32, this.params.fogDensity) *
|
THREE.MathUtils.lerp(0.04, 0.18, this.params.fogDensity) *
|
||||||
THREE.MathUtils.lerp(0.82, 1.18, this.params.fogRange);
|
THREE.MathUtils.lerp(0.78, 1.08, this.params.fogRange);
|
||||||
this.skyHazeBand.position.y = THREE.MathUtils.lerp(300, 520, this.params.fogHeight);
|
this.skyHazeBand.position.y = THREE.MathUtils.lerp(340, 560, this.params.fogHeight);
|
||||||
this.skyHazeBand.scale.set(
|
this.skyHazeBand.scale.set(
|
||||||
THREE.MathUtils.lerp(0.96, 1.16, this.params.fogRange),
|
THREE.MathUtils.lerp(0.98, 1.12, this.params.fogRange),
|
||||||
THREE.MathUtils.lerp(0.88, 1.14, this.params.fogHeight),
|
THREE.MathUtils.lerp(0.92, 1.1, this.params.fogHeight),
|
||||||
THREE.MathUtils.lerp(0.96, 1.16, this.params.fogRange)
|
THREE.MathUtils.lerp(0.98, 1.12, this.params.fogRange)
|
||||||
);
|
);
|
||||||
this.skyHazeBand.visible = this.skyHazeBand.material.opacity > 0.01;
|
this.skyHazeBand.visible = this.skyHazeBand.material.opacity > 0.01;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user