diff --git a/src/mol-geo/geometry/cylinders/cylinders.ts b/src/mol-geo/geometry/cylinders/cylinders.ts index 99929acd159c5d62398dd813a2892a28d5a7037f..41eadfd43cb4bb2c99baa2b03caa9e8441c499f1 100644 --- a/src/mol-geo/geometry/cylinders/cylinders.ts +++ b/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); } diff --git a/src/mol-geo/geometry/spheres/spheres.ts b/src/mol-geo/geometry/spheres/spheres.ts index b7be6f095ad44f85ee525fc7bd7af1c3f82c6a77..0b82bb7da1ccf980b1543cc212d7cf2f3de60947 100644 --- a/src/mol-geo/geometry/spheres/spheres.ts +++ b/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); } diff --git a/src/mol-gl/renderable/cylinders.ts b/src/mol-gl/renderable/cylinders.ts index db145d3edcf2eeff50f53b50d2eb07134fd8e5c4..cbe4fcd8b67031e723c0861e7335d8fc91066335 100644 --- a/src/mol-gl/renderable/cylinders.ts +++ b/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'), }; diff --git a/src/mol-gl/renderable/spheres.ts b/src/mol-gl/renderable/spheres.ts index 73c0e750754cb7617e34d23d32b2c9c6bf261012..a56b2a1f282e93f12c782c7c89ab305bec614b01 100644 --- a/src/mol-gl/renderable/spheres.ts +++ b/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'), }; diff --git a/src/mol-gl/shader/cylinders.frag.ts b/src/mol-gl/shader/cylinders.frag.ts index f41e64f80059d986c5c7312076d5c8d62ee24f9c..c1169f27a6d3c08ba47fbc71dba835b24d0cf1b3 100644 --- a/src/mol-gl/shader/cylinders.frag.ts +++ b/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; + } } } } diff --git a/src/mol-gl/shader/cylinders.vert.ts b/src/mol-gl/shader/cylinders.vert.ts index ff28e5c1bdc061df4b144510702b59cba75cd687..f9d1a0694409d57700e7624388b495217b119538 100644 --- a/src/mol-gl/shader/cylinders.vert.ts +++ b/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); diff --git a/src/mol-gl/shader/spheres.frag.ts b/src/mol-gl/shader/spheres.frag.ts index 7d5348d9563856df561e9ea7a965939e6302132b..9af2d9d39b2f81ce8fc3e20e0b653d19f282d6f3 100644 --- a/src/mol-gl/shader/spheres.frag.ts +++ b/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;