14

I am using Three JS to blend a video texture onto a canvas.

I'm trying to make it so that the background of the videotexture is transparent but what ends up happening is the video is only transparent on some computers and not all.

Below is a screenshot of what it looks like on a computer where it is not showing as transparent. (ironically this will appear transparent if your computer does not suffer this problem) enter image description here

I am trying to figure out why this is. Here's what I've concluded:

  • This is not browser dependent as the problem occurs on different browsers.

  • This is not OS dependent. I've seen this problem sometimes on Mac and sometimes on Windows.

  • This is not monitor dependent because I switched monitors with my QA guy. My QA guy currently sees the transparent box. On my computer I don't. Switching monitors with my QA guy results in me using his monitor but not seeing the transparent box. He however still sees the transparent box despite using my monitor. Ergo, it isn't a monitor problem.

So the question is, what is happening here and what could be causing this transparency problem?

JS Fiddle code

function init() {
    // create container, scenes and camera
    THREE.ImageUtils.crossOrigin = true;

    container = document.createElement('div');
    container.className = "ThreeJSCanvas";
    container.id = "ThreeJSCanvas";
    document.body.appendChild(container);

    camera = new THREE.PerspectiveCamera(50, window.innerWidth / (window.innerHeight - 61), 1, 2000);
    camera.position.z = 100;
cameraInterface = new THREE.PerspectiveCamera(50, window.innerWidth / (window.innerHeight - 61), 1, 2000);
    cameraInterface.position = camera.position;
    cameraInterface.position.z = 100;

    sceneSprites = new THREE.Scene();

    sceneSky = new THREE.Scene();


    //renderer
    renderer3D = new THREE.WebGLRenderer({
        antialias: true,
        preserveDrawingBuffer: true,
        devicePixelRatio: 1 
    });
    renderer3D.autoClear = false;
    renderer3D.setSize(window.innerWidth, (window.innerHeight - 61));
    container.appendChild(renderer3D.domElement);

    // load background image
    var loader = new THREE.OBJLoader();
    loader.load('https://dl.dropboxusercontent.com/s/1cq5i4rio1iudwe/skyDome.obj', function (object) {

        skyMesh = object;

        var ss = THREE.ImageUtils.loadTexture('https://dl.dropboxusercontent.com/s/f7jeyl6cl03aelu/background.jpg');
        var texture = new THREE.MeshBasicMaterial({
            map: ss,
            wrapS: THREE.RepeatWrapping,
            wrapT: THREE.RepeatWrapping,
            transparent: true,
            minFilter: THREE.LinearFilter,
            magFilter: THREE.LinearFilter,
            opacity: 0.7
        });

        skyMesh.position.y = -80;
        skyMesh.children[0].material = texture;
        sceneSky.add(skyMesh);

    });
    createVideo();
    animate()

}


function createVideo() {
    video = document.getElementById( 'video' );
    video.setAttribute('crossorigin', 'anonymous');

    // Create Video Texture for THREE JS
    var videoTexture = new THREE.VideoTexture(video);
    videoTexture.minFilter = THREE.LinearFilter;
    videoTexture.magFilter = THREE.LinearFilter;
    videoTexture.format = THREE.RGBAFormat;

    var materialConfig = new THREE.MeshBasicMaterial({
        map: videoTexture,
        color: 0xffffff,
        blending: THREE.AdditiveBlending,
        transparent: true,
        opacity: 1,
        depthTest: false
    });

    var geometry = new THREE.PlaneBufferGeometry(125, 125);

    var mesh = new THREE.Mesh(geometry, materialConfig);


    sceneSprites.add(mesh);
    video.load();
    video.play();
}

function animate() {
    requestAnimationFrame(animate)
    render()

}

function render() {
    renderer3D.clear()
    renderer3D.render(sceneSky, camera);
    renderer3D.render(sceneSprites, cameraInterface);    
}

init()

EDIT: ADDED JS FIDDLE, edited code to reflect JS Fiddle

https://jsfiddle.net/ytmbL69q/

user3704293
  • 988
  • 2
  • 14
  • 26
Terence Chow
  • 9,287
  • 19
  • 60
  • 120
  • `Opacity = 0`? Why are you using `AdditiveBlending`? I think you will have to provide a live link. And for comparison, provide an image in your post of what we are supposed to see – WestLangley Apr 28 '15 at 17:42
  • @WestLangley if you look closely at the edge of the image above, maybe 1 cm from the left or right edges, you will notice that the black color changes to a slightly less black color. There is a straight line from top to bottom where that color goes from balck to a less black color. This less black color is the transparency failing and instead is a "gray / yellowish / white" overlay that causes the black to be "less black". – Terence Chow Apr 28 '15 at 17:54
  • I played around with many types of blending. Additive blending worked on my screen but not on my QA's screen, so I just assumed that the blending type did not matter. Opacity is set to 0 because I fade it in, I should have been clear about that. Sorry! – Terence Chow Apr 28 '15 at 17:54
  • I have no idea what your are doing. Sorry. – WestLangley Apr 28 '15 at 18:07
  • Overlaying a transparent video on top of something is a very complex graphical process that is unlikely to work on multiple platforms. If you can achieve your affect in a different way (such as pre-rendering the entire video without transparency) that is much more likely to work well. – Andy Ray Apr 29 '15 at 06:41
  • @WestLangley Sorry, can you help now? I've added a JS Fiddle. I've confirmed with my QA guy that the problem is occuring on his computer, however on my computer I can confirm that I don't have this problem. (Note the video is a box with the flickering light in the middle, the background image is stars. If you have this problem you will see a flickering light with a white grayish background box, while the stars will also be visible through the white grayish box. If you don't have this problem you will simply see a flickering light in a background of stars. That is the intended effect...). – Terence Chow Apr 29 '15 at 17:24
  • I am unable to reproduce the problem. You can try setting `premultipliedAlpha: false` in the renderer constructor -- but this is just a guess. You can try avoiding additive blending and instead create a custom ShaderMaterial that discards fragments that are ( near ) black. Or you can render your skybox in front and make it transparent. – WestLangley Apr 29 '15 at 20:00

1 Answers1

1

Guessing it could be a graphic card issue depending on the pc being used.

Three.js is a library that is used on top of webgl for simplicity plus alot of other goodies..

In saying that, graphics cards play a huge role in webgl and how shaders display graphics, not all support everything and not all are universal.. Maybe hence your issue... what you can is firstly check your machines graphics, brand etc..They generally have a document giving info on each cards version of gsls support or look at writing your own shaders to accomadate...

"at this time I was not able to comment"

Careen
  • 548
  • 5
  • 26