Hello,
I spent a lot of time studying examples of how to use onBeforeCompile, in this forum and this guide (Extending three.js materials with GLSL), but I still don’t quite understand how the Replace works.
I made this fiddle with chromakey shader Based on this example using a phongMaterial to demonstrate the expected result
chromakey shader from webcam
The shader material code:
chromakeyMaterial = new THREE.MeshPhongMaterial( {
// color: 0x4080ff,
map: webcamTexture,
dithering: true,
transparent: true,
side: THREE.DoubleSide,
//uniforms: THREE.UniformsLibs.Light
//fog: true
} );
chromakeyMaterial.onBeforeCompile = shader => {
//shader.uniforms.time = { value: 0 };
shader.uniforms.keyColor = { value: [0.0, 1.0, 0.0] };
shader.uniforms.similarity = { value: 0.77 };
shader.uniforms.smoothness = { value: 0.0 };
shader.vertexShader = 'varying vec2 vUv;\n' + shader.vertexShader;
shader.vertexShader = shader.vertexShader.replace(
'#include <map_fragment>'
);
shader.fragmentShader = `
uniform vec3 keyColor;
uniform float similarity;
uniform float smoothness;
uniform vec2 vUv;
uniform sampler2D map;
` + shader.fragmentShader;
shader.fragmentShader = shader.fragmentShader.replace(
'#include <map_fragment>',
[
` vec4 videoColor = texture2D(map, vUv);
float Y1 = 0.299 * keyColor.r + 0.587 * keyColor.g + 0.114 * keyColor.b;
float Cr1 = keyColor.r - Y1;
float Cb1 = keyColor.b - Y1;
float Y2 = 0.299 * videoColor.r + 0.587 * videoColor.g + 0.114 * videoColor.b;
float Cr2 = videoColor.r - Y2;
float Cb2 = videoColor.b - Y2;
float blend = smoothstep(similarity, similarity + smoothness, distance(vec2(Cr2, Cb2), vec2(Cr1, Cb1)));
gl_FragColor = vec4(videoColor.rgb, videoColor.a * blend);
}`
].join( '\n' )
);
};