Browse Source

added xray-shaded option

- mesh geometry
- direct-volume geometry
- spheres geometry
Alexander Rose 4 years ago
parent
commit
2f2e44c032

+ 3 - 0
src/mol-geo/geometry/direct-volume/direct-volume.ts

@@ -167,6 +167,7 @@ export namespace DirectVolume {
         flipSided: PD.Boolean(false, BaseGeometry.ShadingCategory),
         flatShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
         ignoreLight: PD.Boolean(false, BaseGeometry.ShadingCategory),
+        xrayShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
         renderMode: createRenderModeParam(),
         stepsPerCell: PD.Numeric(5, { min: 1, max: 20, step: 1 }),
         jumpLength: PD.Numeric(0, { min: 0, max: 20, step: 0.1 }),
@@ -299,6 +300,7 @@ export namespace DirectVolume {
             dFlatShaded: ValueCell.create(props.flatShaded),
             dFlipSided: ValueCell.create(props.flipSided),
             dIgnoreLight: ValueCell.create(props.ignoreLight),
+            dXrayShaded: ValueCell.create(props.xrayShaded),
         };
     }
 
@@ -315,6 +317,7 @@ export namespace DirectVolume {
         ValueCell.updateIfChanged(values.dFlatShaded, props.flatShaded);
         ValueCell.updateIfChanged(values.dFlipSided, props.flipSided);
         ValueCell.updateIfChanged(values.dIgnoreLight, props.ignoreLight);
+        ValueCell.updateIfChanged(values.dXrayShaded, props.xrayShaded);
         ValueCell.updateIfChanged(values.dRenderMode, props.renderMode.name);
 
         if (props.renderMode.name === 'isosurface') {

+ 18 - 2
src/mol-geo/geometry/mesh/mesh.ts

@@ -24,6 +24,7 @@ import { BaseGeometry } from '../base';
 import { createEmptyOverpaint } from '../overpaint-data';
 import { createEmptyTransparency } from '../transparency-data';
 import { createEmptyClipping } from '../clipping-data';
+import { RenderableState } from '../../../mol-gl/renderable';
 
 export interface Mesh {
     readonly kind: 'mesh',
@@ -332,6 +333,7 @@ export namespace Mesh {
         flipSided: PD.Boolean(false, BaseGeometry.ShadingCategory),
         flatShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
         ignoreLight: PD.Boolean(false, BaseGeometry.ShadingCategory),
+        xrayShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
     };
     export type Params = typeof Params
 
@@ -342,8 +344,8 @@ export namespace Mesh {
         createValuesSimple,
         updateValues,
         updateBoundingSphere,
-        createRenderableState: BaseGeometry.createRenderableState,
-        updateRenderableState: BaseGeometry.updateRenderableState,
+        createRenderableState,
+        updateRenderableState,
         createPositionIterator
     };
 
@@ -403,6 +405,7 @@ export namespace Mesh {
             dFlatShaded: ValueCell.create(props.flatShaded),
             dFlipSided: ValueCell.create(props.flipSided),
             dIgnoreLight: ValueCell.create(props.ignoreLight),
+            dXrayShaded: ValueCell.create(props.xrayShaded),
         };
     }
 
@@ -418,6 +421,7 @@ export namespace Mesh {
         ValueCell.updateIfChanged(values.dFlatShaded, props.flatShaded);
         ValueCell.updateIfChanged(values.dFlipSided, props.flipSided);
         ValueCell.updateIfChanged(values.dIgnoreLight, props.ignoreLight);
+        ValueCell.updateIfChanged(values.dXrayShaded, props.xrayShaded);
     }
 
     function updateBoundingSphere(values: MeshValues, mesh: Mesh) {
@@ -432,4 +436,16 @@ export namespace Mesh {
             ValueCell.update(values.uInvariantBoundingSphere, Vec4.fromSphere(values.uInvariantBoundingSphere.ref.value, invariantBoundingSphere));
         }
     }
+
+    function createRenderableState(props: PD.Values<Params>): RenderableState {
+        const state = BaseGeometry.createRenderableState(props);
+        updateRenderableState(state, props);
+        return state;
+    }
+
+    function updateRenderableState(state: RenderableState, props: PD.Values<Params>) {
+        BaseGeometry.updateRenderableState(state, props);
+        state.opaque = state.opaque && !props.xrayShaded;
+        state.writeDepth = state.opaque;
+    }
 }

+ 18 - 2
src/mol-geo/geometry/spheres/spheres.ts

@@ -24,6 +24,7 @@ import { hashFnv32a } from '../../../mol-data/util';
 import { GroupMapping, createGroupMapping } from '../../util';
 import { createEmptyClipping } from '../clipping-data';
 import { Vec3, Vec4 } from '../../../mol-math/linear-algebra';
+import { RenderableState } from '../../../mol-gl/renderable';
 
 export interface Spheres {
     readonly kind: 'spheres',
@@ -126,6 +127,7 @@ export namespace Spheres {
         sizeFactor: PD.Numeric(1, { min: 0, max: 10, step: 0.1 }),
         doubleSided: PD.Boolean(false, BaseGeometry.CustomQualityParamInfo),
         ignoreLight: PD.Boolean(false, BaseGeometry.ShadingCategory),
+        xrayShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
     };
     export type Params = typeof Params
 
@@ -136,8 +138,8 @@ export namespace Spheres {
         createValuesSimple,
         updateValues,
         updateBoundingSphere,
-        createRenderableState: BaseGeometry.createRenderableState,
-        updateRenderableState: BaseGeometry.updateRenderableState,
+        createRenderableState,
+        updateRenderableState,
         createPositionIterator
     };
 
@@ -201,6 +203,7 @@ export namespace Spheres {
             uSizeFactor: ValueCell.create(props.sizeFactor),
             dDoubleSided: ValueCell.create(props.doubleSided),
             dIgnoreLight: ValueCell.create(props.ignoreLight),
+            dXrayShaded: ValueCell.create(props.xrayShaded),
         };
     }
 
@@ -215,6 +218,7 @@ export namespace Spheres {
         ValueCell.updateIfChanged(values.uSizeFactor, props.sizeFactor);
         ValueCell.updateIfChanged(values.dDoubleSided, props.doubleSided);
         ValueCell.updateIfChanged(values.dIgnoreLight, props.ignoreLight);
+        ValueCell.updateIfChanged(values.dXrayShaded, props.xrayShaded);
     }
 
     function updateBoundingSphere(values: SpheresValues, spheres: Spheres) {
@@ -231,4 +235,16 @@ export namespace Spheres {
         }
         ValueCell.update(values.padding, padding);
     }
+
+    function createRenderableState(props: PD.Values<Params>): RenderableState {
+        const state = BaseGeometry.createRenderableState(props);
+        updateRenderableState(state, props);
+        return state;
+    }
+
+    function updateRenderableState(state: RenderableState, props: PD.Values<Params>) {
+        BaseGeometry.updateRenderableState(state, props);
+        state.opaque = state.opaque && !props.xrayShaded;
+        state.writeDepth = state.opaque;
+    }
 }

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

