From ac8aa717276dac37b59808ce7e5543299a428e59 Mon Sep 17 00:00:00 2001 From: Alexander Rose <alex.rose@rcsb.org> Date: Fri, 16 Nov 2018 16:46:47 -0800 Subject: [PATCH] added global picking threshold for transparent objects --- src/mol-gl/_spec/renderer.spec.ts | 1 + src/mol-gl/renderable.ts | 8 +++++++- src/mol-gl/renderable/direct-volume.ts | 3 ++- src/mol-gl/renderable/lines.ts | 3 ++- src/mol-gl/renderable/mesh.ts | 3 ++- src/mol-gl/renderable/points.ts | 3 ++- src/mol-gl/renderable/schema.ts | 3 +++ src/mol-gl/renderer.ts | 10 +++++++--- src/mol-gl/shader/chunks/assign-material-color.glsl | 2 +- src/mol-gl/shader/chunks/common-frag-params.glsl | 4 +++- src/mol-gl/shader/direct-volume.frag | 5 +++++ src/mol-gl/shader/lines.frag | 2 ++ src/mol-gl/shader/mesh.frag | 3 ++- src/mol-gl/shader/points.frag | 2 ++ 14 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/mol-gl/_spec/renderer.spec.ts b/src/mol-gl/_spec/renderer.spec.ts index e62c5415f..36eea7ecb 100644 --- a/src/mol-gl/_spec/renderer.spec.ts +++ b/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), diff --git a/src/mol-gl/renderable.ts b/src/mol-gl/renderable.ts index 9693861ed..6d9d55ac3 100644 --- a/src/mol-gl/renderable.ts +++ b/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() diff --git a/src/mol-gl/renderable/direct-volume.ts b/src/mol-gl/renderable/direct-volume.ts index 63b2424ed..27ce4e406 100644 --- a/src/mol-gl/renderable/direct-volume.ts +++ b/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 }) diff --git a/src/mol-gl/renderable/lines.ts b/src/mol-gl/renderable/lines.ts index 31ebfd493..54e62c5b4 100644 --- a/src/mol-gl/renderable/lines.ts +++ b/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 }) diff --git a/src/mol-gl/renderable/mesh.ts b/src/mol-gl/renderable/mesh.ts index e79f78159..a3d709094 100644 --- a/src/mol-gl/renderable/mesh.ts +++ b/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 }) diff --git a/src/mol-gl/renderable/points.ts b/src/mol-gl/renderable/points.ts index 95a45cced..f4d87921f 100644 --- a/src/mol-gl/renderable/points.ts +++ b/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 }) diff --git a/src/mol-gl/renderable/schema.ts b/src/mol-gl/renderable/schema.ts index bac604bea..7050ee13b 100644 --- a/src/mol-gl/renderable/schema.ts +++ b/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> } diff --git a/src/mol-gl/renderer.ts b/src/mol-gl/renderer.ts index b3a8d51dd..f999ff70d 100644 --- a/src/mol-gl/renderer.ts +++ b/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 } }, diff --git a/src/mol-gl/shader/chunks/assign-material-color.glsl b/src/mol-gl/shader/chunks/assign-material-color.glsl index bc56340c2..81758eabc 100644 --- a/src/mol-gl/shader/chunks/assign-material-color.glsl +++ b/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 \ No newline at end of file diff --git a/src/mol-gl/shader/chunks/common-frag-params.glsl b/src/mol-gl/shader/chunks/common-frag-params.glsl index c757d1b2f..dc62dbe9b 100644 --- a/src/mol-gl/shader/chunks/common-frag-params.glsl +++ b/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; \ No newline at end of file +uniform float uAlpha; +uniform float uPickingAlphaThreshold; +uniform int uPickable; \ No newline at end of file diff --git a/src/mol-gl/shader/direct-volume.frag b/src/mol-gl/shader/direct-volume.frag index 6be0ab731..7baa242c0 100644 --- a/src/mol-gl/shader/direct-volume.frag +++ b/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) diff --git a/src/mol-gl/shader/lines.frag b/src/mol-gl/shader/lines.frag index 98caeadbf..ec512988b 100644 --- a/src/mol-gl/shader/lines.frag +++ b/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; diff --git a/src/mol-gl/shader/mesh.frag b/src/mol-gl/shader/mesh.frag index 219506027..938589615 100644 --- a/src/mol-gl/shader/mesh.frag +++ b/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 diff --git a/src/mol-gl/shader/points.frag b/src/mol-gl/shader/points.frag index 5ef4153d4..67f8aa47d 100644 --- a/src/mol-gl/shader/points.frag +++ b/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; -- GitLab