Skip to content
Snippets Groups Projects
Commit 8feaacd4 authored by Alexander Rose's avatar Alexander Rose
Browse files

wip, marchin cubes

parent db640554
No related branches found
No related tags found
No related merge requests found
......@@ -22,8 +22,8 @@ varying float vRadius;
#endif
#pragma glslify: import('./chunks/common.glsl')
#pragma glslify: encodeFloatLog = require(./utils/encode-float-log.glsl)
#pragma glslify: decodeFloatLog = require(./utils/decode-float-log.glsl)
// #pragma glslify: encodeFloatLog = require(./utils/encode-float-log.glsl)
// #pragma glslify: decodeFloatLog = require(./utils/decode-float-log.glsl)
#pragma glslify: encodeFloatRGB = require(./utils/encode-float-rgb.glsl)
#pragma glslify: texture3dFrom2dNearest = require(./utils/texture3d-from-2d-nearest.glsl, intMod=intMod, intDiv=intDiv, foo=foo) // foo=foo is a workaround for a bug in glslify
......@@ -58,9 +58,11 @@ void main() {
float density = exp(-uAlpha * ((dist * dist) / radiusSq));
gl_FragColor = vec4(density);
#elif defined(dCalcType_minDistance)
gl_FragColor.a = 1.0 - encodeFloatLog(dist);
gl_FragColor.a = 10000.0 - dist;
// gl_FragColor.a = 1.0 - encodeFloatLog(dist);
#elif defined(dCalcType_groupId)
float minDistance = decodeFloatLog(1.0 - textureMinDist(fragPos).a);
float minDistance = 10000.0 - textureMinDist(fragPos).a;
// float minDistance = decodeFloatLog(1.0 - textureMinDist(fragPos).a);
// TODO verify `length(uBboxSize / uGridDim) * 2.0`
// on some machines `* 2.0` is needed while on others `* 0.5` works
if (dist > minDistance + length(uBboxSize / uGridDim) * 0.5)
......
......@@ -115,7 +115,7 @@ async function calcGaussianDensityTexture2d(ctx: RuntimeContext, webgl: WebGLCon
framebuffer.bind()
setRenderingDefaults(gl)
if (!texture) texture = createTexture(webgl, 'image-uint8', 'rgba', 'ubyte', 'linear')
if (!texture) texture = createTexture(webgl, 'image-float32', 'rgba', 'float', 'nearest')
texture.define(texDimX, texDimY)
function render(fbTex: Texture) {
......@@ -173,7 +173,7 @@ async function calcGaussianDensityTexture3d(ctx: RuntimeContext, webgl: WebGLCon
setRenderingDefaults(gl)
gl.viewport(0, 0, dx, dy)
if (!texture) texture = createTexture(webgl, 'volume-uint8', 'rgba', 'ubyte', 'linear')
if (!texture) texture = createTexture(webgl, 'volume-float32', 'rgba', 'float', 'nearest')
texture.define(dx, dy, dz)
function render(fbTex: Texture) {
......@@ -330,7 +330,7 @@ function getTexture2dSize(gridDim: Vec3) {
return { texDimX, texDimY, texRows, texCols }
}
async function fieldFromTexture2d(ctx: WebGLContext, texture: Texture, dim: Vec3) {
export async function fieldFromTexture2d(ctx: WebGLContext, texture: Texture, dim: Vec3) {
// console.time('fieldFromTexture2d')
const { framebufferCache } = ctx
const [ dx, dy, dz ] = dim
......@@ -343,7 +343,8 @@ async function fieldFromTexture2d(ctx: WebGLContext, texture: Texture, dim: Vec3
const idData = space.create()
const idField = Tensor.create(space, idData)
const image = new Uint8Array(width * height * 4)
// const image = new Uint8Array(width * height * 4)
const image = new Float32Array(width * height * 4)
const framebuffer = framebufferCache.get(FramebufferName).value
framebuffer.bind()
......@@ -365,8 +366,8 @@ async function fieldFromTexture2d(ctx: WebGLContext, texture: Texture, dim: Vec3
for (let iy = 0; iy < dy; ++iy) {
for (let ix = 0; ix < dx; ++ix) {
const idx = 4 * (tmpCol * dx + (iy + tmpRow) * width + ix)
data[j] = image[idx + 3] / 255
idData[j] = decodeFloatRGB(image[idx], image[idx + 1], image[idx + 2])
data[j] = image[idx + 3] // / 255
idData[j] = decodeFloatRGB(image[idx] * 255, image[idx + 1] * 255, image[idx + 2] * 255)
j++
}
}
......
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import './index.html'
import { Canvas3D } from 'mol-canvas3d/canvas3d';
import { Representation } from 'mol-repr/representation';
import { Color } from 'mol-util/color';
import { createRenderObject } from 'mol-gl/render-object';
import { computeGaussianDensity, computeGaussianDensityTexture2d } from 'mol-math/geometry/gaussian-density';
import { PositionData, Box3D, Sphere3D } from 'mol-math/geometry';
import { OrderedSet } from 'mol-data/int';
import { Vec3 } from 'mol-math/linear-algebra';
import { computeMarchingCubesMesh } from 'mol-geo/util/marching-cubes/algorithm';
import { Mesh } from 'mol-geo/geometry/mesh/mesh';
import { ColorNames } from 'mol-util/color/tables';
import { Isosurface } from 'mol-geo/geometry/isosurface/isosurface';
import { calcActiveVoxels } from 'mol-gl/compute/marching-cubes/active-voxels';
import { createHistogramPyramid } from 'mol-gl/compute/histogram-pyramid/reduction';
import { createIsosurfaceBuffers } from 'mol-gl/compute/marching-cubes/isosurface';
const parent = document.getElementById('app')!
parent.style.width = '100%'
parent.style.height = '100%'
const canvas = document.createElement('canvas')
canvas.style.width = '100%'
canvas.style.height = '100%'
parent.appendChild(canvas)
const canvas3d = Canvas3D.create(canvas, parent, {
backgroundColor: ColorNames.white,
cameraMode: 'orthographic'
})
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]),
// }
// const box = Box3D.create(Vec3.create(-1, -1, -1), Vec3.create(1, 1, 1))
const radius = () => 1.6
const props = {
resolution: 0.1,
radiusOffset: 0,
smoothness: 1.5
}
const isoValue = Math.exp(-props.smoothness)
// console.log('bbox', densityTextureData.bbox)
// console.time('gpu gaussian2')
// const densityTextureData2 = await computeGaussianDensityTexture2d(position, box, radius, props, webgl).run()
// webgl.waitForGpuCommandsCompleteSync()
// console.timeEnd('gpu gaussian2')
// console.time('gpu mc2')
// console.time('gpu mc active2')
// const activeVoxelsTex2 = calcActiveVoxels(webgl, densityTextureData2.texture, densityTextureData2.gridDimension, isoValue)
// webgl.waitForGpuCommandsCompleteSync()
// console.timeEnd('gpu mc active2')
// console.time('gpu mc pyramid2')
// const compacted2 = createHistogramPyramid(webgl, activeVoxelsTex2)
// webgl.waitForGpuCommandsCompleteSync()
// console.timeEnd('gpu mc pyramid2')
// console.time('gpu mc vert2')
// const gv2 = createIsosurfaceBuffers(webgl, activeVoxelsTex2, densityTextureData2.texture, compacted2, densityTextureData2.gridDimension, densityTextureData2.transform, isoValue)
// webgl.waitForGpuCommandsCompleteSync()
// console.timeEnd('gpu mc vert2')
// console.timeEnd('gpu mc2')
console.time('gpu gaussian')
const densityTextureData = await computeGaussianDensityTexture2d(position, box, radius, props, webgl).run()
webgl.waitForGpuCommandsCompleteSync()
console.timeEnd('gpu gaussian')
console.time('gpu mc')
console.time('gpu mc active')
const activeVoxelsTex = calcActiveVoxels(webgl, densityTextureData.texture, densityTextureData.gridDimension, isoValue)
webgl.waitForGpuCommandsCompleteSync()
console.timeEnd('gpu mc active')
console.time('gpu mc pyramid')
const compacted = createHistogramPyramid(webgl, activeVoxelsTex)
webgl.waitForGpuCommandsCompleteSync()
console.timeEnd('gpu mc pyramid')
console.time('gpu mc vert')
const gv = createIsosurfaceBuffers(webgl, activeVoxelsTex, densityTextureData.texture, compacted, densityTextureData.gridDimension, densityTextureData.transform, isoValue)
webgl.waitForGpuCommandsCompleteSync()
console.timeEnd('gpu mc vert')
console.timeEnd('gpu mc')
console.log({ ...webgl.stats, programCount: webgl.programCache.count, shaderCount: webgl.shaderCache.count })
const mcIsosurface = Isosurface.create(gv.vertexCount, 1, gv.vertexTexture, gv.normalBuffer, gv.groupBuffer, Sphere3D.fromBox3D(Sphere3D.zero(), densityTextureData.bbox))
const mcIsoSurfaceProps = { doubleSided: true, flatShaded: true, alpha: 1.0 }
const mcIsoSurfaceValues = Isosurface.Utils.createValuesSimple(mcIsosurface, mcIsoSurfaceProps, Color(0x112299), 1)
// console.log('mcIsoSurfaceValues', mcIsoSurfaceValues)
const mcIsoSurfaceState = Isosurface.Utils.createRenderableState(mcIsoSurfaceProps)
const mcIsoSurfaceRenderObject = createRenderObject('isosurface', mcIsoSurfaceValues, mcIsoSurfaceState, -1)
const mcIsoSurfaceRepr = Representation.fromRenderObject('isosurface', mcIsoSurfaceRenderObject)
canvas3d.add(mcIsoSurfaceRepr)
canvas3d.resetCamera()
//
console.time('cpu gaussian')
const densityData = await computeGaussianDensity(position, box, radius, { ...props, useGpu: false }, webgl).run()
console.timeEnd('cpu gaussian')
// console.log({ densityData })
const params = {
isoLevel: isoValue,
scalarField: densityData.field,
idField: densityData.idField
}
console.time('cpu mc')
const surface = await computeMarchingCubesMesh(params).run()
console.timeEnd('cpu mc')
// console.log('surface', surface)
Mesh.computeNormalsImmediate(surface)
const meshProps = { doubleSided: true, flatShaded: true, alpha: 1.0 }
const meshValues = Mesh.Utils.createValuesSimple(surface, meshProps, Color(0x995511), 1)
const meshState = Mesh.Utils.createRenderableState(meshProps)
const meshRenderObject = createRenderObject('mesh', meshValues, meshState, -1)
const meshRepr = Representation.fromRenderObject('mesh', meshRenderObject)
canvas3d.add(meshRepr)
canvas3d.resetCamera()
}
init()
\ No newline at end of file
......@@ -102,6 +102,7 @@ module.exports = [
createApp('model-server-query'),
createBrowserTest('font-atlas'),
createBrowserTest('marching-cubes'),
createBrowserTest('render-lines'),
createBrowserTest('render-mesh'),
createBrowserTest('render-shape'),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment