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

refactored float packing on cpu/gpu

parent 346ffa33
No related branches found
No related tags found
No related merge requests found
Showing
with 80 additions and 66 deletions
......@@ -21,13 +21,14 @@ import { Representation } from 'mol-repr/representation';
import { createRenderTarget } from 'mol-gl/webgl/render-target';
import Scene from 'mol-gl/scene';
import { RenderVariant } from 'mol-gl/webgl/render-item';
import { PickingId, decodeIdRGB } from 'mol-geo/geometry/picking';
import { PickingId } from 'mol-geo/geometry/picking';
import { MarkerAction } from 'mol-geo/geometry/marker-data';
import { Loci, EmptyLoci, isEmptyLoci } from 'mol-model/loci';
import { Color } from 'mol-util/color';
import { Camera } from './camera';
import { ParamDefinition as PD } from 'mol-util/param-definition';
import { BoundingSphereHelper, DebugHelperParams } from './helper/bounding-sphere-helper';
import { decodeFloatRGB } from 'mol-util/float-packing';
export const Canvas3DParams = {
// TODO: FPS cap?
......@@ -276,19 +277,19 @@ namespace Canvas3D {
// TODO slow in Chrome, ok in FF; doesn't play well with gpu surface calc
// await webgl.readPixelsAsync(xp, yp, 1, 1, buffer)
webgl.readPixels(xp, yp, 1, 1, buffer)
const objectId = decodeIdRGB(buffer[0], buffer[1], buffer[2])
const objectId = decodeFloatRGB(buffer[0], buffer[1], buffer[2])
if (objectId === -1) { isIdentifying = false; return; }
instancePickTarget.bind()
// await webgl.readPixelsAsync(xp, yp, 1, 1, buffer)
webgl.readPixels(xp, yp, 1, 1, buffer)
const instanceId = decodeIdRGB(buffer[0], buffer[1], buffer[2])
const instanceId = decodeFloatRGB(buffer[0], buffer[1], buffer[2])
if (instanceId === -1) { isIdentifying = false; return; }
groupPickTarget.bind()
// await webgl.readPixelsAsync(xp, yp, 1, 1, buffer)
webgl.readPixels(xp, yp, 1, 1, buffer)
const groupId = decodeIdRGB(buffer[0], buffer[1], buffer[2])
const groupId = decodeFloatRGB(buffer[0], buffer[1], buffer[2])
if (groupId === -1) { isIdentifying = false; return; }
isIdentifying = false
......
......@@ -4,17 +4,6 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
function decodeFloatRGBA(r: number, g: number, b: number) {
r = Math.floor(r)
g = Math.floor(g)
b = Math.floor(b)
return r * 256 * 256 + g * 256 + b
}
export function decodeIdRGB(r: number, g: number, b: number) {
return decodeFloatRGBA(r, g, b) - 1
}
export interface PickingId {
objectId: number
instanceId: number
......
......@@ -7,9 +7,9 @@
#elif defined(dColorType_groupInstance)
vColor.rgb = readFromTexture(tColor, aInstance * float(uGroupCount) + aGroup, uColorTexDim).rgb;
#elif defined(dColorType_objectPicking)
vColor = vec4(encodeIdRGB(float(uObjectId)), 1.0);
vColor = vec4(encodeFloatRGB(float(uObjectId)), 1.0);
#elif defined(dColorType_instancePicking)
vColor = vec4(encodeIdRGB(aInstance), 1.0);
vColor = vec4(encodeFloatRGB(aInstance), 1.0);
#elif defined(dColorType_groupPicking)
vColor = vec4(encodeIdRGB(aGroup), 1.0);
vColor = vec4(encodeFloatRGB(aGroup), 1.0);
#endif
\ No newline at end of file
......@@ -9,5 +9,5 @@
uniform sampler2D tColor;
#elif defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking)
varying vec4 vColor;
#pragma glslify: encodeIdRGB = require(../utils/encode-id-rgb.glsl)
#pragma glslify: encodeFloatRGB = require(../utils/encode-float-rgb.glsl)
#endif
\ No newline at end of file
......@@ -47,8 +47,8 @@ uniform int uPickable;
#pragma glslify: import('./chunks/common.glsl')
#pragma glslify: readFromTexture = require(./utils/read-from-texture.glsl, intMod=intMod, intDiv=intDiv, foo=foo) // foo=foo is a workaround for a bug in glslify
#pragma glslify: encodeIdRGB = require(./utils/encode-id-rgb.glsl)
#pragma glslify: decodeIdRGB = require(./utils/decode-id-rgb.glsl)
#pragma glslify: encodeFloatRGB = require(./utils/encode-float-rgb.glsl)
#pragma glslify: decodeFloatRGB = require(./utils/decode-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
#pragma glslify: texture3dFrom2dLinear = require(./utils/texture3d-from-2d-linear.glsl, intMod=intMod, intDiv=intDiv, foo=foo) // foo=foo is a workaround for a bug in glslify
......@@ -135,12 +135,12 @@ vec4 raymarch(vec3 startLoc, vec3 step, vec3 viewDir) {
#endif
#if defined(dColorType_objectPicking)
return vec4(encodeIdRGB(float(uObjectId)), 1.0);
return vec4(encodeFloatRGB(float(uObjectId)), 1.0);
#elif defined(dColorType_instancePicking)
return vec4(encodeIdRGB(instance), 1.0);
return vec4(encodeFloatRGB(instance), 1.0);
#elif defined(dColorType_groupPicking)
float group = floor(decodeIdRGB(textureGroup(isoPos).rgb) + 0.5);
return vec4(encodeIdRGB(group), 1.0);
float group = floor(decodeFloatRGB(textureGroup(isoPos).rgb) + 0.5);
return vec4(encodeFloatRGB(group), 1.0);
#else
// compute gradient by central differences
gradient.x = textureVal(isoPos - dx).a - textureVal(isoPos + dx).a;
......@@ -150,7 +150,7 @@ vec4 raymarch(vec3 startLoc, vec3 step, vec3 viewDir) {
float d = float(dot(gradient, viewDir) > 0.0);
gradient = (2.0 * d - 1.0) * gradient;
float group = floor(decodeIdRGB(textureGroup(isoPos).rgb) + 0.5);
float group = floor(decodeFloatRGB(textureGroup(isoPos).rgb) + 0.5);
#if defined(dColorType_instance)
color = readFromTexture(tColor, instance, uColorTexDim).rgb;
......
......@@ -22,7 +22,9 @@ varying float vRadius;
#endif
#pragma glslify: import('./chunks/common.glsl')
#pragma glslify: encodeIdRGB = require(./utils/encode-id-rgb.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
uniform vec3 uBboxSize;
......@@ -46,12 +48,6 @@ uniform float uAlpha;
#endif
#endif
// encode distance logarithmically with given maxDistance
const float maxDistance = 10000.0;
const float distLogFactor = log(maxDistance + 1.0);
float encodeDistLog(float dist) { return log(dist + 1.0) / distLogFactor; }
float decodeDistLog(float logDist) { return exp(logDist * distLogFactor) - 1.0; }
void main() {
vec2 v = gl_FragCoord.xy - vec2(uCurrentX, uCurrentY) - 0.5;
vec3 fragPos = vec3(v.x, v.y, uCurrentSlice) / uGridDim;
......@@ -62,13 +58,13 @@ void main() {
float density = exp(-uAlpha * ((dist * dist) / radiusSq));
gl_FragColor = vec4(density);
#elif defined(dCalcType_minDistance)
gl_FragColor.a = 1.0 - encodeDistLog(dist);
gl_FragColor.a = 1.0 - encodeFloatLog(dist);
#elif defined(dCalcType_groupId)
float minDistance = decodeDistLog(1.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)
discard;
gl_FragColor.rgb = encodeIdRGB(vGroup);
gl_FragColor.rgb = encodeFloatRGB(vGroup);
#endif
}
\ No newline at end of file
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
const float maxFloat = 10000.0; // NOTE constant also set in in encodeFloatLog and in TypeScript
const float floatLogFactor = log(maxFloat + 1.0);
float decodeFloatLog(in float value) { return exp(value * floatLogFactor) - 1.0; }
#pragma glslify: export(decodeFloatLog)
\ No newline at end of file
......@@ -5,7 +5,7 @@
*/
float decodeFloatRGB(const in vec3 rgb) {
return rgb.r * 256.0 * 256.0 * 255.0 + rgb.g * 256.0 * 255.0 + rgb.b * 255.0;
return (rgb.r * 256.0 * 256.0 * 255.0 + rgb.g * 256.0 * 255.0 + rgb.b * 255.0) - 1.0;
}
#pragma glslify: export(decodeFloatRGB)
\ No newline at end of file
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
#pragma glslify: decodeFloatRGB = require(../utils/decode-float-rgb.glsl)
float decodeIdRGB(const in vec3 v) {
return decodeFloatRGB(v) - 1.0;
}
#pragma glslify: export(decodeIdRGB)
\ No newline at end of file
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
const float maxFloat = 10000.0; // NOTE constant also set in in decodeFloatLog and in TypeScript
const float floatLogFactor = log(maxFloat + 1.0);
float encodeFloatLog(in float value) { return log(value + 1.0) / floatLogFactor; }
#pragma glslify: export(encodeFloatLog)
\ No newline at end of file
......@@ -5,7 +5,7 @@
*/
vec3 encodeFloatRGB(in float value) {
value = clamp(value, 0.0, 16777216.0);
value = clamp(value, 0.0, 16777216.0 - 1.0) + 1.0;
vec3 c = vec3(0.0);
c.b = mod(value, 256.0);
value = floor(value / 256.0);
......
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
#pragma glslify: encodeFloatRGB = require(../utils/encode-float-rgb.glsl)
vec3 encodeIdRGB(const in float v) {
return encodeFloatRGB(v + 1.0);
}
#pragma glslify: export(encodeIdRGB)
\ No newline at end of file
......@@ -18,7 +18,7 @@ import { createRenderable, createGaussianDensityRenderObject } from 'mol-gl/rend
import { WebGLContext } from 'mol-gl/webgl/context';
import { createTexture, Texture } from 'mol-gl/webgl/texture';
import { GLRenderingContext } from 'mol-gl/webgl/compat';
import { decodeIdRGB } from 'mol-geo/geometry/picking';
import { decodeFloatRGB } from 'mol-util/float-packing';
/** name for shared framebuffer used for gpu gaussian surface operations */
const FramebufferName = 'gaussian-density-gpu'
......@@ -329,7 +329,7 @@ async function fieldFromTexture2d(ctx: WebGLContext, texture: Texture, dim: Vec3
for (let ix = 0; ix < dx; ++ix) {
const idx = 4 * (tmpCol * dx + (iy + tmpRow) * width + ix)
data[j] = image[idx + 3] / 255
idData[j] = decodeIdRGB(image[idx], image[idx + 1], image[idx + 2])
idData[j] = decodeFloatRGB(image[idx], image[idx + 1], image[idx + 2])
j++
}
}
......
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { clamp } from 'mol-math/interpolate';
const maxFloat = 10000.0; // NOTE same constant is set in shaders
const floatLogFactor = Math.log(maxFloat + 1.0);
/** encode float logarithmically */
export function encodeFloatLog(value: number) { return Math.log(value + 1.0) / floatLogFactor }
/** decode logarithmically encoded float */
export function decodeFloatLog(value: number) { return Math.exp(value * floatLogFactor) - 1.0 }
/** encode float as rgb triplet */
export function encodeFloatRGB(value: number) {
value = clamp(value, 0.0, 16777216.0 - 1.0) + 1.0
const b = (value % 256) / 255.0
value = Math.floor(value / 256.0)
const g = (value % 256) / 255.0
value = Math.floor(value / 256.0)
const r = (value % 256) / 255.0
return [r, g, b]
}
/** decode float encoded as rgb triplet */
export function decodeFloatRGB(r: number, g: number, b: number) {
return (Math.floor(r) * 256 * 256 + Math.floor(g) * 256 + Math.floor(b)) - 1
}
\ No newline at end of file
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