Browse Source

use single channel for downsampled depth when possible

Alexander Rose 2 years ago
parent
commit
a3645f5acc

+ 3 - 1
src/mol-canvas3d/passes/postprocessing.ts

@@ -452,7 +452,9 @@ export class PostprocessingPass {
         const sw = Math.floor(width * this.ssaoScale);
         const sh = Math.floor(height * this.ssaoScale);
 
-        this.downsampledDepthTarget = webgl.createRenderTarget(sw, sh, false, drawPass.packedDepth ? 'uint8' : 'float32', 'linear');
+        this.downsampledDepthTarget = drawPass.packedDepth
+            ? webgl.createRenderTarget(sw, sh, false, 'uint8', 'linear', 'rgba')
+            : webgl.createRenderTarget(sw, sh, false, 'float32', 'linear', webgl.isWebGL2 ? 'alpha' : 'rgba');
         this.downsampleDepthRenderable = createCopyRenderable(webgl, depthTextureOpaque);
 
         this.ssaoDepthTexture = webgl.resources.texture('image-uint8', 'rgba', 'ubyte', 'linear');

+ 4 - 4
src/mol-gl/webgl/context.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -208,7 +208,7 @@ export interface WebGLContext {
     /** Cache for textures, managed by consumers */
     readonly namedTextures: { [name: string]: Texture }
 
-    createRenderTarget: (width: number, height: number, depth?: boolean, type?: 'uint8' | 'float32' | 'fp16', filter?: TextureFilter) => RenderTarget
+    createRenderTarget: (width: number, height: number, depth?: boolean, type?: 'uint8' | 'float32' | 'fp16', filter?: TextureFilter, format?: 'rgba' | 'alpha') => RenderTarget
     unbindFramebuffer: () => void
     readPixels: (x: number, y: number, width: number, height: number, buffer: Uint8Array | Float32Array | Int32Array) => void
     readPixelsAsync: (x: number, y: number, width: number, height: number, buffer: Uint8Array) => Promise<void>
@@ -328,8 +328,8 @@ export function createContext(gl: GLRenderingContext, props: Partial<{ pixelScal
             contextRestored.next(now());
         },
 
-        createRenderTarget: (width: number, height: number, depth?: boolean, type?: 'uint8' | 'float32' | 'fp16', filter?: TextureFilter) => {
-            const renderTarget = createRenderTarget(gl, resources, width, height, depth, type, filter);
+        createRenderTarget: (width: number, height: number, depth?: boolean, type?: 'uint8' | 'float32' | 'fp16', filter?: TextureFilter, format?: 'rgba' | 'alpha') => {
+            const renderTarget = createRenderTarget(gl, resources, width, height, depth, type, filter, format);
             renderTargets.add(renderTarget);
             return {
                 ...renderTarget,

+ 9 - 5
src/mol-gl/webgl/render-target.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -28,14 +28,18 @@ export interface RenderTarget {
     destroy: () => void
 }
 
-export function createRenderTarget(gl: GLRenderingContext, resources: WebGLResources, _width: number, _height: number, depth = true, type: 'uint8' | 'float32' | 'fp16' = 'uint8', filter: TextureFilter = 'nearest'): RenderTarget {
+export function createRenderTarget(gl: GLRenderingContext, resources: WebGLResources, _width: number, _height: number, depth = true, type: 'uint8' | 'float32' | 'fp16' = 'uint8', filter: TextureFilter = 'nearest', format: 'rgba' | 'alpha' = 'rgba'): RenderTarget {
+
+    if (format === 'alpha' && !isWebGL2(gl)) {
+        throw new Error('cannot render to alpha format in webgl1');
+    }
 
     const framebuffer = resources.framebuffer();
     const targetTexture = type === 'fp16'
-        ? resources.texture('image-float16', 'rgba', 'fp16', filter)
+        ? resources.texture('image-float16', format, 'fp16', filter)
         : type === 'float32'
-            ? resources.texture('image-float32', 'rgba', 'float', filter)
-            : resources.texture('image-uint8', 'rgba', 'ubyte', filter);
+            ? resources.texture('image-float32', format, 'float', filter)
+            : resources.texture('image-uint8', format, 'ubyte', filter);
     // make a depth renderbuffer of the same size as the targetTexture
     const depthRenderbuffer = !depth
         ? null