Depth buffer in macOS

How can I get the depth buffer in mac, I’m struggling with this for a while, I’ve got it to work for windows but when I go to test it in mac I either get ERROR:FRAMEBUFFER_INCOMPLETE_ATTACHMENT or I see the scene without the effect I’m trying to make

We have a fix for this in the next engine release that should be happening this week. https://github.com/playcanvas/engine/pull/3132

Also, there is an engine example for post effects that use the depth buffer that may help? http://playcanvas.github.io/#graphics/post-effects.html (brokeh in particular)

Oh, great news! I’ll take a look at this example also. Thank you!

This example of post effect does not work on macos, in windows is just fine, (how much I hate macos, it always produces a lot of problems :’) ), I got a code that can get the depth buffer and renders it in macos but the depth does not seam to be cleaning.

Here is the code:

pc.extend(pc, function() {
    
    var TEST = function (graphicsDevice, fs) {
        pc.PostEffect.call(this, graphicsDevice);

        // Shaders
        var attributes = {
            aPosition: pc.SEMANTIC_POSITION
        };

        var passThroughVert = [
            "attribute vec2 aPosition;",
            "",
            "varying vec2 vUv0;",
            "",
            "void main(void)",
            "{",
            "    gl_Position = vec4(aPosition, 0.0, 1.0);",
            "    vUv0 = (aPosition.xy + 1.0) * 0.5;",
            "}"
        ].join("\n");

        var ssaoFrag = "precision " + graphicsDevice.precision + " float;\n";
            ssaoFrag +=      (graphicsDevice.webgl2) ? "#define GL2 \n" : "\n";
            ssaoFrag +=  pc.shaderChunks.screenDepthPS + "\n";
            ssaoFrag += "varying vec2 vUv0; void main(void) {";
            ssaoFrag += "gl_FragColor = texture2D(uDepthMap, vUv0); }";
   
        this.ssaoShader = new pc.Shader(graphicsDevice, {
            attributes: attributes,
            vshader: passThroughVert,
            fshader: ssaoFrag
        });
    };

    // Our effect must derive from pc.PostEffect
    TEST = pc.inherits(TEST, pc.PostEffect);
    TEST.prototype = pc.extend(TEST.prototype, {
         render: function (inputTarget, outputTarget, rect) {
            var device = this.device;
            var scope = device.scope;

            scope.resolve("uInputTexture").setValue(inputTarget.colorBuffer);
            pc.drawFullscreenQuad(device, outputTarget, this.vertexBuffer, this.ssaoShader, rect);
        }
    });
    
    return {
        TEST: TEST
    };
    
}());

var Test = pc.createScript('test');
Test.attributes.add('testShader',{type:'asset', default:null});

// initialize code called once per entity
Test.prototype.initialize = function () {
    
   
    console.log(this.colorEffect);
    
     //this.entity.camera.requestDepthMap();

    var depthLayer = this.app.scene.layers.getLayerById(pc.LAYERID_DEPTH);
    depthLayer.incrementCounter();
    this.depthFix();
    //Creating effects ===
    this.TEST = new pc.TEST(this.app.graphicsDevice, this.testShader.resource);
 
    // Add effect to the camera
    this.queueCam = this.entity.camera.postEffects;
    this.queueCam.addEffect(this.TEST);

     this.on('state', function (enabled) {
        if (enabled) 
        {
            this.queueCam.addEffect(this.TEST);
            
        } 
        else 
        {
           this.queueCam.removeEffect(this.TEST);
          
        }
    });
};


Test.prototype.depthFix = function () {
    
    var depthLayer = this.app.scene.layers.getLayerByName('Depth');
    var self = this.app;
    
    depthLayer.onPostCull = function (cameraPass) {
        // Collect all rendered mesh instances with the same render target as World has, depthWrite == true and prior to this layer to replicate blitFramebuffer on WebGL2
        var visibleObjects = this.instances.visibleOpaque[cameraPass];
        var visibleList = visibleObjects.list;
        var visibleLength = 0;
        var layers = self.scene.layers.layerList;
        var subLayerEnabled = self.scene.layers.subLayerEnabled;
        var isTransparent = self.scene.layers.subLayerList;
        var rt = self.defaultLayerWorld.renderTarget;
        var cam = this.cameras[cameraPass];
        var layer;
        var j;
        var layerVisibleList, layerCamId, layerVisibleListLength, drawCall, transparent;
        for (var i = 0; i < layers.length; i++) {
            layer = layers[i];
            if (layer === this) break;
            //if (layer.renderTarget !== rt || !layer.enabled || !subLayerEnabled[i]) continue;
            layerCamId = layer.cameras.indexOf(cam);
            if (layerCamId < 0) continue;
            transparent = isTransparent[i];
            layerVisibleList = transparent ? layer.instances.visibleTransparent[layerCamId] : layer.instances.visibleOpaque[layerCamId];
            layerVisibleListLength = layerVisibleList.length;
            layerVisibleList = layerVisibleList.list;
            for (j = 0; j < layerVisibleListLength; j++) {
                drawCall = layerVisibleList[j];
                if (drawCall.material && drawCall.material.depthWrite && !drawCall._noDepthDrawGl1) {
                    visibleList[visibleLength] = drawCall;
                    visibleLength++;
                }
            }
        }
        visibleObjects.length = visibleLength;
    };
};

