import { Color, ShaderMaterial, UniformsLib, UniformsUtils } from 'three'; import { BaseTexture } from '../resource/texture'; export const vertex = /* glsl */ ` varying vec3 vViewPosition; varying vec2 vUv; #include #include #include #include #include #include #include #include #include #include #include #include #include void main() { vUv = uv; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include vViewPosition = - mvPosition.xyz; #include #include #include #include } `; export const fragment = /* glsl */ ` uniform vec3 emissive; uniform vec3 specular; uniform float shininess; uniform sampler2D baseT; uniform sampler2D maskT; uniform vec3 colorMask; varying vec2 vUv; #include #include #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 baseTex = texture2D(baseT, vUv); vec4 maskTex = texture2D(maskT, vUv); vec3 combine = mix(baseTex.rgb, colorMask, maskTex.r); vec4 diffuseColor = vec4( combine, 1.0 ); ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); vec3 totalEmissiveRadiance = emissive; #include #include #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 #include #include #include #include #include #include } `; let instance: PonyEyes; export class PonyEyes { private base!: BaseTexture; private mask!: BaseTexture; public shader!: ShaderMaterial; async initialize() { this.base = await BaseTexture.load('/assets/eyes/eye-base.png'); this.mask = await BaseTexture.load('/assets/eyes/eye-mask.png'); this.base.texture.flipY = false; this.mask.texture.flipY = false; this.shader = new ShaderMaterial({ vertexShader: vertex, fragmentShader: fragment, lights: true, uniforms: UniformsUtils.merge([ UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.fog, UniformsLib.lights, { baseT: { value: this.base.texture }, maskT: { value: this.mask.texture }, colorMask: { value: new Color(0xff0000) }, shininess: { value: 100 }, }, ]), }); } public getShader(): ShaderMaterial { return this.shader.clone(); } public setColor( shader: ShaderMaterial, color: number | string, ): ShaderMaterial { shader.uniforms.colorMask.value = new Color(color); return shader; } public static getInstance(): PonyEyes { if (!instance) { instance = new PonyEyes(); } return instance; } }