Parcourir la source

webgl resource reuse improvements

- reuse common compute renderables
- add dRenderVariant to existing schema object
Alexander Rose il y a 4 ans
Parent
commit
5a8a6310f8

+ 2 - 3
src/mol-canvas3d/passes/draw.ts

@@ -32,7 +32,7 @@ const DepthMergeSchema = {
     uTexSize: UniformSpec('v2'),
     dPackedDepth: DefineSpec('boolean'),
 };
-
+const DepthMergeShaderCode = ShaderCode('depth-merge', quad_vert, depthMerge_frag);
 type DepthMergeRenderable = ComputeRenderable<Values<typeof DepthMergeSchema>>
 
 function getDepthMergeRenderable(ctx: WebGLContext, depthTexturePrimitives: Texture, depthTextureVolumes: Texture, packedDepth: boolean): DepthMergeRenderable {
@@ -45,8 +45,7 @@ function getDepthMergeRenderable(ctx: WebGLContext, depthTexturePrimitives: Text
     };
 
     const schema = { ...DepthMergeSchema };
-    const shaderCode = ShaderCode('depth-merge', quad_vert, depthMerge_frag);
-    const renderItem = createComputeRenderItem(ctx, 'triangles', shaderCode, schema, values);
+    const renderItem = createComputeRenderItem(ctx, 'triangles', DepthMergeShaderCode, schema, values);
 
     return createComputeRenderable(renderItem, values);
 }

+ 5 - 3
src/mol-canvas3d/passes/multi-sample.ts

@@ -28,7 +28,7 @@ const ComposeSchema = {
     uTexSize: UniformSpec('v2'),
     uWeight: UniformSpec('f'),
 };
-
+const ComposeShaderCode = ShaderCode('compose', quad_vert, compose_frag);
 type ComposeRenderable = ComputeRenderable<Values<typeof ComposeSchema>>
 
 function getComposeRenderable(ctx: WebGLContext, colorTexture: Texture): ComposeRenderable {
@@ -40,8 +40,7 @@ function getComposeRenderable(ctx: WebGLContext, colorTexture: Texture): Compose
     };
 
     const schema = { ...ComposeSchema };
-    const shaderCode = ShaderCode('compose', quad_vert, compose_frag);
-    const renderItem = createComputeRenderItem(ctx, 'triangles', shaderCode, schema, values);
+    const renderItem = createComputeRenderItem(ctx, 'triangles', ComposeShaderCode, schema, values);
 
     return createComputeRenderable(renderItem, values);
 }
