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;
}
}