Added superrender
This commit is contained in:
parent
32e54bbdf1
commit
cc78c886c8
2 changed files with 143 additions and 0 deletions
110
renderer/superrenderer.cpp
Normal file
110
renderer/superrenderer.cpp
Normal file
|
@ -0,0 +1,110 @@
|
|||
//
|
||||
// Created by arvids on 13.12.22.
|
||||
//
|
||||
|
||||
#include "superrenderer.h"
|
||||
#include "common/ray.h"
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
#include <iomanip>
|
||||
#include "camera/camera.h"
|
||||
#include "scene/scene.h"
|
||||
|
||||
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) {
|
||||
float const aspectRatio = static_cast<float>(height) / width;
|
||||
for (int y = heightOffset; y < height; y += heightStep) {
|
||||
for (int x = widthOffset; x < width; x += widthStep) {
|
||||
Color fragmentColor = {};
|
||||
fragmentColor = calcSuperColor(scene, camera, width, height, superSamplingFactor, aspectRatio, y, x,
|
||||
fragmentColor);
|
||||
fragmentColor /= static_cast<float>(superSamplingFactor * superSamplingFactor);
|
||||
image->setPixelAt(x, y, clamped(fragmentColor));
|
||||
// Super hacky progress bar!
|
||||
if (++*k % stepSize == 0) {
|
||||
std::cout << "=" << std::flush;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Color &
|
||||
SuperRenderer::calcSuperColor(const Scene *scene, const Camera *camera, int width, int height, int superSamplingFactor,
|
||||
const float aspectRatio, int y, int x, Color &fragmentColor) {
|
||||
for (int x1 = 0; x1 < superSamplingFactor; x1++) {
|
||||
for (int y1 = 0; y1 < superSamplingFactor; y1++) {
|
||||
float offsetX = (-0.5f + static_cast<float>(x1) / static_cast<float>(superSamplingFactor - 1));
|
||||
float offsetY = (-0.5f + static_cast<float>(y1) / static_cast<float>(superSamplingFactor - 1));
|
||||
|
||||
Ray ray = camera->createRay(((static_cast<float>(x) + offsetX) / static_cast<float>(width) * 2.0f - 1),
|
||||
-((static_cast<float>(y) + offsetY) / static_cast<float>(height) * 2.0f - 1) * aspectRatio);
|
||||
fragmentColor += scene->traceRay(ray);
|
||||
}
|
||||
}
|
||||
return fragmentColor;
|
||||
}
|
||||
|
||||
Texture SuperRenderer::renderImage(Scene const &scene, Camera const &camera, int width, int height) {
|
||||
Texture image(width, height);
|
||||
|
||||
// Setup timer
|
||||
std::chrono::steady_clock::time_point start, stop;
|
||||
|
||||
// Reset Ray counting
|
||||
Ray::resetRayCount();
|
||||
|
||||
// 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);
|
||||
|
||||
/* Start timer */ start = std::chrono::steady_clock::now();
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Call the renderThread function yourself
|
||||
renderThread(&scene, &camera, &image, width, nThreads, nThreads - 1, height, 1, 0, &k, stepSize,
|
||||
this->superSamplingFactor);
|
||||
|
||||
// Rejoin the threads
|
||||
for (int t = 0; t < nThreads - 1; ++t) {
|
||||
threads[t].join();
|
||||
}
|
||||
|
||||
// Stop timer
|
||||
stop = std::chrono::steady_clock::now();
|
||||
|
||||
std::cout << "| Done!" << std::endl;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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;
|
||||
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
void SuperRenderer::setSuperSamplingFactor(int superSamplingFactor) {
|
||||
SuperRenderer::superSamplingFactor = superSamplingFactor;
|
||||
}
|
33
renderer/superrenderer.h
Normal file
33
renderer/superrenderer.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// Created by arvids on 13.12.22.
|
||||
//
|
||||
|
||||
#ifndef CG1_TRACER_SUPERRENDERER_H
|
||||
#define CG1_TRACER_SUPERRENDERER_H
|
||||
|
||||
#include "renderer.h"
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
||||
class SuperRenderer : public Renderer {
|
||||
public:
|
||||
static void
|
||||
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);
|
||||
|
||||
Texture renderImage(const Scene &scene, const Camera &camera, int width, int height) override;
|
||||
void setSuperSamplingFactor(int superSamplingFactor);
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
int superSamplingFactor;
|
||||
|
||||
static Color &
|
||||
calcSuperColor(const Scene *scene, const Camera *camera, int width, int height, int superSamplingFactor,
|
||||
const float aspectRatio, int y, int x, Color &fragmentColor);
|
||||
};
|
||||
|
||||
|
||||
#endif //CG1_TRACER_SUPERRENDERER_H
|
Loading…
Reference in a new issue