Browse Source

dpoit, render volumes with standard blending

Alexander Rose 2 years ago
parent
commit
379fcd4494
3 changed files with 33 additions and 29 deletions
  1. 11 18
      src/mol-canvas3d/passes/draw.ts
  2. 22 4
      src/mol-gl/renderer.ts
  3. 0 7
      src/mol-gl/shader/direct-volume.frag.ts

+ 11 - 18
src/mol-canvas3d/passes/draw.ts

@@ -154,29 +154,17 @@ export class DrawPass {
             this.postprocessing.render(camera, false, transparentBackground, renderer.props.backgroundColor, postprocessingProps);
         }
 
-        let dpoitTextures;
-        // render transparent primitives and volumes
-        if (scene.opacityAverage < 1 || scene.volumes.renderables.length > 0) {
-
-            dpoitTextures = this.dpoit.bind();
+        // render transparent primitives
+        if (scene.opacityAverage < 1) {
+            const dpoitTextures = this.dpoit.bind();
 
             if (isTimingMode) this.webgl.timer.mark('DpoitPasses.render');
 
-            if (scene.opacityAverage < 1) {
-                renderer.renderDpoitTransparent(scene.primitives, camera, this.depthTextureOpaque, dpoitTextures);
-            }
-            if (scene.volumes.renderables.length > 0) {
-                renderer.renderDpoitTransparent(scene.volumes, camera, this.depthTextureOpaque, dpoitTextures);
-            }
+            renderer.renderDpoitTransparent(scene.primitives, camera, this.depthTextureOpaque, dpoitTextures);
 
             for (let i = 0; i < iterations; i++) {
-                dpoitTextures = this.dpoit.bindDualDepthPeeling();
-                if (scene.opacityAverage < 1) {
-                    renderer.renderDpoitTransparent(scene.primitives, camera, this.depthTextureOpaque, dpoitTextures);
-                }
-                if (scene.volumes.renderables.length > 0) {
-                    renderer.renderDpoitTransparent(scene.volumes, camera, this.depthTextureOpaque, dpoitTextures);
-                }
+                const dpoitTextures = this.dpoit.bindDualDepthPeeling();
+                renderer.renderDpoitTransparent(scene.primitives, camera, this.depthTextureOpaque, dpoitTextures);
 
                 if (PostprocessingPass.isEnabled(postprocessingProps)) {
                     this.postprocessing.target.bind();
@@ -196,6 +184,11 @@ export class DrawPass {
             }
             this.dpoit.render();
         }
+
+        // render transparent volumes
+        if (scene.volumes.renderables.length > 0) {
+            renderer.renderDpoitVolume(scene.volumes, camera, this.depthTextureOpaque);
+        }
     }
 
     private _renderWboit(renderer: Renderer, camera: ICamera, scene: Scene, transparentBackground: boolean, postprocessingProps: PostprocessingProps) {

+ 22 - 4
src/mol-gl/renderer.ts

@@ -73,6 +73,7 @@ interface Renderer {
     renderWboitTransparent: (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => void
     renderDpoitOpaque: (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => void
     renderDpoitTransparent: (group: Scene.Group, camera: ICamera, depthTexture: Texture | null, dpoitTextures: { depth: Texture, frontColor: Texture, backColor: Texture }) => void
+    renderDpoitVolume: (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => void
 
     setProps: (props: Partial<RendererProps>) => void
     setViewport: (x: number, y: number, width: number, height: number) => void
@@ -144,7 +145,7 @@ namespace Renderer {
     const enum Flag {
         None = 0,
         BlendedFront = 1,
-        BlendedBack = 2
+        BlendedBack = 2,
     }
 
     const enum Mask {
@@ -620,7 +621,7 @@ namespace Renderer {
                 // TODO: simplify, handle in renderable.state???
                 // uAlpha is updated in "render" so we need to recompute it here
                 const alpha = clamp(r.values.alpha.ref.value * r.state.alphaFactor, 0, 1);
-                if ((alpha === 1 && r.values.transparencyAverage.ref.value !== 1 && r.values.dGeometryType.ref.value !== 'directVolume' && r.values.dPointStyle?.ref.value !== 'fuzzy' && !r.values.dXrayShaded?.ref.value) || r.values.dTransparentBackfaces?.ref.value === 'opaque') {
+                if ((alpha === 1 && r.values.transparencyAverage.ref.value !== 1 && r.values.dPointStyle?.ref.value !== 'fuzzy' && !r.values.dXrayShaded?.ref.value) || r.values.dTransparentBackfaces?.ref.value === 'opaque') {
                     renderObject(r, 'colorDpoit', Flag.None);
                 }
             }
@@ -643,17 +644,33 @@ namespace Renderer {
             for (let i = 0, il = renderables.length; i < il; ++i) {
                 const r = renderables[i];
 
-
                 // TODO: simplify, handle in renderable.state???
                 // uAlpha is updated in "render" so we need to recompute it here
                 const alpha = clamp(r.values.alpha.ref.value * r.state.alphaFactor, 0, 1);
-                if (alpha < 1 || r.values.transparencyAverage.ref.value > 0 || r.values.dGeometryType.ref.value === 'directVolume' || r.values.dPointStyle?.ref.value === 'fuzzy' || !!r.values.uBackgroundColor || r.values.dXrayShaded?.ref.value) {
+                if (alpha < 1 || r.values.transparencyAverage.ref.value > 0 || r.values.dPointStyle?.ref.value === 'fuzzy' || !!r.values.uBackgroundColor || r.values.dXrayShaded?.ref.value) {
                     renderObject(r, 'colorDpoit', Flag.None);
                 }
             }
             if (isTimingMode) ctx.timer.markEnd('Renderer.renderDpoitTransparent');
         };
 
+        const renderDpoitVolume = (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => {
+            if (isTimingMode) ctx.timer.mark('Renderer.renderDpoitVolume');
+            state.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
+            state.enable(gl.BLEND);
+
+            updateInternal(group, camera, depthTexture, Mask.Transparent, false);
+
+            const { renderables } = group;
+            for (let i = 0, il = renderables.length; i < il; ++i) {
+                const r = renderables[i];
+                if (r.values.dGeometryType.ref.value === 'directVolume') {
+                    renderObject(r, 'colorDpoit', Flag.None);
+                }
+            }
+            if (isTimingMode) ctx.timer.markEnd('Renderer.renderDpoitVolume');
+        };
+
         return {
             clear: (toBackgroundColor: boolean, ignoreTransparentBackground?: boolean) => {
                 state.enable(gl.SCISSOR_TEST);
@@ -699,6 +716,7 @@ namespace Renderer {
             renderWboitTransparent,
             renderDpoitOpaque,
             renderDpoitTransparent,
+            renderDpoitVolume,
 
             setProps: (props: Partial<RendererProps>) => {
                 if (props.backgroundColor !== undefined && props.backgroundColor !== p.backgroundColor) {

+ 0 - 7
src/mol-gl/shader/direct-volume.frag.ts

@@ -62,12 +62,6 @@ uniform int uGroupCount;
     uniform sampler2D tMarker;
 #endif
 
-#if defined(dRenderVariant_colorDpoit)
-    #define MAX_DPOIT_DEPTH 99999.0
-    uniform sampler2D tDpoitDepth;
-    uniform sampler2D tDpoitFrontColor;
-#endif
-
 uniform float uMetalness;
 uniform float uRoughness;
 
@@ -361,6 +355,5 @@ void main() {
     float fragmentDepth = calcDepth((uModelView * vec4(start, 1.0)).xyz);
     float preFogAlpha = clamp(preFogAlphaBlended, 0.0, 1.0);
     #include wboit_write
-    #include dpoit_write
 }
 `;