From a3687808ea22ec7bb51873974cb2ec6dd23ec552 Mon Sep 17 00:00:00 2001 From: Kseninia Mikhaylova Date: Thu, 26 Sep 2024 14:52:27 +0300 Subject: [PATCH] texture scaling --- components/model/fence.vue | 4 +++ utils/material.ts | 56 +++++++++++++++++++++++++++++--------- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/components/model/fence.vue b/components/model/fence.vue index 9ff3eed..e48a4a1 100644 --- a/components/model/fence.vue +++ b/components/model/fence.vue @@ -183,5 +183,9 @@ watch([instanced_lamelle, lamelle_color], setLamellesColor) + + + + \ No newline at end of file diff --git a/utils/material.ts b/utils/material.ts index 2be14d3..2ca8880 100644 --- a/utils/material.ts +++ b/utils/material.ts @@ -2,12 +2,42 @@ import { Color, DataTexture, DoubleSide, MeshBasicMaterial, MeshStandardMaterial import { useLoader, type TresLoader } from '@tresjs/core' import { getFilename, patterns, type patternTypes } from "~/components/pattern" + const set_metaril_func = (scene: any, material: any) => { scene.children.forEach((el: any) => { if (el.isMesh && !el.isInstancedMesh) { el.castShadow = true el.receiveShadow = true } + + if (el.material) { + // Получите UV-координаты + const uvAttribute = el.geometry.getAttribute('uv'); + const uvs = []; + + for (let i = 0; i < uvAttribute.count; i++) { + uvs.push(uvAttribute.getX(i), uvAttribute.getY(i)); + } + + // Вычисление минимальных и максимальных UV + const minU = Math.min(...uvs.filter((_, index) => index % 2 === 0)); // X координаты + const maxU = Math.max(...uvs.filter((_, index) => index % 2 === 0)); + const minV = Math.min(...uvs.filter((_, index) => index % 2 === 1)); // Y координаты + const maxV = Math.max(...uvs.filter((_, index) => index % 2 === 1)); + + // Определите размеры текстуры на поверхности + const surfaceWidth = maxU - minU; + const surfaceHeight = (maxV - minV) * el.scale.y; + + material.normalMap.wrapS = RepeatWrapping; + material.normalMap.wrapT = RepeatWrapping; + material.normalMap.repeat.set(surfaceWidth, surfaceHeight); + material.normalMap.needsUpdate = true + + console.log(`Ширина текстуры на поверхности: ${surfaceWidth * 128}`); + console.log(`Высота текстуры на поверхности: ${surfaceHeight * 128}`); + } + if (el.material) el.material = material set_metaril_func(el, material) }) @@ -23,23 +53,23 @@ for (let index = 0; index < patterns.length; index++) { } function generateNoiseTexture(width: number, height: number) { const size = width * height; - const data = new Uint8Array( 4 * size ); - const color = new Color( 0xffffff ); - - for ( let i = 0; i < size; i ++ ) { - const r = Math.floor( Math.random() * 255 ); + const data = new Uint8Array(4 * size); + const color = new Color(0xffffff); + + for (let i = 0; i < size; i++) { + const r = Math.floor(Math.random() * 255); const g = 0; - const b = Math.floor( Math.random() * 255 ); - + const b = Math.floor(Math.random() * 255); + const stride = i * 4; - data[ stride ] = r; - data[ stride + 1 ] = g; - data[ stride + 2 ] = b; - data[ stride + 3 ] = 255; + data[stride] = r; + data[stride + 1] = g; + data[stride + 2] = b; + data[stride + 3] = 255; } - + // used the buffer to create a DataTexture - const texture = new DataTexture( data, width, height ); + const texture = new DataTexture(data, width, height); texture.needsUpdate = true; return texture; }