import { ShaderMaterial, TextureLoader, UniformsLib } from 'three' const vertexShader = ` #define PHONG varying vec3 vViewPosition; #ifndef FLAT_SHADED varying vec3 vNormal; #endif #include #include #include #include #include #include #include #include #include #include #include #include void main() { #include #include #include #include #include #include #include #include #ifndef FLAT_SHADED // Normal computed with derivatives when FLAT_SHADED vNormal = normalize( transformedNormal ); #endif #include #include #include #include #include #include #include vViewPosition = - mvPosition.xyz; #include #include #include #include } ` const fragmentShader = ` #define PHONG #ifndef FLAT_SHADED varying vec3 vNormal; #endif uniform vec3 diffuse; uniform vec3 emissive; uniform vec3 specular; uniform float shininess; uniform float opacity; // ####### custom uniforms ######### uniform sampler2D mapNW; uniform sampler2D mapSW; uniform sampler2D mapNE; uniform sampler2D mapSE; // ################################# #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void main() { #include vec4 diffuseColor = vec4( diffuse, opacity ); ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); vec3 totalEmissiveRadiance = emissive; #include #ifdef USE_MAP vec4 colorSW = mix(mix(texture2D(mapSW, vUv * 2.), vec4(0.), step(0.5, vUv.x)), vec4(0.), step(0.5, vUv.y)); vec4 colorNW = mix(mix(texture2D(mapNW, vUv * 2. + vec2(0., -1.)), vec4(0.), step(0.5, vUv.x)), vec4(0.), 1. - step(0.5, vUv.y)); vec4 colorSE = mix(mix(texture2D(mapSE, vUv * 2. + vec2(-1., 0.)), vec4(0.), 1. - step(0.5, vUv.x)), vec4(0.), step(0.5, vUv.y)); vec4 colorNE = mix(mix(texture2D(mapNE, vUv * 2. + vec2(-1., -1.)), vec4(0.), 1. - step(0.5, vUv.x)), vec4(0.), 1. - step(0.5, vUv.y)); // texelColor = mapTexelToLinear(texelColor); diffuseColor *= colorSW + colorNW + colorNE + colorSE; #endif #include #include #include #include #include #include #include // accumulation #include #include #include #include // modulation #include vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance; #include gl_FragColor = vec4( outgoingLight, diffuseColor.a ); #include #include #include #include #include } ` const loader = new TextureLoader() export type QuadTextureMaterialOptions = { lights: boolean wireframe: boolean fog: boolean } export const defaultTextureOptions: QuadTextureMaterialOptions = { lights: true, wireframe: false, fog: true } export const QuadTextureMaterial = ( urls: string[], options: Partial = {} ) => { return Promise.all(urls.map((url) => loader.loadAsync(url))).then((maps) => { const opts = { uniforms: { mapNW: { value: maps[0] }, mapSW: { value: maps[1] }, mapNE: { value: maps[2] }, mapSE: { value: maps[3] }, ...UniformsLib.common, ...UniformsLib.lights, ...UniformsLib.fog }, vertexShader, fragmentShader, defines: { USE_MAP: true, USE_UV: true } } return new ShaderMaterial({ ...opts, ...Object.assign(defaultTextureOptions, options) }) }) }