소스 검색

wip, solid impostor flag

Alexander Rose 2 년 전
부모
커밋
cba12e487f

+ 3 - 0
src/mol-geo/geometry/cylinders/cylinders.ts

@@ -158,6 +158,7 @@ export namespace Cylinders {
         ignoreLight: PD.Boolean(false, BaseGeometry.ShadingCategory),
         xrayShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
         transparentBackfaces: PD.Select('off', PD.arrayToOptions(['off', 'on', 'opaque']), BaseGeometry.ShadingCategory),
+        solidInterior: PD.Boolean(true, BaseGeometry.ShadingCategory),
         bumpFrequency: PD.Numeric(0, { min: 0, max: 10, step: 0.1 }, BaseGeometry.ShadingCategory),
         bumpAmplitude: PD.Numeric(1, { min: 0, max: 5, step: 0.1 }, BaseGeometry.ShadingCategory),
     };
@@ -245,6 +246,7 @@ export namespace Cylinders {
             dIgnoreLight: ValueCell.create(props.ignoreLight),
             dXrayShaded: ValueCell.create(props.xrayShaded),
             dTransparentBackfaces: ValueCell.create(props.transparentBackfaces),
+            dSolidInterior: ValueCell.create(props.solidInterior),
             uBumpFrequency: ValueCell.create(props.bumpFrequency),
             uBumpAmplitude: ValueCell.create(props.bumpAmplitude),
         };
@@ -263,6 +265,7 @@ export namespace Cylinders {
         ValueCell.updateIfChanged(values.dIgnoreLight, props.ignoreLight);
         ValueCell.updateIfChanged(values.dXrayShaded, props.xrayShaded);
         ValueCell.updateIfChanged(values.dTransparentBackfaces, props.transparentBackfaces);
+        ValueCell.updateIfChanged(values.dSolidInterior, props.solidInterior);
         ValueCell.updateIfChanged(values.uBumpFrequency, props.bumpFrequency);
         ValueCell.updateIfChanged(values.uBumpAmplitude, props.bumpAmplitude);
     }

+ 3 - 0
src/mol-geo/geometry/spheres/spheres.ts

@@ -130,6 +130,7 @@ export namespace Spheres {
         ignoreLight: PD.Boolean(false, BaseGeometry.ShadingCategory),
         xrayShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
         transparentBackfaces: PD.Select('off', PD.arrayToOptions(['off', 'on', 'opaque']), BaseGeometry.ShadingCategory),
+        solidInterior: PD.Boolean(true, BaseGeometry.ShadingCategory),
         bumpFrequency: PD.Numeric(0, { min: 0, max: 10, step: 0.1 }, BaseGeometry.ShadingCategory),
         bumpAmplitude: PD.Numeric(1, { min: 0, max: 5, step: 0.1 }, BaseGeometry.ShadingCategory),
     };
@@ -212,6 +213,7 @@ export namespace Spheres {
             dIgnoreLight: ValueCell.create(props.ignoreLight),
             dXrayShaded: ValueCell.create(props.xrayShaded),
             dTransparentBackfaces: ValueCell.create(props.transparentBackfaces),
+            dSolidInterior: ValueCell.create(props.solidInterior),
             uBumpFrequency: ValueCell.create(props.bumpFrequency),
             uBumpAmplitude: ValueCell.create(props.bumpAmplitude),
         };
@@ -230,6 +232,7 @@ export namespace Spheres {
         ValueCell.updateIfChanged(values.dIgnoreLight, props.ignoreLight);
         ValueCell.updateIfChanged(values.dXrayShaded, props.xrayShaded);
         ValueCell.updateIfChanged(values.dTransparentBackfaces, props.transparentBackfaces);
+        ValueCell.updateIfChanged(values.dSolidInterior, props.solidInterior);
         ValueCell.updateIfChanged(values.uBumpFrequency, props.bumpFrequency);
         ValueCell.updateIfChanged(values.uBumpAmplitude, props.bumpAmplitude);
     }

+ 1 - 0
src/mol-gl/renderable/cylinders.ts

@@ -27,6 +27,7 @@ export const CylindersSchema = {
     dIgnoreLight: DefineSpec('boolean'),
     dXrayShaded: DefineSpec('boolean'),
     dTransparentBackfaces: DefineSpec('string', ['off', 'on', 'opaque']),
+    dSolidInterior: DefineSpec('boolean'),
     uBumpFrequency: UniformSpec('f', 'material'),
     uBumpAmplitude: UniformSpec('f', 'material'),
 };

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

@@ -24,6 +24,7 @@ export const SpheresSchema = {
     dIgnoreLight: DefineSpec('boolean'),
     dXrayShaded: DefineSpec('boolean'),
     dTransparentBackfaces: DefineSpec('string', ['off', 'on', 'opaque']),
+    dSolidInterior: DefineSpec('boolean'),
     uBumpFrequency: UniformSpec('f', 'material'),
     uBumpAmplitude: UniformSpec('f', 'material'),
 };

