import { type patternIds } from './../components/pattern'; import { Color, DataTexture, DoubleSide, MeshBasicMaterial, MeshStandardMaterial, RepeatWrapping, RGBFormat, ShaderMaterial, Texture, TextureLoader, Vector2 } from "three" import { useLoader, } from '@tresjs/core' import { NodeToyMaterial } from '@nodetoy/three-nodetoy'; import { data } from './shaderData.ts'; import { getFilename, patterns, } from "~/components/pattern" 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) { loaded_patterns[filename] = useLoader(TextureLoader, filename) } } Promise.all(Object.keys(loaded_patterns)) function generateNoiseTexture(width: number, height: number) { const size = width * height; const data = new Uint8Array(4 * size); for (let i = 0; i < size; i++) { const r = Math.floor(Math.random() * 255) * 0.05; const g = 0; const b = Math.floor(Math.random() * 255) * 0.05; const stride = i * 4; 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); texture.needsUpdate = true; return texture; } const m_onBeforeCompile = (shader) => { // Добавляем uniform переменную shader.uniforms.u_resolution = { value: new Vector2(20.0, 20.0) }; // Изменяем вершинный шейдер shader.vertexShader = ` ${shader.vertexShader} `.replace( `#include `, `#include ` ); // Изменяем фрагментный шейдер shader.fragmentShader = ` uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; float random (in float x) { return fract(sin(x)*1e4); } // Based on Morgan McGuire @morgan3d // https://www.shadertoy.com/view/4dS3Wd float noise (in vec3 p) { const vec3 step = vec3(110.0, 241.0, 171.0); vec3 i = floor(p); vec3 f = fract(p); // For performance, compute the base input to a // 1D random from the integer part of the // argument and the incremental change to the // 1D based on the 3D -> 1D wrapping float n = dot(i, step); vec3 u = f * f * (3.0 - 2.0 * f); return mix( mix(mix(random(n + dot(step, vec3(0,0,0))), random(n + dot(step, vec3(1,0,0))), u.x), mix(random(n + dot(step, vec3(0,1,0))), random(n + dot(step, vec3(1,1,0))), u.x), u.y), mix(mix(random(n + dot(step, vec3(0,0,1))), random(n + dot(step, vec3(1,0,1))), u.x), mix(random(n + dot(step, vec3(0,1,1))), random(n + dot(step, vec3(1,1,1))), u.x), u.y), u.z); } ${shader.fragmentShader}` .replace( '#include ', ` #include // vec2 normal_st = gl_FragCoord.xy/vec2(u_resolution); vec2 normal_st = gl_PointCoord.xy/vec2(u_resolution); vec3 normal_pos = vec3(normal_st*5.0,1.0*0.5); vec3 normal_noise = vec3(noise(normal_pos)); vec3 modifiedNormal = normalize(normal + normal_noise); normal = modifiedNormal; ` ) .replace( `#include `, `#include vec2 st = gl_FragCoord.xy/vec2(u_resolution); vec3 pos = vec3(st*5.0,1.0*0.5); vec3 color = vec3(noise(pos)); gl_FragColor = vec4(normal,1.0); ` ); }; const m = new MeshStandardMaterial({ // alphaMap: pattern ? texture : null, transparent: true, opacity: 1, roughness: 0.5, metalness: 0, side: DoubleSide, }) export const set_material = (scene: any, color: any, pattern: { pattern: patternIds, count: number } | undefined = undefined) => { let c = color const material = m.clone() material.color = new Color(c || '#9c9c00') 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 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) }); }