cloudy-raytracer/renderer/superrenderer.cpp

95 lines
3.3 KiB
C++
Raw Normal View History

2022-12-25 09:26:13 +01:00
#include "renderer/superrenderer.h"
2022-12-13 02:47:01 +01:00
#include "camera/camera.h"
#include "scene/scene.h"
2022-12-25 09:26:13 +01:00
#include <chrono>
#include <iomanip>
#include <iostream>
#include <thread>
void SuperRenderer::renderThread(const Scene *scene, Camera const *camera, Texture *image, int width, int widthStep, int widthOffset, int height, int heightStep, int heightOffset, std::atomic<int> *k, int const stepSize,
int superSamplingFactor) {
int const sampleCount = superSamplingFactor * superSamplingFactor;
float const samplingStep = 1.0f / superSamplingFactor;
float const aspectRatio = static_cast<float>(height) / width;
for (int y = heightOffset; y < image->height(); y += heightStep) {
for (int x = widthOffset; x < image->width(); x += widthStep) {
// The fragment color is averaged over all sub-pixel rays
Color fragmentColor;
for (int xs = 0; xs < superSamplingFactor; ++xs) {
for (int ys = 0; ys < superSamplingFactor; ++ys) {
Ray ray = camera->createRay(((xs * samplingStep + x) / width * 2 - 1), -((ys * samplingStep + y) / height * 2 - 1) * aspectRatio);
fragmentColor += scene->traceRay(ray);
2022-12-13 02:47:01 +01:00
}
2022-12-25 09:26:13 +01:00
}
image->setPixelAt(x, y, clamped(fragmentColor / float(sampleCount)));
2022-12-13 02:47:01 +01:00
2022-12-25 09:26:13 +01:00
// Super hacky progress bar!
if (++*k % stepSize == 0) {
std::cout << "=" << std::flush;
}
2022-12-13 02:47:01 +01:00
}
2022-12-25 09:26:13 +01:00
}
2022-12-13 02:47:01 +01:00
}
Texture SuperRenderer::renderImage(Scene const &scene, Camera const &camera, int width, int height) {
2022-12-25 09:26:13 +01:00
Texture image(width, height);
2022-12-13 02:47:01 +01:00
2022-12-25 09:26:13 +01:00
// Setup timer
std::chrono::steady_clock::time_point start, stop;
2022-12-13 02:47:01 +01:00
2022-12-25 09:26:13 +01:00
// ICGVARIANT ray_counting
// Reset Ray counting
Ray::resetRayCount();
2022-12-13 02:47:01 +01:00
2022-12-25 09:26:13 +01:00
// ENDVARIANT ray_counting
// Super-hacky progress bar!
std::cout << "(SuperRenderer): Begin rendering..." << std::endl;
std::cout << "| 0%";
int const barSize = 50;
int const stepSize = (width * height) / barSize;
for (int i = 0; i < barSize - 3 - 5; ++i)
std::cout << " ";
std::cout << "100% |" << std::endl << "|";
std::atomic<int> k(0);
2022-12-13 02:47:01 +01:00
2022-12-25 09:26:13 +01:00
// Start timer
start = std::chrono::steady_clock::now();
2022-12-13 02:47:01 +01:00
2022-12-25 09:26:13 +01:00
// Spawn a thread for every logical processor -1, calling the renderThread function
int const nThreads = std::thread::hardware_concurrency();
std::vector<std::thread> threads;
for (int t = 0; t < nThreads - 1; ++t) {
threads.emplace_back(renderThread, &scene, &camera, &image, width, nThreads, t, height, 1, 0, &k, stepSize, this->superSamplingFactor_);
}
2022-12-13 02:47:01 +01:00
2022-12-25 09:26:13 +01:00
// Call the renderThread function yourself
renderThread(&scene, &camera, &image, width, nThreads, nThreads - 1, height, 1, 0, &k, stepSize, this->superSamplingFactor_);
2022-12-13 02:47:01 +01:00
2022-12-25 09:26:13 +01:00
// Rejoin the threads
for (int t = 0; t < nThreads - 1; ++t) {
threads[t].join();
}
2022-12-13 02:47:01 +01:00
2022-12-25 09:26:13 +01:00
// Stop timer
stop = std::chrono::steady_clock::now();
2022-12-13 02:47:01 +01:00
2022-12-25 09:26:13 +01:00
std::cout << "| Done!" << std::endl;
2022-12-13 02:47:01 +01:00
2022-12-25 09:26:13 +01:00
// Calculate the Time taken in seconds
double seconds = std::chrono::duration_cast<std::chrono::duration<double>>(stop - start).count();
std::cout << "Time: " << seconds << "s" << std::endl;
// ICGVARIANT ray_counting
// Get the number of seconds per ray
int rays = Ray::getRayCount();
std::cout << "Paths: " << rays << std::endl;
std::cout << "Paths per second: " << std::fixed << std::setprecision(0) << rays / seconds << std::endl;
2022-12-13 02:47:01 +01:00
2022-12-25 09:26:13 +01:00
// ENDVARIANT ray_counting
2022-12-13 02:47:01 +01:00
2022-12-25 09:26:13 +01:00
return image;
2022-12-13 02:47:01 +01:00
}