diff --git a/viewer/glow-extras/viewer/detail/MeshShaderBuilder.cc b/viewer/glow-extras/viewer/detail/MeshShaderBuilder.cc
index 370e47662832d4ce4c6cc89e0cc3a4dc4f061647..592a3412d523757636a240dde5e59abe95e1c13f 100644
--- a/viewer/glow-extras/viewer/detail/MeshShaderBuilder.cc
+++ b/viewer/glow-extras/viewer/detail/MeshShaderBuilder.cc
@@ -188,23 +188,31 @@ glow::SharedProgram MeshShaderBuilder::createProgram()
         fsCode += mFragmentLocations + "\n";
         fsCode += mFragmentShaderDecl + "\n";
         fsCode += R"(
-uint hash_combine(uint seed, uint h) {
-    return seed ^ h + uint(0x9e3779b9) + (seed << 6) + (seed >> 2);
-}
 
-uint wang_hash(uint seed) {
-    seed = (seed ^ uint(61)) ^ (seed >> 16);
-    seed *= 9;
-    seed = seed ^ (seed >> 4);
-    seed *= 0x27d4eb2d;
-    seed = seed ^ (seed >> 15);
-    return seed;
+// see https://nullprogram.com/blog/2018/07/31/
+uint hash_triple32(uint x) {
+    x ^= x >> 17;
+    x *= 0xed5ad4bbU;
+    x ^= x >> 11;
+    x *= 0xac4c1b51U;
+    x ^= x >> 15;
+    x *= 0x31848babU;
+    x ^= x >> 14;
+    return x;
 }
 
-float wang_float(uint hash) {
+// full u32 to [0..1]
+float hash_u32_to_float(uint hash) {
     return hash / float(0x7FFFFFFF) / 2.0;
 }
 
+float make_hashed_threshold(float vertex_id, uint seed) {
+    uint h = hash_triple32(floatBitsToUint(vertex_id));
+    h = h * 4111 + uint(gl_FragCoord.x);
+    h = h * 4099 + uint(gl_FragCoord.y);
+    h = h * 5003 + uint(seed);
+    return hash_u32_to_float(hash_triple32(h));
+}
 
 )";
         fsCode += "void main() {\n";
diff --git a/viewer/glow-extras/viewer/renderables/LineRenderable.cc b/viewer/glow-extras/viewer/renderables/LineRenderable.cc
index 12454c3fd1bae218bcff77b515d55495ed7ed419..555cc0387a1b4eb78b5a3e06d88c2e62e4465eab 100644
--- a/viewer/glow-extras/viewer/renderables/LineRenderable.cc
+++ b/viewer/glow-extras/viewer/renderables/LineRenderable.cc
@@ -777,14 +777,9 @@ float distance2(vec3 a, vec3 b)
                 sbForward.addFragmentShaderCode(R"(
                                          if (uIsTransparent)
                                          {
-                                            uint h = uint(gl_FragCoord.x) * 4096 + uint(gl_FragCoord.y);
-                                            h = hash_combine(h, uint(uSeed * 12391));
-                                            h = hash_combine(h, uint(gl_FragCoord.z * 12391));
-                                            h = wang_hash(h);
-
                                             float a = vColor.a;
 
-                                            if (wang_float(h) > a)
+                                            if (a < make_hashed_threshold(gl_FragCoord.z, uSeed))
                                                 discard;
                                          })");
 
diff --git a/viewer/glow-extras/viewer/renderables/MeshRenderable.cc b/viewer/glow-extras/viewer/renderables/MeshRenderable.cc
index e66bd2046dd30d1b7bf2c426373908b20aa646f4..9cbadf08e3430a93bbe19119bf463abbca1260ff 100644
--- a/viewer/glow-extras/viewer/renderables/MeshRenderable.cc
+++ b/viewer/glow-extras/viewer/renderables/MeshRenderable.cc
@@ -265,11 +265,6 @@ void MeshRenderable::init()
             sb.addFragmentShaderCode(R"(
                                      if (uIsTransparent)
                                      {
-                                        uint h = uint(gl_FragCoord.x) * 4096 + uint(gl_FragCoord.y);
-                                        h = hash_combine(h, uint(uSeed));
-                                        h = hash_combine(h, uint(vVertexID * 17));
-                                        h = wang_hash(h);
-
                                         float a = vColor.a;
 
                                         if (uFresnel)
@@ -280,7 +275,7 @@ void MeshRenderable::init()
                                             a = mix(vColor.a, 1, t);
                                         }
 
-                                        if (wang_float(h) > a)
+                                        if (a < make_hashed_threshold(vVertexID, uSeed))
                                             discard;
                                      })");
 
diff --git a/viewer/glow-extras/viewer/renderables/PointRenderable.cc b/viewer/glow-extras/viewer/renderables/PointRenderable.cc
index bc7eba53667207598f25a6be5a74d5ad0305102f..c93e5e497efe81c2863d3c9a91e64044c492e9d4 100644
--- a/viewer/glow-extras/viewer/renderables/PointRenderable.cc
+++ b/viewer/glow-extras/viewer/renderables/PointRenderable.cc
@@ -590,11 +590,6 @@ void PointRenderable::init()
                 sbForward.addFragmentShaderCode(R"(
                                          if (uIsTransparent)
                                          {
-                                            uint h = uint(gl_FragCoord.x) * 4096 + uint(gl_FragCoord.y);
-                                            h = hash_combine(h, uint(uSeed));
-                                            h = hash_combine(h, uint(vVertexID * 17));
-                                            h = wang_hash(h);
-
                                             float a = vColor.a;
 
                                             if (uFresnel)
@@ -605,7 +600,7 @@ void PointRenderable::init()
                                                 a = mix(vColor.a, 1, t);
                                             }
 
-                                            if (wang_float(h) > a)
+                                            if (a < make_hashed_threshold(vVertexID, uSeed))
                                                 discard;
                                          })");