Skip to content

Commit

Permalink
add density scale
Browse files Browse the repository at this point in the history
  • Loading branch information
孙万捷 authored and 孙万捷 committed Jul 18, 2016
1 parent 2d19a05 commit 8a25f9d
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 75 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ set(HOST_SOURCES main.cpp
core/VolumeReader.cpp
core/lights/lights.cpp gui/AddAreaLightDialog.cpp gui/AddAreaLightDialog.h)

set(DEVICE_SOURCES pathtracer.cu)
set(DEVICE_SOURCES pathtracer.cu raycasting.cu)

cuda_compile(DEVICE_OBJS ${DEVICE_SOURCES})

Expand Down
5 changes: 4 additions & 1 deletion core/cuda_volume.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class cudaVolume
__host__ __device__ void SetYClipPlane(const glm::vec2& clip) {y_clip = clip;}
__host__ __device__ void SetZClipPlane(const glm::vec2& clip) {z_clip = clip;}

__host__ __device__ void SetDensityScale(float s = 1.f) {densityScale = s;}

__device__ float operator ()(const glm::vec3& pointInWorld) const
{
return GetIntensity(pointInWorld);
Expand Down Expand Up @@ -83,7 +85,7 @@ class cudaVolume
{
#ifdef __CUDACC__
auto texCoord = GetNormalizedTexCoord(pointInWorld);
return tex3D<float>(tex, texCoord.x, texCoord.y, texCoord.z);
return tex3D<float>(tex, texCoord.x, texCoord.y, texCoord.z) * densityScale;
#else
return 0.f;
#endif
Expand All @@ -101,6 +103,7 @@ class cudaVolume
private:
cudaBBox bbox;
cudaTextureObject_t tex;
float densityScale;
glm::vec3 spacing;
glm::vec3 invSpacing;
glm::vec2 x_clip;
Expand Down
3 changes: 2 additions & 1 deletion gui/canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ void Canvas::LoadVolume(std::string filename)
volumeReader.Read(filename);
volumeReader.CreateDeviceVolume(&deviceVolume);
deviceVolume.SetClipPlane(glm::vec2(-1.f, 1.f), glm::vec2(-1.f, 1.f), glm::vec2(-1.f, 1.f));
deviceVolume.SetDensityScale(1.f);
setup_volume(deviceVolume);

ZoomToExtent();
Expand Down Expand Up @@ -85,7 +86,7 @@ void Canvas::paintGL()
glVertex2f(1.f, -1.f);
glEnd();

render_raycasting(img, volumeReader.GetElementBoundingSphereRadius());
render_raycasting(img, deviceVolume, transferFunction, camera, volumeReader.GetElementBoundingSphereRadius());
}
else
{
Expand Down
20 changes: 14 additions & 6 deletions gui/canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,6 @@ class Canvas : public QGLWidget
explicit Canvas(const QGLFormat& format, QWidget* parent = 0);
virtual ~Canvas();

void SetTransferFunction(const cudaTextureObject_t& tex, float maxOpacity)
{
transferFunction.Set(tex, maxOpacity);
setup_transferfunction(transferFunction);
ReStartRender();
};
void LoadVolume(std::string filename);
void StartTimer() {timerId = this->startTimer(0);}
void KillTimer() {this->killTimer(timerId);}
Expand All @@ -52,6 +46,20 @@ class Canvas : public QGLWidget
renderParams.frameNo = 0;
}

void SetTransferFunction(const cudaTextureObject_t& tex, float maxOpacity)
{
transferFunction.Set(tex, maxOpacity);
setup_transferfunction(transferFunction);
ReStartRender();
}

void SetDensityScale(double s)
{
deviceVolume.SetDensityScale(s);
setup_volume(deviceVolume);
ReStartRender();
}

void SetScatterTimes(double val)
{
renderParams.traceDepth = val;
Expand Down
7 changes: 7 additions & 0 deletions gui/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ void MainWindow::ConfigureTransferFunction()
ui->colorTransferFunc->view()->setAxesToChartBounds();

connect(tf, SIGNAL(Changed()), this, SLOT(onTransferFunctionChanged()));

connect(ui->SliderWidget_DensityScale, SIGNAL(valueChanged(double)), this, SLOT(onDensityScaleChanged(double)));
}

void MainWindow::onTransferFunctionChanged()
Expand Down Expand Up @@ -465,3 +467,8 @@ void MainWindow::onZClipChanged(double min, double max)
{
canvas->SetZClipPlane(min, max);
}

void MainWindow::onDensityScaleChanged(double s)
{
canvas->SetDensityScale(s);
}
1 change: 1 addition & 0 deletions gui/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class MainWindow : public QMainWindow

private slots:
void onTransferFunctionChanged();
void onDensityScaleChanged(double s);
void onScatterTimesChanged(double val);

void onEnvLightUOffsetChanged(double u);
Expand Down
28 changes: 26 additions & 2 deletions gui/mainwindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<y>-144</y>
<width>363</width>
<height>694</height>
<height>730</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
Expand Down Expand Up @@ -179,6 +179,30 @@
<string>Transfer Function</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_20">
<property name="text">
<string>Density scale</string>
</property>
</widget>
</item>
<item>
<widget class="ctkSliderWidget" name="SliderWidget_DensityScale">
<property name="decimals">
<number>3</number>
</property>
<property name="singleStep">
<double>0.001000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="ctkVTKScalarsToColorsWidget" name="opacityTransferFunc">
<property name="minimumSize">
Expand Down
63 changes: 0 additions & 63 deletions pathtracer.cu
Original file line number Diff line number Diff line change
Expand Up @@ -298,67 +298,4 @@ extern "C" void render_pathtracer(glm::u8vec4* img, const RenderParams& renderPa

kernel_pathtracer<<<gridSize, blockSize>>>(renderParams, wangHash(renderParams.frameNo));
hdr_to_ldr<<<gridSize, blockSize>>>(img, renderParams);
}

// front to back composite
__global__ void kernel_raycasting(glm::u8vec4* img, float stepSize)
{
auto idx = blockDim.x * blockIdx.x + threadIdx.x;
auto idy = blockDim.y * blockIdx.y + threadIdx.y;
auto offset = idy * WIDTH + idx;

cudaRay ray;
camera.GenerateRay(idx, idy, &ray);

glm::vec4 L = glm::vec4(0.f);

float tNear, tFar, t;
if(volume.Intersect(ray, &tNear, &tFar))
{
t = tNear;
while(t <= tFar)
{
auto ptInWorld = ray.PointOnRay(t);
auto intensity = volume(ptInWorld);
auto color_opacity = transferFunction(intensity);

// apply lighting
auto gradient = volume.Gradient_CentralDiff(ptInWorld);
auto gradientMagnitude = sqrtf(glm::dot(gradient, gradient));
float cosTerm = 1.f;
float specularTerm = 0.f;
if(gradientMagnitude > 1e-3)
{
auto normal = glm::normalize(gradient);
auto lightDir = glm::normalize(camera.pos - ptInWorld);
cosTerm = fabsf(glm::dot(normal, lightDir));

specularTerm = powf(cosTerm, 30.f);
}

color_opacity.x = color_opacity.x * color_opacity.w * cosTerm * 0.8f + color_opacity.w * specularTerm * 0.2f;
color_opacity.y = color_opacity.y * color_opacity.w * cosTerm * 0.8f + color_opacity.w * specularTerm * 0.2f;
color_opacity.z = color_opacity.z * color_opacity.w * cosTerm * 0.8f + color_opacity.w * specularTerm * 0.2f;

L += (1.f - L.w) * color_opacity;

if(L.w > 0.95f) break;

t += stepSize * 0.5f;
}

}

L.x = fminf(L.x, 1.f);
L.y = fminf(L.y, 1.f);
L.z = fminf(L.z, 1.f);
img[offset] = glm::u8vec4(L.x * 255, L.y * 255, L.z * 255, 255 * L.w);
}

extern "C" void render_raycasting(glm::u8vec4* img, float stepSize)
{
dim3 blockSize(16, 16);
dim3 gridSize(WIDTH / blockSize.x, HEIGHT / blockSize.y);

kernel_raycasting<<<gridSize, blockSize>>>(img, stepSize);
}
75 changes: 75 additions & 0 deletions raycasting.cu
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#define GLM_FORCE_NO_CTOR_INIT
#define GLM_FORCE_INLINE
#include <glm/glm.hpp>

#include <cuda_runtime.h>
#include <device_launch_parameters.h>
#include <curand_kernel.h>

#include "common.h"
#include "utils/helper_cuda.h"
#include "core/cuda_camera.h"
#include "core/cuda_transfer_function.h"
#include "core/cuda_volume.h"

__global__ void kernel_raycasting(glm::u8vec4* img, cudaVolume volume, cudaTransferFunction transferFunction, cudaCamera camera, float stepSize)
{
auto idx = blockDim.x * blockIdx.x + threadIdx.x;
auto idy = blockDim.y * blockIdx.y + threadIdx.y;
auto offset = idy * WIDTH + idx;

cudaRay ray;
camera.GenerateRay(idx, idy, &ray);

glm::vec4 L = glm::vec4(0.f);

float tNear, tFar, t;
if(volume.Intersect(ray, &tNear, &tFar))
{
t = tNear;
while(t <= tFar)
{
auto ptInWorld = ray.PointOnRay(t);
auto intensity = volume(ptInWorld);
auto color_opacity = transferFunction(intensity);

// apply lighting
auto gradient = volume.Gradient_CentralDiff(ptInWorld);
auto gradientMagnitude = sqrtf(glm::dot(gradient, gradient));
float cosTerm = 1.f;
float specularTerm = 0.f;
if(gradientMagnitude > 1e-3)
{
auto normal = glm::normalize(gradient);
auto lightDir = glm::normalize(camera.pos - ptInWorld);
cosTerm = fabsf(glm::dot(normal, lightDir));

specularTerm = powf(cosTerm, 30.f);
}

color_opacity.x = color_opacity.x * color_opacity.w * cosTerm * 0.8f + color_opacity.w * specularTerm * 0.2f;
color_opacity.y = color_opacity.y * color_opacity.w * cosTerm * 0.8f + color_opacity.w * specularTerm * 0.2f;
color_opacity.z = color_opacity.z * color_opacity.w * cosTerm * 0.8f + color_opacity.w * specularTerm * 0.2f;

L += (1.f - L.w) * color_opacity;

if(L.w > 0.95f) break;

t += stepSize * 0.5f;
}

}

L.x = fminf(L.x, 1.f);
L.y = fminf(L.y, 1.f);
L.z = fminf(L.z, 1.f);
img[offset] = glm::u8vec4(L.x * 255, L.y * 255, L.z * 255, 255 * L.w);
}

extern "C" void render_raycasting(glm::u8vec4* img, cudaVolume& volume, cudaTransferFunction& transferFunction, cudaCamera& camera, float stepSize)
{
dim3 blockSize(16, 16);
dim3 gridSize(WIDTH / blockSize.x, HEIGHT / blockSize.y);

kernel_raycasting<<<gridSize, blockSize>>>(img, volume, transferFunction, camera, stepSize);
}
2 changes: 1 addition & 1 deletion raycasting.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
#ifndef SUNVOLUMERENDER_RAYCASTING_H_H
#define SUNVOLUMERENDER_RAYCASTING_H_H

extern "C" void render_raycasting(glm::u8vec4* img, float stepSize);
extern "C" void render_raycasting(glm::u8vec4* img, cudaVolume& volume, cudaTransferFunction& transferFunction, cudaCamera& camera, float stepSize);

#endif //SUNVOLUMERENDER_RAYCASTING_H_H

0 comments on commit 8a25f9d

Please sign in to comment.