diff --git a/src/mol-gl/renderable/schema.ts b/src/mol-gl/renderable/schema.ts index 24ab5c36d0bca2f2d710bb059c6d7ca3f041c232..92078c52f47c48b0489ae282fa0c1652e053fa4b 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 335aa8cc5b27241c0e3490eb63da68eed508d3b7..f25e539ed05a89ae4716335015786de083fb534b 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 2b4ad6f805c4d5ddbb95d7aefb0125e4f68f4d69..e140b26d87a5e86dca4609ae9c16db5e92e80645 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 0000000000000000000000000000000000000000..40375bedb6cedf226aab2bb5fc590628cb052758 --- /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 789f6e0491fe03f57e51c6ebc75b86d17fe0eadf..c4daf6f6108a8e0065c096fe2a040740d35ed191 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 28d04173c777ac782cfea172149e2df5c2a948b2..1525fce4da7faa2dacb4815172f91018d811d768 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 2cac7901d90c20fee3fb7d04b1969a0d6da451b1..39e842ada3bed1baa6da0885d86c50bc49d296b0 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 beea4dbec152ff5db80f207436fc0ad30615ec23..426ae9fd131a5387b76dd25612ace3be7fee0e9e 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