257 lines
7.0 KiB
JavaScript
257 lines
7.0 KiB
JavaScript
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 };
|