I’m trying to use the onBeforeCompile function to keep meshphong material base code, making some changes to make the chromakey algorithm work. I don’t know if I’m on the right way, as on the console nothing looks wrong, but the webcam image still doesn’t appear.
These are chromakey’s vertex shaders and fragment shaders:
vertex shader
varying vec2 vUv;
void main( void ) {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}
fragment shader
uniform vec3 keyColor;
uniform float similarity;
uniform float smoothness;
varying vec2 vUv;
uniform sampler2D map;
void main() {
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);
}
And here is my trying implementation with onBeforeCompile:
mesh = new THREE.Mesh(
new THREE.PlaneBufferGeometry( 16, 9 ),
new THREE.MeshPhongMaterial( { color: 0x004080, depthWrite: false, map:null } )
);
geometry.scale( 0.4, 0.5, 0.5 );
mesh.material.onBeforeCompile = shader => {
shader.vertexShader = shader.vertexShader.replace(
`#include <uv_pars_vertex>`,
`varying vec2 vUv;`
);
shader.vertexShader = shader.vertexShader.replace(
`#include <uv_vertex>`,
` vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);`
);
shader.fragmentShader = shader.fragmentShader.replace(
`#include <color_pars_fragment>`,
` uniform vec3 keyColor;
uniform float similarity;
uniform float smoothness;
varying vec2 vUv;
uniform sampler2D map; `
);
shader.fragmentShader = shader.fragmentShader.replace(
`#include <color_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); `
);
const uniforms = ({
keyColor: { value: new THREE.Color(data.keyColor) },
similarity: { value: data.similarity },
smoothness: { value: data.smoothness },
map: { value: webcamTexture },
});
shader.uniforms = THREE.UniformsUtils.merge([shader.uniforms, uniforms]);
chromakeyMaterial = shader;
};
…
function render() {
renderer.render(scene, camera);
if(chromakeyMaterial) {
chromakeyMaterial.uniforms.map.value = webcamTexture;
}
}