171 lines
6.6 KiB
Vue
171 lines
6.6 KiB
Vue
<script setup lang="ts">
|
|
import {
|
|
ReinhardToneMapping, PCFSoftShadowMap, RepeatWrapping,
|
|
Color, DataTexture,
|
|
PMREMGenerator, Euler,
|
|
FrontSide
|
|
} from 'three';
|
|
import { EXRLoader } from 'three/examples/jsm/Addons.js';
|
|
import { useTexture } from '@tresjs/core'
|
|
import { useGLTF, vLightHelper } from '@tresjs/cientos'
|
|
const section_count = useState('section_count')
|
|
|
|
const { scene, renderer, camera } = useTresContext()
|
|
renderer.value.toneMapping = ReinhardToneMapping
|
|
|
|
renderer.value.shadowMap.enabled = true
|
|
// renderer.value.shadowMap.type = PCFSoftShadowMap
|
|
|
|
// const pbrTexture = await useTexture({
|
|
// map: '/texture/Grass01_MR_2K/Grass01_2K_BaseColor.png ',
|
|
// displacementMap: '/texture/Grass01_MR_2K/Grass01_2K_Height.png ',
|
|
// roughnessMap: '/texture/Grass01_MR_2K/Grass01_2K_Roughness.png',
|
|
// normalMap: '/texture/Grass01_MR_2K/Grass01_2K_Normal.png ',
|
|
// aoMap: '/texture/Grass01_MR_2K/Grass01_2K_AO.png ',
|
|
// // metalnessMap: '/texture/Ground039_4K-JPG_Color.jpg',
|
|
// // matcap: '/textures/Ground039_4K-JPG_Color.jpg',
|
|
// // alphaMap: '/textures/myAlphaMapTexture.jpg'
|
|
// })
|
|
const pbrTexture = await useTexture({
|
|
map: '/texture/Grass004_2K-PNG/Grass004_2K-PNG_Color.png',
|
|
displacementMap: '/texture/Grass004_2K-PNG/Grass004_2K-PNG_Displacement.png',
|
|
roughnessMap: '/texture/Grass004_2K-PNG/Grass004_2K-PNG_Roughness.png',
|
|
normalMap: '/texture/Grass004_2K-PNG/Grass004_2K-PNG_NormalDX.png',
|
|
aoMap: '/texture/Grass004_2K-PNG/Grass004_2K-PNG_AmbientOcclusion.png',
|
|
})
|
|
const groundMaterial = {
|
|
map: pbrTexture.map,
|
|
displacementMap: pbrTexture.displacementMap,
|
|
normalMap: pbrTexture.normalMap,
|
|
color: "#555",
|
|
roughness: 0.25,
|
|
metalness: 0,
|
|
side: FrontSide
|
|
}
|
|
const repeat = 10
|
|
for (const key in pbrTexture) {
|
|
if (Object.prototype.hasOwnProperty.call(pbrTexture, key)) {
|
|
const key_p = key as keyof typeof pbrTexture
|
|
const element = pbrTexture[key_p]
|
|
if (element && element.wrapS) {
|
|
element.wrapS = RepeatWrapping
|
|
element.wrapT = RepeatWrapping
|
|
element.repeat.x = repeat
|
|
element.repeat.y = repeat
|
|
element.flipY = false
|
|
}
|
|
}
|
|
}
|
|
const { scene: top } = await useGLTF('/models_one/verh_100.glb')
|
|
const { scene: fence } = await useGLTF('/models_one/fence.glb')
|
|
const { scene: fastening } = await useGLTF('/models_one/krepleniye_planok (1).glb')
|
|
const { scene: lamelle } = await useGLTF('/models_one/lamel_100.glb')
|
|
const { scene: light } = await useGLTF('/models_light/zabor_so_svetom.glb')
|
|
|
|
const { seek, seekAll } = useSeek()
|
|
watch(section_count, () => {
|
|
const fences = seekAll(scene.value, 'name', 'fence')
|
|
const base = seek(scene.value, 'name', 'base')
|
|
const n = (section_count.value as number)
|
|
if (fences.length > n) {
|
|
for (let i = fences.length; i > n; i--) {
|
|
const item = fences[i - 1]
|
|
if (item) {
|
|
base?.remove(item)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
const width = 512;
|
|
const height = 512;
|
|
const size = width * height;
|
|
const data = new Uint8Array(4 * size);
|
|
const color = new Color(0xffffff);
|
|
const r = Math.floor(color.r * 25);
|
|
const g = Math.floor(color.g * 25);
|
|
const b = Math.floor(color.b * 255);
|
|
for (let i = 0; i < size; i++) {
|
|
const stride = i * 4;
|
|
data[stride] = r;
|
|
data[stride + 1] = g;
|
|
data[stride + 2] = b;
|
|
data[stride + 3] = 255;
|
|
}
|
|
const texture_one = new DataTexture(data, width, height);
|
|
texture_one.needsUpdate = true;
|
|
|
|
const canvas = document.createElement('canvas')
|
|
canvas.width = 512
|
|
canvas.height = 512
|
|
const ctx = canvas.getContext('2d')
|
|
ctx.fillStyle = "red"
|
|
ctx.fillRect(10, 10, 512, 512)
|
|
// console.log(canvas.toDataURL())
|
|
const texture = new DataTexture(ctx?.getImageData(0, 0, 512, 512).data.buffer, width, height);
|
|
texture.needsUpdate = true;
|
|
|
|
const pmremGenerator = new PMREMGenerator(renderer.value);
|
|
pmremGenerator.compileEquirectangularShader();
|
|
onMounted(() => {
|
|
new EXRLoader()
|
|
.load('/hdrmaps/kloppenheim_06_4k.exr', function (texture) {
|
|
const exrCubeRenderTarget = pmremGenerator.fromEquirectangular(texture);
|
|
const exrBackground = exrCubeRenderTarget.texture;
|
|
const newEnvMap = exrCubeRenderTarget ? exrCubeRenderTarget.texture : null;
|
|
|
|
scene.value.environment = newEnvMap
|
|
scene.value.background = exrBackground
|
|
scene.value.backgroundRotation = new Euler(0, 5, 0)
|
|
texture.dispose();
|
|
});
|
|
})
|
|
|
|
const pointLight = light.children[2]
|
|
pointLight.color = '#f0dea9'
|
|
pointLight.shadow.camera.near = 50
|
|
const k = 1
|
|
pointLight.shadow.mapSize.width = 512 * k
|
|
pointLight.shadow.mapSize.height = 512 * k
|
|
pointLight.shadow.bias = -0.001
|
|
</script>
|
|
<template>
|
|
<TresGroup :translate-y="-3.25" name="base">
|
|
<TresMesh receive-shadow :position-y="-0.65" name="ground">
|
|
<TresCircleGeometry :args="[100, 32]" :rotate-x="-Math.PI * 0.5" />
|
|
<TresMeshStandardMaterial v-bind="groundMaterial" />
|
|
</TresMesh>
|
|
<TresMesh receive-shadow :position-y="-0.25" :position-x="10" name="ground" v-if="false">
|
|
<TresCircleGeometry :args="[10]" :rotate-x="-Math.PI * 0.5" />
|
|
<TresMeshStandardMaterial color="#eee" />
|
|
</TresMesh>
|
|
<TresMesh receive-shadow name="ground_test" :position-z="-10" v-if="false">
|
|
<TresCircleGeometry :args="[5]" :rotate-x="-Math.PI * 0.5" />
|
|
<TresMeshStandardMaterial :map="texture_one" />
|
|
</TresMesh>
|
|
<TresMesh receive-shadow name="ground_test" :position-z="10" v-if="false">
|
|
<TresCircleGeometry :args="[5]" :rotate-x="-Math.PI * 0.5" />
|
|
<TresMeshStandardMaterial :map="texture" />
|
|
</TresMesh>
|
|
<TresMesh :position="Object.values(pointLight.position).map((el: any) => el * 2.5)" cast-shadow receive-shadow>
|
|
<TresBoxGeometry :args="[1, 1, 1]" />
|
|
<TresMeshStandardMaterial :map="texture_one" />
|
|
</TresMesh>
|
|
|
|
<TresPointLight v-bind="pointLight" :intensity="pointLight.intensity * 0.25"
|
|
:position="Object.values(pointLight.position).map((el: any) => el * 3)" cast-shadow />
|
|
|
|
<TresAmbientLight color="rgb(191,231,255)" :intensity="5" />
|
|
<template v-if="false">
|
|
<template v-for="i in light.children[1].children">
|
|
<TresDirectionalLight :position="i.position" :intensity="5" color="rgb(191,231,255)" cast-shadow />
|
|
</template>
|
|
</template>
|
|
|
|
<template v-for="i in section_count">
|
|
<template v-if="i <= 20">
|
|
<ModelFence :index="i" :models="{ top, fence, fastening, lamelle }" />
|
|
</template>
|
|
</template>
|
|
</TresGroup>
|
|
</template> |