Browse Source

Merge pull request #531 from molstar/safari-wboit

add missing depth renderbuffer to wboit pass
David Sehnal 2 years ago
parent
commit
d9b2b99c86

+ 2 - 0
CHANGELOG.md

@@ -6,6 +6,8 @@ Note that since we don't clearly distinguish between a public and private interf
 
 ## [Unreleased]
 
+- Fix wboit in Safari >=15 (add missing depth renderbuffer to wboit pass)
+
 ## [v3.14.0] - 2022-08-20
 
 - Expose inter-bonds compute params in structure

+ 11 - 1
src/mol-canvas3d/passes/wboit.ts

@@ -18,6 +18,8 @@ import { evaluateWboit_frag } from '../../mol-gl/shader/evaluate-wboit.frag';
 import { Framebuffer } from '../../mol-gl/webgl/framebuffer';
 import { Vec2 } from '../../mol-math/linear-algebra';
 import { isDebugMode, isTimingMode } from '../../mol-util/debug';
+import { isWebGL2 } from '../../mol-gl/webgl/compat';
+import { Renderbuffer } from '../../mol-gl/webgl/renderbuffer';
 
 const EvaluateWboitSchema = {
     ...QuadSchema,
@@ -50,6 +52,7 @@ export class WboitPass {
     private readonly framebuffer: Framebuffer;
     private readonly textureA: Texture;
     private readonly textureB: Texture;
+    private readonly depthRenderbuffer: Renderbuffer;
 
     private _supported = false;
     get supported() {
@@ -87,6 +90,7 @@ export class WboitPass {
         if (width !== w || height !== h) {
             this.textureA.define(width, height);
             this.textureB.define(width, height);
+            this.depthRenderbuffer.setSize(width, height);
             ValueCell.update(this.renderable.values.uTexSize, Vec2.set(this.renderable.values.uTexSize.ref.value, width, height));
         }
     }
@@ -106,6 +110,8 @@ export class WboitPass {
 
         this.textureA.attachFramebuffer(this.framebuffer, 'color0');
         this.textureB.attachFramebuffer(this.framebuffer, 'color1');
+
+        this.depthRenderbuffer.attachFramebuffer(this.framebuffer);
     }
 
     static isSupported(webgl: WebGLContext) {
@@ -128,7 +134,7 @@ export class WboitPass {
     constructor(private webgl: WebGLContext, width: number, height: number) {
         if (!WboitPass.isSupported(webgl)) return;
 
-        const { resources } = webgl;
+        const { resources, gl } = webgl;
 
         this.textureA = resources.texture('image-float32', 'rgba', 'float', 'nearest');
         this.textureA.define(width, height);
@@ -136,6 +142,10 @@ export class WboitPass {
         this.textureB = resources.texture('image-float32', 'rgba', 'float', 'nearest');
         this.textureB.define(width, height);
 
+        this.depthRenderbuffer = isWebGL2(gl)
+            ? resources.renderbuffer('depth32f', 'depth', width, height)
+            : resources.renderbuffer('depth16', 'depth', width, height);
+
         this.renderable = getEvaluateWboitRenderable(webgl, this.textureA, this.textureB);
         this.framebuffer = resources.framebuffer();
 

+ 5 - 5
src/mol-gl/shader/cylinders.frag.ts

@@ -109,14 +109,14 @@ void main() {
 
     vec3 vViewPosition = vModelPosition + intersection.x * rayDir;
     vViewPosition = (uView * vec4(vViewPosition, 1.0)).xyz;
-    gl_FragDepthEXT = calcDepth(vViewPosition);
+    float fragmentDepth = calcDepth(vViewPosition);
 
-    vec3 vModelPosition = (uInvView * vec4(vViewPosition, 1.0)).xyz;
+    if (fragmentDepth < 0.0) discard;
+    if (fragmentDepth > 1.0) discard;
 
-    if (gl_FragDepthEXT < 0.0) discard;
-    if (gl_FragDepthEXT > 1.0) discard;
+    gl_FragDepthEXT = fragmentDepth;
 
-    float fragmentDepth = gl_FragDepthEXT;
+    vec3 vModelPosition = (uInvView * vec4(vViewPosition, 1.0)).xyz;
     #include assign_material_color
 
     #if defined(dRenderVariant_pick)

+ 7 - 7
src/mol-gl/shader/spheres.frag.ts

@@ -70,17 +70,17 @@ void main(void){
     }
 
     vec3 vViewPosition = cameraPos;
-    gl_FragDepthEXT = calcDepth(vViewPosition);
-    if (!flag && gl_FragDepthEXT >= 0.0) {
-        gl_FragDepthEXT = 0.0 + (0.0000001 / vRadius);
+    float fragmentDepth = calcDepth(vViewPosition);
+    if (!flag && fragmentDepth >= 0.0) {
+        fragmentDepth = 0.0 + (0.0000001 / vRadius);
     }
 
-    vec3 vModelPosition = (uInvView * vec4(vViewPosition, 1.0)).xyz;
+    if (fragmentDepth < 0.0) discard;
+    if (fragmentDepth > 1.0) discard;
 
-    if (gl_FragDepthEXT < 0.0) discard;
-    if (gl_FragDepthEXT > 1.0) discard;
+    gl_FragDepthEXT = fragmentDepth;
 
-    float fragmentDepth = gl_FragDepthEXT;
+    vec3 vModelPosition = (uInvView * vec4(vViewPosition, 1.0)).xyz;
     #include assign_material_color
 
     #if defined(dRenderVariant_pick)

+ 1 - 1
src/mol-plugin/config.ts

@@ -31,7 +31,7 @@ export const PluginConfig = {
         PixelScale: item('plugin-config.pixel-scale', 1),
         PickScale: item('plugin-config.pick-scale', 0.25),
         PickPadding: item('plugin-config.pick-padding', 3),
-        EnableWboit: item('plugin-config.enable-wboit', PluginFeatureDetection.wboit),
+        EnableWboit: item('plugin-config.enable-wboit', true),
         // as of Oct 1 2021, WebGL 2 doesn't work on iOS 15.
         // TODO: check back in a few weeks to see if it was fixed
         PreferWebGl1: item('plugin-config.prefer-webgl1', PluginFeatureDetection.preferWebGl1),

+ 0 - 6
src/mol-plugin/features.ts

@@ -29,10 +29,4 @@ export const PluginFeatureDetection = {
         const isTouchScreen = navigator.maxTouchPoints >= 4; // true for iOS 13 (and hopefully beyond)
         return !(window as any).MSStream && (isIOS || (isAppleDevice && isTouchScreen));
     },
-    get wboit() {
-        if (typeof navigator === 'undefined' || typeof window === 'undefined') return true;
-
-        // disable Wboit in Safari 15
-        return !/Version\/15.\d Safari/.test(navigator.userAgent);
-    }
 };