text: import { ShaderMaterial } from 'three';
  
  export default class RefractionMaterial extends ShaderMaterial {
    constructor(options) {
      super({
        vertexShader: `varying vec3 worldNormal;
        varying vec3 viewDirection;
        void main() {
          vec4 transformedNormal = vec4(normal, 0.);
          vec4 transformedPosition = vec4(position, 1.0);
          #ifdef USE_INSTANCING
            transformedNormal = instanceMatrix * transformedNormal;
            transformedPosition = instanceMatrix * transformedPosition;
          #endif
          worldNormal = normalize( modelViewMatrix * transformedNormal).xyz;
          viewDirection = normalize((modelMatrix * vec4( position, 1.0)).xyz - cameraPosition);;
          gl_Position = projectionMatrix * modelViewMatrix * transformedPosition;
        }`,
        fragmentShader: `uniform sampler2D envMap;
        uniform sampler2D backfaceMap;
        uniform vec2 resolution;
        varying vec3 worldNormal;
        varying vec3 viewDirection;
        float fresnelFunc(vec3 viewDirection, vec3 worldNormal) {
          return pow(1.05 + dot(viewDirection, worldNormal), 100.0);
        }
        void main() {
          vec2 uv = gl_FragCoord.xy / resolution;
          vec3 normal = worldNormal * (1.0 - 0.7) - texture2D(backfaceMap, uv).rgb * 0.7;
          vec4 color = texture2D(envMap, uv += refract(viewDirection, normal, 1.0/1.5).xy);
          //gl_FragColor = vec4(mix(color.rgb, vec3(0.15), fresnelFunc(viewDirection, normal)), 1.0);
          gl_FragColor = vec4(mix(color.rgb, vec3(0.4), fresnelFunc(viewDirection, normal)), 1.0);
        }`,
        uniforms: {
          envMap: { value: options.envMap },
          backfaceMap: { value: options.backfaceMap },
          resolution: { value: options.resolution },
        },
      });
    }
  }
  