@@ -81,11 +80,14 @@ export class MultiSamplePass {
     }
 
     setSize(width: number, height: number) {
+        const [w, h] = this.compose.values.uTexSize.ref.value;
+        if (width !== w || height !== h) {
         this.colorTarget.setSize(width, height);
         this.composeTarget.setSize(width, height);
         this.holdTarget.setSize(width, height);
         ValueCell.update(this.compose.values.uTexSize, Vec2.set(this.compose.values.uTexSize.ref.value, width, height));
     }
+    }
 
     setProps(props: Partial<MultiSampleProps>) {
         if (props.mode !== undefined) this.props.mode = props.mode;

+ 7 - 2
src/mol-canvas3d/passes/pick.ts

@@ -58,8 +58,12 @@ export class PickPass {
 
     setSize(width: number, height: number) {
         this.pickScale = this.pickBaseScale / this.webgl.pixelRatio;
-        this.pickWidth = Math.ceil(width * this.pickScale);
-        this.pickHeight = Math.ceil(height * this.pickScale);
+        const pickWidth = Math.ceil(width * this.pickScale);
+        const pickHeight = Math.ceil(height * this.pickScale);
+
+        if (pickWidth !== this.pickWidth || pickHeight !== this.pickHeight) {
+            this.pickWidth = pickWidth;
+            this.pickHeight = pickHeight;
 
         this.objectPickTarget.setSize(this.pickWidth, this.pickHeight);
         this.instancePickTarget.setSize(this.pickWidth, this.pickHeight);
@@ -67,6 +71,7 @@ export class PickPass {
 
         this.setupBuffers();
     }
+    }
 
     render() {
         const { renderer, scene, camera, handleHelper: { scene: handleScene } } = this;

+ 24 - 22
src/mol-canvas3d/passes/postprocessing.ts

@@ -44,26 +44,7 @@ const PostprocessingSchema = {
     uOutlineScale: UniformSpec('f'),
     uOutlineThreshold: UniformSpec('f'),
 };
-
-export const PostprocessingParams = {
-    occlusion: PD.MappedStatic('off', {
-        on: PD.Group({
-            kernelSize: PD.Numeric(4, { min: 1, max: 32, step: 1 }),
-            bias: PD.Numeric(0.5, { min: 0, max: 1, step: 0.01 }),
-            radius: PD.Numeric(64, { min: 0, max: 256, step: 1 }),
-        }),
-        off: PD.Group({})
-    }, { cycle: true, description: 'Darken occluded crevices with the ambient occlusion effect' }),
-    outline: PD.MappedStatic('off', {
-        on: PD.Group({
-            scale: PD.Numeric(1, { min: 0, max: 10, step: 1 }),
-            threshold: PD.Numeric(0.8, { min: 0, max: 5, step: 0.01 }),
-        }),
-        off: PD.Group({})
-    }, { cycle: true, description: 'Draw outline around 3D objects' })
-};
-export type PostprocessingProps = PD.Values<typeof PostprocessingParams>
-
+const PostprocessingShaderCode = ShaderCode('postprocessing', quad_vert, postprocessing_frag);
 type PostprocessingRenderable = ComputeRenderable<Values<typeof PostprocessingSchema>>
 
 function getPostprocessingRenderable(ctx: WebGLContext, colorTexture: Texture, depthTexture: Texture, packedDepth: boolean, props: Partial<PostprocessingProps>): PostprocessingRenderable {
@@ -92,12 +73,30 @@ function getPostprocessingRenderable(ctx: WebGLContext, colorTexture: Texture, d
     };
 
     const schema = { ...PostprocessingSchema };
-    const shaderCode = ShaderCode('postprocessing', quad_vert, postprocessing_frag);
-    const renderItem = createComputeRenderItem(ctx, 'triangles', shaderCode, schema, values);
+    const renderItem = createComputeRenderItem(ctx, 'triangles', PostprocessingShaderCode, schema, values);
 
     return createComputeRenderable(renderItem, values);
 }
 
+export const PostprocessingParams = {
+    occlusion: PD.MappedStatic('off', {
+        on: PD.Group({
+            kernelSize: PD.Numeric(4, { min: 1, max: 32, step: 1 }),
+            bias: PD.Numeric(0.5, { min: 0, max: 1, step: 0.01 }),
+            radius: PD.Numeric(64, { min: 0, max: 256, step: 1 }),
+        }),
+        off: PD.Group({})
+    }, { cycle: true, description: 'Darken occluded crevices with the ambient occlusion effect' }),
+    outline: PD.MappedStatic('off', {
+        on: PD.Group({
+            scale: PD.Numeric(1, { min: 0, max: 10, step: 1 }),
+            threshold: PD.Numeric(0.8, { min: 0, max: 5, step: 0.01 }),
+        }),
+        off: PD.Group({})
+    }, { cycle: true, description: 'Draw outline around 3D objects' })
+};
+export type PostprocessingProps = PD.Values<typeof PostprocessingParams>
+
 export class PostprocessingPass {
     target: RenderTarget
     props: PostprocessingProps
@@ -116,9 +115,12 @@ export class PostprocessingPass {
     }
 
     setSize(width: number, height: number) {
+        const [w, h] = this.renderable.values.uTexSize.ref.value;
+        if (width !== w || height !== h) {
         this.target.setSize(width, height);
         ValueCell.update(this.renderable.values.uTexSize, Vec2.set(this.renderable.values.uTexSize.ref.value, width, height));
     }
+    }
 
     setProps(props: Partial<PostprocessingProps>) {
         this.props = produce(this.props, p => {

+ 3 - 1
src/mol-gl/webgl/render-item.ts

@@ -57,7 +57,9 @@ const ComputeRenderVariants = Object.keys(ComputeRenderVariant) as ComputeRender
 
 function createProgramVariant(ctx: WebGLContext, variant: string, defineValues: DefineValues, shaderCode: ShaderCode, schema: RenderableSchema) {
     defineValues = { ...defineValues, dRenderVariant: ValueCell.create(variant) };
-    schema = { ...schema, dRenderVariant: DefineSpec('string') };
+    if (schema.dRenderVariant === undefined) {
+        Object.defineProperty(schema, 'dRenderVariant', { value: DefineSpec('string') });
+    }
     return ctx.resources.program(defineValues, shaderCode, schema);
 }