Browse Source

added global picking threshold for transparent objects

Alexander Rose 6 years ago
parent
commit
ac8aa71727

+ 1 - 0
src/mol-gl/_spec/renderer.spec.ts

@@ -69,6 +69,7 @@ function createPoints() {
         ...size,
 
         uAlpha: ValueCell.create(1.0),
+        uPickingAlphaThreshold: ValueCell.create(0.3),
         uHighlightColor: ValueCell.create(Vec3.create(1.0, 0.4, 0.6)),
         uSelectColor: ValueCell.create(Vec3.create(0.2, 1.0, 0.1)),
         uInstanceCount: ValueCell.create(1),

+ 7 - 1
src/mol-gl/renderable.ts

@@ -9,6 +9,7 @@ import { RenderableValues, Values, RenderableSchema } from './renderable/schema'
 import { RenderVariant, RenderItem } from './webgl/render-item';
 import { Sphere3D } from 'mol-math/geometry';
 import { Vec3 } from 'mol-math/linear-algebra';
+import { ValueCell } from 'mol-util';
 
 export type RenderableState = {
     visible: boolean
@@ -42,7 +43,12 @@ export function createRenderable<T extends Values<RenderableSchema>>(renderItem:
         },
         get opaque () { return values.uAlpha && values.uAlpha.ref.value === 1 },
 
-        render: (variant: RenderVariant) => renderItem.render(variant),
+        render: (variant: RenderVariant) => {
+            if (values.uPickable) {
+                ValueCell.updateIfChanged(values.uPickable, state.pickable ? 1 : 0)
+            }
+            renderItem.render(variant)
+        },
         getProgram: (variant: RenderVariant) => renderItem.getProgram(variant),
         update: () => renderItem.update(),
         dispose: () => renderItem.destroy()

+ 2 - 1
src/mol-gl/renderable/direct-volume.ts

@@ -57,7 +57,8 @@ export type DirectVolumeValues = Values<DirectVolumeSchema>
 export function DirectVolumeRenderable(ctx: WebGLContext, id: number, values: DirectVolumeValues, state: RenderableState): Renderable<DirectVolumeValues> {
     const schema = { ...GlobalUniformSchema, ...InternalSchema, ...DirectVolumeSchema }
     const internalValues: InternalValues = {
-        uObjectId: ValueCell.create(id)
+        uObjectId: ValueCell.create(id),
+        uPickable: ValueCell.create(state.pickable ? 1 : 0)
     }
     const shaderCode = DirectVolumeShaderCode
     const renderItem = createRenderItem(ctx, 'triangles', shaderCode, schema, { ...values, ...internalValues })

+ 2 - 1
src/mol-gl/renderable/lines.ts

@@ -28,7 +28,8 @@ export type LinesValues = Values<LinesSchema>
 export function LinesRenderable(ctx: WebGLContext, id: number, values: LinesValues, state: RenderableState): Renderable<LinesValues> {
     const schema = { ...GlobalUniformSchema, ...InternalSchema, ...LinesSchema }
     const internalValues: InternalValues = {
-        uObjectId: ValueCell.create(id)
+        uObjectId: ValueCell.create(id),
+        uPickable: ValueCell.create(state.pickable ? 1 : 0)
     }
     const shaderCode = LinesShaderCode
     const renderItem = createRenderItem(ctx, 'triangles', shaderCode, schema, { ...values, ...internalValues })

+ 2 - 1
src/mol-gl/renderable/mesh.ts

@@ -26,7 +26,8 @@ export type MeshValues = Values<MeshSchema>
 export function MeshRenderable(ctx: WebGLContext, id: number, values: MeshValues, state: RenderableState): Renderable<MeshValues> {
     const schema = { ...GlobalUniformSchema, ...InternalSchema, ...MeshSchema }
     const internalValues: InternalValues = {
-        uObjectId: ValueCell.create(id)
+        uObjectId: ValueCell.create(id),
+        uPickable: ValueCell.create(state.pickable ? 1 : 0)
     }
     const shaderCode = MeshShaderCode
     const renderItem = createRenderItem(ctx, 'triangles', shaderCode, schema, { ...values, ...internalValues })

+ 2 - 1
src/mol-gl/renderable/points.ts

@@ -25,7 +25,8 @@ export type PointsValues = Values<PointsSchema>
 export function PointsRenderable(ctx: WebGLContext, id: number, values: PointsValues, state: RenderableState): Renderable<PointsValues> {
     const schema = { ...GlobalUniformSchema, ...InternalSchema, ...PointsSchema }
     const internalValues: InternalValues = {
-        uObjectId: ValueCell.create(id)
+        uObjectId: ValueCell.create(id),
+        uPickable: ValueCell.create(state.pickable ? 1 : 0)
     }
     const shaderCode = PointsShaderCode
     const renderItem = createRenderItem(ctx, 'points', shaderCode, schema, { ...values, ...internalValues })

+ 3 - 0
src/mol-gl/renderable/schema.ts

@@ -149,12 +149,15 @@ export const GlobalUniformSchema = {
     uFogNear: UniformSpec('f'),
     uFogFar: UniformSpec('f'),
     uFogColor: UniformSpec('v3'),
+
+    uPickingAlphaThreshold: UniformSpec('f'),
 }
 export type GlobalUniformSchema = typeof GlobalUniformSchema
 export type GlobalUniformValues = { [k in keyof GlobalUniformSchema]: ValueCell<any> }
 
 export const InternalSchema = {
     uObjectId: UniformSpec('i'),
+    uPickable: UniformSpec('i'),
 }
 export type InternalSchema = typeof InternalSchema
 export type InternalValues = { [k in keyof InternalSchema]: ValueCell<any> }

+ 7 - 3
src/mol-gl/renderer.ts

@@ -45,14 +45,15 @@ interface Renderer {
 
 export const DefaultRendererProps = {
     clearColor: Color(0x000000),
-    viewport: Viewport.create(0, 0, 0, 0)
+    viewport: Viewport.create(0, 0, 0, 0),
+    pickingAlphaThreshold: 0.5,
 }
 export type RendererProps = typeof DefaultRendererProps
 
 namespace Renderer {
     export function create(ctx: WebGLContext, camera: Camera, props: Partial<RendererProps> = {}): Renderer {
         const { gl } = ctx
-        let { clearColor, viewport: _viewport } = { ...DefaultRendererProps, ...props }
+        let { clearColor, viewport: _viewport, pickingAlphaThreshold } = { ...DefaultRendererProps, ...props }
 
         const viewport = Viewport.clone(_viewport)
         const viewportVec4 = Viewport.toVec4(Vec4.zero(), viewport)
@@ -98,12 +99,14 @@ namespace Renderer {
             uFogNear: ValueCell.create(camera.state.near),
             uFogFar: ValueCell.create(camera.state.far / 50),
             uFogColor: ValueCell.create(Vec3.clone(fogColor)),
+
+            uPickingAlphaThreshold: ValueCell.create(pickingAlphaThreshold),
         }
 
         let currentProgramId = -1
         const renderObject = (r: Renderable<RenderableValues & BaseValues>, variant: RenderVariant) => {
             const program = r.getProgram(variant)
-            if (r.state.visible && (variant === 'draw' || r.state.pickable)) {
+            if (r.state.visible) {
                 if (currentProgramId !== program.id) {
                     program.use()
                     program.setUniforms(globalUniforms)
@@ -192,6 +195,7 @@ namespace Renderer {
             get props() {
                 return {
                     clearColor,
+                    pickingAlphaThreshold,
                     viewport
                 }
             },

+ 1 - 1
src/mol-gl/shader/chunks/assign-material-color.glsl

@@ -3,5 +3,5 @@
 #elif defined(dColorType_attribute) || defined(dColorType_instance) || defined(dColorType_group) || defined(dColorType_groupInstance)
     vec4 material = vec4(vColor.rgb, uAlpha);
 #elif defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking)
-    vec4 material = vColor;
+    vec4 material = uPickable == 1 ? vColor : vec4(0.0, 0.0, 0.0, 1.0); // set to empty picking id
 #endif

+ 3 - 1
src/mol-gl/shader/chunks/common-frag-params.glsl

@@ -12,4 +12,6 @@ uniform float uFogNear;
 uniform float uFogFar;
 uniform vec3 uFogColor;
 
-uniform float uAlpha;
+uniform float uAlpha;
+uniform float uPickingAlphaThreshold;
+uniform int uPickable;

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

@@ -123,6 +123,11 @@ vec4 raymarch(vec3 startLoc, vec3 step, vec3 viewDir) {
                 tmp = ((prevValue - uIsoValue) / ((prevValue - uIsoValue) - (value - uIsoValue)));
                 isoPos = mix(pos - step, pos, tmp);
 
+                #if defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking)
+                    if (uAlpha < uPickingAlphaThreshold)
+                        discard; // ignore so the element below can be picked
+                #else
+
                 #if defined(dColorType_objectPicking)
                     return vec4(encodeIdRGB(float(uObjectId)), 1.0);
                 #elif defined(dColorType_instancePicking)

+ 2 - 0
src/mol-gl/shader/lines.frag

@@ -14,6 +14,8 @@ void main(){
     #pragma glslify: import('./chunks/assign-material-color.glsl')
 
     #if defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking)
+        if (uAlpha < uPickingAlphaThreshold)
+            discard; // ignore so the element below can be picked
         gl_FragColor = material;
     #else
         gl_FragColor = material;

+ 2 - 1
src/mol-gl/shader/mesh.frag

@@ -33,7 +33,8 @@ void main() {
     #pragma glslify: import('./chunks/assign-material-color.glsl')
 
     #if defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking)
-        // gl_FragColor = vec4(material.r, material.g, material.a, 1.0);
+        if (uAlpha < uPickingAlphaThreshold)
+            discard; // ignore so the element below can be picked
         gl_FragColor = material;
     #else
         // determine surface to light direction

+ 2 - 0
src/mol-gl/shader/points.frag

@@ -21,6 +21,8 @@ void main(){
     #pragma glslify: import('./chunks/assign-material-color.glsl')
 
     #if defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking)
+        if (uAlpha < uPickingAlphaThreshold)
+            discard; // ignore so the element below can be picked
         gl_FragColor = material;
     #else
         gl_FragColor = material;