+ 35 - 7
src/mol-gl/shader/cylinders.frag.ts

@@ -53,6 +53,16 @@ bool CylinderImpostor(
     bool topCap = (vCap > 0.9 && vCap < 1.1) || vCap >= 2.9;
     bool bottomCap = (vCap > 1.9 && vCap < 2.1) || vCap >= 2.9;
 
+    #ifdef dSolidInterior
+        bool topInterior = !topCap;
+        bool bottomInterior = !bottomCap;
+        topCap = true;
+        bottomCap = true;
+    #else
+        bool topInterior = false;
+        bool bottomInterior = false;
+    #endif
+
     // body outside
     h = sqrt(h);
     float t = (-k1 - h) / k2;
@@ -73,18 +83,18 @@ bool CylinderImpostor(
         // top cap
         t = -baoc / bard;
         if (abs(k1 + k2 * t) < h) {
-            interior = false;
+            interior = topInterior;
             cameraNormal = -ba / baba;
             modelPosition = rayOrigin + t * rayDir;
             viewPosition = (uView * vec4(modelPosition, 1.0)).xyz;
             fragmentDepth = calcDepth(viewPosition);
             if (fragmentDepth > 0.0) return true;
         }
-    } else if(bottomCap && y >= 0.0) {
+    } else if (bottomCap && y >= 0.0) {
         // bottom cap
         t = (baba - baoc) / bard;
         if (abs(k1 + k2 * t) < h) {
-            interior = false;
+            interior = bottomInterior;
             cameraNormal = ba / baba;
             modelPosition = rayOrigin + t * rayDir;
             viewPosition = (uView * vec4(modelPosition, 1.0)).xyz;
@@ -104,7 +114,13 @@ bool CylinderImpostor(
             modelPosition = rayOrigin + t * rayDir;
             viewPosition = (uView * vec4(modelPosition, 1.0)).xyz;
             fragmentDepth = calcDepth(viewPosition);
-            return true;
+            if (fragmentDepth > 0.0) {
+                #ifdef dSolidInterior
+                    fragmentDepth = 0.0 + (0.0000001 / vSize);
+                    cameraNormal = -rayDir;
+                #endif
+                return true;
+            }
         }
 
         if (topCap && y < 0.0) {
@@ -116,9 +132,15 @@ bool CylinderImpostor(
                 modelPosition = rayOrigin + t * rayDir;
                 viewPosition = (uView * vec4(modelPosition, 1.0)).xyz;
                 fragmentDepth = calcDepth(viewPosition);
-                if (fragmentDepth > 0.0) return true;
+                if (fragmentDepth > 0.0) {
+                    #ifdef dSolidInterior
+                        fragmentDepth = 0.0 + (0.0000001 / vSize);
+                        cameraNormal = -rayDir;
+                    #endif
+                    return true;
+                }
             }
-        } else if(bottomCap && y >= 0.0) {
+        } else if (bottomCap && y >= 0.0) {
             // bottom cap
             t = (baba - baoc) / bard;
             if (abs(k1 + k2 * t) < -h) {
@@ -127,7 +149,13 @@ bool CylinderImpostor(
                 modelPosition = rayOrigin + t * rayDir;
                 viewPosition = (uView * vec4(modelPosition, 1.0)).xyz;
                 fragmentDepth = calcDepth(viewPosition);
-                if (fragmentDepth > 0.0) return true;
+                if (fragmentDepth > 0.0) {
+                    #ifdef dSolidInterior
+                        fragmentDepth = 0.0 + (0.0000001 / vSize);
+                        cameraNormal = -rayDir;
+                    #endif
+                    return true;
+                }
             }
         }
     }

+ 4 - 3
src/mol-gl/shader/cylinders.vert.ts

@@ -57,9 +57,10 @@ void main() {
     // ensure cylinder 'dir' is pointing towards the camera
     if(dot(camDir, dir) < 0.0) {
         dir = -dir;
-        vec3 tmp = vStart;
-        vStart = vEnd;
-        vEnd = tmp;
+        // TODO: revisit
+        // vec3 tmp = vStart;
+        // vStart = vEnd;
+        // vEnd = tmp;
     }
 
     vec3 left = cross(camDir, dir);

+ 6 - 3
src/mol-gl/shader/spheres.frag.ts

@@ -81,9 +81,12 @@ void main(void){
     vec3 vViewPosition = cameraPos;
     vec3 vModelPosition = modelPos;
 
-    if (interior && !clipped) {
-        fragmentDepth = 0.0 + (0.0000001 / vRadius);
-    }
+    #ifdef dSolidInterior
+        if (interior && !clipped) {
+            fragmentDepth = 0.0 + (0.0000001 / vRadius);
+            cameraNormal = -mix(normalize(vPoint), vec3(0.0, 0.0, 1.0), uIsOrtho);
+        }
+    #endif
 
     gl_FragDepthEXT = fragmentDepth;