Bladeren bron

wip, gl tweaks and fixes

Alexander Rose 6 jaren geleden
bovenliggende
commit
fac58a8d95

+ 10 - 15
src/mol-gl/compute/histogram-pyramid/reduction.ts

@@ -7,30 +7,24 @@
 import { createComputeRenderable } from '../../renderable'
 import { WebGLContext } from '../../webgl/context';
 import { createComputeRenderItem } from '../../webgl/render-item';
-import { AttributeSpec, Values, TextureSpec, ValueSpec, UniformSpec } from '../../renderable/schema';
+import { Values, TextureSpec, UniformSpec } from '../../renderable/schema';
 import { Texture, createTexture } from 'mol-gl/webgl/texture';
 import { ShaderCode } from 'mol-gl/shader-code';
 import { ValueCell } from 'mol-util';
 import { GLRenderingContext } from 'mol-gl/webgl/compat';
-import { QuadPositions } from '../util';
+import { printTexture, QuadSchema, QuadValues } from '../util';
 import { Vec2 } from 'mol-math/linear-algebra';
 import { getHistopyramidSum } from './sum';
 
 const HistopyramidReductionSchema = {
-    drawCount: ValueSpec('number'),
-    instanceCount: ValueSpec('number'),
-    aPosition: AttributeSpec('float32', 2, 0),
-
+    ...QuadSchema,
     tPreviousLevel: TextureSpec('texture', 'rgba', 'float', 'nearest'),
     uSize: UniformSpec('f'),
 }
 
 function getHistopyramidReductionRenderable(ctx: WebGLContext, initialTexture: Texture) {
     const values: Values<typeof HistopyramidReductionSchema> = {
-        drawCount: ValueCell.create(6),
-        instanceCount: ValueCell.create(1),
-        aPosition: ValueCell.create(QuadPositions),
-
+        ...QuadValues,
         tPreviousLevel: ValueCell.create(initialTexture),
         uSize: ValueCell.create(0),
     }
@@ -38,8 +32,7 @@ function getHistopyramidReductionRenderable(ctx: WebGLContext, initialTexture: T
     const schema = { ...HistopyramidReductionSchema }
     const shaderCode = ShaderCode(
         require('mol-gl/shader/quad.vert').default,
-        require('mol-gl/shader/histogram-pyramid/reduction.frag').default,
-        { standardDerivatives: false, fragDepth: false }
+        require('mol-gl/shader/histogram-pyramid/reduction.frag').default
     )
     const renderItem = createComputeRenderItem(ctx, 'triangles', shaderCode, schema, values)
 
@@ -73,6 +66,7 @@ export function createHistogramPyramid(ctx: WebGLContext, inputTexture: Texture)
 
     // This part set the levels
     const levels = Math.ceil(Math.log(inputTextureMaxDim) / Math.log(2))
+    console.log('levels', levels)
 
     const initialTexture = createTexture(ctx, 'image-float32', 'rgba', 'float', 'nearest')
     initialTexture.load({ array: new Float32Array(4), width: 1, height: 1 })
@@ -89,6 +83,7 @@ export function createHistogramPyramid(ctx: WebGLContext, inputTexture: Texture)
     const pyramidTexture = createTexture(ctx, 'image-float32', 'rgba', 'float', 'nearest')
     pyramidTexture.define(Math.pow(2, levels), Math.pow(2, levels))
 
+    // TODO cache globally for reuse
     const levelTextures: Texture[] = []
     for (let i = 0; i < levels; ++i) {
         const tex = createTexture(ctx, 'image-float32', 'rgba', 'float', 'nearest')
@@ -106,7 +101,7 @@ export function createHistogramPyramid(ctx: WebGLContext, inputTexture: Texture)
         levelTextures[currLevel].attachFramebuffer(framebuffer, 0)
 
         const size = Math.pow(2, currLevel)
-        // console.log('size', size, 'draw-level', currLevel, 'read-level', levels - i)
+        console.log('size', size, 'draw-level', currLevel, 'read-level', levels - i)
         gl.clear(gl.COLOR_BUFFER_BIT)
 
         ValueCell.update(renderable.values.uSize, Math.pow(2, i + 1) / initialTextureMaxDim)
@@ -139,13 +134,13 @@ export function createHistogramPyramid(ctx: WebGLContext, inputTexture: Texture)
         offset += size;
     }
 
-    // printTexture(ctx, pyramidTexture, 3)
+    printTexture(ctx, pyramidTexture, 3)
 
     //
 
     const finalCount = getHistopyramidSum(ctx, levelTextures[0])
     const height = Math.ceil(finalCount / Math.pow(2, levels))
-    // console.log('height', height)
+    console.log('height', height, 'finalCount', finalCount)
 
     //
 

+ 6 - 12
src/mol-gl/compute/histogram-pyramid/sum.ts

@@ -7,35 +7,28 @@
 import { createComputeRenderable } from '../../renderable'
 import { WebGLContext } from '../../webgl/context';
 import { createComputeRenderItem } from '../../webgl/render-item';
-import { AttributeSpec, Values, TextureSpec, ValueSpec } from '../../renderable/schema';
+import { Values, TextureSpec } from '../../renderable/schema';
 import { Texture, createTexture } from 'mol-gl/webgl/texture';
 import { ShaderCode } from 'mol-gl/shader-code';
 import { ValueCell } from 'mol-util';
 import { decodeFloatRGB } from 'mol-util/float-packing';
-import { QuadPositions, readTexture } from '../util';
+import { readTexture, QuadSchema, QuadValues } from '../util';
 
 const HistopyramidSumSchema = {
-    drawCount: ValueSpec('number'),
-    instanceCount: ValueSpec('number'),
-    aPosition: AttributeSpec('float32', 2, 0),
-
+    ...QuadSchema,
     tTexture: TextureSpec('texture', 'rgba', 'float', 'nearest'),
 }
 
 function getHistopyramidSumRenderable(ctx: WebGLContext, texture: Texture) {
     const values: Values<typeof HistopyramidSumSchema> = {
-        drawCount: ValueCell.create(6),
-        instanceCount: ValueCell.create(1),
-        aPosition: ValueCell.create(QuadPositions),
-
+        ...QuadValues,
         tTexture: ValueCell.create(texture),
     }
 
     const schema = { ...HistopyramidSumSchema }
     const shaderCode = ShaderCode(
         require('mol-gl/shader/quad.vert').default,
-        require('mol-gl/shader/histogram-pyramid/sum.frag').default,
-        { standardDerivatives: false, fragDepth: false }
+        require('mol-gl/shader/histogram-pyramid/sum.frag').default
     )
     const renderItem = createComputeRenderItem(ctx, 'triangles', shaderCode, schema, values)
 
@@ -54,6 +47,7 @@ export function getHistopyramidSum(ctx: WebGLContext, pyramidTopTexture: Texture
     encodeFloatRenderable.update()
     encodeFloatRenderable.use()
 
+    // TODO cache globally for reuse
     const encodedFloatTexture = createTexture(ctx, 'image-uint8', 'rgba', 'ubyte', 'nearest')
     encodedFloatTexture.define(1, 1)
     encodedFloatTexture.attachFramebuffer(framebuffer, 0)

+ 5 - 10
src/mol-gl/compute/marching-cubes/active-voxels.ts

@@ -7,22 +7,20 @@
 import { createComputeRenderable } from '../../renderable'
 import { WebGLContext } from '../../webgl/context';
 import { createComputeRenderItem } from '../../webgl/render-item';
-import { AttributeSpec, Values, TextureSpec, ValueSpec, UniformSpec } from '../../renderable/schema';
+import { Values, TextureSpec, UniformSpec } from '../../renderable/schema';
 import { Texture, createTexture } from 'mol-gl/webgl/texture';
 import { ShaderCode } from 'mol-gl/shader-code';
 import { ValueCell } from 'mol-util';
 import { GLRenderingContext } from 'mol-gl/webgl/compat';
 import { Vec3 } from 'mol-math/linear-algebra';
-import { QuadPositions } from '../util';
+import { QuadSchema, QuadValues } from '../util';
 import { getTriCount } from './tables';
 
 /** name for shared framebuffer used for gpu marching cubes operations */
 const FramebufferName = 'marching-cubes'
 
 const ActiveVoxelsSchema = {
-    drawCount: ValueSpec('number'),
-    instanceCount: ValueSpec('number'),
-    aPosition: AttributeSpec('float32', 2, 0),
+    ...QuadSchema,
 
     tTriCount: TextureSpec('image-uint8', 'alpha', 'ubyte', 'nearest'),
     tVolumeData: TextureSpec('texture', 'rgba', 'ubyte', 'nearest'),
@@ -34,9 +32,7 @@ const ActiveVoxelsSchema = {
 
 function getActiveVoxelsRenderable(ctx: WebGLContext, volumeData: Texture, gridDimensions: Vec3, isoValue: number) {
     const values: Values<typeof ActiveVoxelsSchema> = {
-        drawCount: ValueCell.create(6),
-        instanceCount: ValueCell.create(1),
-        aPosition: ValueCell.create(QuadPositions),
+        ...QuadValues,
 
         tTriCount: ValueCell.create(getTriCount()),
         tVolumeData: ValueCell.create(volumeData),
@@ -49,8 +45,7 @@ function getActiveVoxelsRenderable(ctx: WebGLContext, volumeData: Texture, gridD
     const schema = { ...ActiveVoxelsSchema }
     const shaderCode = ShaderCode(
         require('mol-gl/shader/quad.vert').default,
-        require('mol-gl/shader/marching-cubes/active-voxels.frag').default,
-        { standardDerivatives: false, fragDepth: false }
+        require('mol-gl/shader/marching-cubes/active-voxels.frag').default
     )
     const renderItem = createComputeRenderItem(ctx, 'triangles', shaderCode, schema, values)
 

+ 4 - 8
src/mol-gl/compute/marching-cubes/isosurface.ts

@@ -7,13 +7,13 @@
 import { createComputeRenderable } from '../../renderable'
 import { WebGLContext } from '../../webgl/context';
 import { createComputeRenderItem } from '../../webgl/render-item';
-import { AttributeSpec, Values, TextureSpec, ValueSpec, UniformSpec } from '../../renderable/schema';
+import { Values, TextureSpec, UniformSpec } from '../../renderable/schema';
 import { Texture, createTexture } from 'mol-gl/webgl/texture';
 import { ShaderCode } from 'mol-gl/shader-code';
 import { ValueCell } from 'mol-util';
 import { GLRenderingContext } from 'mol-gl/webgl/compat';
 import { Vec3, Vec2, Mat4 } from 'mol-math/linear-algebra';
-import { QuadPositions } from '../util';
+import { QuadSchema, QuadValues } from '../util';
 import { HistogramPyramid } from '../histogram-pyramid/reduction';
 import { getTriIndices } from './tables';
 
@@ -21,9 +21,7 @@ import { getTriIndices } from './tables';
 const FramebufferName = 'marching-cubes'
 
 const IsosurfaceSchema = {
-    drawCount: ValueSpec('number'),
-    instanceCount: ValueSpec('number'),
-    aPosition: AttributeSpec('float32', 2, 0),
+    ...QuadSchema,
 
     tTriIndices: TextureSpec('image-uint8', 'alpha', 'ubyte', 'nearest'),
     tActiveVoxelsPyramid: TextureSpec('texture', 'rgba', 'float', 'nearest'),
@@ -45,9 +43,7 @@ const IsosurfaceSchema = {
 function getIsosurfaceRenderable(ctx: WebGLContext, activeVoxelsPyramid: Texture, activeVoxelsBase: Texture, volumeData: Texture, activeVoxelsTotal: Texture, gridDimensions: Vec3, transform: Mat4, isoValue: number, levels: number, scale: Vec2) {
     // console.log('uSize', Math.pow(2, levels))
     const values: Values<typeof IsosurfaceSchema> = {
-        drawCount: ValueCell.create(6),
-        instanceCount: ValueCell.create(1),
-        aPosition: ValueCell.create(QuadPositions),
+        ...QuadValues,
 
         tTriIndices: ValueCell.create(getTriIndices()),
         tActiveVoxelsPyramid: ValueCell.create(activeVoxelsPyramid),

+ 18 - 3
src/mol-gl/compute/util.ts

@@ -7,13 +7,28 @@
 import { WebGLContext } from 'mol-gl/webgl/context';
 import { Texture } from 'mol-gl/webgl/texture';
 import { printTextureImage } from 'mol-gl/renderable/util';
-import { defaults } from 'mol-util';
+import { defaults, ValueCell } from 'mol-util';
+import { ValueSpec, AttributeSpec } from 'mol-gl/renderable/schema';
 
 export const QuadPositions = new Float32Array([
-     1.0,  1.0,  -1.0,  1.0,  -1.0, -1.0, // First triangle:
-    -1.0, -1.0,   1.0, -1.0,   1.0,  1.0  // Second triangle:
+     1.0,  1.0,  -1.0,  1.0,  -1.0, -1.0, // First triangle
+    -1.0, -1.0,   1.0, -1.0,   1.0,  1.0  // Second triangle
 ])
 
+export const QuadSchema = {
+    drawCount: ValueSpec('number'),
+    instanceCount: ValueSpec('number'),
+    aPosition: AttributeSpec('float32', 2, 0)
+}
+
+export const QuadValues = {
+    drawCount: ValueCell.create(6),
+    instanceCount: ValueCell.create(1),
+    aPosition: ValueCell.create(QuadPositions),
+}
+
+//
+
 export function readTexture(ctx: WebGLContext, texture: Texture, width?: number, height?: number) {
     const { gl, framebufferCache } = ctx
     width = defaults(width, texture.width)

+ 2 - 2
src/mol-gl/shader/histogram-pyramid/reduction.frag

@@ -1,5 +1,5 @@
-precision mediump float;
-precision mediump sampler2D;
+precision highp float;
+precision highp sampler2D;
 
 // input texture (previous level used to evaluate the new level)
 uniform sampler2D tPreviousLevel;

+ 2 - 2
src/mol-gl/shader/histogram-pyramid/sum.frag

@@ -4,8 +4,8 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-precision mediump float;
-precision mediump sampler2D;
+precision highp float;
+precision highp sampler2D;
 
 uniform sampler2D tTexture;
 

+ 21 - 11
src/mol-gl/shader/marching-cubes/active-voxels.frag

@@ -1,5 +1,5 @@
-precision mediump float;
-precision mediump sampler2D;
+precision highp float;
+precision highp sampler2D;
 
 uniform sampler2D tTriCount;
 uniform sampler2D tVolumeData;
@@ -10,6 +10,16 @@ uniform vec3 uGridTexDim;
 
 varying vec2 vCoordinate;
 
+// cube corners
+const vec3 c0 = vec3(0., 0., 0.);
+const vec3 c1 = vec3(1., 0., 0.);
+const vec3 c2 = vec3(1., 1., 0.);
+const vec3 c3 = vec3(0., 1., 0.);
+const vec3 c4 = vec3(0., 0., 1.);
+const vec3 c5 = vec3(1., 0., 1.);
+const vec3 c6 = vec3(1., 1., 1.);
+const vec3 c7 = vec3(0., 1., 1.);
+
 vec3 index3dFrom2d(vec2 coord) {
     vec2 gridTexPos = coord * uGridTexDim.xy;
     vec2 columnRow = floor(gridTexPos / uGridDim.xy);
@@ -27,7 +37,7 @@ vec4 texture3dFrom2dNearest(sampler2D tex, vec3 pos, vec3 gridDim, vec2 texDim)
     float column = intMod(zSlice * gridDim.x, texDim.x) / gridDim.x;
     float row = floor(intDiv(zSlice * gridDim.x, texDim.x));
     vec2 coord = (vec2(column * gridDim.x, row * gridDim.y) + (pos.xy * gridDim.xy)) / texDim;
-    return texture2D(tex, coord);
+    return texture2D(tex, coord + 0.5 / texDim);
 }
 
 vec4 voxel(vec3 pos) {
@@ -39,16 +49,16 @@ void main(void) {
 
     // get MC case as the sum of corners that are below the given iso level
     float c = step(voxel(posXYZ).a, uIsoValue)
-        + 2. * step(voxel(posXYZ + vec3(1., 0., 0.) / uGridDim).a, uIsoValue)
-        + 4. * step(voxel(posXYZ + vec3(1., 1., 0.) / uGridDim).a, uIsoValue)
-        + 8. * step(voxel(posXYZ + vec3(0., 1., 0.) / uGridDim).a, uIsoValue)
-        + 16. * step(voxel(posXYZ + vec3(0., 0., 1.) / uGridDim).a, uIsoValue)
-        + 32. * step(voxel(posXYZ + vec3(1., 0., 1.) / uGridDim).a, uIsoValue)
-        + 64. * step(voxel(posXYZ + vec3(1., 1., 1.) / uGridDim).a, uIsoValue)
-        + 128. * step(voxel(posXYZ + vec3(0., 1., 1.) / uGridDim).a, uIsoValue);
+        + 2. * step(voxel(posXYZ + c1 / uGridDim).a, uIsoValue)
+        + 4. * step(voxel(posXYZ + c2 / uGridDim).a, uIsoValue)
+        + 8. * step(voxel(posXYZ + c3 / uGridDim).a, uIsoValue)
+        + 16. * step(voxel(posXYZ + c4 / uGridDim).a, uIsoValue)
+        + 32. * step(voxel(posXYZ + c5 / uGridDim).a, uIsoValue)
+        + 64. * step(voxel(posXYZ + c6 / uGridDim).a, uIsoValue)
+        + 128. * step(voxel(posXYZ + c7 / uGridDim).a, uIsoValue);
     c *= step(c, 254.);
 
     // get total triangles to generate for calculated MC case from triCount texture
     float totalTrianglesToGenerate = texture2D(tTriCount, vec2(intMod(c, 16.), floor(c / 16.)) / 16.).a;
-    gl_FragColor = vec4(vec3(totalTrianglesToGenerate * 255.0 * 3.0), c);
+    gl_FragColor = vec4(vec3(floor(totalTrianglesToGenerate * 255.0 + 0.5) * 3.0), c);
 }

+ 34 - 39
src/mol-gl/shader/marching-cubes/isosurface.frag

@@ -20,22 +20,15 @@ uniform vec2 uScale;
 
 varying vec2 vCoordinate;
 
-// const vec3 c0  = vec3(0., 0., 0.);
-// const vec3 c1  = vec3(1., 0., 0.);
-// const vec3 c2  = vec3(1., 1., 0.);
-// const vec3 c3  = vec3(0., 1., 0.);
-// const vec3 c4  = vec3(0., 0., 1.);
-// const vec3 c5  = vec3(1., 0., 1.);
-// const vec3 c6  = vec3(1., 1., 1.);
-// const vec3 c7  = vec3(0., 1., 1.);
-
-const vec3 p0 = vec3(1., 0., 0.);
-const vec3 p1 = vec3(1., 1., 0.);
-const vec3 p2 = vec3(0., 1., 0.);
-const vec3 p3 = vec3(0., 0., 1.);
-const vec3 p4 = vec3(1., 0., 1.);
-const vec3 p5 = vec3(1., 1., 1.);
-const vec3 p6 = vec3(0., 1., 1.);
+// cube corners
+const vec3 c0 = vec3(0., 0., 0.);
+const vec3 c1 = vec3(1., 0., 0.);
+const vec3 c2 = vec3(1., 1., 0.);
+const vec3 c3 = vec3(0., 1., 0.);
+const vec3 c4 = vec3(0., 0., 1.);
+const vec3 c5 = vec3(1., 0., 1.);
+const vec3 c6 = vec3(1., 1., 1.);
+const vec3 c7 = vec3(0., 1., 1.);
 
 vec3 index3dFrom2d(vec2 coord) {
     vec2 gridTexPos = coord * uGridTexDim.xy;
@@ -107,7 +100,7 @@ void main(void) {
     vec2 coord2d = position * uScale;
     vec3 coord3d = floor(index3dFrom2d(coord2d) + 0.5);
 
-    float edgeIndex = texture2D(tActiveVoxelsBase, position * uScale).a;
+    float edgeIndex = floor(texture2D(tActiveVoxelsBase, position * uScale).a + 0.5);
 
     // current vertex for the up to 15 MC cases
     float currentVertex = vI - dot(m, starts);
@@ -127,29 +120,30 @@ void main(void) {
 
     // apply bit masks
     vec3 b0 = coord3d +
-                m1.y * p0 +
-                m1.z * p1 +
-                m1.w * p2 +
-                m2.x * p3 +
-                m2.y * p4 +
-                m2.z * p5 +
-                m2.w * p6 +
-                m3.y * p0 +
-                m3.z * p1 +
-                m3.w * p2;
+                m1.y * c1 +
+                m1.z * c2 +
+                m1.w * c3 +
+                m2.x * c4 +
+                m2.y * c5 +
+                m2.z * c6 +
+                m2.w * c7 +
+                m3.y * c1 +
+                m3.z * c2 +
+                m3.w * c3;
     vec3 b1 = coord3d +
-                m1.x * p0 +
-                m1.y * p1 +
-                m1.z * p2 +
-                m2.x * p4 +
-                m2.y * p5 +
-                m2.z * p6 +
-                m2.w * p3 +
-                m3.x * p3 +
-                m3.y * p4 +
-                m3.z * p5 +
-                m3.w * p6;
-
+                m1.x * c1 +
+                m1.y * c2 +
+                m1.z * c3 +
+                m2.x * c5 +
+                m2.y * c6 +
+                m2.z * c7 +
+                m2.w * c4 +
+                m3.x * c4 +
+                m3.y * c5 +
+                m3.z * c6 +
+                m3.w * c7;
+
+    // the conditionals that are avoided by above bitmasks
     // vec3 b0 = coord3d;
     // vec3 b1 = coord3d;
     // if (mcIndex == 0.0) {
@@ -184,5 +178,6 @@ void main(void) {
     float v1 = voxel(b1 / uGridDim).a;
 
     float t = (uIsoValue - v0) / (v0 - v1);
+    t = -0.5;
     gl_FragColor.xyz = b0 + t * (b0 - b1);
 }

+ 5 - 5
src/mol-gl/webgl/context.ts

@@ -276,13 +276,13 @@ export function createContext(gl: GLRenderingContext): WebGLContext {
     const framebufferCache: FramebufferCache = createFramebufferCache(gl, stats)
 
     const parameters = {
-        maxTextureSize: gl.getParameter(gl.MAX_TEXTURE_SIZE),
-        maxDrawBuffers: isWebGL2(gl) ? gl.getParameter(gl.MAX_DRAW_BUFFERS) : 0,
-        maxVertexTextureImageUnits: gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS),
+        maxTextureSize: gl.getParameter(gl.MAX_TEXTURE_SIZE) as number,
+        maxDrawBuffers: isWebGL2(gl) ? gl.getParameter(gl.MAX_DRAW_BUFFERS) as number : 0,
+        maxVertexTextureImageUnits: gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS) as number,
     }
 
-    if (parameters.maxVertexTextureImageUnits < 4) {
-        throw new Error('Need "MAX_VERTEX_TEXTURE_IMAGE_UNITS" >= 4')
+    if (parameters.maxVertexTextureImageUnits < 8) {
+        throw new Error('Need "MAX_VERTEX_TEXTURE_IMAGE_UNITS" >= 8')
     }
 
     let readPixelsAsync: (x: number, y: number, width: number, height: number, buffer: Uint8Array) => Promise<void>

+ 14 - 14
src/tests/browser/marching-cubes.ts

@@ -39,21 +39,21 @@ canvas3d.animate()
 async function init() {
     const { webgl } = canvas3d
 
-    const position: PositionData = {
-        x: [0, 2],
-        y: [0, 2],
-        z: [0, 2],
-        indices: OrderedSet.ofSortedArray([0, 1]),
-    }
-    const box = Box3D.create(Vec3.create(-1, -1, -1), Vec3.create(3, 3, 3))
     // const position: PositionData = {
-    //     x: [0],
-    //     y: [0],
-    //     z: [0],
-    //     indices: OrderedSet.ofSortedArray([0]),
+    //     x: [0, 2],
+    //     y: [0, 2],
+    //     z: [0, 2],
+    //     indices: OrderedSet.ofSortedArray([0, 1]),
     // }
-    // const box = Box3D.create(Vec3.create(-1, -1, -1), Vec3.create(1, 1, 1))
-    const radius = () => 1.6
+    // const box = Box3D.create(Vec3.create(-1, -1, -1), Vec3.create(3, 3, 3))
+    const position: PositionData = {
+        x: [0],
+        y: [0],
+        z: [0],
+        indices: OrderedSet.ofSortedArray([0]),
+    }
+    const box = Box3D.create(Vec3.create(-1, -1, -1), Vec3.create(1, 1, 1))
+    const radius = () => 1.4
     const props = {
         resolution: 0.1,
         radiusOffset: 0,
@@ -138,7 +138,7 @@ async function init() {
     console.timeEnd('cpu mc')
     // console.log('surface', surface)
     Mesh.computeNormalsImmediate(surface)
-    const meshProps = { doubleSided: true, flatShaded: true, alpha: 1.0 }
+    const meshProps = { doubleSided: true, flatShaded: true, alpha: 0.1 }
     const meshValues = Mesh.Utils.createValuesSimple(surface, meshProps, Color(0x995511), 1)
     const meshState = Mesh.Utils.createRenderableState(meshProps)
     const meshRenderObject = createRenderObject('mesh', meshValues, meshState, -1)