1
votes

I am using the three.js library in my coding, and I want to put a transparent hole in the scene. This hole would be a 3d object itself, so objects in front of it would be rendered, but objects behind it would not be rendered.

I have tried to set this 3d "hole's" material to a basic material so I could just read pixel data and set certain pixels to transparent based on that. But as soon as I retrieve the canvas context, the program stops working.

My question is how do I read and write pixel data on a three.js canvas, or if it is possible, does the three.js library already have a way of accomplishing this?

//EDIT//

I found a way to read pixel data on the three.js canvas using renderer.context and some other code. My new question now is how do I change the color of individual pixels in three.js or webgl

//EDIT//

I can now read pixel data and alter it, then put it into a THREE.js texture using the DataTexture method. But now whenever I apply that texture to a plane, the plane returns white.

var texture = new THREE.Texture();
function SetTransparent(){
    var pixels = new Uint8Array(window.innerWidth*window.innerHeight*4);
    gl.readPixels(0, 0, window.innerWidth, window.innerHeight, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
    var length = pixels.length/4;
    /*for (var i = 0; i < length; i++) {
        if (pixels[i*4] === 0 && pixels[i*4+1] === 0 && pixels[i*4+2] === 0 && pixels[i*4+3] === 255){
            pixels[i*4+3] = 0;
        }
    }*/
    var editTex = new THREE.DataTexture(pixels, window.innerWidth, window.innerHeight, THREE.RGBAFormat, THREE.UnsignedByteType);
    texture = editTex;
    texture.needsUpdate = true;
}
1
Check this: medium.com/@Zadvorsky/webgl-masking-composition-75b82dd4cdfd , but in attempt to remove all creative details, ended up with not working fiddle: jsfiddle.net/mmalex/y2kt3Lrf , maybe someone can help to find a bug.Alex Khoroshylov
That's not exactly what I was looking for. I want to 1. Convert the renderer output into a Uint8Array, 2. Edit values in that array based on the renderer output, and 3. Return those values into a texture for outputing into canvasArgentum Manus
I see... Doing it as you described and without shaders will drop fps significantly.Alex Khoroshylov

1 Answers

0
votes

Finally solved my problem. I read all of my pixel data with webglcontex.readpixels(parameters);. I then took that data and processed it according to colors and put it inside of a 2d canvas.

var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

var SetCanvas = function(data){
    var w = window.innerWidth;
    var h = window.innerHeight;
    Array.from({length: h}, (val, i) => data.slice(i * w * 4, (i + 1) * w * 4))
        .forEach((val, i) => data.set(val, (h - i - 1) * w * 4));
    var id = ctx.createImageData(window.innerWidth, window.innerHeight);
    id.data.set(data);
    ctx.putImageData(id, 0, 0);
};