Chromakey shader, Help please!

Hi all,
Im trying to play a video texture on material with chromakey shader (its a green screen video)
there is no problem playing the video but using a chromakey shader really got me.
Using a new created material attached to videoTexture.js
Can anyone give me some help on how to use it?

those are my scripts
Videotexture.js:

var Videotexture = pc.createScript('videotexture');

Videotexture.attributes.add('shader', { type: 'asset', assetType: 'shader' });


Videotexture.attributes.add('materials', {
    type: 'asset',
    assetType: 'material',
    array: true
});

Videotexture.attributes.add('video', {
    type: 'asset'
});

// initialize code called once per entity
Videotexture.prototype.initialize = function() {
    var app = this.app;
    
    // Create a texture to hold the video frame data            
    var videoTexture = new pc.Texture(this.app.graphicsDevice, {
        format: pc.PIXELFORMAT_R8_G8_B8,
        width: 1,
        height: 1,
        autoMipmap: false
    });
    videoTexture.minFilter = pc.FILTER_LINEAR;
    videoTexture.magFilter = pc.FILTER_LINEAR;
    videoTexture.addressU = pc.ADDRESS_CLAMP_TO_EDGE;
    videoTexture.addressV = pc.ADDRESS_CLAMP_TO_EDGE;

    // Create HTML Video Element to play the video
    var video = document.createElement('video');
    video.addEventListener('canplay', function (e) {
        videoTexture.setSource(video);
    });
    video.src = this.video.getFileUrl();
    video.crossOrigin = 'anonymous';
    video.loop = true;
    video.muted = true; // This line allows video to play without prior interaction from the user

    // Get the material that we want to play the video on and assign the new video
    // texture to it.
    for (var i = 0; i < this.materials.length; i++) {
        var material = this.materials[i].resource;
        material.setShader(this.shader.resource);
       // material.chunks.opacityTexPS = this.shader.resource;
        material.setParameter('texture_opacityMap', videoTexture);
        material.emissiveMap = videoTexture;
        material.diffuseMap = videoTexture;
        //material.opacityMap = videoTexture;
        
       //material.setShader(this.shader);
        
        
        material.update();
    }

    this.videoTexture = videoTexture;
   
    this.upload = true;

    
        video.play();
   
};

// update code called every frame
Videotexture.prototype.update = function(dt) {
    // Upload the video data to the texture every other frame
    this.upload = !this.upload;
    if (this.upload) {
        this.videoTexture.upload();
         for (var i = 0; i < this.materials.length; i++) {
        var material = this.materials[i].resource;
        material.setParameter('texture_opacityMap', this.videoTexture);
        material.emissiveMap = this.videoTexture;
        material.diffuseMap = this.videoTexture;
        //material.opacityMap = this.videoTexture;
        material.update();
    }
    }
    
    
   
    
};

chromecast.glsl:

uniform sampler2D texture_opacityMap;

vec3 rgb2hsv(vec3 rgb)
{
	float Cmax = max(rgb.r, max(rgb.g, rgb.b));
	float Cmin = min(rgb.r, min(rgb.g, rgb.b));
    float delta = Cmax - Cmin;

	vec3 hsv = vec3(0., 0., Cmax);
	
	if (Cmax > Cmin)
	{
		hsv.y = delta / Cmax;

		if (rgb.r == Cmax)
			hsv.x = (rgb.g - rgb.b) / delta;
		else
		{
			if (rgb.g == Cmax)
				hsv.x = 2. + (rgb.b - rgb.r) / delta;
			else
				hsv.x = 4. + (rgb.r - rgb.g) / delta;
		}
		hsv.x = fract(hsv.x / 6.);
	}
	return hsv;
}


void getOpacity() {
	
	vec3 color = texture2D(texture_opacityMap, $UV).rgb;
    
	vec3 backgroundColor = vec3(0.196,0.992,0.196);
	vec3 weights = vec3(4., 1., 2.);

	vec3 hsv = rgb2hsv(color);
	vec3 target = rgb2hsv(backgroundColor);
	float dist = length(weights * (target - hsv));
	float alpha = 1. - clamp(3. * dist - 1.5, 0., 1.);
    
    if( alpha < 0.7 ){
        dAlpha = 1.0;    
    }else{
        dAlpha = 0.0;
    }
    
}

Check this project out:
https://playcanvas.com/project/523575/overview/video-chromakeying

It was meant to demonstrate how something like that would be done in PlayCanvas, though the quality is poor since chromakeying is something very complex.

It is a good start nonetheless.

1 Like