Browse Source

add cameraClipping.minNear param

Alexander Rose 2 năm trước cách đây
mục cha
commit
5d28aa4f2e

+ 1 - 0
CHANGELOG.md

@@ -7,6 +7,7 @@ Note that since we don't clearly distinguish between a public and private interf
 ## [Unreleased]
 
 - Fix Dual depth peeling when post-processing is off or when rendering direct-volumes
+- Add `cameraClipping.minNear` parameter
 
 ## [v3.18.0] - 2022-09-17
 

+ 11 - 7
src/mol-canvas3d/camera.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -260,7 +260,8 @@ namespace Camera {
             radius: 0,
             radiusMax: 10,
             fog: 50,
-            clipFar: true
+            clipFar: true,
+            minNear: 5,
         };
     }
 
@@ -276,6 +277,7 @@ namespace Camera {
         radiusMax: number
         fog: number
         clipFar: boolean
+        minNear: number
     }
 
     export function copySnapshot(out: Snapshot, source?: Partial<Snapshot>) {
@@ -292,6 +294,7 @@ namespace Camera {
         if (typeof source.radiusMax !== 'undefined') out.radiusMax = source.radiusMax;
         if (typeof source.fog !== 'undefined') out.fog = source.fog;
         if (typeof source.clipFar !== 'undefined') out.clipFar = source.clipFar;
+        if (typeof source.minNear !== 'undefined') out.minNear = source.minNear;
 
         return out;
     }
@@ -303,6 +306,7 @@ namespace Camera {
             && a.radiusMax === b.radiusMax
             && a.fog === b.fog
             && a.clipFar === b.clipFar
+            && a.minNear === b.minNear
             && Vec3.exactEquals(a.position, b.position)
             && Vec3.exactEquals(a.up, b.up)
             && Vec3.exactEquals(a.target, b.target);
@@ -370,7 +374,7 @@ function updatePers(camera: Camera) {
 }
 
 function updateClip(camera: Camera) {
-    let { radius, radiusMax, mode, fog, clipFar } = camera.state;
+    let { radius, radiusMax, mode, fog, clipFar, minNear } = camera.state;
     if (radius < 0.01) radius = 0.01;
 
     const normalizedFar = clipFar ? radius : radiusMax;
@@ -384,12 +388,12 @@ function updateClip(camera: Camera) {
 
     if (mode === 'perspective') {
         // set at least to 5 to avoid slow sphere impostor rendering
-        near = Math.max(Math.min(radiusMax, 5), near);
-        far = Math.max(5, far);
+        near = Math.max(Math.min(radiusMax, minNear), near);
+        far = Math.max(minNear, far);
     } else {
         // not too close to 0 as it causes issues with outline rendering
-        near = Math.max(Math.min(radiusMax, 5), near);
-        far = Math.max(5, far);
+        near = Math.max(Math.min(radiusMax, minNear), near);
+        far = Math.max(minNear, far);
     }
 
     if (near === far) {

+ 6 - 1
src/mol-canvas3d/canvas3d.ts

@@ -65,6 +65,7 @@ export const Canvas3DParams = {
     cameraClipping: PD.Group({
         radius: PD.Numeric(100, { min: 0, max: 99, step: 1 }, { label: 'Clipping', description: 'How much of the scene to show.' }),
         far: PD.Boolean(true, { description: 'Hide scene in the distance' }),
+        minNear: PD.Numeric(5, { min: 0.1, max: 10, step: 0.1 }, { description: 'Note, may cause performance issues rendering impostors when set too small and cause issues with outline rendering when too close to 0.' }),
     }, { pivot: 'radius' }),
     viewport: PD.MappedStatic('canvas', {
         canvas: PD.Group({}),
@@ -322,6 +323,7 @@ namespace Canvas3D {
             mode: p.camera.mode,
             fog: p.cameraFog.name === 'on' ? p.cameraFog.params.intensity : 0,
             clipFar: p.cameraClipping.far,
+            minNear: p.cameraClipping.minNear,
             fov: degToRad(p.camera.fov),
         }, { x, y, width, height }, { pixelScale: attribs.pixelScale });
         const stereoCamera = new StereoCamera(camera, p.camera.stereo.params);
@@ -687,7 +689,7 @@ namespace Canvas3D {
                 cameraFog: camera.state.fog > 0
                     ? { name: 'on' as const, params: { intensity: camera.state.fog } }
                     : { name: 'off' as const, params: {} },
-                cameraClipping: { far: camera.state.clipFar, radius },
+                cameraClipping: { far: camera.state.clipFar, radius, minNear: camera.state.minNear },
                 cameraResetDurationMs: p.cameraResetDurationMs,
                 sceneRadiusFactor: p.sceneRadiusFactor,
                 transparentBackground: p.transparentBackground,
@@ -814,6 +816,9 @@ namespace Canvas3D {
                     if (props.cameraClipping.far !== undefined && props.cameraClipping.far !== camera.state.clipFar) {
                         cameraState.clipFar = props.cameraClipping.far;
                     }
+                    if (props.cameraClipping.minNear !== undefined && props.cameraClipping.minNear !== camera.state.minNear) {
+                        cameraState.minNear = props.cameraClipping.minNear;
+                    }
                     if (props.cameraClipping.radius !== undefined) {
                         const radius = (getSceneRadius() / 100) * (100 - props.cameraClipping.radius);
                         if (radius > 0 && radius !== cameraState.radius) {

+ 1 - 0
src/mol-plugin-ui/viewport/simple-settings.tsx

@@ -135,6 +135,7 @@ const SimpleSettingsMapping = ParamMapping({
         canvas.cameraClipping = {
             radius: s.clipping.radius,
             far: s.clipping.far,
+            minNear: s.clipping.minNear,
         };
 
         props.layout = s.layout;