feat(LOD): 增加两个LOD的应用案例

This commit is contained in:
zhangjingshi 2024-12-15 12:29:35 +08:00
parent ceb4af3752
commit 5a77615ecd
7 changed files with 227 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,36 @@
<template>
<TresLOD ref="lodRef">
<TresMesh ref="mesh1Ref">
<TresSphereGeometry :args="[2, 36, 36]" />
<TresMeshStandardMaterial color="#ff0000" wireframe />
</TresMesh>
<TresMesh ref="mesh2Ref">
<TresSphereGeometry :args="[2, 12, 12]" />
<TresMeshStandardMaterial color="#00ff00" wireframe />
</TresMesh>
<TresMesh ref="mesh3Ref">
<TresSphereGeometry :args="[2, 4, 4]" />
<TresMeshStandardMaterial color="#0000ff" wireframe />
</TresMesh>
</TresLOD>
</template>
<script setup lang="ts">
import { LOD, Mesh } from 'three'
import { shallowRef, watch } from 'vue'
const lodRef = shallowRef<LOD>()
const mesh1Ref = shallowRef<InstanceType<typeof Mesh>>()
const mesh2Ref = shallowRef<InstanceType<typeof Mesh>>()
const mesh3Ref = shallowRef<InstanceType<typeof Mesh>>()
watch([mesh1Ref, mesh2Ref, mesh3Ref], () => {
if (mesh1Ref.value && mesh2Ref.value && mesh3Ref.value) {
lodRef.value?.addLevel(mesh1Ref.value, 0)
lodRef.value?.addLevel(mesh2Ref.value, 10)
lodRef.value?.addLevel(mesh3Ref.value, 20)
}
})
</script>

View File

@ -0,0 +1,50 @@
<template>
<TresLOD ref="lodRef" :autoUpdate="false">
<TresMesh ref="mesh1Ref">
<TresSphereGeometry :args="[2, 36, 36]" />
<TresMeshStandardMaterial color="#ff0000" wireframe />
</TresMesh>
<TresMesh ref="mesh2Ref">
<TresSphereGeometry :args="[2, 12, 12]" />
<TresMeshStandardMaterial color="#00ff00" wireframe />
</TresMesh>
<TresMesh ref="mesh3Ref">
<TresSphereGeometry :args="[2, 4, 4]" />
<TresMeshStandardMaterial color="#0000ff" wireframe />
</TresMesh>
</TresLOD>
</template>
<script setup lang="ts">
import { useTresContext } from '@tresjs/core'
import { LOD, Mesh } from 'three'
import { shallowRef, watch } from 'vue'
const lodRef = shallowRef<InstanceType<typeof LOD>>()
const mesh1Ref = shallowRef<InstanceType<typeof Mesh>>()
const mesh2Ref = shallowRef<InstanceType<typeof Mesh>>()
const mesh3Ref = shallowRef<InstanceType<typeof Mesh>>()
watch([mesh1Ref, mesh2Ref, mesh3Ref], () => {
if (mesh1Ref.value && mesh2Ref.value && mesh3Ref.value) {
lodRef.value?.addLevel(mesh1Ref.value, 0)
lodRef.value?.addLevel(mesh2Ref.value, 10)
lodRef.value?.addLevel(mesh3Ref.value, 20)
updateLOD()
}
})
const { camera } = useTresContext()
const updateLOD = () => {
if (camera.value) lodRef.value?.update(camera.value)
}
const getLevel = () => {
return lodRef.value?.getCurrentLevel()
}
defineExpose({ updateLOD, getLevel })
</script>

14
src/plugins/lod/config.js Normal file
View File

@ -0,0 +1,14 @@
export default {
"name": "lod",
"title": "LOD",
"intro": "LOD的应用",
"version": "0.0.1",
"author": "石头web",
"website": "icegl.cn",
"state": "active",
"require": [],
"preview": [
{ "src": "plugins/lod/preview/basicLod.png", "type": "img", "name": "basicLod", "title": "基础LOD" },
{ "src": "plugins/lod/preview/manualLod.png", "type": "img", "name": "manualLod", "title": "手动LOD" },
]
}

View File

@ -0,0 +1,41 @@
<template>
<TresCanvas clearColor="#201919" v-bind="state">
<TresPerspectiveCamera :fov="60" :near="0.1" :far="2000" :position="[0, 0, 200]" :look-at="[0, 0, 0]" />
<TresAmbientLight :intensity="2" />
<OrbitControls v-bind="controlsState" />
<Suspense>
<SphereWithLOD :position="[10, 0, 0]" />
</Suspense>
<Suspense>
<SphereWithLOD :position="[0, 0, 0]" />
</Suspense>
<Suspense>
<SphereWithLOD :position="[-10, 0, 0]" />
</Suspense>
<TresGridHelper :args="[50, 50]" :position="[0, -5, 0]" />
</TresCanvas>
</template>
<script setup lang="ts">
import { reactive } from 'vue'
import { OrbitControls } from '@tresjs/cientos'
import SphereWithLOD from '../components/SphereWithLOD.vue'
const state = reactive({
windowSize: true,
alpha: true,
antialias: true,
autoClear: false,
disableRender: true,
})
const controlsState = reactive({
enableDamping: true,
enableZoom: true,
enablePan: true,
enableRotate: true,
makeDefault: true,
})
</script>
<style></style>

View File

@ -0,0 +1,86 @@
<template>
<TresCanvas v-bind="state">
<TresPerspectiveCamera ref="cameraRef" :fov="60" :near="0.1" :far="2000" :position="[0, 0, 25]" :look-at="[0, 0, 0]" />
<TresAmbientLight :intensity="2" />
<Suspense>
<SphereWithManualLOD ref="sphereRef" />
</Suspense>
<OrbitControls v-bind="controlsState" />
</TresCanvas>
</template>
<script setup lang="ts">
import { reactive, shallowRef } from 'vue'
import { OrbitControls } from '@tresjs/cientos'
import SphereWithManualLOD from '../components/SphereWithManualLOD.vue'
import { Pane, TextBladeApi } from 'tweakpane'
import { PerspectiveCamera } from 'three'
const sphereRef = shallowRef<InstanceType<typeof SphereWithManualLOD>>()
const cameraRef = shallowRef<InstanceType<typeof PerspectiveCamera>>()
const panel = new Pane()
panel.addButton({ title: '更新LOD' }).on('click', () => {
sphereRef.value?.updateLOD()
})
const levelBinding = panel.addBlade({
view: 'text',
label: 'LOD级别',
parse: (v: any) => String(v),
value: '0',
}) as TextBladeApi<string | undefined | number>
panel.addButton({ title: '获取LOD级别' }).on('click', () => {
if (sphereRef.value) {
const level = sphereRef.value.getLevel()
levelBinding.value = level
}
})
const state = reactive({
windowSize: true,
alpha: true,
antialias: true,
autoClear: false,
disableRender: true,
})
const controlsState = reactive({
enableDamping: true,
enableZoom: true,
enablePan: true,
enableRotate: true,
makeDefault: true,
})
</script>
<style scoped>
.control-panel {
position: fixed;
top: 20px;
right: 20px;
background: rgba(0, 0, 0, 0.7);
padding: 20px;
border-radius: 8px;
color: white;
}
.slider-container {
margin-bottom: 10px;
}
button {
padding: 8px 16px;
background: #4caf50;
border: none;
border-radius: 4px;
color: white;
cursor: pointer;
}
button:hover {
background: #45a049;
}
</style>