diff --git a/src/mol-gl/_spec/renderer.spec.ts b/src/mol-gl/_spec/renderer.spec.ts index e62c5415f7be59b638ff97167f2ca012d6d2c34a..36eea7ecb91febd51622980ccdf630f28d131926 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 9693861ed06631f06bb82b8b3cef778c2664403d..6d9d55ac3e5612ea01df7663062484f09dcf4503 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 63b2424ed608744a5e6b6651d284b2a991a5412a..27ce4e40668fb0b78c587187fbb6564d0fb006f3 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 31ebfd493eca89c14021d916f7dc81a93987a62e..54e62c5b448bf5b4bf8bcf88037092564fcf52ce 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 e79f78159a7ecbc1500a6adbfe796d08b1b4b7af..a3d70909409dda202f1649ab5397ae0cc47e8d29 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 95a45cceda95c18e52b6c1829b94b8deeff5169b..f4d87921f388afdefe195965d0b290dc6465ea9e 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 bac604bea5230fd1a8f6eb2d8f453d14a9247d00..7050ee13bbd19865f39421d3722a6046e71ff6e0 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 b3a8d51dd2d961cc6326bc2798358947b754b910..f999ff70d05bcd35ba7f46c0306ecffeb202bc8c 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 bc56340c25f74d749e9c8cc6377ac9ca265b2035..81758eabcd3b6630f7e7cd1cf3f2f819f419695e 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 c757d1b2f5afa54efad4236d533b9f4535bc64da..dc62dbe9bec92fae2018665d136b5f10e624f71b 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 6be0ab731366d502314f61722f6b124b308dc092..7baa242c02aae1f90c6b47ebf9678152ff1f3cef 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 98caeadbf7fd714c79fb17425b2fd7f44ec24de8..ec512988b00b2fabea4fc65183284fc200a3d347 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 2195060272cbc736d150e39d3d58166569d1f2b3..93858961510496217a7121ee8182aee085218313 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 5ef4153d4cfc66a9f10177a2eca17ecc3a836c36..67f8aa47d44abdbfe229c868e2a64d1e12e16374 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;