This is the fragment shader example of how to access the depth on all platforms:

            fshader: `
                precision ${this.device.precision} float;
                ${gl2}
                ${shaderChunks.screenDepthPS}
                varying vec2 uv0;
                void main() {
                    float depth = getLinearScreenDepth(uv0) * camera_params.x;
                    gl_FragColor = vec4(vec3(depth), 1.0);
                }
                `

also, not sure if you’re doing ssao as the names suggest, but have a look here if yes

2 Likes

I have looked at the ssao branch, I tried to use this script link, in my project and It works in windows but not in macos.
I had a function called depth fix which I found in other forums that helps to get the depth correctly but the depthbuffer doesn’t seem to be clearing in macos.


And every time I resize the windows in cleans :woman_shrugging:

ssaoPlay.prototype.depthFix = function () {
    
    var depthLayer = this.app.scene.layers.getLayerByName('Depth');
    var self = this.app;
    
    depthLayer.onPostCull = function (cameraPass) {
        // Collect all rendered mesh instances with the same render target as World has, depthWrite == true and prior to this layer to replicate blitFramebuffer on WebGL2
        var visibleObjects = this.instances.visibleOpaque[cameraPass];
        var visibleList = visibleObjects.list;
        var visibleLength = 0;
        var layers = self.scene.layers.layerList;
        var subLayerEnabled = self.scene.layers.subLayerEnabled;
        var isTransparent = self.scene.layers.subLayerList;
        var rt = self.defaultLayerWorld.renderTarget;
        var cam = this.cameras[cameraPass];
        var layer;
        var j;
        var layerVisibleList, layerCamId, layerVisibleListLength, drawCall, transparent;
        for (var i = 0; i < layers.length; i++) {
            layer = layers[i];
            if (layer === this) break;
            //if (layer.renderTarget !== rt || !layer.enabled || !subLayerEnabled[i]) continue;
            layerCamId = layer.cameras.indexOf(cam);
            if (layerCamId < 0) continue;
            transparent = isTransparent[i];
            layerVisibleList = transparent ? layer.instances.visibleTransparent[layerCamId] : layer.instances.visibleOpaque[layerCamId];
            layerVisibleListLength = layerVisibleList.length;
            layerVisibleList = layerVisibleList.list;
            for (j = 0; j < layerVisibleListLength; j++) {
                drawCall = layerVisibleList[j];
                if (drawCall.material && drawCall.material.depthWrite && !drawCall._noDepthDrawGl1) {
                    visibleList[visibleLength] = drawCall;
                    visibleLength++;
                }
            }
        }
        visibleObjects.length = visibleLength;
    };
};

Does this work for you?
http://playcanvas.github.io/#graphics/post-effects.html

I use Mac and it works fine on my side. Run it, press keys 1, 2, 3 to disable first 3 effects … and in the texture on the right side - I can see the sphere moving around and the buffer is clearing, it does not leave the trail. Do you see the same?

I can see this, the depth buffer looks white in this scene. Also I tried to open it on windows and it’s not fully white.

MACOS:


Windows:

If this works on you mac maybe is some option of the browser or the computer, it tried it on Chrome and Safari.

PD: Sorry for replaying late, I can only test this at work and I’ve been working at other things

This is strange. What version of Mac / OS do you have?
Could you also share the screenshots of https://webglreport.com/ - webgl2 part, as I suspect that’s what you are using.

We’ve tried in this versions MacOS Big Sur 11.2.3 (20D91) and MacOS Catalina 10.15.7 (19H1217).
This is the webgl2 from the MacOS with the Big Sur version:

This is the webgl2 data from MacOs with version Catalina:

I run the same Catalina version, and it all works fine, and has been working fine for last many months. @Leonidas - have you had any issues with the depth on Macs?

I may had, now that you ask. The god rays effect PR I submitted seems to leak light all over the place specifically on desktop Macs (both Safari and Chrome).

I haven’t reported it yet, since I wanted to investigate first, but now that it came up I will try and see if the first pass (depth pass) is where the effect fails.

1 Like

Now we’ve tested it again on safari, chrome and firefox and in the Catalina 10.15.7 version only works on safari and with the Big Sur 11.2.3 version doesn’t work in any of them.

@mvaligursky FYI I’ve tested the post effect that broke only on macOS, the GodRays post effect from the draft PR. Depth buffer access isn’t the issue there, screen depth is reported correctly.

Thanks for that @Leonidas .

Hello, @mvaligursky any update for that?

Martin is currently away this week so hopefully he be able to catch up next week

1 Like

I still cannot reproduce the error on the Mac. I was on latest Catalina, now upgraded to Big Sur 11.5.1, and PlayCanvas Examples displays the depth map in bottom right corner correctly in both cases.

Hi @mvaligursky ,

I have tried 3 iMacs and I could not see the depth map. But with my boss’s Macbook I see it. I’ll give you the specifications of the iMac and the Macbook.

iMacs:


MacBook:

I see this: