From 5a5939408fe6417fdf32413035b5e92f46fc4468 Mon Sep 17 00:00:00 2001 From: Alexander Rose <alexander.rose@weirdbyte.de> Date: Sun, 8 Dec 2019 00:23:18 -0800 Subject: [PATCH] support for interior-color (mesh, spheres) --- src/mol-gl/renderable/schema.ts | 2 + src/mol-gl/renderer.ts | 14 +++++ src/mol-gl/shader-code.ts | 2 + .../chunks/apply-interior-color.glsl.ts | 9 ++++ .../chunks/assign-material-color.glsl.ts | 6 --- .../shader/chunks/common-frag-params.glsl.ts | 3 ++ src/mol-gl/shader/mesh.frag.ts | 3 ++ src/mol-gl/shader/spheres.frag.ts | 52 ++++++------------- 8 files changed, 48 insertions(+), 43 deletions(-) create mode 100644 src/mol-gl/shader/chunks/apply-interior-color.glsl.ts diff --git a/src/mol-gl/renderable/schema.ts b/src/mol-gl/renderable/schema.ts index 24ab5c36d..92078c52f 100644 --- a/src/mol-gl/renderable/schema.ts +++ b/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> } diff --git a/src/mol-gl/renderer.ts b/src/mol-gl/renderer.ts index 335aa8cc5..f25e539ed 100644 --- a/src/mol-gl/renderer.ts +++ b/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) diff --git a/src/mol-gl/shader-code.ts b/src/mol-gl/shader-code.ts index 2b4ad6f80..e140b26d8 100644 --- a/src/mol-gl/shader-code.ts +++ b/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, diff --git a/src/mol-gl/shader/chunks/apply-interior-color.glsl.ts b/src/mol-gl/shader/chunks/apply-interior-color.glsl.ts new file mode 100644 index 000000000..40375bedb --- /dev/null +++ b/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; + } +} +` \ No newline at end of file diff --git a/src/mol-gl/shader/chunks/assign-material-color.glsl.ts b/src/mol-gl/shader/chunks/assign-material-color.glsl.ts index 789f6e049..c4daf6f61 100644 --- a/src/mol-gl/shader/chunks/assign-material-color.glsl.ts +++ b/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); diff --git a/src/mol-gl/shader/chunks/common-frag-params.glsl.ts b/src/mol-gl/shader/chunks/common-frag-params.glsl.ts index 28d04173c..1525fce4d 100644 --- a/src/mol-gl/shader/chunks/common-frag-params.glsl.ts +++ b/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; ` \ No newline at end of file diff --git a/src/mol-gl/shader/mesh.frag.ts b/src/mol-gl/shader/mesh.frag.ts index 2cac7901d..39e842ada 100644 --- a/src/mol-gl/shader/mesh.frag.ts +++ b/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 diff --git a/src/mol-gl/shader/spheres.frag.ts b/src/mol-gl/shader/spheres.frag.ts index beea4dbec..426ae9fd1 100644 --- a/src/mol-gl/shader/spheres.frag.ts +++ b/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 -- GitLab