From aa931fab7bf77adb8e72e6567480c52999918abf Mon Sep 17 00:00:00 2001
From: Alexander Rose <alexander.rose@weirdbyte.de>
Date: Sat, 23 Jul 2022 12:45:24 -0700
Subject: [PATCH] add dVaryingGroup to avoid flat qualifier more

---
 CHANGELOG.md                                  |  1 +
 src/mol-geo/geometry/mesh/mesh.ts             |  4 ++++
 .../geometry/texture-mesh/texture-mesh.ts     |  3 +++
 src/mol-gl/renderable/mesh.ts                 |  1 +
 src/mol-gl/renderable/texture-mesh.ts         |  2 +-
 .../shader/chunks/color-frag-params.glsl.ts   |  3 ++-
 .../shader/chunks/color-vert-params.glsl.ts   |  3 ++-
 .../shader/chunks/common-frag-params.glsl.ts  | 10 ++++++----
 .../shader/chunks/common-vert-params.glsl.ts  | 10 ++++++----
 src/mol-model-formats/shape/ply.ts            |  6 +++++-
 .../structure/visual/gaussian-surface-mesh.ts | 19 +++++++++++++++++--
 .../visual/molecular-surface-mesh.ts          |  8 +++++++-
 src/mol-repr/volume/isosurface.ts             |  6 ++++++
 13 files changed, 61 insertions(+), 15 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 243602929..463462db5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ Note that since we don't clearly distinguish between a public and private interf
 - Fix: only update camera state if manualReset is off (#494)
 - Improve handling principal axes of points in a plane
 - Add 'material' annotation support for textures
+- More effort to avoid using ``flat`` qualifier in shaders: add ``dVaryingGroup``
 
 ## [v3.12.1] - 2022-07-20
 
diff --git a/src/mol-geo/geometry/mesh/mesh.ts b/src/mol-geo/geometry/mesh/mesh.ts
index 29b08ba3a..10b9c9b05 100644
--- a/src/mol-geo/geometry/mesh/mesh.ts
+++ b/src/mol-geo/geometry/mesh/mesh.ts
@@ -45,6 +45,8 @@ export interface Mesh {
     readonly normalBuffer: ValueCell<Float32Array>,
     /** Group buffer as array of group ids for each vertex wrapped in a value cell */
     readonly groupBuffer: ValueCell<Float32Array>,
+    /** Indicates that group may vary within a triangle, wrapped in a value cell */
+    readonly varyingGroup: ValueCell<boolean>,
 
     /** Bounding sphere of the mesh */
     readonly boundingSphere: Sphere3D
@@ -95,6 +97,7 @@ export namespace Mesh {
             indexBuffer: ValueCell.create(indices),
             normalBuffer: ValueCell.create(normals),
             groupBuffer: ValueCell.create(groups),
+            varyingGroup: ValueCell.create(false),
             get boundingSphere() {
                 const newHash = hashCode(mesh);
                 if (newHash !== currentHash) {
@@ -686,6 +689,7 @@ export namespace Mesh {
             aNormal: mesh.normalBuffer,
             aGroup: mesh.groupBuffer,
             elements: mesh.indexBuffer,
+            dVaryingGroup: mesh.varyingGroup,
             boundingSphere: ValueCell.create(boundingSphere),
             invariantBoundingSphere: ValueCell.create(invariantBoundingSphere),
             uInvariantBoundingSphere: ValueCell.create(Vec4.ofSphere(invariantBoundingSphere)),
diff --git a/src/mol-geo/geometry/texture-mesh/texture-mesh.ts b/src/mol-geo/geometry/texture-mesh/texture-mesh.ts
index 8c9415439..0a246b3e0 100644
--- a/src/mol-geo/geometry/texture-mesh/texture-mesh.ts
+++ b/src/mol-geo/geometry/texture-mesh/texture-mesh.ts
@@ -38,6 +38,7 @@ export interface TextureMesh {
     readonly vertexTexture: ValueCell<Texture>,
     readonly groupTexture: ValueCell<Texture>,
     readonly normalTexture: ValueCell<Texture>,
+    readonly varyingGroup: ValueCell<boolean>,
     readonly doubleBuffer: TextureMesh.DoubleBuffer
 
     readonly boundingSphere: Sphere3D
@@ -92,6 +93,7 @@ export namespace TextureMesh {
                 vertexTexture: ValueCell.create(vertexTexture),
                 groupTexture: ValueCell.create(groupTexture),
                 normalTexture: ValueCell.create(normalTexture),
+                varyingGroup: ValueCell.create(false),
                 doubleBuffer: new DoubleBuffer(),
                 boundingSphere: Sphere3D.clone(boundingSphere),
                 meta: {}
@@ -157,6 +159,7 @@ export namespace TextureMesh {
             tPosition: textureMesh.vertexTexture,
             tGroup: textureMesh.groupTexture,
             tNormal: textureMesh.normalTexture,
+            dVaryingGroup: textureMesh.varyingGroup,
 
             boundingSphere: ValueCell.create(boundingSphere),
             invariantBoundingSphere: ValueCell.create(invariantBoundingSphere),
diff --git a/src/mol-gl/renderable/mesh.ts b/src/mol-gl/renderable/mesh.ts
index 5b04ba32b..fa5244d23 100644
--- a/src/mol-gl/renderable/mesh.ts
+++ b/src/mol-gl/renderable/mesh.ts
@@ -17,6 +17,7 @@ export const MeshSchema = {
     aPosition: AttributeSpec('float32', 3, 0),
     aNormal: AttributeSpec('float32', 3, 0),
     elements: ElementsSpec('uint32'),
+    dVaryingGroup: DefineSpec('boolean'),
     dFlatShaded: DefineSpec('boolean'),
     uDoubleSided: UniformSpec('b', 'material'),
     dFlipSided: DefineSpec('boolean'),
diff --git a/src/mol-gl/renderable/texture-mesh.ts b/src/mol-gl/renderable/texture-mesh.ts
index 48cd5ce00..2436be94e 100644
--- a/src/mol-gl/renderable/texture-mesh.ts
+++ b/src/mol-gl/renderable/texture-mesh.ts
@@ -17,7 +17,7 @@ export const TextureMeshSchema = {
     tPosition: TextureSpec('texture', 'rgb', 'float', 'nearest'),
     tGroup: TextureSpec('texture', 'alpha', 'float', 'nearest'),
     tNormal: TextureSpec('texture', 'rgb', 'float', 'nearest'),
-
+    dVaryingGroup: DefineSpec('boolean'),
     dFlatShaded: DefineSpec('boolean'),
     uDoubleSided: UniformSpec('b', 'material'),
     dFlipSided: DefineSpec('boolean'),
diff --git a/src/mol-gl/shader/chunks/color-frag-params.glsl.ts b/src/mol-gl/shader/chunks/color-frag-params.glsl.ts
index 82d1601d2..4027046f9 100644
--- a/src/mol-gl/shader/chunks/color-frag-params.glsl.ts
+++ b/src/mol-gl/shader/chunks/color-frag-params.glsl.ts
@@ -27,7 +27,7 @@ uniform float uBumpiness;
         varying vec4 vSubstance;
     #endif
 #elif defined(dRenderVariant_pick)
-    #if __VERSION__ == 100
+    #if __VERSION__ == 100 || !defined(dVaryingGroup)
         #ifdef requiredDrawBuffers
             varying vec4 vObject;
             varying vec4 vInstance;
@@ -36,6 +36,7 @@ uniform float uBumpiness;
             varying vec4 vColor;
         #endif
     #else
+        // avoid flat until EXT_provoking_vertex is supported
         #ifdef requiredDrawBuffers
             flat in vec4 vObject;
             flat in vec4 vInstance;
diff --git a/src/mol-gl/shader/chunks/color-vert-params.glsl.ts b/src/mol-gl/shader/chunks/color-vert-params.glsl.ts
index 5459d2fc3..0b4c5c45f 100644
--- a/src/mol-gl/shader/chunks/color-vert-params.glsl.ts
+++ b/src/mol-gl/shader/chunks/color-vert-params.glsl.ts
@@ -55,7 +55,7 @@ uniform float uBumpiness;
         #endif
     #endif
 #elif defined(dRenderVariant_pick)
-    #if __VERSION__ == 100
+    #if __VERSION__ == 100 || !defined(dVaryingGroup)
         #ifdef requiredDrawBuffers
             varying vec4 vObject;
             varying vec4 vInstance;
@@ -64,6 +64,7 @@ uniform float uBumpiness;
             varying vec4 vColor;
         #endif
     #else
+        // avoid flat until EXT_provoking_vertex is supported
         #ifdef requiredDrawBuffers
             flat out vec4 vObject;
             flat out vec4 vInstance;
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 ed80baa09..5722cb8a2 100644
--- a/src/mol-gl/shader/chunks/common-frag-params.glsl.ts
+++ b/src/mol-gl/shader/chunks/common-frag-params.glsl.ts
@@ -14,10 +14,11 @@ uniform int uMarkingType;
     uniform vec3 uClipObjectScale[dClipObjectCount];
 
     #if defined(dClipping)
-        #if __VERSION__ == 100 || defined(dClippingType_instance)
+        #if __VERSION__ == 100 || defined(dClippingType_instance) || !defined(dVaryingGroup)
             varying float vClipping;
         #else
-            flat in float vClipping; // avoid if possible, causes slowdown, ASR
+            // avoid flat until EXT_provoking_vertex is supported
+            flat in float vClipping;
         #endif
     #endif
 #endif
@@ -32,10 +33,11 @@ uniform int uMarkingType;
 
 #if defined(dNeedsMarker)
     uniform float uMarker;
-    #if __VERSION__ == 100 || defined(dMarkerType_instance)
+    #if __VERSION__ == 100 || defined(dMarkerType_instance) || !defined(dVaryingGroup)
         varying float vMarker;
     #else
-        flat in float vMarker; // avoid if possible, causes slowdown, ASR
+        // avoid flat until EXT_provoking_vertex is supported
+        flat in float vMarker;
     #endif
 #endif
 
diff --git a/src/mol-gl/shader/chunks/common-vert-params.glsl.ts b/src/mol-gl/shader/chunks/common-vert-params.glsl.ts
index e93faa764..2e391530c 100644
--- a/src/mol-gl/shader/chunks/common-vert-params.glsl.ts
+++ b/src/mol-gl/shader/chunks/common-vert-params.glsl.ts
@@ -21,10 +21,11 @@ uniform int uPickType;
     #if defined(dClipping)
         uniform vec2 uClippingTexDim;
         uniform sampler2D tClipping;
-        #if __VERSION__ == 100 || defined(dClippingType_instance)
+        #if __VERSION__ == 100 || defined(dClippingType_instance) || !defined(dVaryingGroup)
             varying float vClipping;
         #else
-            flat out float vClipping; // avoid if possible, causes slowdown, ASR
+            // avoid flat until EXT_provoking_vertex is supported
+            flat out float vClipping;
         #endif
     #endif
 #endif
@@ -33,10 +34,11 @@ uniform int uPickType;
     uniform float uMarker;
     uniform vec2 uMarkerTexDim;
     uniform sampler2D tMarker;
-    #if __VERSION__ == 100 || defined(dMarkerType_instance)
+    #if __VERSION__ == 100 || defined(dMarkerType_instance) || !defined(dVaryingGroup)
         varying float vMarker;
     #else
-        flat out float vMarker; // avoid if possible, causes slowdown, ASR
+        // avoid flat until EXT_provoking_vertex is supported
+        flat out float vMarker;
     #endif
 #endif
 
diff --git a/src/mol-model-formats/shape/ply.ts b/src/mol-model-formats/shape/ply.ts
index d94a8047f..3d488a888 100644
--- a/src/mol-model-formats/shape/ply.ts
+++ b/src/mol-model-formats/shape/ply.ts
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Schäfer, Marco <marco.schaefer@uni-tuebingen.de>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -19,6 +19,7 @@ import { ParamDefinition as PD } from '../../mol-util/param-definition';
 import { ColorNames } from '../../mol-util/color/names';
 import { deepClone } from '../../mol-util/object';
 import { stringToWords } from '../../mol-util/string';
+import { ValueCell } from '../../mol-util/value-cell';
 
 // TODO support 'edge' element, see https://www.mathworks.com/help/vision/ug/the-ply-format.html
 // TODO support missing face element
@@ -170,6 +171,9 @@ async function getMesh(ctx: RuntimeContext, vertex: PlyTable, face: PlyList, gro
     const m = MeshBuilder.getMesh(builderState);
     if (!hasNormals) Mesh.computeNormals(m);
 
+    // TODO: check if needed
+    ValueCell.updateIfChanged(m.varyingGroup, true);
+
     return m;
 }
 
diff --git a/src/mol-repr/structure/visual/gaussian-surface-mesh.ts b/src/mol-repr/structure/visual/gaussian-surface-mesh.ts
index 884f70452..bab823704 100644
--- a/src/mol-repr/structure/visual/gaussian-surface-mesh.ts
+++ b/src/mol-repr/structure/visual/gaussian-surface-mesh.ts
@@ -28,6 +28,7 @@ import { applyTextureMeshColorSmoothing } from '../../../mol-geo/geometry/textur
 import { ColorSmoothingParams, getColorSmoothingProps } from '../../../mol-geo/geometry/base';
 import { Vec3 } from '../../../mol-math/linear-algebra';
 import { isTimingMode } from '../../../mol-util/debug';
+import { ValueCell } from '../../../mol-util/value-cell';
 
 const SharedParams = {
     ...GaussianDensityParams,
@@ -101,7 +102,12 @@ async function createGaussianSurfaceMesh(ctx: VisualContext, unit: Unit, structu
     (surface.meta.resolution as GaussianSurfaceMeta['resolution']) = resolution;
 
     Mesh.transform(surface, transform);
-    if (ctx.webgl && !ctx.webgl.isWebGL2) Mesh.uniformTriangleGroup(surface);
+    if (ctx.webgl && !ctx.webgl.isWebGL2) {
+        Mesh.uniformTriangleGroup(surface);
+        ValueCell.updateIfChanged(surface.varyingGroup, false);
+    } else {
+        ValueCell.updateIfChanged(surface.varyingGroup, true);
+    }
 
     const sphere = Sphere3D.expand(Sphere3D(), unit.boundary.sphere, maxRadius);
     surface.setBoundingSphere(sphere);
@@ -162,7 +168,12 @@ async function createStructureGaussianSurfaceMesh(ctx: VisualContext, structure:
     (surface.meta.resolution as GaussianSurfaceMeta['resolution']) = resolution;
 
     Mesh.transform(surface, transform);
-    if (ctx.webgl && !ctx.webgl.isWebGL2) Mesh.uniformTriangleGroup(surface);
+    if (ctx.webgl && !ctx.webgl.isWebGL2) {
+        Mesh.uniformTriangleGroup(surface);
+        ValueCell.updateIfChanged(surface.varyingGroup, false);
+    } else {
+        ValueCell.updateIfChanged(surface.varyingGroup, true);
+    }
 
     const sphere = Sphere3D.expand(Sphere3D(), structure.boundary.sphere, maxRadius);
     surface.setBoundingSphere(sphere);
@@ -237,6 +248,8 @@ async function createGaussianSurfaceTextureMesh(ctx: VisualContext, unit: Unit,
     const surface = TextureMesh.create(gv.vertexCount, groupCount, gv.vertexTexture, gv.groupTexture, gv.normalTexture, boundingSphere, textureMesh);
     (surface.meta as GaussianSurfaceMeta).resolution = densityTextureData.resolution;
 
+    ValueCell.updateIfChanged(surface.varyingGroup, ctx.webgl.isWebGL2);
+
     return surface;
 }
 
@@ -311,6 +324,8 @@ async function createStructureGaussianSurfaceTextureMesh(ctx: VisualContext, str
     const surface = TextureMesh.create(gv.vertexCount, groupCount, gv.vertexTexture, gv.groupTexture, gv.normalTexture, boundingSphere, textureMesh);
     (surface.meta as GaussianSurfaceMeta).resolution = densityTextureData.resolution;
 
+    ValueCell.updateIfChanged(surface.varyingGroup, ctx.webgl.isWebGL2);
+
     return surface;
 }
 
diff --git a/src/mol-repr/structure/visual/molecular-surface-mesh.ts b/src/mol-repr/structure/visual/molecular-surface-mesh.ts
index 173a5181c..72e1a972c 100644
--- a/src/mol-repr/structure/visual/molecular-surface-mesh.ts
+++ b/src/mol-repr/structure/visual/molecular-surface-mesh.ts
@@ -22,6 +22,7 @@ import { Texture } from '../../../mol-gl/webgl/texture';
 import { WebGLContext } from '../../../mol-gl/webgl/context';
 import { applyMeshColorSmoothing } from '../../../mol-geo/geometry/mesh/color-smoothing';
 import { ColorSmoothingParams, getColorSmoothingProps } from '../../../mol-geo/geometry/base';
+import { ValueCell } from '../../../mol-util';
 
 export const MolecularSurfaceMeshParams = {
     ...UnitsMeshParams,
@@ -55,7 +56,12 @@ async function createMolecularSurfaceMesh(ctx: VisualContext, unit: Unit, struct
     }
 
     Mesh.transform(surface, transform);
-    if (ctx.webgl && !ctx.webgl.isWebGL2) Mesh.uniformTriangleGroup(surface);
+    if (ctx.webgl && !ctx.webgl.isWebGL2) {
+        Mesh.uniformTriangleGroup(surface);
+        ValueCell.updateIfChanged(surface.varyingGroup, false);
+    } else {
+        ValueCell.updateIfChanged(surface.varyingGroup, true);
+    }
 
     const sphere = Sphere3D.expand(Sphere3D(), unit.boundary.sphere, maxRadius);
     surface.setBoundingSphere(sphere);
diff --git a/src/mol-repr/volume/isosurface.ts b/src/mol-repr/volume/isosurface.ts
index 7f413cc88..f6d6b9304 100644
--- a/src/mol-repr/volume/isosurface.ts
+++ b/src/mol-repr/volume/isosurface.ts
@@ -29,6 +29,7 @@ import { WebGLContext } from '../../mol-gl/webgl/context';
 import { CustomPropertyDescriptor } from '../../mol-model/custom-property';
 import { Texture } from '../../mol-gl/webgl/texture';
 import { BaseGeometry } from '../../mol-geo/geometry/base';
+import { ValueCell } from '../../mol-util/value-cell';
 
 export const VolumeIsosurfaceParams = {
     isoValue: Volume.IsoValueParam
@@ -94,6 +95,9 @@ export async function createVolumeIsosurfaceMesh(ctx: VisualContext, volume: Vol
         // 2nd arg means not to split triangles based on group id. Splitting triangles
         // is too expensive if each cell has its own group id as is the case here.
         Mesh.uniformTriangleGroup(surface, false);
+        ValueCell.updateIfChanged(surface.varyingGroup, false);
+    } else {
+        ValueCell.updateIfChanged(surface.varyingGroup, true);
     }
 
     surface.setBoundingSphere(Volume.getBoundingSphere(volume));
@@ -190,6 +194,8 @@ async function createVolumeIsosurfaceTextureMesh(ctx: VisualContext, volume: Vol
     const groupCount = volume.grid.cells.data.length;
     const surface = TextureMesh.create(gv.vertexCount, groupCount, gv.vertexTexture, gv.groupTexture, gv.normalTexture, Volume.getBoundingSphere(volume), textureMesh);
 
+    ValueCell.updateIfChanged(surface.varyingGroup, ctx.webgl.isWebGL2);
+
     return surface;
 }
 
-- 
GitLab