加入导出功能
This commit is contained in:
@@ -6,6 +6,7 @@ import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
|
||||
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
|
||||
import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';
|
||||
import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js';
|
||||
import Stats from 'three/addons/libs/stats.module.js';
|
||||
import { TerrainGenerator } from './TerrainGenerator.js';
|
||||
import { VegetationSystem } from './VegetationSystem.js';
|
||||
|
||||
@@ -35,6 +36,7 @@ export class OceanScene {
|
||||
this.bloomPass = null;
|
||||
this.rainPass = null;
|
||||
this.snowPass = null;
|
||||
this.stats = null;
|
||||
this.cloudGroup = null;
|
||||
this.cloudMaterials = [];
|
||||
this.cloudLayers = [];
|
||||
@@ -83,8 +85,6 @@ export class OceanScene {
|
||||
};
|
||||
|
||||
this.clock = new THREE.Clock();
|
||||
this.frameCount = 0;
|
||||
this.lastTime = performance.now();
|
||||
this.lightningFlash = 0;
|
||||
this.lightningLocalFlash = 0;
|
||||
this.lightningBurstEnd = 0;
|
||||
@@ -94,6 +94,7 @@ export class OceanScene {
|
||||
|
||||
async init() {
|
||||
this.initRenderer();
|
||||
this.initStats();
|
||||
this.initScene();
|
||||
this.initCamera();
|
||||
this.initControls();
|
||||
@@ -123,6 +124,18 @@ export class OceanScene {
|
||||
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
||||
this.container.appendChild(this.renderer.domElement);
|
||||
}
|
||||
|
||||
initStats() {
|
||||
this.stats = new Stats();
|
||||
this.stats.showPanel(0);
|
||||
this.stats.dom.style.position = 'fixed';
|
||||
this.stats.dom.style.left = '0';
|
||||
this.stats.dom.style.top = '0';
|
||||
this.stats.dom.style.bottom = 'auto';
|
||||
this.stats.dom.style.margin = '0';
|
||||
this.stats.dom.style.zIndex = '120';
|
||||
this.container.appendChild(this.stats.dom);
|
||||
}
|
||||
|
||||
initScene() {
|
||||
this.scene = new THREE.Scene();
|
||||
@@ -1535,6 +1548,7 @@ export class OceanScene {
|
||||
|
||||
animate() {
|
||||
requestAnimationFrame(() => this.animate());
|
||||
this.stats?.begin();
|
||||
|
||||
const time = this.clock.getElapsedTime();
|
||||
this.updateLightning(time);
|
||||
@@ -1589,18 +1603,7 @@ export class OceanScene {
|
||||
} else {
|
||||
this.renderer.render(this.scene, this.camera);
|
||||
}
|
||||
|
||||
this.frameCount++;
|
||||
const currentTime = performance.now();
|
||||
if (currentTime - this.lastTime >= 1000) {
|
||||
const fps = Math.round(this.frameCount * 1000 / (currentTime - this.lastTime));
|
||||
const fpsElement = document.getElementById('fps');
|
||||
if (fpsElement) {
|
||||
fpsElement.textContent = fps;
|
||||
}
|
||||
this.frameCount = 0;
|
||||
this.lastTime = currentTime;
|
||||
}
|
||||
this.stats?.end();
|
||||
}
|
||||
|
||||
hideLoading() {
|
||||
|
||||
90
src/main.js
90
src/main.js
@@ -37,6 +37,89 @@ function setupControls(oceanScene) {
|
||||
gui.domElement.style.zIndex = '120';
|
||||
|
||||
const params = oceanScene.params;
|
||||
const presetKeys = [
|
||||
'elevation',
|
||||
'azimuth',
|
||||
'exposure',
|
||||
'turbidity',
|
||||
'rayleigh',
|
||||
'bloomStrength',
|
||||
'bloomRadius',
|
||||
'cloudCoverage',
|
||||
'cloudDensity',
|
||||
'cloudElevation',
|
||||
'fogDensity',
|
||||
'fogHeight',
|
||||
'fogRange',
|
||||
'rainEnabled',
|
||||
'rainScreenIntensity',
|
||||
'rainVeilIntensity',
|
||||
'rainDropSize',
|
||||
'rainSpeed',
|
||||
'rainAudioEnabled',
|
||||
'rainAudioVolume',
|
||||
'snowEnabled',
|
||||
'snowIntensity',
|
||||
'snowSpeed',
|
||||
'lightningEnabled',
|
||||
'lightningIntensity'
|
||||
];
|
||||
const presetComments = {
|
||||
elevation: '太阳高度角',
|
||||
azimuth: '太阳方位角',
|
||||
exposure: '场景曝光度',
|
||||
turbidity: '天空浑浊度',
|
||||
rayleigh: '瑞利散射强度',
|
||||
bloomStrength: '泛光强度',
|
||||
bloomRadius: '泛光扩散范围',
|
||||
cloudCoverage: '云层覆盖度',
|
||||
cloudDensity: '云层密度',
|
||||
cloudElevation: '云层高度',
|
||||
fogDensity: '雾气浓度',
|
||||
fogHeight: '雾气高度',
|
||||
fogRange: '雾气范围',
|
||||
rainEnabled: '是否启用雨效',
|
||||
rainScreenIntensity: '屏幕雨滴强度',
|
||||
rainVeilIntensity: '雨线强度',
|
||||
rainDropSize: '雨滴尺寸',
|
||||
rainSpeed: '雨效速度',
|
||||
rainAudioEnabled: '是否启用雨声',
|
||||
rainAudioVolume: '雨声音量',
|
||||
snowEnabled: '是否启用降雪',
|
||||
snowIntensity: '雪量',
|
||||
snowSpeed: '降雪速度',
|
||||
lightningEnabled: '是否启用雷闪',
|
||||
lightningIntensity: '雷闪强度'
|
||||
};
|
||||
|
||||
const exportActions = {
|
||||
导出预设: () => {
|
||||
const preset = {
|
||||
meta: {
|
||||
version: 1,
|
||||
comment: '场景预设导出文件',
|
||||
exportedAt: new Date().toISOString()
|
||||
},
|
||||
comments: Object.fromEntries(
|
||||
presetKeys.map((key) => [key, presetComments[key]])
|
||||
),
|
||||
params: Object.fromEntries(
|
||||
presetKeys.map((key) => [key, params[key]])
|
||||
)
|
||||
};
|
||||
|
||||
const blob = new Blob([JSON.stringify(preset, null, 2)], { type: 'application/json' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
const stamp = new Date().toISOString().replace(/[:.]/g, '-');
|
||||
link.href = url;
|
||||
link.download = `scene-preset-${stamp}.json`;
|
||||
link.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
};
|
||||
|
||||
gui.add(exportActions, '导出预设');
|
||||
|
||||
const skyFolder = gui.addFolder('天空');
|
||||
skyFolder.add(params, 'elevation', 0, 90, 0.1).name('太阳高度').onChange((value) => oceanScene.setSunElevation(value));
|
||||
@@ -46,8 +129,8 @@ function setupControls(oceanScene) {
|
||||
skyFolder.add(params, 'rayleigh', 0, 4, 0.01).name('瑞利散射').onChange((value) => oceanScene.setRayleigh(value));
|
||||
|
||||
const bloomFolder = gui.addFolder('泛光');
|
||||
bloomFolder.add(params, 'bloomStrength', 0, 3, 0.01).name('强度').onChange((value) => oceanScene.setBloomStrength(value));
|
||||
bloomFolder.add(params, 'bloomRadius', 0, 1, 0.01).name('扩散').onChange((value) => oceanScene.setBloomRadius(value));
|
||||
bloomFolder.add(params, 'bloomStrength', 0, 1, 0.01).name('强度').onChange((value) => oceanScene.setBloomStrength(value));
|
||||
bloomFolder.add(params, 'bloomRadius', 0, 3, 0.01).name('扩散').onChange((value) => oceanScene.setBloomRadius(value));
|
||||
|
||||
const cloudFolder = gui.addFolder('云层');
|
||||
cloudFolder.add(params, 'cloudCoverage', 0, 1, 0.01).name('覆盖度').onChange((value) => oceanScene.setCloudCoverage(value));
|
||||
@@ -75,8 +158,7 @@ function setupControls(oceanScene) {
|
||||
snowFolder.add(params, 'snowIntensity', 0, 1.5, 0.01).name('雪量').onChange((value) => oceanScene.setSnowIntensity(value));
|
||||
snowFolder.add(params, 'snowSpeed', 0.2, 2.2, 0.01).name('速度').onChange((value) => oceanScene.setSnowSpeed(value));
|
||||
|
||||
skyFolder.open();
|
||||
rainFolder.open();
|
||||
gui.close();
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
|
||||
Reference in New Issue
Block a user