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

wip, direct volume rendering

parent 0df5c9a1
No related branches found
No related tags found
No related merge requests found
......@@ -134,8 +134,9 @@ function createVolumeTexture3d(volume: VolumeData) {
let i = 0
for (let z = 0; z < depth; ++z) {
for (let y = 0; y < height; ++y) {
for (let x = 0; x < width; ++x) {
for (let y = 0; y < height; ++y) {
array[i + 3] = ((get(data, x, y, z) - stats.min) / (stats.max - stats.min)) * 255
i += 4
}
......
......@@ -126,12 +126,16 @@ export const GlobalUniformSchema = {
uModelView: UniformSpec('m4'),
uInvModelView: UniformSpec('m4'),
uProjection: UniformSpec('m4'),
uInvProjection: UniformSpec('m4'),
uModelViewProjection: UniformSpec('m4'),
uInvModelViewProjection: UniformSpec('m4'),
// uLightPosition: Uniform('v3'),
uLightColor: UniformSpec('v3'),
uLightAmbient: UniformSpec('v3'),
uPixelRatio: UniformSpec('f'),
uViewportHeight: UniformSpec('f'),
uViewport: UniformSpec('v4'),
uHighlightColor: UniformSpec('v3'),
uSelectColor: UniformSpec('v3'),
......
......@@ -10,7 +10,7 @@ import { Camera } from 'mol-view/camera/base';
import Scene from './scene';
import { Context, createImageData } from './webgl/context';
import { Mat4, Vec3 } from 'mol-math/linear-algebra';
import { Mat4, Vec3, Vec4 } from 'mol-math/linear-algebra';
import { Renderable } from './renderable';
import { Color } from 'mol-util/color';
import { ValueCell } from 'mol-util';
......@@ -54,6 +54,7 @@ namespace Renderer {
let { clearColor, viewport: _viewport } = { ...DefaultRendererProps, ...props }
const viewport = Viewport.clone(_viewport)
const viewportVec4 = Viewport.toVec4(Vec4.zero(), viewport)
// const lightPosition = Vec3.create(0, 0, -100)
const lightColor = Vec3.create(1.0, 1.0, 1.0)
......@@ -72,6 +73,9 @@ namespace Renderer {
const invView = Mat4.invert(Mat4.identity(), view)
const modelView = Mat4.clone(camera.view)
const invModelView = Mat4.invert(Mat4.identity(), modelView)
const invProjection = Mat4.invert(Mat4.identity(), camera.projection)
const modelViewProjection = Mat4.mul(Mat4.identity(), modelView, camera.projection)
const invModelViewProjection = Mat4.invert(Mat4.identity(), modelViewProjection)
const globalUniforms: GlobalUniformValues = {
uModel: ValueCell.create(Mat4.identity()),
......@@ -79,10 +83,14 @@ namespace Renderer {
uInvView: ValueCell.create(invView),
uModelView: ValueCell.create(modelView),
uInvModelView: ValueCell.create(invModelView),
uInvProjection: ValueCell.create(invProjection),
uProjection: ValueCell.create(Mat4.clone(camera.projection)),
uModelViewProjection: ValueCell.create(modelViewProjection),
uInvModelViewProjection: ValueCell.create(invModelViewProjection),
uPixelRatio: ValueCell.create(ctx.pixelRatio),
uViewportHeight: ValueCell.create(viewport.height),
uViewport: ValueCell.create(viewportVec4),
uLightColor: ValueCell.create(Vec3.clone(lightColor)),
uLightAmbient: ValueCell.create(Vec3.clone(lightAmbient)),
......@@ -143,6 +151,9 @@ namespace Renderer {
ValueCell.update(globalUniforms.uModelView, Mat4.mul(modelView, scene.view, camera.view))
ValueCell.update(globalUniforms.uInvModelView, Mat4.invert(invModelView, modelView))
ValueCell.update(globalUniforms.uProjection, camera.projection)
ValueCell.update(globalUniforms.uInvProjection, Mat4.invert(invProjection, camera.projection))
ValueCell.update(globalUniforms.uModelViewProjection, Mat4.mul(modelViewProjection, modelView, camera.projection))
ValueCell.update(globalUniforms.uInvModelViewProjection, Mat4.invert(invModelViewProjection, modelViewProjection))
ValueCell.update(globalUniforms.uFogFar, camera.fogFar)
ValueCell.update(globalUniforms.uFogNear, camera.fogNear)
......@@ -171,6 +182,7 @@ namespace Renderer {
Viewport.set(viewport, x, y, width, height)
gl.viewport(x, y, width, height)
ValueCell.update(globalUniforms.uViewportHeight, height)
ValueCell.update(globalUniforms.uViewport, Vec4.set(viewportVec4, x, y, width, height))
},
getImageData: () => {
const { width, height } = viewport
......
......@@ -17,12 +17,7 @@ varying vec3 origPos;
uniform float uAlpha;
uniform mat4 uInvView;
uniform mat4 uModelView;
uniform mat4 uInvModelView;
uniform float uIsoValue;
uniform vec3 uBboxMin;
uniform vec3 uBboxMax;
uniform vec3 uBboxSize;
uniform vec3 uGridDim;
uniform sampler2D tTransferTex;
......@@ -33,56 +28,6 @@ uniform sampler2D tTransferTex;
uniform sampler3D tGridTex;
#endif
// float uIsoValue = exp(-1.5);
// float uIsoValue = 0.7;
varying vec4 vNearPos;
varying vec4 vFarPos;
varying vec3 vPosition;
#pragma glslify: transpose = require(./utils/transpose.glsl)
vec3 extractCameraPos(const in mat4 modelView) {
// Get the 3 basis vector planes at the camera origin and transform them into model space.
//
// NOTE: Planes have to be transformed by the inverse transpose of a matrix
// Nice reference here: http://www.opengl.org/discussion_boards/showthread.php/159564-Clever-way-to-transform-plane-by-matrix
//
// So for a transform to model space we need to do:
// inverse(transpose(inverse(MV)))
// This equals : transpose(MV) - see Lemma 5 in http://mathrefresher.blogspot.com.au/2007/06/transpose-of-matrix.html
//
// As each plane is simply (1,0,0,0), (0,1,0,0), (0,0,1,0) we can pull the data directly from the transpose matrix.
//
mat4 modelViewT = transpose(modelView);
// Get plane normals
vec3 n1 = vec3(modelViewT[0]);
vec3 n2 = vec3(modelViewT[1]);
vec3 n3 = vec3(modelViewT[2]);
// Get plane distances
float d1 = modelViewT[0].w;
float d2 = modelViewT[1].w;
float d3 = modelViewT[2].w;
// Get the intersection of these 3 planes
// (uisng math from RealTime Collision Detection by Christer Ericson)
vec3 n2n3 = cross(n2, n3);
float denom = dot(n1, n2n3);
vec3 top = (n2n3 * d1) + cross(n1, (d3 * n2) - (d2 * n3));
return top / -denom;
}
vec3 palette(in float t, in vec3 a, in vec3 b, in vec3 c, in vec3 d) {
return a + b * cos(6.28318 * (c * t + d));
}
vec3 palette1(in float t) {
return palette(t, vec3(0.5,0.5,0.5),vec3(0.5,0.5,0.5),vec3(1.0,1.0,1.0),vec3(0.0,0.10,0.20));
}
#if defined(dGridTexType_2d)
// TODO workaround due to some kind of GPU bug
float myMod(float a, float b) {
......@@ -121,48 +66,31 @@ vec4 transferFunction(float value) {
const float gradOffset = 0.5;
const vec3 color = vec3(0.45, 0.55, 0.8);
vec4 raymarch(vec3 cameraPos) {
vec3 pos = unitCoord;
vec4 raymarch(vec3 startLoc, vec3 step, vec3 viewDir) {
vec3 scaleVol = vec3(1.0) / uGridDim;
vec3 pos = startLoc + scaleVol * 0.5;
float prevValue = -127.0;
float value = 0.0;
// float MAX_STEPS_F = max(max(uGridDim.x, uGridDim.y), uGridDim.z);
// int MAX_STEPS = 2 * int(length(vec3(imgresx, imgresy, imgresz)));
float stepSize = 1.0 / float(dMaxSteps);
vec4 src = vec4(0.0);
vec4 dst = vec4(0.0);
vec3 rayDir = normalize(origPos - cameraPos);
// rayDir = normalize(vec3(1.0, 1.0, 0.0));
// return vec4(rayDir, 0.5);
vec3 isoPos;
float tmp;
vec3 gradient = vec3(1.0);
vec3 step = rayDir * (1.0 / uGridDim) * 0.5;
#if defined(dRenderMode_isosurface)
vec3 isoPos;
float tmp;
vec3 scaleVol = vec3(1.0) / uGridDim;
vec3 dx = vec3(gradOffset * scaleVol.x, 0.0, 0.0);
vec3 dy = vec3(0.0, gradOffset * scaleVol.y, 0.0);
vec3 dz = vec3(0.0, 0.0, gradOffset * scaleVol.z);
// dst = vec4(textureVal(vec3(pos.xy, 0.6)).xyz, 0.5);
// vec2 foo = (vec2(5.0 * uGridDim.x, 5.0 * uGridDim.y) + (pos.xy * uGridDim.xy)) / uGridTexDim;
// dst = texture2D(tGridTex, foo);
// dst = texture2D(tGridTex, unitCoord.xy);
// dst.xyz = pos;
// return mix(dst, vec4(1.0, 0.0, 0.0, 1.0), 0.5);
vec3 gradient = vec3(1.0);
vec3 dx = vec3(gradOffset * scaleVol.x, 0.0, 0.0);
vec3 dy = vec3(0.0, gradOffset * scaleVol.y, 0.0);
vec3 dz = vec3(0.0, 0.0, gradOffset * scaleVol.z);
#endif
for(int i = 0; i < dMaxSteps; ++i){
if( pos.x <= 1.0 && pos.y <= 1.0 && pos.z <= 1.0 && pos.x >= 0.0 && pos.y >= 0.0 && pos.z >= 0.0) {
value = textureVal(pos).a; // current voxel value
} else {
value = textureVal(pos).a; // current voxel value
if(pos.x > 1.01 || pos.y > 1.01 || pos.z > 1.01 || pos.x < -0.01 || pos.y < -0.01 || pos.z < -0.01)
break;
}
#if defined(dRenderMode_volume)
// src = texture1D(transferRGBASampler, scalarData);
src = transferFunction(value);
// src.rgb = palette1(value);
// src.a = 1.0 - pow(1.0 - src.a, 0.5);
src.rgb *= src.a;
dst = (1.0 - dst.a) * src + dst; // standard blending
#endif
......@@ -181,10 +109,10 @@ vec4 raymarch(vec3 cameraPos) {
gradient.z = textureVal(isoPos - dz).a - textureVal(isoPos + dz).a;
gradient = normalize(gradient);
float d = float(dot(gradient, normalize(cameraPos)) > 0.0);
float d = float(dot(gradient, viewDir) > 0.0);
gradient = (2.0 * d - 1.0) * gradient;
src.rgb = color.rgb * abs(dot(gradient, normalize(cameraPos)));
src.rgb = color.rgb * abs(dot(gradient, viewDir));
src.a = uAlpha;
// draw interior darker
......@@ -208,56 +136,14 @@ vec4 raymarch(vec3 cameraPos) {
void main () {
vec3 cameraPos = uInvView[3].xyz / uInvView[3].w;
// vec3 cameraPos = extractCameraPos(uModelView);
// vec3 cameraPos = vec3(10.0, 0.0, 0.0);
gl_FragColor = raymarch(cameraPos);
vec3 rayDir = normalize(origPos - cameraPos);
vec3 startLoc = unitCoord;
vec3 step = rayDir * (1.0 / uGridDim) * 0.5;
gl_FragColor = raymarch(startLoc, step, normalize(cameraPos));
if (length(gl_FragColor.rgb) < 0.00001) discard;
#if defined(dRenderMode_volume)
gl_FragColor.a = uAlpha;
#endif
// gl_FragColor = vec4(unitCoord, 1.0);
// gl_FragColor = vec4(1.0, 0.0, 0.0, 0.5);
}
// const float relativeStepSize = 1.0;
// vec3 u_size = uGridDim;
// void main () {
// // Normalize clipping plane info
// vec3 farPos = vFarPos.xyz / vFarPos.w;
// vec3 nearPos = vNearPos.xyz / vNearPos.w;
// // Calculate unit vector pointing in the view direction through this fragment.
// vec3 viewRay = normalize(nearPos.xyz - farPos.xyz);
// // Compute the (negative) distance to the front surface or near clipping plane.
// // v_position is the back face of the cuboid, so the initial distance calculated in the dot
// // product below is the distance from near clip plane to the back of the cuboid
// float distance = dot(nearPos - vPosition, viewRay);
// distance = max(distance, min((-0.5 - vPosition.x) / viewRay.x, (u_size.x - 0.5 - vPosition.x) / viewRay.x));
// distance = max(distance, min((-0.5 - vPosition.y) / viewRay.y, (u_size.y - 0.5 - vPosition.y) / viewRay.y));
// distance = max(distance, min((-0.5 - vPosition.z) / viewRay.z, (u_size.z - 0.5 - vPosition.z) / viewRay.z));
// // Now we have the starting position on the front surface
// vec3 front = vPosition + viewRay * distance;
// // Decide how many steps to take
// int nsteps = int(-distance / relativeStepSize + 0.5);
// // if (nsteps < 1)
// // discard;
// // Get starting location and step vector in texture coordinates
// vec3 step = ((vPosition - front) / u_size) / float(nsteps);
// vec3 startLoc = front / u_size;
// // For testing: show the number of steps. This helps to establish
// // whether the rays are correctly oriented
// gl_FragColor = vec4(0.0, float(nsteps) / 1.0 / u_size.x, 1.0, 1.0);
// gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
// return;
// // if (u_renderstyle == 0)
// // cast_mip(startLoc, step, nsteps, viewRay);
// // else if (u_renderstyle == 1)
// // cast_iso(start_loc, step, nsteps, view_ray);
// if (gl_FragColor.a < 0.05)
// discard;
// }
\ No newline at end of file
}
\ No newline at end of file
......@@ -15,41 +15,13 @@ varying vec3 origPos;
uniform vec3 uBboxSize;
uniform vec3 uBboxMin;
uniform vec3 uBboxMax;
uniform mat4 uTransform;
uniform mat4 uInvView;
uniform mat4 uModelView;
uniform mat4 uInvModelView;
uniform mat4 uProjection, uView, uModel;
varying vec4 vNearPos;
varying vec4 vFarPos;
varying vec3 vPosition;
uniform mat4 uProjection;
void main() {
unitCoord = aPosition + vec3(0.5);
vec4 mvPosition = uView * uModel * vec4(unitCoord * uBboxSize + uBboxMin, 1.0);
// vec4 mvPosition = vec4(unitCoord * uBboxSize + uBboxMin, 1.0);
// origPos = mvPosition.xyz;
vec4 mvPosition = uModelView * vec4(unitCoord * uBboxSize + uBboxMin, 1.0);
origPos = unitCoord * uBboxSize + uBboxMin;
gl_Position = uProjection * mvPosition;
}
// void main() {
// // Project local vertex coordinate to camera position. Then do a step
// // backward (in cam coords) to the near clipping plane, and project back. Do
// // the same for the far clipping plane. This gives us all the information we
// // need to calculate the ray and truncate it to the viewing cone.
// vec3 position = aPosition * uBboxSize + uBboxMin;
// vec4 position4 = vec4(position, 1.0);
// vec4 posInCam = uView * position4;
// // Intersection of ray and near clipping plane (z = -1 in clip coords)
// posInCam.z = -posInCam.w;
// vNearPos = uInvView * posInCam;
// // Intersection of ray and far clipping plane (z = +1 in clip coords)
// posInCam.z = posInCam.w;
// vFarPos = uInvView * posInCam;
// // Set varyings and output pos
// vPosition = position;
// gl_Position = uProjection * uModelView * position4;
// }
\ No newline at end of file
}
\ No newline at end of file
......@@ -30,6 +30,14 @@ export namespace Viewport {
viewport.height = height
return viewport
}
export function toVec4(v4: Vec4, viewport: Viewport): Vec4 {
v4[0] = viewport.x
v4[1] = viewport.y
v4[2] = viewport.width
v4[3] = viewport.height
return v4
}
}
const tmpVec3 = Vec3.zero()
......
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