Jump to content

Antialiasing and RenderTargetTexture


Nico
 Share

Recommended Posts

Hi guys,

 

I have made a small tutorial for BABYLON.Tools.CreateScreenshot method, and I saw that RenderTargetTexture seems not to use antialiasing. Does somebody have an idea about this ? I am using WebGL readPixels method to get the picture (readed pixel by pixel), does this method is not compatible with antialiasing ? (I don't know a lot about WebGL, I'm just trying things, and see what it does)

Link to comment
Share on other sites

I have tried to use a FxaaPostProcess, to create it before creating my renderTargetTexture, but it is not yet applied when I render my texture, it is applied after (I can see it on my babylon scene). I have tried to do a scene.render() before rendering my texture but the result is the same. I can't find if I must do something to force applying this postprocess. If I don't detachPostProcess on my camera and do a second render just after, the postprocess is applied (so texture are compatible with postprocess).

 

Here is my test code if it can help :

public static CreateScreenshot(engine: Engine, camera: Camera, size: any, antialias?: boolean): void {    var width: number;    var height: number;    var scene = engine.scenes[0];    var previousCamera: BABYLON.Camera = null;    if (scene.activeCamera !== camera) {        previousCamera = scene.activeCamera;        scene.activeCamera = camera;    }    //If a precision value is specified    if (size.precision) {        width = Math.round(engine.getRenderWidth() * size.precision);        height = Math.round(width / engine.getAspectRatio(camera));        size = { width: width, height: height };    }    else if (size.width && size.height) {        width = size.width;        height = size.height;    }    //If passing only width, computing height to keep display canvas ratio.    else if (size.width && !size.height) {        width = size.width;        height = Math.round(width / engine.getAspectRatio(camera));        size = { width: width, height: height };    }    //If passing only height, computing width to keep display canvas ratio.    else if (size.height && !size.width) {        height = size.height;        width = Math.round(height * engine.getAspectRatio(camera));        size = { width: width, height: height };    }    //Assuming here that "size" parameter is a number    else if (!isNaN(size)) {        height = size;        width = size;    }    else {        Tools.Error("Invalid 'size' parameter !");        return;    }    var fxaa: BABYLON.FxaaPostProcess;    if (antialias) {        fxaa = new BABYLON.FxaaPostProcess("fxaaScreenshot", 1.0, camera);    }    //At this point size can be a number, or an object (according to engine.prototype.createRenderTargetTexture method)    var texture = new RenderTargetTexture("screenShot", size, engine.scenes[0]);    texture.renderList = engine.scenes[0].meshes;    texture.onAfterRender = () => {        // Read the contents of the framebuffer        var numberOfChannelsByLine = width * 4;        var halfHeight = height / 2;        //Reading datas from WebGL        var data = engine.readPixels(0, 0, width, height);        //To flip image on Y axis.        for (var i = 0; i < halfHeight; i++) {            for (var j = 0; j < numberOfChannelsByLine; j++) {                var currentCell = j + i * numberOfChannelsByLine;                var targetLine = height - i - 1;                var targetCell = j + targetLine * numberOfChannelsByLine;                var temp = data[currentCell];                data[currentCell] = data[targetCell];                data[targetCell] = temp;            }        }        // Create a 2D canvas to store the result        if (!screenshotCanvas) {            screenshotCanvas = document.createElement('canvas');        }        screenshotCanvas.width = width;        screenshotCanvas.height = height;        var context = screenshotCanvas.getContext('2d');        // Copy the pixels to a 2D canvas        var imageData = context.createImageData(width, height);        imageData.data.set(data);        context.putImageData(imageData, 0, 0);        var base64Image = screenshotCanvas.toDataURL();        //Creating a link if the browser have the download attribute on the a tag, to automatically start download generated image.        if (("download" in document.createElement("a"))) {            var a = window.document.createElement("a");            a.href = base64Image;            var date = new Date();            var stringDate = date.getFullYear() + "/" + date.getMonth() + "/" + date.getDate() + "-" + date.getHours() + ":" + date.getMinutes();            a.setAttribute("download", "screenshot-" + stringDate + ".png");            window.document.body.appendChild(a);            a.addEventListener("click", () => {                a.parentElement.removeChild(a);            });            a.click();            //Or opening a new tab with the image if it is not possible to automatically start download.        } else {            var newWindow = window.open("");            var img = newWindow.document.createElement("img");            img.src = base64Image;            newWindow.document.body.appendChild(img);        }    };        //scene.render(); //Doesn't solve the problem    texture.render();    texture.dispose();    if (previousCamera) {        scene.activeCamera = previousCamera;    }    if (antialias) {        camera.detachPostProcess(fxaa);    }}
Link to comment
Share on other sites

It is awesome it works like a charm ! But an old problem came back, when I activate the FxaaPostProcess if I try to get a screenshot with a different ratio than my engine, it give my a weird picture again  :unsure:

Here is some screenshot example to explain what I am trying to say (should more understandable  :) ) :

Without AA screenshot:

screenpop.png

With AA screenshot: 

screenpyp.png

 

If you want to see an example (using precision mode to keep my canvas ratio) : 

Without AA: 

screenzmz.png

With AA:

screenooo.png

 

It makes this screenshot feature very nice, thanks again for helping !  :)

Link to comment
Share on other sites

You can find my code here

I have used BuildOurOwnBabylonJS solution, so you just have to build and run it, and try it on a demo (I have added 2 buttons to quickly generate 720x720 screenshot with or without antialiasing).

Link to comment
Share on other sites

  • 1 year later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...