Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example with custom shader (Camera green-screen effect) #5007

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions examples/test/canvas-texture-video/components/canvas-updater.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* global AFRAME */

AFRAME.registerComponent('canvas-updater', {
dependencies: ['geometry', 'material'],

tick: function () {
var el = this.el;
var material;

material = el.getObject3D('mesh').material;
if (!material.map) { return; }
material.map.needsUpdate = true;
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/* global AFRAME */

/**
* Draw dynamic colorful rectangles.
*/
AFRAME.registerComponent('draw-canvas-video-green-screen', {

schema: {
canvas: {type: 'selector'},
myvideo: {type: 'selector'}
},

init: function () {
// --------- here I capture my own stream in order to transmit it as I want ----
var constraints = {
video: true
};

// Get my camera stream (to do some processing before capturing to canvas
var myvideo = this.myvideo = document.createElement('video');
var promise = navigator.mediaDevices.getUserMedia(constraints);

promise.then(SuccessCallback);

function SuccessCallback (stream) {
myvideo.srcObject = stream;
myvideo.play();
}

this.canvas = this.data.canvas;
this.ctx = this.canvas.getContext('2d');
this.w = this.canvas.width;
this.h = this.canvas.height;
},

tick: function (t) {
var ctx = this.ctx;
var myvideo = this.myvideo;
var r, g; //, b; // r,g,b level of a pixel
var w = this.w;
var h = this.h;
ctx.drawImage(myvideo, 0, 0, w, h);

var imageData = ctx.getImageData(0, 0, w, h);

for (var i = 0; i < imageData.data.length; i += 4) {
r = imageData.data[i]; // red level of pixel
g = imageData.data[i + 1]; // green level of pixel
// b = imageData.data[i + 2]; // blue level of pixel
if (g - r > 0.08) { // if green is 2% more than red then we set this pixel as transparent by setting the alpha=0
// imageData.data[i] = 0; // red: you can use various colors, e.g. for video effects
// imageData.data[i + 1] = 0; // green
// imageData.data[i + 2] = 0; // blue
imageData.data[i + 3] = 0; // alpha is zero
}
}
ctx.putImageData(imageData, 0, 0);
}
});
27 changes: 27 additions & 0 deletions examples/test/canvas-texture-video/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<title>Canvas Texture with green screen effect</title>
<meta name="description" content="Canvas Texture with Green Screen Effect - A-Frame">
<script src="../../../dist/aframe-master.js"></script>
<script src="./components/canvas-updater.js"></script>
<script src="./components/draw-canvas-video-green-screen.js"></script>
</head>
<body>
<a-scene stats>


<a-assets>
<canvas id="helloWorldCanvas" crossOrigin="anonymous"></canvas>
</a-assets>

<a-entity material="shader: flat; src: #helloWorldCanvas"
geometry="primitive: plane; width: 160; height: 90"
position="0 60 -250" rotation="0 35 0"
canvas-updater
draw-canvas-video-green-screen="canvas: #helloWorldCanvas">
</a-entity>
</a-scene>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* global AFRAME */
/**
* Start video
*/
AFRAME.registerComponent('video-init-component', {

schema: {
videoDOM: {type: 'selector'}
},

init: function () {
var promise = navigator.mediaDevices.getUserMedia({video: true});
promise.then(SuccessCallback);

var myvideo = this.data.videoDOM;

// we can not call this inside the function below
function SuccessCallback (stream) {
myvideo.srcObject = stream;
myvideo.play();
}
}
});
26 changes: 26 additions & 0 deletions examples/test/shader-texture-video/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<title>Green Screen custom video shader</title>
<meta name="description" content="Texture with Video Custom shader for green pixels - A-Frame">
<script src="../../../dist/aframe-master.js"></script>
<script src="./components/video-init-component.js"></script>
<script src="shaders/green-screen.js"></script>
</head>
<body>

<a-scene stats>
<a-assets>
<video id="camvideo" crossOrigin="anonymous" src="#"></video>
</a-assets>

<a-entity material="shader: green-screen; uMap: #camvideo"
geometry="primitive: plane; width: 160; height: 90"
position="0 60 -250" rotation="0 35 0"
video-init-component="videoDOM:#camvideo"
>
</a-entity>
</a-scene>
</body>
</html>
37 changes: 37 additions & 0 deletions examples/test/shader-texture-video/shaders/green-screen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* global AFRAME */
/**
* The Green screen shader
*/
AFRAME.registerShader('green-screen', {

schema: {
uMap: {type: 'map', is: 'uniform'},
greenThreshold:{type: 'float', is: 'uniform', default:0.08}
},

vertexShader: `varying vec2 vUv;

void main() {
vec4 worldPosition = modelViewMatrix * vec4( position, 1.0 );
vec3 vWorldPosition = worldPosition.xyz;
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`,

fragmentShader: `varying vec2 vUv;
uniform sampler2D uMap;
uniform float greenThreshold;

void main() {
vec2 uv = vUv;
vec4 tex1 = texture2D(uMap, uv * 1.0);
if (tex1.g - tex1.r > greenThreshold)
gl_FragColor = vec4(0,0,0,0);
else
gl_FragColor = vec4(tex1.r,tex1.g,tex1.b,1.0);
}`

});