added levoy transfer function

This commit is contained in:
Robin 2025-01-20 15:20:59 +01:00
parent bae68db6b8
commit 9f7700ae80
6 changed files with 66 additions and 39 deletions

View File

@ -2,41 +2,33 @@
#include "cuda_error.h"
// ----------------------- Colour mapping -----------------------
// __device__ __constant__ ColorStop d_stopsPythonLike[5];
__device__ __constant__ ColorStop d_stopsPythonLike[11];
__device__ __constant__ ColorStop d_stopsPythonLike[5];
// __device__ __constant__ ColorStop d_stopsPythonLike[11];
__device__ __constant__ ColorStop d_stopsGrayscale[2];
__device__ __constant__ ColorStop d_stopsBluePurleRed[3];
// const ColorStop h_stopsPythonLike[] = {
// { 0.0f, Color3::init(0.2298057f, 0.29871797f, 0.75368315f) }, // Dark Blue
// { 0.25f, Color3::init(0.23437708f, 0.30554173f, 0.75967953f) }, // Mid Blue
// { 0.5f, Color3::init(0.27582712f, 0.36671692f, 0.81255294f) }, // White
// { 0.75f, Color3::init(0.79606387f, 0.84869321f, 0.93347147f) }, // Light Orange
// { 1.0f, Color3::init(0.70567316f, 0.01555616f, 0.15023281f) } // Red
// };
// const ColorStop h_stopsPythonLike[] = {
// { 0.0f, Color3::init(0.2298057f, 0.29871797f, 0.75368315f) }, // Dark Blue
// { 0.85f, Color3::init(0.23437708f, 0.30554173f, 0.75967953f) }, // Mid Blue
// { 0.90f, Color3::init(0.27582712f, 0.36671692f, 0.81255294f) }, // White
// { 0.95f, Color3::init(0.79606387f, 0.84869321f, 0.93347147f) }, // Light Orange
// { 1.0f, Color3::init(0.70567316f, 0.01555616f, 0.15023281f) } // Red
// };
const ColorStop h_stopsPythonLike[] = {
{ 0.0f, Color3::init(0.2298057f, 0.29871797f, 0.75368315f) }, // Dark Blue
{ 0.25f, Color3::init(0.23437708f, 0.30554173f, 0.75967953f) }, // Mid Blue
{ 0.5f, Color3::init(0.27582712f, 0.36671692f, 0.81255294f) }, // White
{ 0.75f, Color3::init(0.79606387f, 0.84869321f, 0.93347147f) }, // Light Orange
{ 1.0f, Color3::init(0.70567316f, 0.01555616f, 0.15023281f) } // Red
};
// Python "jet" colour scheme
const ColorStop h_stopsPythonLike[] = {
{ 0.00f, Color3::init(0.00000000f, 0.00000000f, 0.50000000f) },
{ 0.82f, Color3::init(0.00000000f, 0.00000000f, 0.94563280f) },
{ 0.84f, Color3::init(0.00000000f, 0.30000000f, 1.00000000f) },
{ 0.86f, Color3::init(0.00000000f, 0.69215686f, 1.00000000f) },
{ 0.88f, Color3::init(0.16129032f, 1.00000000f, 0.80645161f) },
{ 0.90f, Color3::init(0.49019608f, 1.00000000f, 0.47754586f) },
{ 0.92f, Color3::init(0.80645161f, 1.00000000f, 0.16129032f) },
{ 0.94f, Color3::init(1.00000000f, 0.77051561f, 0.00000000f) },
{ 0.96f, Color3::init(1.00000000f, 0.40740741f, 0.00000000f) },
{ 0.98f, Color3::init(0.94563280f, 0.02977487f, 0.00000000f) },
{ 1.00f, Color3::init(0.50000000f, 0.00000000f, 0.00000000f) },
};
// const ColorStop h_stopsPythonLike[] = {
// { 0.00f, Color3::init(0.00000000f, 0.00000000f, 0.50000000f) },
// { 0.82f, Color3::init(0.00000000f, 0.00000000f, 0.94563280f) },
// { 0.84f, Color3::init(0.00000000f, 0.30000000f, 1.00000000f) },
// { 0.86f, Color3::init(0.00000000f, 0.69215686f, 1.00000000f) },
// { 0.88f, Color3::init(0.16129032f, 1.00000000f, 0.80645161f) },
// { 0.90f, Color3::init(0.49019608f, 1.00000000f, 0.47754586f) },
// { 0.92f, Color3::init(0.80645161f, 1.00000000f, 0.16129032f) },
// { 0.94f, Color3::init(1.00000000f, 0.77051561f, 0.00000000f) },
// { 0.96f, Color3::init(1.00000000f, 0.40740741f, 0.00000000f) },
// { 0.98f, Color3::init(0.94563280f, 0.02977487f, 0.00000000f) },
// { 1.00f, Color3::init(0.50000000f, 0.00000000f, 0.00000000f) },
// };
const ColorStop h_stopsGrayscale[] = {
{ 0.0f, Color3::init(0.0f, 0.0f, 0.0f) }, // No colour
@ -84,6 +76,8 @@ __device__ int d_tfComboSelectedColor;
__device__ float d_opacityConst;
__device__ bool d_showSilhouettes;
__device__ float d_silhouettesThreshold;
__device__ float d_levoyFocus;
__device__ float d_levoyWidth;
// ----------------------- Raycasting -----------------------
__device__ int d_samplesPerPixel;

View File

@ -78,11 +78,14 @@ extern __device__ int d_samplesPerPixel;
// Silhouettes
extern __device__ bool d_showSilhouettes;
extern __device__ float d_silhouettesThreshold;
// controlling levoy opacity function
extern __device__ float d_levoyFocus;
extern __device__ float d_levoyWidth;
const int lenStopsPythonLike = 11;
const int lenStopsPythonLike = 5;
const int lenStopsGrayscale = 2;
const int lenStopsBluePurpleRed = 3;
extern __constant__ ColorStop d_stopsPythonLike[11];
extern __constant__ ColorStop d_stopsPythonLike[5];
extern __constant__ ColorStop d_stopsGrayscale[2];
extern __constant__ ColorStop d_stopsBluePurleRed[3];

View File

@ -92,7 +92,6 @@ void Window::free(float* data) {
void Window::tick() {
std::cout << "tick tick\n";
// manually track time diff
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
float diff = (float) std::chrono::duration_cast<std::chrono::milliseconds>(now - this->last_frame).count();
@ -101,12 +100,10 @@ void Window::tick() {
// input
this->widget->tick(1000.0/diff);
std::cout << "setting tick render\n";
// tick render
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_DEPTH_TEST);
std::cout << "blabla\n";
if (!this->widget->paused) this->quad->render();
this->shader->use();
glBindVertexArray(this->quad->VAO);
@ -114,14 +111,11 @@ void Window::tick() {
glDrawArrays(GL_TRIANGLES, 0, 6); // draw current frame to texture
// render ImGui context
std::cout << "rendering\n";
this->widget->render();
std::cout << "done rendering\n";
// check for events
glfwSwapBuffers(this->window);
glfwPollEvents();
std::cout << "done tick tick\n";
}

View File

@ -45,9 +45,12 @@ Widget::Widget(GLFWwindow* window) {
this->sigmoidExp = -250.0f;
this->alphaAcumLimit = 0.4f;
this->tfComboSelected = 2;
this->tfComboSelectedColor = 0;
this->opacityConst = 100;
this->showSilhouettes = false;
this->silhouettesThreshold = 0.02f;
this->levoyFocus = 0.5;
this->levoyWidth = 1;
};
// REFACTOR: should probably not have all the logic in one function; something like a list of ImplementedWidgets with each a Render() function (a la interface) would be better.
@ -73,13 +76,18 @@ void Widget::tick(double fps) {
ImGui::InputFloat("Sig. sxp", &this->sigmoidExp, 10.0f, 100.0f, "%.0f");
ImGui::DragFloat("Alpha accum. limit", &this->alphaAcumLimit, 0.01f, 0.0f, 1.0f, "%.2f");
ImGui::DragInt("Opacity const. (log [1e-5, 1])", &this->opacityConst, 1, 0, 100, "%d%%", ImGuiSliderFlags_AlwaysClamp);
ImGui::DragFloat("Levoy Width", &this->levoyWidth, 0.01f, 0.0f, 100.0f, "%.2f");
// ImGui::DragFloat("Levoy Focus", &this->levoyFocus, 0.01f, 250.0f, 350.0f, "%.2f");
ImGui::DragFloat("Levoy Focus", &this->levoyFocus, 0.01f, 0.0f, 1.0f, "%.2f");
// the items[] contains the entries for the combobox. The selected index is stored as an int on this->tfComboSelected
// the default entry is set in the constructor, so if you want that to be a specific entry just change it
// whatever value is selected here is available on the gpu as d_tfComboSelected.
const char* items[] = {"Opacity - gradient", "Opacity - sigmoid", "Opacity - constant", "..."};
const char* items[] = {"Opacity - gradient", "Opacity - sigmoid", "Opacity - constant", "Opacity - levoy"};
if (ImGui::BeginCombo("Transfer function", items[this->tfComboSelected])) {
// std::cout << "hello???\n";
for (int n = 0; n < IM_ARRAYSIZE(items); n++) {
// std::cout << "letsssssa a asdfa???\n";
const bool is_selected = (this->tfComboSelected == n);
if (ImGui::Selectable(items[n], is_selected))
this->tfComboSelected = n;
@ -171,11 +179,14 @@ void Widget::copyToDevice() {
cudaMemcpyToSymbol(&d_tfComboSelected, &this->tfComboSelected, sizeof(int));
cudaMemcpyToSymbol(&d_showSilhouettes, &this->showSilhouettes, sizeof(bool));
cudaMemcpyToSymbol(&d_silhouettesThreshold, &this->silhouettesThreshold, sizeof(float));
cudaMemcpyToSymbol(&d_levoyFocus, &this->levoyFocus, sizeof(float));
cudaMemcpyToSymbol(&d_levoyWidth, &this->levoyWidth, sizeof(float));
this->opacityConstReal = std::pow(10.0f, (-5 + 0.05 * this->opacityConst));
cudaMemcpyToSymbol(&d_opacityConst, &this->opacityConstReal, sizeof(float));
cudaMemcpyToSymbol(&d_tfComboSelectedColor, &this->tfComboSelectedColor, sizeof(int));
}
Widget::~Widget() {

View File

@ -32,6 +32,8 @@ public:
float opacityConstReal;
bool showSilhouettes;
float silhouettesThreshold;
float levoyFocus;
float levoyWidth;
ImGuiIO io;

View File

@ -3,10 +3,29 @@
#include <stdio.h>
// [Levoy 1988]
__device__ float levoyOpacity(const Vec3 &grad, float val) {
float r = d_levoyWidth; // width
float fv = d_levoyFocus; // chosen value
float epsilon = 1E-8;
float gradMag = grad.length();
if ((gradMag < epsilon) && ((val - epsilon) <= fv) && (fv <= (val + epsilon))) return 1.0f;
if (gradMag < epsilon) return 0.0f;
float lowBound = val - r*gradMag;
float upperBound = val + r*gradMag;
// float lowBound = fv - r;
// float upperBound = fv + r;
if (!((lowBound <= fv) && (fv <= upperBound))) return 0.0f;
// if ((lowBound <= gradMag) && (gradMag <= upperBound)) return 1.0f;
// return 0.0f;
float alpha = d_opacityConst*(1 - (1/r)*fabs((fv-val)/gradMag));
return alpha;
}
__device__ float opacityFromGradient(const Vec3 &grad, const Vec3& rayDir) {
float gradMag = grad.length();
// float gradMag = 1-fabs(grad.normalize().dot(rayDir));
// float gradMag = grad.length()*(1-fabs(grad.normalize().dot(rayDir))); // Alternative, but not particularly better
float alpha = 1.0f - expf(-d_opacityK * gradMag);
return alpha;
@ -84,6 +103,10 @@ __device__ float4 transferFunction(float density, const Vec3& grad, const Point3
alpha = d_opacityConst;
break;
case 3:
alpha = levoyOpacity(grad, normDensity);
break;
default:
alpha = 1.0f; // This should not be reached anyway
break;