light helper

This commit is contained in:
Kseninia Mikhaylova 2024-06-12 16:21:24 +03:00
parent 48065712de
commit c638a6e91e
10 changed files with 184 additions and 94 deletions

View File

@ -1,30 +1,71 @@
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'
import { OrbitControls, Environment } from '@tresjs/cientos'
import { OrbitControls, Environment, vLightHelper } from '@tresjs/cientos'
const controlsState = reactive({
minDistance: 5,
maxDistance: 15,
maxDistance: 12,
enablePan: false,
// enableZoom: false,
maxPolarAngle: (Math.PI / 2) - 0.2,
// maxZoom: 2,
// minZoom: 1,
})
const cameraStat = reactive({
position: [-4, 2, 8],
aspect: 1920 / 600,
fov: 40,
})
onMounted(() => {
cameraStat.aspect = window.innerWidth / 600
})
const spot = reactive({
x: 10, y: 10, z: 10, intensity: 100, distance: 10, color: 'red'
})
const directional = reactive({
x: 20, y: 10, z: 10, intensity: 100, distance: 10, color: 'green'
})
const point = reactive({
x: 30, y: 10, z: 10, intensity: 100, distance: 10, color: 'blue'
})
</script>
<template>
<div class="container min-w-full relative">
<Loader />
<TresCanvas shadows>
<TresPerspectiveCamera :position="[-4, 2, 8]" />
<OrbitControls v-bind="controlsState" make-default />
<Suspense>
<Environment files='/hdrmaps/kloppenheim_06_4k.hdr' :background="true" />
</Suspense>
<Suspense>
<ModelParametric />
</Suspense>
</TresCanvas>
<div>
<h2>spot</h2>
<template v-for="(label, key) in spot">
<label :for="key">{{ key }}</label>
<input :id="key" :type="key == 'color' ? 'text' : 'number'" v-model="spot[key]" style="width: 100px" />
</template>
<h2>directional</h2>
<template v-for="(label, key) in directional">
<label :for="key">{{ key }}</label>
<input :id="key" :type="key == 'color' ? 'text' : 'number'" v-model="directional[key]"
style="width: 100px" />
</template>
<h2>point</h2>
<template v-for="(label, key) in point">
<label :for="key">{{ key }}</label>
<input :id="key" :type="key == 'color' ? 'text' : 'number'" v-model="point[key]" style="width: 100px" />
</template>
</div>
<ClientOnly fallback-tag="div" fallback="Загрузка 3D модели">
<Loader />
<TresCanvas shadows>
<TresPerspectiveCamera v-bind="cameraStat" />
<OrbitControls v-bind="controlsState" make-default />
<Suspense>
<Environment files='/hdrmaps/kloppenheim_06_4k.hdr' :background="true" />
</Suspense>
<Suspense>
<ModelParametric />
</Suspense>
<TresSpotLight v-bind="spot" :position="[spot.x, spot.y, spot.z]" cast-shadow v-light-helper />
<TresDirectionalLight v-bind="directional" :position="[directional.x, directional.y, directional.z]" cast-shadow
v-light-helper />
<TresPointLight v-bind="point" :position="[point.x, point.y, point.z]" cast-shadow v-light-helper />
</TresCanvas>
</ClientOnly>
</div>
</template>

View File

