diff --git a/src/consts.cu b/src/consts.cu index 3e3b336..63f6242 100644 --- a/src/consts.cu +++ b/src/consts.cu @@ -55,3 +55,6 @@ __device__ float d_alphaAcumLimit; __device__ int d_tfComboSelected; __device__ int d_tfComboSelectedColor; __device__ float d_opacityConst; + +// ----------------------- Raycasting ----------------------- +__device__ int d_samplesPerPixel; diff --git a/src/consts.h b/src/consts.h index 93b04f2..b43dcd0 100644 --- a/src/consts.h +++ b/src/consts.h @@ -30,9 +30,6 @@ const float MAX_SPEED = 14.0f; // --------------------------- Raycasting Constants --------------------------- -const int SAMPLES_PER_PIXEL = 4; - -// const float alphaAcumLimit = 0.4f; // TODO: Atm, this only works with sigmoid const float minAllowedDensity = 0.001f; const float stepSize = 0.02f; @@ -74,6 +71,8 @@ extern __device__ int d_tfComboSelected; extern __device__ int d_tfComboSelectedColor; // constant opacity option extern __device__ float d_opacityConst; +// samples per pixel +extern __device__ int d_samplesPerPixel; const int lenStopsPythonLike = 5; const int lenStopsGrayscale = 2; diff --git a/src/gui/input/Widget.cpp b/src/gui/input/Widget.cpp index 1ad2e2c..5884138 100644 --- a/src/gui/input/Widget.cpp +++ b/src/gui/input/Widget.cpp @@ -25,6 +25,7 @@ Widget::Widget(GLFWwindow* window) { this->fps = (char*)malloc(512*sizeof(char)); this->paused = true; this->renderOnce = false; + this->samplesPerPixel = 1; this->opacityK = 0; this->sigmoidShift = 0.5f; @@ -101,6 +102,7 @@ void Widget::tick(double fps) { } sprintf(this->fps, "%.3f fps\n", fps); ImGui::Text(this->fps); + ImGui::DragInt("Samples per pixel", &this->samplesPerPixel, 1, 1, 16, "%d", ImGuiSliderFlags_AlwaysClamp); ImGui::End(); ImGui::Begin("Camera Controls"); @@ -125,6 +127,8 @@ void Widget::copyToDevice() { cudaMemcpyToSymbol(&d_cameraDir, &this->cameraDir, sizeof(Vec3)); cudaMemcpyToSymbol(&d_lightPos, &this->lightPos, sizeof(Point3)); cudaMemcpyToSymbol(&d_backgroundColor, &this->bgColor, sizeof(Color3)); + + cudaMemcpyToSymbol(&d_samplesPerPixel, &this->samplesPerPixel, sizeof(int)); // cudaMemcpyToSymbol(&d_opacityK, &this->opacityK, sizeof(float)); this->opacityKReal = std::pow(10.0f, (-10 + 0.1 * this->opacityK)); diff --git a/src/gui/input/Widget.h b/src/gui/input/Widget.h index 73f5cc6..0fb1d28 100644 --- a/src/gui/input/Widget.h +++ b/src/gui/input/Widget.h @@ -17,6 +17,7 @@ public: bool paused; bool renderOnce; char* fps; + int samplesPerPixel; int tfComboSelected; int tfComboSelectedColor; diff --git a/src/illumination/Raycaster.cu b/src/illumination/Raycaster.cu index 9e6db0d..beb98d9 100644 --- a/src/illumination/Raycaster.cu +++ b/src/illumination/Raycaster.cu @@ -20,14 +20,14 @@ __global__ void raycastKernel(float* volumeData, FrameBuffer framebuffer, const float accumR = 0.0f; float accumG = 0.0f; float accumB = 0.0f; - float accumA = 1.0f * (float)SAMPLES_PER_PIXEL; + float accumA = 1.0f * (float)d_samplesPerPixel; // Initialize random state for ray scattering curandState randState; curand_init(1234, px + py * width, 0, &randState); // Multiple samples per pixel - for (int s = 0; s < SAMPLES_PER_PIXEL; s++) { + for (int s = 0; s < d_samplesPerPixel; s++) { // Map to [-1, 1] float jitterU = (curand_uniform(&randState) - 0.5f) / width; float jitterV = (curand_uniform(&randState) - 0.5f) / height; @@ -71,11 +71,11 @@ __global__ void raycastKernel(float* volumeData, FrameBuffer framebuffer, const intersectAxis(d_cameraPos.z, rayDir.z, 0.0f, (float)VOLUME_DEPTH); if (tNear > tFar) { - // No intersection -> Set to brackground color (multiply by SAMPLES_PER_PIXEL because we divide by it later) - accumR = d_backgroundColor.x * (float)SAMPLES_PER_PIXEL; - accumG = d_backgroundColor.y * (float)SAMPLES_PER_PIXEL; - accumB = d_backgroundColor.z * (float)SAMPLES_PER_PIXEL; - accumA = 1.0f * (float)SAMPLES_PER_PIXEL; + // No intersection -> Set to brackground color (multiply by d_samplesPerPixel because we divide by it later) + accumR = d_backgroundColor.x * (float)d_samplesPerPixel; + accumG = d_backgroundColor.y * (float)d_samplesPerPixel; + accumB = d_backgroundColor.z * (float)d_samplesPerPixel; + accumA = 1.0f * (float)d_samplesPerPixel; } else { if (tNear < 0.0f) tNear = 0.0f; @@ -130,10 +130,10 @@ __global__ void raycastKernel(float* volumeData, FrameBuffer framebuffer, const // Average samples - accumR /= (float)SAMPLES_PER_PIXEL; - accumG /= (float)SAMPLES_PER_PIXEL; - accumB /= (float)SAMPLES_PER_PIXEL; - accumA /= (float)SAMPLES_PER_PIXEL; + accumR /= (float)d_samplesPerPixel; + accumG /= (float)d_samplesPerPixel; + accumB /= (float)d_samplesPerPixel; + accumA /= (float)d_samplesPerPixel; // Final colour framebuffer.writePixel(px, py, accumR, accumG, accumB, accumA);