diff --git a/src/consts.cu b/src/consts.cu index 415d3f4..69235dd 100644 --- a/src/consts.cu +++ b/src/consts.cu @@ -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; diff --git a/src/consts.h b/src/consts.h index dfcf1f4..f303c5e 100644 --- a/src/consts.h +++ b/src/consts.h @@ -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]; diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 8f19b1b..9ab73a5 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -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(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"; } diff --git a/src/gui/input/Widget.cpp b/src/gui/input/Widget.cpp index b03a795..daa5856 100644 --- a/src/gui/input/Widget.cpp +++ b/src/gui/input/Widget.cpp @@ -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() { diff --git a/src/gui/input/Widget.h b/src/gui/input/Widget.h index 34799c4..a28a718 100644 --- a/src/gui/input/Widget.h +++ b/src/gui/input/Widget.h @@ -32,6 +32,8 @@ public: float opacityConstReal; bool showSilhouettes; float silhouettesThreshold; + float levoyFocus; + float levoyWidth; ImGuiIO io; diff --git a/src/illumination/transferFunction.cu b/src/illumination/transferFunction.cu index 6fc6fc8..72dd27b 100644 --- a/src/illumination/transferFunction.cu +++ b/src/illumination/transferFunction.cu @@ -3,10 +3,29 @@ #include +// [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; @@ -83,6 +102,10 @@ __device__ float4 transferFunction(float density, const Vec3& grad, const Point3 case 2: alpha = d_opacityConst; break; + + case 3: + alpha = levoyOpacity(grad, normDensity); + break; default: alpha = 1.0f; // This should not be reached anyway