Bladeren bron

wip, transparency

Alexander Rose 6 jaren geleden
bovenliggende
commit
971dc2f61e

+ 1 - 1
src/mol-gl/_spec/renderer.spec.ts

@@ -138,7 +138,7 @@ describe('renderer', () => {
 
         scene.add(points)
         expect(ctx.bufferCount).toBe(4);
-        expect(ctx.textureCount).toBe(4);
+        expect(ctx.textureCount).toBe(5);
         expect(ctx.vaoCount).toBe(4);
         expect(ctx.programCache.count).toBe(4);
         expect(ctx.shaderCache.count).toBe(8);

+ 2 - 2
src/mol-gl/renderer.ts

@@ -177,7 +177,7 @@ namespace Renderer {
                 gl.depthMask(true)
                 for (let i = 0, il = renderables.length; i < il; ++i) {
                     const r = renderables[i]
-                    if (r.state.opaque) renderObject(r, variant)
+                    if (r.state.opaque && !r.values.dTransparency.ref.value) renderObject(r, variant)
                 }
 
                 gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
@@ -185,7 +185,7 @@ namespace Renderer {
                 for (let i = 0, il = renderables.length; i < il; ++i) {
                     const r = renderables[i]
                     gl.depthMask(r.values.uAlpha.ref.value === 1.0)
-                    if (!r.state.opaque) renderObject(r, variant)
+                    if (!r.state.opaque || r.values.dTransparency.ref.value) renderObject(r, variant)
                 }
             } else {
                 // picking

+ 1 - 1
src/mol-gl/shader/chunks/assign-color-varying.glsl

@@ -19,5 +19,5 @@
 #endif
 
 #ifdef dTransparency
-    vTransparency = readFromTexture(tTransparency, aInstance * float(uGroupCount) + aGroup, uTransparencyTexDim);
+    vTransparency = readFromTexture(tTransparency, aInstance * float(uGroupCount) + aGroup, uTransparencyTexDim).a;
 #endif

+ 36 - 1
src/mol-gl/shader/chunks/assign-material-color.glsl

@@ -13,5 +13,40 @@
 
 // apply transparency
 #if defined(dTransparency) && (defined(dColorType_uniform) || defined(dColorType_attribute) || defined(dColorType_instance) || defined(dColorType_group) || defined(dColorType_groupInstance))
-    material.a *= 1 - vTransparency;
+    float ma = material.a * (1.0 - vTransparency);
+    ivec2 pixelCoord = ivec2(gl_FragCoord.xy);
+
+    // const mat4 thresholdMatrix = mat4(
+    //     1.0 / 17.0,  9.0 / 17.0,  3.0 / 17.0, 11.0 / 17.0,
+    //     13.0 / 17.0,  5.0 / 17.0, 15.0 / 17.0,  7.0 / 17.0,
+    //     4.0 / 17.0, 12.0 / 17.0,  2.0 / 17.0, 10.0 / 17.0,
+    //     16.0 / 17.0,  8.0 / 17.0, 14.0 / 17.0,  6.0 / 17.0
+    // );
+    // float at = thresholdMatrix[pixelCoord.x % 4][pixelCoord.y % 4];
+
+    // https://research.nvidia.com/publication/hashed-alpha-testing
+    // Find the discretized derivatives of our coordinates
+    float maxDeriv = max(length(dFdx(vViewPosition)), length(dFdy(vViewPosition)));
+    float pixScale = 1.0 / maxDeriv;
+    // Find two nearest log-discretized noise scales
+    vec2 pixScales = vec2(exp2(floor(log2(pixScale))), exp2(ceil(log2(pixScale))));
+    // Compute alpha thresholds at our two noise scales
+    vec2 alpha = vec2(hash3d(floor(pixScales.x * vViewPosition)), hash3d(floor(pixScales.y * vViewPosition)));
+    // Factor to interpolate lerp with
+    float lerpFactor = fract(log2(pixScale));
+    // Interpolate alpha threshold from noise at two scales
+    float x = (1.0 - lerpFactor) * alpha.x + lerpFactor * alpha.y;
+    // Pass into CDF to compute uniformly distrib threshold
+    float a = min(lerpFactor, 1.0 - lerpFactor);
+    vec3 cases = vec3(
+        x * x / (2.0 * a * (1.0 - a)),
+        (x - 0.5 * a) / (1.0 - a),
+        1.0 - ((1.0 - x) * (1.0 - x) / (2.0 * a * (1.0 - a)))
+    );
+    // Find our final, uniformly distributed alpha threshold
+    float at = (x < (1.0 - a)) ? ((x < a) ? cases.x : cases.y) : cases.z;
+    // Avoids ατ == 0. Could also do
+    at = clamp(at, 1.0e-6, 1.0);
+
+    if (ma < 0.99 && (ma < 0.01 || ma < at)) discard;
 #endif

+ 8 - 0
src/mol-gl/shader/chunks/common.glsl

@@ -1,6 +1,14 @@
 float intDiv(float a, float b) { return float(int(a) / int(b)); }
 float intMod(float a, float b) { return a - b * float(int(a) / int(b)); }
 
+float hash2d(vec2 coord2d) {
+    return fract(1.0e4 * sin(17.0 * coord2d.x + 0.1 * coord2d.y) * (0.1 + abs(sin(13.0 * coord2d.y + coord2d.x))));
+}
+
+float hash3d(vec3 coord3d) {
+    return hash2d(vec2(hash2d(coord3d.xy), coord3d.z));
+}
+
 #if __VERSION__ != 300
     // transpose
 

+ 1 - 0
src/mol-repr/structure/complex-representation.ts

@@ -69,6 +69,7 @@ export function ComplexRepresentation<P extends StructureParams>(label: string,
         if (state.alphaFactor !== undefined && visual) visual.setAlphaFactor(state.alphaFactor)
         if (state.pickable !== undefined && visual) visual.setPickable(state.pickable)
         if (state.overpaint !== undefined && visual) visual.setOverpaint(state.overpaint)
+        if (state.transparency !== undefined && visual) visual.setTransparency(state.transparency)
         if (state.transform !== undefined && visual) visual.setTransform(state.transform)
         if (state.unitTransforms !== undefined && visual) {
             // Since ComplexVisuals always renders geometries between units the application of `unitTransforms`

+ 1 - 1
src/mol-repr/structure/complex-visual.ts

@@ -197,7 +197,7 @@ export function ComplexVisual<G extends Geometry, P extends ComplexParams & Geom
         setTransform(matrix?: Mat4, instanceMatrices?: Float32Array | null) {
             Visual.setTransform(renderObject, matrix, instanceMatrices)
         },
-        setOverpaint(overpaint: Overpaint, clear = false) {
+        setOverpaint(overpaint: Overpaint) {
             return Visual.setOverpaint(renderObject, overpaint, lociApply, true)
         },
         setTransparency(transparency: Transparency) {

+ 2 - 1
src/mol-repr/structure/units-representation.ts

@@ -172,11 +172,12 @@ export function UnitsRepresentation<P extends UnitsParams>(label: string, ctx: R
     }
 
     function setState(state: Partial<StructureRepresentationState>) {
-        const { visible, alphaFactor, pickable, overpaint, transform, unitTransforms } = state
+        const { visible, alphaFactor, pickable, overpaint, transparency, transform, unitTransforms } = state
         if (visible !== undefined) visuals.forEach(({ visual }) => visual.setVisibility(visible))
         if (alphaFactor !== undefined) visuals.forEach(({ visual }) => visual.setAlphaFactor(alphaFactor))
         if (pickable !== undefined) visuals.forEach(({ visual }) => visual.setPickable(pickable))
         if (overpaint !== undefined) visuals.forEach(({ visual }) => visual.setOverpaint(overpaint))
+        if (transparency !== undefined) visuals.forEach(({ visual }) => visual.setTransparency(transparency))
         if (transform !== undefined) visuals.forEach(({ visual }) => visual.setTransform(transform))
         if (unitTransforms !== undefined) {
             visuals.forEach(({ visual, group }) => {

+ 1 - 0
src/mol-repr/visual.ts

@@ -97,6 +97,7 @@ namespace Visual {
             lociApply(loci, apply)
         }
         ValueCell.update(tOverpaint, tOverpaint.ref.value)
+        console.log(renderObject)
     }
 
     export function setTransparency(renderObject: GraphicsRenderObject | undefined, transparency: Transparency, lociApply: LociApply, clear: boolean) {

+ 1 - 0
src/mol-repr/volume/representation.ts

@@ -254,6 +254,7 @@ export function VolumeRepresentation<P extends VolumeParams>(label: string, ctx:
         if (state.alphaFactor !== undefined && visual) visual.setAlphaFactor(state.alphaFactor)
         if (state.pickable !== undefined && visual) visual.setPickable(state.pickable)
         if (state.overpaint !== undefined && visual) visual.setOverpaint(state.overpaint)
+        if (state.transparency !== undefined && visual) visual.setTransparency(state.transparency)
         if (state.transform !== undefined && visual) visual.setTransform(state.transform)
 
         Representation.updateState(_state, state)