import { Color, DoubleSide, MeshStandardMaterial, RepeatWrapping, Texture, TextureLoader, type WebGLProgramParameters } from "three" import { useLoader, } from '@tresjs/core' import { getFilename, patterns, type patternIds, } from "~/components/pattern" import vertexShader from '../shaders/noise/vertex.vert?raw' import normalShader from '../shaders/noise/normal.frag?raw' import dithShader from '../shaders/noise/dith.frag?raw' import noiseShader from '../shaders/noise/pnoise.glsl?raw' const set_metaril_func = (scene: any, material: any) => { scene.children.forEach((el: any) => { if (el.isMesh) { el.castShadow = true el.receiveShadow = true } el.material = material set_metaril_func(el, material) }) } const loaded_patterns: { [key: string]: any } = {} for (let index = 0; index < patterns.length; index++) { const element = patterns[index]; const filename = getFilename(element.id) if (filename) { // @ts-ignore loaded_patterns[filename] = useLoader(TextureLoader, filename) } } Promise.all(Object.keys(loaded_patterns)) const noiseMaterial = new MeshStandardMaterial({ // alphaMap: pattern ? texture : null, transparent: true, opacity: 1, roughness: 0.2, metalness: 0, side: DoubleSide, }) const m_onBeforeCompile = (shader: WebGLProgramParameters) => { // Изменяем вершинный шейдер shader.vertexShader = ` varying vec3 vPosition; ${shader.vertexShader} `.replace( `#include `, `#include ${vertexShader} ` ); // Изменяем фрагментный шейдер shader.fragmentShader = ` varying vec3 vPosition; ${noiseShader} ${shader.fragmentShader}` .replace( '#include ', `#include ${normalShader} ` ) .replace( `#include `, `#include ${dithShader} ` ); }; export const set_material = ( scene: any, color: any, pattern: { pattern: patternIds, count: number } | undefined = undefined, noise_material: boolean = false, ) => { let c = color const material = noiseMaterial.clone() material.color = new Color(c || '#9c9c00') if (noise_material) { material.onBeforeCompile = m_onBeforeCompile } const promises = [] if (pattern && pattern.pattern !== undefined) { const filename = getFilename(pattern.pattern) if (filename) { const texture = loaded_patterns[filename] promises.push(texture) texture.then((res: Texture) => { res.wrapT = RepeatWrapping; res.repeat.set(1, pattern.count); res.needsUpdate = true material.alphaMap = res scene.renderOrder = 0 return res }) } } if (scene) set_metaril_func(scene, material) else console.log(scene) Promise.all(promises).then((values) => { if (scene) set_metaril_func(scene, material) else console.log(scene) }); }