@@ -89,6 +89,7 @@ export const DirectVolumeSchema = {
     dFlipSided: DefineSpec('boolean'),
     dFlatShaded: DefineSpec('boolean'),
     dIgnoreLight: DefineSpec('boolean'),
+    dXrayShaded: DefineSpec('boolean'),
 };
 export type DirectVolumeSchema = typeof DirectVolumeSchema
 export type DirectVolumeValues = Values<DirectVolumeSchema>

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

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -20,6 +20,7 @@ export const MeshSchema = {
     dDoubleSided: DefineSpec('boolean'),
     dFlipSided: DefineSpec('boolean'),
     dIgnoreLight: DefineSpec('boolean'),
+    dXrayShaded: DefineSpec('boolean'),
 } as const;
 export type MeshSchema = typeof MeshSchema
 export type MeshValues = Values<MeshSchema>

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

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -21,6 +21,7 @@ export const SpheresSchema = {
     padding: ValueSpec('number'),
     dDoubleSided: DefineSpec('boolean'),
     dIgnoreLight: DefineSpec('boolean'),
+    dXrayShaded: DefineSpec('boolean'),
 };
 export type SpheresSchema = typeof SpheresSchema
 export type SpheresValues = Values<SpheresSchema>

+ 2 - 2
src/mol-gl/renderer.ts

@@ -476,7 +476,7 @@ namespace Renderer {
             for (let i = 0, il = renderables.length; i < il; ++i) {
                 const r = renderables[i];
                 // TODO: simplify, handle on renderable.state???
-                if (r.values.uAlpha.ref.value === 1 && r.values.transparencyAverage.ref.value !== 1 && r.values.dRenderMode?.ref.value !== 'volume' && !r.values.dPointFilledCircle?.ref.value) {
+                if (r.values.uAlpha.ref.value === 1 && r.values.transparencyAverage.ref.value !== 1 && r.values.dRenderMode?.ref.value !== 'volume' && !r.values.dPointFilledCircle?.ref.value && !r.values.dXrayShaded?.ref.value) {
                     renderObject(r, 'colorWboit');
                 }
             }
@@ -489,7 +489,7 @@ namespace Renderer {
             for (let i = 0, il = renderables.length; i < il; ++i) {
                 const r = renderables[i];
                 // TODO: simplify, handle on renderable.state???
-                if (r.values.uAlpha.ref.value < 1 || r.values.transparencyAverage.ref.value > 0 || r.values.dRenderMode?.ref.value === 'volume' || r.values.dPointFilledCircle?.ref.value || !!r.values.uBackgroundColor) {
+                if (r.values.uAlpha.ref.value < 1 || r.values.transparencyAverage.ref.value > 0 || r.values.dRenderMode?.ref.value === 'volume' || r.values.dPointFilledCircle?.ref.value || !!r.values.uBackgroundColor || r.values.dXrayShaded?.ref.value) {
                     renderObject(r, 'colorWboit');
                 }
             }

+ 4 - 0
src/mol-gl/shader/chunks/apply-light-color.glsl.ts

@@ -47,4 +47,8 @@ RE_IndirectDiffuse_Physical(irradiance, geometry, physicalMaterial, reflectedLig
 vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular;
 
 gl_FragColor = vec4(outgoingLight, color.a);
+
+#ifdef dXrayShaded
+    gl_FragColor.a *= 1.0 - max(0.001, abs(dot(normal, vec3(0, 0, 1))));
+#endif
 `;

+ 2 - 1
src/mol-repr/util.ts

@@ -54,6 +54,7 @@ export interface QualityProps {
     linearSegments: number
     resolution: number
     doubleSided: boolean
+    xrayShaded: boolean
     alpha: number
 }
 
@@ -180,7 +181,7 @@ export function getQualityProps(props: Partial<QualityProps>, data?: any) {
 
     resolution = Math.min(resolution, 20);
 
-    if (props.alpha !== undefined && props.alpha < 1) {
+    if ((props.alpha !== undefined && props.alpha < 1) || !!props.xrayShaded) {
         doubleSided = false;
     }