@ -134,61 +134,64 @@ const toggleModal = () => {
</script>
<template>
<div class="container py-4">
<form class="form">
<div class="form-row">
<div class="form-item">
<label for="length">Длина секции, мм</label>
<Icon type="button" @click="increment('length', -1)" name="mdi:minus-circle-outline"
:class="auto_section_width ? `disabled` : ''" />
<input id="length" type="number" v-bind="parametric.length" v-model="form_state.length"
:disabled="auto_section_width" :ref="form_refs.length" />
<Icon type="button" @click="increment('length', 1)" name="mdi:plus-circle-outline"
:class="auto_section_width ? `disabled` : ''" />
<Icon name="mdi:calculator-variant" @click="autoSectionWidth" />
<ClientOnly fallback-tag="div" fallback="Загрузка 3D модели">
<form class="form">
<div class="form-row">
<div class="form-item">
<label for="length">Длина секции, мм</label>
<Icon type="button" @click="increment('length', -1)" name="mdi:minus-circle-outline"
:class="auto_section_width ? `disabled` : ''" />
<input id="length" type="number" v-bind="parametric.length" v-model="form_state.length"
:disabled="auto_section_width" :ref="form_refs.length" />
<Icon type="button" @click="increment('length', 1)" name="mdi:plus-circle-outline"
:class="auto_section_width ? `disabled` : ''" />
<Icon name="mdi:calculator-variant" @click="autoSectionWidth" />
</div>
<div class="form-item">
<label for="height">Высота забора, мм</label>
<Icon type="button" @click="increment('height', -1)" name="mdi:minus-circle-outline" />
<input id="height" type="number" v-bind="parametric.height" v-model="form_state.height"
:ref="form_refs.height" />
<Icon type="button" @click="increment('height', 1)" name="mdi:plus-circle-outline" />
</div>
</div>
<div class="form-item">
<label for="height">Высота забора, мм</label>
<Icon type="button" @click="increment('height', -1)" name="mdi:minus-circle-outline" />
<input id="height" type="number" v-bind="parametric.height" v-model="form_state.height"
:ref="form_refs.height" />
<Icon type="button" @click="increment('height', 1)" name="mdi:plus-circle-outline" />
<div class="form-row">
<div class="form-item">
<label for="lamelle_color">Цвет ламелей</label>
<input id="lamelle_color" type="text" v-model="lamelle_color" disabled />
<template v-for="item in predefLamelleColors">
<ColorPicker :color="item" :cb="setLamelleColor" :open="false"
:active="lamelle_color == item" />
</template>
<ColorPicker :cb="setLamelleColor" />
</div>
<div class="form-item">
<label for="pillar_color">Цвет столба</label>
<input id="pillar_color" type="text" v-model="pillar_color" disabled />
<template v-for="item in predefPillarColors">
<ColorPicker :color="item" :cb="setPillarColor" :open="false"
:active="pillar_color == item" />
</template>
<ColorPicker :cb="setPillarColor" />
</div>
</div>
</div>
<div class="form-row">
<div class="form-item">
<label for="lamelle_color">Цвет ламелей</label>
<input id="lamelle_color" type="text" v-model="lamelle_color" disabled />
<template v-for="item in predefLamelleColors">
<ColorPicker :color="item" :cb="setLamelleColor" :open="false"
:active="lamelle_color == item" />
</template>
<ColorPicker :cb="setLamelleColor" />
<div class="form-row">
<div class="form-item">
<label for="total_length">Общая длина забора, м</label>
<Icon type="button" @click="increment('total_length', -1)" name="mdi:minus-circle-outline" />
<input type="number" id="total_length" v-bind="parametric.total_length"
v-model="form_state.total_length" :ref="form_refs.total_length" />
<Icon type="button" @click="increment('total_length', 1)" name="mdi:plus-circle-outline" />
</div>
<div class="form-item grow">
<label for="calculation">Приблизительный расчет забора</label>
<textarea id="calculation" disabled class="w-full">{{ calc_text }}</textarea>
</div>
</div>
<div class="form-item">
<label for="pillar_color">Цвет столба</label>
<input id="pillar_color" type="text" v-model="pillar_color" disabled />
<template v-for="item in predefPillarColors">
<ColorPicker :color="item" :cb="setPillarColor" :open="false" :active="pillar_color == item" />
</template>
<ColorPicker :cb="setPillarColor" />
<div class="form-row justify-center">
<button @click.prevent="toggleModal">Купить прямо сейчас</button>
</div>
</div>
<div class="form-row">
<div class="form-item">
<label for="total_length">Общая длина забора, м</label>
<Icon type="button" @click="increment('total_length', -1)" name="mdi:minus-circle-outline" />
<input type="number" id="total_length" v-bind="parametric.total_length"
v-model="form_state.total_length" :ref="form_refs.total_length" />
<Icon type="button" @click="increment('total_length', 1)" name="mdi:plus-circle-outline" />
</div>
<div class="form-item grow">
<label for="calculation">Приблизительный расчет забора</label>
<textarea id="calculation" disabled class="w-full">{{ calc_text }}</textarea>
</div>
</div>
<div class="form-row justify-center">
<button @click.prevent="toggleModal">Купить прямо сейчас</button>
</div>
</form>
</form>
</ClientOnly>
</div>
</template>

View File

@ -36,24 +36,26 @@ const targetExplosion = useState('targetExplosion', () => {
</script>
<template>
<div class="container min-w-full" ref="container">
<template v-for="(value, key) in targetExplosion" v-if="false">
<div>
<label for="key">{{ key }}</label>
<input type="number" v-for="(item, n) in value" v-model="targetExplosion[key][n]" step="0.25">
</div>
</template>
<TresCanvas preset="realistic">
<TresPerspectiveCamera :position="[-7, 2, 4]" />
<OrbitControls v-bind="controlsState" make-default />
<Suspense>
<Environment files='/hdrmaps/kiara_1_dawn_4k.hdr' :background="false" />
</Suspense>
<ModelDiagram />
<ClientOnly fallback-tag="div" fallback="Загрузка 3D модели">
<template v-for="(value, key) in targetExplosion" v-if="false">
<div>
<label for="key">{{ key }}</label>
<input type="number" v-for="(item, n) in value" v-model="targetExplosion[key][n]" step="0.25">
</div>
</template>
<TresCanvas preset="realistic">
<TresPerspectiveCamera :position="[-7, 2, 4]" />
<OrbitControls v-bind="controlsState" make-default />
<Suspense>
<Environment files='/hdrmaps/kiara_1_dawn_4k.hdr' :background="false" />
</Suspense>
<ModelDiagram />
<TresDirectionalLight :position="[2, 2, 2]" :intensity="2" color="#f2f2f2" cast-shadow />
<TresDirectionalLight :position="[2, 2, -2]" :intensity="1" color="#f2f2f2" cast-shadow />
<TresAmbientLight />
</TresCanvas>
<TresDirectionalLight :position="[2, 2, 2]" :intensity="2" color="#f2f2f2" cast-shadow />
<TresDirectionalLight :position="[2, 2, -2]" :intensity="1" color="#f2f2f2" cast-shadow />
<TresAmbientLight />
</TresCanvas>
</ClientOnly>
</div>
</template>

View File

@ -66,9 +66,9 @@ watch(fence_section, () => {
</TresGroup>
</TresGroup>
<TresGroup name="lamelles" :position-x="pillar_size * 0.5" :position-z="0.02">
<TresGroup name="lamelles">
<template v-for="(n, i) in lamelles_count">
<TresGroup :position-y="(lSize * i)" :scale-x="fence_section * 10">
<TresGroup :position="[pillar_size * 0.5, (lSize * i), 0.02]" :scale-x="fence_section * 10">
<ModelItem :model="props.models.lamelle" :color="lamelle_color" />
</TresGroup>
</template>

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import { ReinhardToneMapping, PCFShadowMap, RepeatWrapping } from 'three';
import { ReinhardToneMapping, PCFShadowMap, RepeatWrapping, Color, DataTexture, RGBAFormat } from 'three';
import { useTexture } from '@tresjs/core'
import { useGLTF } from '@tresjs/cientos'
const section_count = useState('section_count')
@ -11,16 +11,16 @@ renderer.value.shadowMap.enabled = true
renderer.value.shadowMap.type = PCFShadowMap
const pbrTexture = await useTexture({
map: '/texture/Ground039_4K-JPG_Color.jpg',
displacementMap: '/texture/Ground039_4K-JPG_Displacement.jpg',
roughnessMap: '/texture/Ground039_4K-JPG_Roughness.jpg',
normalMap: '/texture/Ground039_4K-JPG_NormalGL.jpg',
aoMap: '/texture/Ground039_4K-JPG_AmbientOcclusion.jpg',
metalnessMap: '/texture/Ground039_4K-JPG_Color.jpg',
map: '/texture/Grass001_4K-JPG/Grass001_4K-JPG_Color.jpg',
// displacementMap: '/texture/Ground039_4K-JPG_Displacement.jpg',
roughnessMap: '/texture/Grass001_4K-JPG/Grass001_4K-JPG_Roughness.jpg',
normalMap: '/texture/Grass001_4K-JPG/Grass001_4K-JPG_NormalGL.jpg',
aoMap: '/texture/Grass001_4K-JPG/Grass001_4K-JPG_AmbientOcclusion.jpg',
// metalnessMap: '/texture/Ground039_4K-JPG_Color.jpg',
// matcap: '/textures/Ground039_4K-JPG_Color.jpg',
// alphaMap: '/textures/myAlphaMapTexture.jpg'
})
const repeat = 5
const repeat = 10
for (const key in pbrTexture) {
if (Object.prototype.hasOwnProperty.call(pbrTexture, key)) {
const element = pbrTexture[key];
@ -51,12 +51,56 @@ watch(section_count, () => {
}
}
})
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;
</script>
<template>
<TresGroup :translate-y="-3.25" name="base">
<TresMesh receive-shadow :translate-y="-0.5" name="ground">
<TresMesh receive-shadow :position-y="-0.5" name="ground">
<TresCircleGeometry :args="[55, 32]" :rotate-x="-Math.PI * 0.5" />
<TresMeshStandardMaterial v-bind="pbrTexture" :metalness="1" :roughness="0.8" :opacity="0.5" />
<TresMeshStandardMaterial v-bind="pbrTexture" />
</TresMesh>
<TresMesh receive-shadow :position-y="-0.25" :position-x="10" name="ground">
<TresCircleGeometry :args="[10]" :rotate-x="-Math.PI * 0.5" />
<TresMeshStandardMaterial color="#eee" />
</TresMesh>
<TresMesh receive-shadow name="ground_test" :position-z="-10">
<TresCircleGeometry :args="[5]" :rotate-x="-Math.PI * 0.5" />
<TresMeshStandardMaterial :map="texture_one" />
</TresMesh>
<TresMesh receive-shadow name="ground_test" :position-z="10">
<TresCircleGeometry :args="[5]" :rotate-x="-Math.PI * 0.5" />
<TresMeshStandardMaterial :map="texture" />
</TresMesh>
<TresMesh :position="[-9, 0, 2]" cast-shadow receive-shadow>
<TresBoxGeometry :args="[1, 1, 1]" />
<TresMeshStandardMaterial :map="texture_one" />
</TresMesh>
<template v-for="i in section_count">
<template v-if="i <= 20">

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 MiB