UNPKG

@react-three/drei

Version:

useful add-ons for react-three-fiber

257 lines (241 loc) 7.19 kB
import { MeshStandardMaterial } from 'three'; class MeshReflectorMaterial extends MeshStandardMaterial { constructor(parameters = {}) { super(parameters); this._tDepth = { value: null }; this._distortionMap = { value: null }; this._tDiffuse = { value: null }; this._tDiffuseBlur = { value: null }; this._textureMatrix = { value: null }; this._hasBlur = { value: false }; this._mirror = { value: 0.0 }; this._mixBlur = { value: 0.0 }; this._blurStrength = { value: 0.5 }; this._minDepthThreshold = { value: 0.9 }; this._maxDepthThreshold = { value: 1 }; this._depthScale = { value: 0 }; this._depthToBlurRatioBias = { value: 0.25 }; this._distortion = { value: 1 }; this._mixContrast = { value: 1.0 }; this.setValues(parameters); } onBeforeCompile(shader) { var _shader$defines; if (!((_shader$defines = shader.defines) != null && _shader$defines.USE_UV)) { shader.defines.USE_UV = ''; } shader.uniforms.hasBlur = this._hasBlur; shader.uniforms.tDiffuse = this._tDiffuse; shader.uniforms.tDepth = this._tDepth; shader.uniforms.distortionMap = this._distortionMap; shader.uniforms.tDiffuseBlur = this._tDiffuseBlur; shader.uniforms.textureMatrix = this._textureMatrix; shader.uniforms.mirror = this._mirror; shader.uniforms.mixBlur = this._mixBlur; shader.uniforms.mixStrength = this._blurStrength; shader.uniforms.minDepthThreshold = this._minDepthThreshold; shader.uniforms.maxDepthThreshold = this._maxDepthThreshold; shader.uniforms.depthScale = this._depthScale; shader.uniforms.depthToBlurRatioBias = this._depthToBlurRatioBias; shader.uniforms.distortion = this._distortion; shader.uniforms.mixContrast = this._mixContrast; shader.vertexShader = ` uniform mat4 textureMatrix; varying vec4 my_vUv; ${shader.vertexShader}`; shader.vertexShader = shader.vertexShader.replace('#include <project_vertex>', `#include <project_vertex> my_vUv = textureMatrix * vec4( position, 1.0 ); gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );`); shader.fragmentShader = ` uniform sampler2D tDiffuse; uniform sampler2D tDiffuseBlur; uniform sampler2D tDepth; uniform sampler2D distortionMap; uniform float distortion; uniform float cameraNear; uniform float cameraFar; uniform bool hasBlur; uniform float mixBlur; uniform float mirror; uniform float mixStrength; uniform float minDepthThreshold; uniform float maxDepthThreshold; uniform float mixContrast; uniform float depthScale; uniform float depthToBlurRatioBias; varying vec4 my_vUv; ${shader.fragmentShader}`; shader.fragmentShader = shader.fragmentShader.replace('#include <emissivemap_fragment>', `#include <emissivemap_fragment> float distortionFactor = 0.0; #ifdef USE_DISTORTION distortionFactor = texture2D(distortionMap, vUv).r * distortion; #endif vec4 new_vUv = my_vUv; new_vUv.x += distortionFactor; new_vUv.y += distortionFactor; vec4 base = texture2DProj(tDiffuse, new_vUv); vec4 blur = texture2DProj(tDiffuseBlur, new_vUv); vec4 merge = base; #ifdef USE_NORMALMAP vec2 normal_uv = vec2(0.0); vec4 normalColor = texture2D(normalMap, vUv * normalScale); vec3 my_normal = normalize( vec3( normalColor.r * 2.0 - 1.0, normalColor.b, normalColor.g * 2.0 - 1.0 ) ); vec3 coord = new_vUv.xyz / new_vUv.w; normal_uv = coord.xy + coord.z * my_normal.xz * 0.05; vec4 base_normal = texture2D(tDiffuse, normal_uv); vec4 blur_normal = texture2D(tDiffuseBlur, normal_uv); merge = base_normal; blur = blur_normal; #endif float depthFactor = 0.0001; float blurFactor = 0.0; #ifdef USE_DEPTH vec4 depth = texture2DProj(tDepth, new_vUv); depthFactor = smoothstep(minDepthThreshold, maxDepthThreshold, 1.0-(depth.r * depth.a)); depthFactor *= depthScale; depthFactor = max(0.0001, min(1.0, depthFactor)); #ifdef USE_BLUR blur = blur * min(1.0, depthFactor + depthToBlurRatioBias); merge = merge * min(1.0, depthFactor + 0.5); #else merge = merge * depthFactor; #endif #endif float reflectorRoughnessFactor = roughness; #ifdef USE_ROUGHNESSMAP vec4 reflectorTexelRoughness = texture2D( roughnessMap, vUv ); reflectorRoughnessFactor *= reflectorTexelRoughness.g; #endif #ifdef USE_BLUR blurFactor = min(1.0, mixBlur * reflectorRoughnessFactor); merge = mix(merge, blur, blurFactor); #endif vec4 newMerge = vec4(0.0, 0.0, 0.0, 1.0); newMerge.r = (merge.r - 0.5) * mixContrast + 0.5; newMerge.g = (merge.g - 0.5) * mixContrast + 0.5; newMerge.b = (merge.b - 0.5) * mixContrast + 0.5; diffuseColor.rgb = diffuseColor.rgb * ((1.0 - min(1.0, mirror)) + newMerge.rgb * mixStrength); `); } get tDiffuse() { return this._tDiffuse.value; } set tDiffuse(v) { this._tDiffuse.value = v; } get tDepth() { return this._tDepth.value; } set tDepth(v) { this._tDepth.value = v; } get distortionMap() { return this._distortionMap.value; } set distortionMap(v) { this._distortionMap.value = v; } get tDiffuseBlur() { return this._tDiffuseBlur.value; } set tDiffuseBlur(v) { this._tDiffuseBlur.value = v; } get textureMatrix() { return this._textureMatrix.value; } set textureMatrix(v) { this._textureMatrix.value = v; } get hasBlur() { return this._hasBlur.value; } set hasBlur(v) { this._hasBlur.value = v; } get mirror() { return this._mirror.value; } set mirror(v) { this._mirror.value = v; } get mixBlur() { return this._mixBlur.value; } set mixBlur(v) { this._mixBlur.value = v; } get mixStrength() { return this._blurStrength.value; } set mixStrength(v) { this._blurStrength.value = v; } get minDepthThreshold() { return this._minDepthThreshold.value; } set minDepthThreshold(v) { this._minDepthThreshold.value = v; } get maxDepthThreshold() { return this._maxDepthThreshold.value; } set maxDepthThreshold(v) { this._maxDepthThreshold.value = v; } get depthScale() { return this._depthScale.value; } set depthScale(v) { this._depthScale.value = v; } get depthToBlurRatioBias() { return this._depthToBlurRatioBias.value; } set depthToBlurRatioBias(v) { this._depthToBlurRatioBias.value = v; } get distortion() { return this._distortion.value; } set distortion(v) { this._distortion.value = v; } get mixContrast() { return this._mixContrast.value; } set mixContrast(v) { this._mixContrast.value = v; } } export { MeshReflectorMaterial };