Browse Source

support for interior-color (mesh, spheres)

Alexander Rose 5 years ago
parent
commit
5a5939408f

+ 2 - 0
src/mol-gl/renderable/schema.ts

@@ -171,6 +171,8 @@ export const GlobalUniformSchema = {
     uTransparentBackground: UniformSpec('i'),
     uPickingAlphaThreshold: UniformSpec('f'),
     uInteriorDarkening: UniformSpec('f'),
+    uInteriorColorFlag: UniformSpec('i'),
+    uInteriorColor: UniformSpec('v3'),
 }
 export type GlobalUniformSchema = typeof GlobalUniformSchema
 export type GlobalUniformValues = Values<GlobalUniformSchema> // { [k in keyof GlobalUniformSchema]: ValueCell<any> }

+ 14 - 0
src/mol-gl/renderer.ts

@@ -49,6 +49,8 @@ export const RendererParams = {
     transparentBackground: PD.Boolean(false, { description: 'Background opacity of the 3D canvas' }),
     pickingAlphaThreshold: PD.Numeric(0.5, { min: 0.0, max: 1.0, step: 0.01 }, { description: 'The minimum opacity value needed for an object to be pickable.' }),
     interiorDarkening: PD.Numeric(0.5, { min: 0.0, max: 1.0, step: 0.01 }),
+    interiorColorFlag: PD.Boolean(true),
+    interiorColor: PD.Color(Color.fromNormalizedRgb(0.3, 0.3, 0.3)),
 
     lightIntensity: PD.Numeric(0.6, { min: 0.0, max: 1.0, step: 0.01 }),
     ambientIntensity: PD.Numeric(0.4, { min: 0.0, max: 1.0, step: 0.01 }),
@@ -66,6 +68,7 @@ namespace Renderer {
 
         const viewport = Viewport()
         const bgColor = Color.toVec3Normalized(Vec3(), p.backgroundColor)
+        const interiorColor = Color.toVec3Normalized(Vec3(), p.interiorColor)
 
         const view = Mat4()
         const invView = Mat4()
@@ -112,6 +115,8 @@ namespace Renderer {
             uTransparentBackground: ValueCell.create(p.transparentBackground ? 1 : 0),
             uPickingAlphaThreshold: ValueCell.create(p.pickingAlphaThreshold),
             uInteriorDarkening: ValueCell.create(p.interiorDarkening),
+            uInteriorColorFlag: ValueCell.create(p.interiorColorFlag ? 1 : 0),
+            uInteriorColor: ValueCell.create(interiorColor),
         }
         const globalUniformList = Object.entries(globalUniforms)
 
@@ -243,6 +248,15 @@ namespace Renderer {
                     p.interiorDarkening = props.interiorDarkening
                     ValueCell.update(globalUniforms.uInteriorDarkening, p.interiorDarkening)
                 }
+                if (props.interiorColorFlag !== undefined && props.interiorColorFlag !== p.interiorColorFlag) {
+                    p.interiorColorFlag = props.interiorColorFlag
+                    ValueCell.update(globalUniforms.uInteriorColorFlag, p.interiorColorFlag ? 1 : 0)
+                }
+                if (props.interiorColor !== undefined && props.interiorColor !== p.interiorColor) {
+                    p.interiorColor = props.interiorColor
+                    Color.toVec3Normalized(interiorColor, p.interiorColor)
+                    ValueCell.update(globalUniforms.uInteriorColor, Vec3.copy(globalUniforms.uInteriorColor.ref.value, interiorColor))
+                }
                 if (props.backgroundColor !== undefined && props.backgroundColor !== p.backgroundColor) {
                     p.backgroundColor = props.backgroundColor
                     Color.toVec3Normalized(bgColor, p.backgroundColor)

+ 2 - 0
src/mol-gl/shader-code.ts

@@ -30,6 +30,7 @@ export interface ShaderCode {
 }
 
 import apply_fog from './shader/chunks/apply-fog.glsl'
+import apply_interior_color from './shader/chunks/apply-interior-color.glsl'
 import apply_light_color from './shader/chunks/apply-light-color.glsl'
 import apply_marker_color from './shader/chunks/apply-marker-color.glsl'
 import assign_color_varying from './shader/chunks/assign-color-varying.glsl'
@@ -55,6 +56,7 @@ import texture3d_from_2d_nearest from './shader/chunks/texture3d-from-2d-nearest
 
 const ShaderChunks: { [k: string]: string } = {
     apply_fog,
+    apply_interior_color,
     apply_light_color,
     apply_marker_color,
     assign_color_varying,

+ 9 - 0
src/mol-gl/shader/chunks/apply-interior-color.glsl.ts

@@ -0,0 +1,9 @@
+export default `
+if (interior) {
+    if (uInteriorColorFlag == 1) {
+        gl_FragColor.rgb = uInteriorColor;
+    } else {
+        gl_FragColor.rgb *= 1.0 - uInteriorDarkening;
+    }
+}
+`

+ 0 - 6
src/mol-gl/shader/chunks/assign-material-color.glsl.ts

@@ -13,12 +13,6 @@ export default `
     #endif
 #endif
 
-#if defined(dColorType_uniform) || defined(dColorType_attribute) || defined(dColorType_instance) || defined(dColorType_group) || defined(dColorType_groupInstance)
-    if (gl_FrontFacing == false) {
-        material.rgb *= 1.0 - uInteriorDarkening;
-    }
-#endif
-
 // mix material with overpaint
 #if defined(dOverpaint) && (defined(dColorType_uniform) || defined(dColorType_attribute) || defined(dColorType_instance) || defined(dColorType_group) || defined(dColorType_groupInstance))
     material.rgb = mix(material.rgb, vOverpaint.rgb, vOverpaint.a);

+ 3 - 0
src/mol-gl/shader/chunks/common-frag-params.glsl.ts

@@ -25,4 +25,7 @@ uniform int uPickable;
 uniform int uTransparentBackground;
 
 uniform float uInteriorDarkening;
+uniform int uInteriorColorFlag;
+uniform vec3 uInteriorColor;
+bool interior;
 `

+ 3 - 0
src/mol-gl/shader/mesh.frag.ts

@@ -15,6 +15,7 @@ precision highp int;
 #include normal_frag_params
 
 void main() {
+    interior = !gl_FrontFacing; // TODO take dFlipSided into account
     #include assign_material_color
 
     #if defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking)
@@ -29,6 +30,8 @@ void main() {
             #include assign_normal
             #include apply_light_color
         #endif
+
+        #include apply_interior_color
         #include apply_marker_color
         #include apply_fog
     #endif

+ 15 - 37
src/mol-gl/shader/spheres.frag.ts

@@ -23,8 +23,6 @@ varying float vRadiusSq;
 varying vec3 vPoint;
 varying vec3 vPointViewPosition;
 
-bool flag2 = false;
-bool interior = false;
 vec3 cameraPos;
 vec3 cameraNormal;
 
@@ -60,21 +58,13 @@ bool Impostor(out vec3 cameraPos, out vec3 cameraNormal){
 
     cameraPos = rayDirection * negT + rayOrigin;
 
-    #ifdef NEAR_CLIP
-        if (calcDepth(cameraPos) <= 0.0){
-            cameraPos = rayDirection * posT + rayOrigin;
-            interior = true;
-        } else if(calcClip(cameraPos) > 0.0) {
-            cameraPos = rayDirection * posT + rayOrigin;
-            interior = true;
-            flag2 = true;
-        }
-    #else
-        if (calcDepth(cameraPos) <= 0.0) {
-            cameraPos = rayDirection * posT + rayOrigin;
-            interior = true;
-        }
-    #endif
+    
+    if (calcDepth(cameraPos) <= 0.0) {
+        cameraPos = rayDirection * posT + rayOrigin;
+        interior = true;
+    } else {
+        interior = false;
+    }
 
     cameraNormal = normalize(cameraPos - cameraSpherePos);
     cameraNormal *= float(!interior) * 2.0 - 1.0;
@@ -84,29 +74,16 @@ bool Impostor(out vec3 cameraPos, out vec3 cameraNormal){
 
 void main(void){
     bool flag = Impostor(cameraPos, cameraNormal);
-
-    #ifdef NEAR_CLIP
-        if (calcClip(cameraPos) > 0.0)
+    #ifndef dDoubleSided
+        if (interior)
             discard;
     #endif
 
     // FIXME not compatible with custom clipping plane
     // Set the depth based on the new cameraPos.
     gl_FragDepthEXT = calcDepth(cameraPos);
-    if (!flag) {
-        // clamp to near clipping plane and add a tiny value to
-        // make spheres with a greater radius occlude smaller ones
-        #ifdef NEAR_CLIP
-            if (flag2) {
-                gl_FragDepthEXT = max(0.0, calcDepth(vec3(-(uClipNear - 0.5))) + (0.0000001 / vRadius));
-            } else if (gl_FragDepthEXT >= 0.0) {
-                gl_FragDepthEXT = 0.0 + (0.0000001 / vRadius);
-            }
-        #else
-            if (gl_FragDepthEXT >= 0.0) {
-                gl_FragDepthEXT = 0.0 + (0.0000001 / vRadius);
-            }
-        #endif
+    if (!flag && gl_FragDepthEXT >= 0.0) {
+        gl_FragDepthEXT = 0.0 + (0.0000001 / vRadius);
     }
 
     // bugfix (mac only?)
@@ -126,11 +103,12 @@ void main(void){
         #ifdef dIgnoreLight
             gl_FragColor = material;
         #else
-        vec3 normal = -cameraNormal;
-        vec3 vViewPosition = cameraPos;
-        #include apply_light_color
+            vec3 normal = -cameraNormal;
+            vec3 vViewPosition = cameraPos;
+            #include apply_light_color
         #endif
 
+        #include apply_interior_color
         #include apply_marker_color
         #include apply_fog
     #endif