pushing this.
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,3 +2,6 @@
|
|||||||
/bin/
|
/bin/
|
||||||
/web/output/
|
/web/output/
|
||||||
imgui.ini
|
imgui.ini
|
||||||
|
#prototyping in python below
|
||||||
|
*.py
|
||||||
|
/venv/
|
||||||
|
|||||||
@@ -43,10 +43,10 @@ void generateNoiseGrid(VoxelGrid& grid, PNoise2& noise) {
|
|||||||
|
|
||||||
// Create grayscale color based on noise value
|
// Create grayscale color based on noise value
|
||||||
uint8_t grayValue = static_cast<uint8_t>(noiseVal * 255);
|
uint8_t grayValue = static_cast<uint8_t>(noiseVal * 255);
|
||||||
Vec3ui8 color(grayValue, grayValue, grayValue);
|
Vec3ui8 color(grayValue, grayValue, 0);
|
||||||
#pragma omp critical
|
#pragma omp critical
|
||||||
if (active > threshold) {
|
if (active > threshold) {
|
||||||
grid.set(x, y, z, active, color);
|
grid.set(x, y, z, true, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,16 +66,18 @@ bool renderView(const std::string& filename, VoxelGrid& grid, const Vec3f& posit
|
|||||||
size_t height = RENDER_HEIGHT;
|
size_t height = RENDER_HEIGHT;
|
||||||
|
|
||||||
// Render the view
|
// Render the view
|
||||||
|
//frame output = grid.renderFrame(position, direction, up, 40, RENDER_WIDTH, RENDER_HEIGHT);
|
||||||
grid.renderOut(renderBuffer, width, height, cam);
|
grid.renderOut(renderBuffer, width, height, cam);
|
||||||
|
|
||||||
// Save to BMP
|
// Save to BMP
|
||||||
|
//bool success = BMPWriter::saveBMP(filename, output);
|
||||||
bool success = BMPWriter::saveBMP(filename, renderBuffer, width, height);
|
bool success = BMPWriter::saveBMP(filename, renderBuffer, width, height);
|
||||||
|
|
||||||
if (success) {
|
// if (success) {
|
||||||
std::cout << "Saved: " << filename << std::endl;
|
// std::cout << "Saved: " << filename << std::endl;
|
||||||
} else {
|
// } else {
|
||||||
std::cout << "Failed to save: " << filename << std::endl;
|
// std::cout << "Failed to save: " << filename << std::endl;
|
||||||
}
|
// }
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
#include "../basicdefines.hpp"
|
#include "../basicdefines.hpp"
|
||||||
|
|
||||||
struct Voxel {
|
struct Voxel {
|
||||||
float active;
|
//float active;
|
||||||
|
bool active;
|
||||||
//Vec3f position;
|
//Vec3f position;
|
||||||
Vec3ui8 color;
|
Vec3ui8 color;
|
||||||
};
|
};
|
||||||
@@ -27,7 +28,8 @@ struct Camera {
|
|||||||
|
|
||||||
class VoxelGrid {
|
class VoxelGrid {
|
||||||
private:
|
private:
|
||||||
size_t width, height, depth;
|
Vec3T gridSize;
|
||||||
|
//size_t width, height, depth;
|
||||||
std::vector<Voxel> voxels;
|
std::vector<Voxel> voxels;
|
||||||
float radians(float rads) {
|
float radians(float rads) {
|
||||||
return rads * (M_PI / 180);
|
return rads * (M_PI / 180);
|
||||||
@@ -67,21 +69,30 @@ private:
|
|||||||
|
|
||||||
std::pair<float,float> rayBoxIntersect(const Vec3f& origin, const Vec3f& direction) {
|
std::pair<float,float> rayBoxIntersect(const Vec3f& origin, const Vec3f& direction) {
|
||||||
Vec3f tBMin = Vec3f(0,0,0);
|
Vec3f tBMin = Vec3f(0,0,0);
|
||||||
Vec3f tBMax = Vec3f(width, height, depth);
|
Vec3f tBMax = gridSize.toFloat();
|
||||||
float tmin = 0;
|
float tmin = -INF;
|
||||||
float tmax = INF;
|
float tmax = INF;
|
||||||
Vec3f invDir = direction.safeInverse();
|
Vec3f invDir = direction.safeInverse();
|
||||||
|
bool allParallel = true;
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
if (abs(direction[i]) < EPSILON) {
|
if (abs(direction[i]) < EPSILON) {
|
||||||
if (origin[i] < tBMin[i] || origin[i] > tBMax[i]) return std::make_pair(0.0f, 0.0f);
|
if (!(origin[i] < tBMin[i] || origin[i] > tBMax[i])) continue;
|
||||||
float t1 = tBMin[i] - origin[i] * invDir[i];
|
|
||||||
float t2 = tBMax[i] - origin[i] * invDir[i];
|
|
||||||
if (t1 > t2) std::swap(t1, t2);
|
|
||||||
if (t1 > tmin) tmin = t1;
|
|
||||||
if (t2 < tmax) tmax = t2;
|
|
||||||
if (tmin > tmax) return std::make_pair(0,0);
|
|
||||||
}
|
}
|
||||||
|
allParallel = false;
|
||||||
|
float t1 = (tBMin[i] - origin[i]) * invDir[i];
|
||||||
|
float t2 = (tBMax[i] - origin[i]) * invDir[i];
|
||||||
|
|
||||||
|
if (t1 > t2) std::swap(t1, t2);
|
||||||
|
|
||||||
|
if (t1 > tmin) tmin = t1;
|
||||||
|
if (t2 < tmax) tmax = t2;
|
||||||
|
|
||||||
|
if (tmin > tmax) return std::make_pair(0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
if (allParallel) {
|
||||||
|
return std::make_pair(0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
if (tmax < 0) return std::make_pair(0.0f, 0.0f);
|
||||||
return std::make_pair(tmin, tmax);
|
return std::make_pair(tmin, tmax);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,53 +117,53 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VoxelGrid(size_t w, size_t h, size_t d) : width(w), height(h), depth(d) {
|
VoxelGrid(size_t w, size_t h, size_t d) : gridSize(w,h,d) {
|
||||||
voxels.resize(w * h * d);
|
voxels.resize(w * h * d);
|
||||||
}
|
}
|
||||||
|
|
||||||
Voxel& get(size_t x, size_t y, size_t z) {
|
Voxel& get(size_t x, size_t y, size_t z) {
|
||||||
return voxels[z * width * height + y * width + x];
|
return voxels[z * gridSize.x * gridSize.y + y * gridSize.x + x];
|
||||||
}
|
}
|
||||||
|
|
||||||
const Voxel& get(size_t x, size_t y, size_t z) const {
|
const Voxel& get(size_t x, size_t y, size_t z) const {
|
||||||
return voxels[z * width * height + y * width + x];
|
return voxels[z * gridSize.x * gridSize.y + y * gridSize.x + x];
|
||||||
}
|
}
|
||||||
|
|
||||||
Voxel& get(const Vec3T& xyz) {
|
Voxel& get(const Vec3T& xyz) {
|
||||||
return voxels[xyz.z*width*height+xyz.y*width+xyz.x];
|
return voxels[xyz.z * gridSize.x * gridSize.y + xyz.y * gridSize.x + xyz.x];
|
||||||
}
|
}
|
||||||
|
|
||||||
void resize() {
|
void resize() {
|
||||||
//TODO: proper resizing
|
//TODO: proper resizing
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(size_t x, size_t y, size_t z, float active, Vec3ui8 color) {
|
void set(size_t x, size_t y, size_t z, bool active, Vec3ui8 color) {
|
||||||
set(Vec3T(x,y,z), active, color);
|
set(Vec3T(x,y,z), active, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(Vec3T pos, float active, Vec3ui8 color) {
|
void set(Vec3T pos, bool active, Vec3ui8 color) {
|
||||||
if (pos.x >= 0 || pos.y >= 0 || pos.z >= 0) {
|
if (pos.x >= 0 || pos.y >= 0 || pos.z >= 0) {
|
||||||
if (!(pos.x < width)) {
|
if (!(pos.x < gridSize.x)) {
|
||||||
//until resizing added:
|
//until resizing added:
|
||||||
return;
|
return;
|
||||||
width = pos.x;
|
gridSize.x = pos.x;
|
||||||
resize();
|
resize();
|
||||||
}
|
}
|
||||||
else if (!(pos.y < height)) {
|
else if (!(pos.y < gridSize.y)) {
|
||||||
//until resizing added:
|
//until resizing added:
|
||||||
return;
|
return;
|
||||||
height = pos.y;
|
gridSize.y = pos.y;
|
||||||
resize();
|
resize();
|
||||||
}
|
}
|
||||||
else if (!(pos.z < depth)) {
|
else if (!(pos.z < gridSize.z)) {
|
||||||
//until resizing added:
|
//until resizing added:
|
||||||
return;
|
return;
|
||||||
depth = pos.z;
|
gridSize.z = pos.z;
|
||||||
resize();
|
resize();
|
||||||
}
|
}
|
||||||
|
|
||||||
Voxel& v = get(pos);
|
Voxel& v = get(pos);
|
||||||
v.active = std::clamp(active, 0.0f, 1.0f);
|
v.active = active; // std::clamp(active, 0.0f, 1.0f);
|
||||||
v.color = color;
|
v.color = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -163,7 +174,7 @@ public:
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool inGrid(Vec3<T> voxl) {
|
bool inGrid(Vec3<T> voxl) {
|
||||||
return (voxl >= 0 && voxl.x < width && voxl.y < height && voxl.z < depth);
|
return (voxl >= 0 && voxl.x < gridSize.x && voxl.y < gridSize.y && voxl.z < gridSize.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Vec3f> genPixelDirs(const Vec3f& pos, const Vec3f& dir, size_t imgWidth, size_t imgHeight, float fov) {
|
std::vector<Vec3f> genPixelDirs(const Vec3f& pos, const Vec3f& dir, size_t imgWidth, size_t imgHeight, float fov) {
|
||||||
@@ -208,78 +219,110 @@ public:
|
|||||||
return rayDirWorld.normalized();
|
return rayDirWorld.normalized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool castRay(const Vec3f& origin, const Vec3f& direction, float maxDist, Vec3f& hitColor) {
|
||||||
|
Vec3f dir = direction.normalized();
|
||||||
|
Vec3T pos = origin.floorToT();
|
||||||
|
Vec3i step = Vec3i(dir.x > 0 ? -1 : 1, dir.y > 0 ? -1 : 1, dir.z > 0 ? -1 : 1);
|
||||||
|
Vec3f tMax;
|
||||||
|
Vec3f tDelta;
|
||||||
|
if (abs(dir.x) > EPSILON) {
|
||||||
|
tMax.x = (static_cast<size_t>(pos.x) + (step.x > 0 ? 1 : 0) - pos.x) / dir.x;
|
||||||
|
tDelta.x = step.x / dir.x;
|
||||||
|
} else {
|
||||||
|
tMax.x = INF;
|
||||||
|
tDelta.x = INF;
|
||||||
|
}
|
||||||
|
if (abs(dir.y) > EPSILON) {
|
||||||
|
tMax.y = (static_cast<size_t>(pos.y) + (step.y > 0 ? 1 : 0) - pos.y) / dir.y;
|
||||||
|
tDelta.y = step.y / dir.y;
|
||||||
|
} else {
|
||||||
|
tMax.y = INF;
|
||||||
|
tDelta.y = INF;
|
||||||
|
}
|
||||||
|
if (abs(dir.z) > EPSILON) {
|
||||||
|
tMax.z = (static_cast<size_t>(pos.z) + (step.z > 0 ? 1 : 0) - pos.z) / dir.z;
|
||||||
|
tDelta.z = step.z / dir.z;
|
||||||
|
} else {
|
||||||
|
tMax.z = INF;
|
||||||
|
tDelta.z = INF;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto intersect = rayBoxIntersect(origin, dir);
|
||||||
|
float tEntry = intersect.first;
|
||||||
|
float tExit = intersect.second;
|
||||||
|
if (tEntry <= 0 && tExit <= 0) return false;
|
||||||
|
if (tEntry > maxDist) return false;
|
||||||
|
|
||||||
|
float dist = 0;
|
||||||
|
while (dist < maxDist) {
|
||||||
|
if (inGrid(pos)) {
|
||||||
|
Voxel cv = get(pos);
|
||||||
|
if (cv.active) {
|
||||||
|
Vec3f norm = Vec3f(0,0,0);
|
||||||
|
if (tMax.x <= tMax.y && tMax.x <= tMax.z) norm.x = -step.x;
|
||||||
|
else if (tMax.y <= tMax.x && tMax.y <= tMax.z) norm.y = -step.y;
|
||||||
|
else norm.z = -step.z;
|
||||||
|
hitColor = cv.color.toFloat() / 255;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tMax.x <= tMax.y && tMax.x <= tMax.z) {
|
||||||
|
pos.x += step.x;
|
||||||
|
dist += tDelta.x;
|
||||||
|
//dist = tMax.x;
|
||||||
|
tMax.x += tDelta.x;
|
||||||
|
} else if (tMax.y <= tMax.x && tMax.y <= tMax.z) {
|
||||||
|
pos.y += step.y;
|
||||||
|
//dist = tMax.y;
|
||||||
|
dist += tDelta.y;
|
||||||
|
tMax.y += tDelta.y;
|
||||||
|
} else {
|
||||||
|
pos.z += step.z;
|
||||||
|
//dist = tMax.z;
|
||||||
|
dist += tDelta.z;
|
||||||
|
tMax.z += tDelta.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool rayCast(const Vec3f& origin, const Vec3f& direction, float maxDist, Vec3f& hitColor) {
|
bool rayCast(const Vec3f& origin, const Vec3f& direction, float maxDist, Vec3f& hitColor) {
|
||||||
Vec3f dir = direction.normalized();
|
Vec3f dir = direction.normalized();
|
||||||
if (abs(dir.length()) < EPSILON) return false;
|
if (abs(dir.length()) < EPSILON) return false;
|
||||||
|
|
||||||
Vec3f invDir = dir.safeInverse();
|
|
||||||
Vec3T currentVoxel = origin.floorToT();
|
|
||||||
|
|
||||||
if (dir.x == 0 || dir.y == 0 || dir.z == 0) {
|
if (dir.x == 0 || dir.y == 0 || dir.z == 0) {
|
||||||
return specialCases(origin, dir, maxDist, hitColor);
|
return specialCases(origin, dir, maxDist, hitColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float tStart;
|
||||||
|
Vec3f invDir = dir.safeInverse();
|
||||||
|
Vec3T currentVoxel = origin.floorToT();
|
||||||
if (!inGrid(currentVoxel)) {
|
if (!inGrid(currentVoxel)) {
|
||||||
std::pair<float,float> re = rayBoxIntersect(origin, dir);
|
std::pair<float,float> re = rayBoxIntersect(origin, dir);
|
||||||
float tEntry = re.first;
|
float tEntry = re.first;
|
||||||
float tExit = re.second;
|
float tExit = re.second;
|
||||||
if (tEntry < EPSILON || tExit < EPSILON) return false;
|
if (tEntry < EPSILON || tExit < EPSILON) return false;
|
||||||
float tStart = std::max(0.0f, tEntry);
|
if (tEntry > maxDist) return false;
|
||||||
if (tStart > maxDist) return false;
|
tStart = tEntry;
|
||||||
Vec3f gridOrig = origin + dir * tStart;
|
|
||||||
currentVoxel = gridOrig.floorToT();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec3f gridOrig = origin + dir * tStart;
|
||||||
|
currentVoxel = gridOrig.floorToT();
|
||||||
Vec3i8 step = Vec3i8(dir.x >= 0 ? 1 : -1, dir.y >= 0 ? 1 : -1, dir.z >= 0 ? 1 : -1);
|
Vec3i8 step = Vec3i8(dir.x >= 0 ? 1 : -1, dir.y >= 0 ? 1 : -1, dir.z >= 0 ? 1 : -1);
|
||||||
Vec3f tMax;
|
Vec3f tMax;
|
||||||
|
float tDist = tStart;
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
if (step[i] > 0) {
|
if (step[i] > 0) {
|
||||||
tMax[i] = ((currentVoxel[i] + 1) - origin[i]) * invDir[i];
|
tMax[i] = ((currentVoxel[i] + 1) - gridOrig[i]) * invDir[i];
|
||||||
} else {
|
} else {
|
||||||
tMax[i] = (currentVoxel[i] - origin[i]) * invDir[i];
|
tMax[i] = (currentVoxel[i] - gridOrig[i]) * invDir[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Vec3f tDelta = invDir.abs();
|
Vec3f tDelta = invDir.abs();
|
||||||
// Vec3f dir = direction.normalized();
|
|
||||||
// if (abs(dir.length()) < EPSILON) return false;
|
|
||||||
|
|
||||||
// Vec3f invDir = dir.safeInverse();
|
|
||||||
// Vec3T currentVoxel = origin.floorToT();
|
|
||||||
|
|
||||||
// if (dir.x == 0 || dir.y == 0 || dir.z == 0) {
|
|
||||||
// return specialCases(origin, dir, maxDist, hitColor);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //if (!inGrid(currentVoxel)) {
|
|
||||||
// std::pair<float,float> re = rayBoxIntersect(origin, dir);
|
|
||||||
// float tEntry = re.first;
|
|
||||||
// float tExit = re.second;
|
|
||||||
// float tStart = std::max(0.0f, tEntry);
|
|
||||||
// if (tEntry < EPSILON || tExit < EPSILON || tStart > maxDist) return false;
|
|
||||||
// Vec3f gridOrig = origin + dir * tStart;
|
|
||||||
// currentVoxel = gridOrig.floorToT();
|
|
||||||
// //}
|
|
||||||
|
|
||||||
// Vec3i8 step = Vec3i8(direction.x >= 0 ? 1 : -1, direction.y >= 0 ? 1 : -1, direction.z >= 0 ? 1 : -1);
|
|
||||||
// Vec3f tMax;
|
|
||||||
// Vec3f tDelta = invDir.abs();
|
|
||||||
// for (int i = 0; i < 3; i++) {
|
|
||||||
// //if (step[i] != 0) {
|
|
||||||
// if (step[i] > 0) {
|
|
||||||
// tMax[i] = ((currentVoxel[i] + 1) - origin[i]) * invDir[i];
|
|
||||||
// } else {
|
|
||||||
// tMax[i] = (currentVoxel[i] - origin[i]) * invDir[i];
|
|
||||||
// }
|
|
||||||
// //tDelta[i] = fabs(1.0f / dir[i]);
|
|
||||||
// //} else {
|
|
||||||
// //tMax[i] = INF;
|
|
||||||
// //tDelta[i] = INF;
|
|
||||||
// //}
|
|
||||||
// }
|
|
||||||
|
|
||||||
float aalpha = 0;
|
float aalpha = 0;
|
||||||
|
|
||||||
while (inGrid(currentVoxel) && aalpha < 1) {
|
while (inGrid(currentVoxel) && aalpha < 1 && tDist <= maxDist) {
|
||||||
Voxel cv = get(currentVoxel);
|
Voxel cv = get(currentVoxel);
|
||||||
if (cv.active > EPSILON) {
|
if (cv.active > EPSILON) {
|
||||||
float alpha = cv.active * (1.0f - aalpha);
|
float alpha = cv.active * (1.0f - aalpha);
|
||||||
@@ -289,15 +332,17 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tMax.x < tMax.y && tMax.x < tMax.z) {
|
if (tMax.x < tMax.y && tMax.x < tMax.z) {
|
||||||
|
tDist = tDist + tDelta.x;
|
||||||
if (tMax.x > maxDist) break;
|
if (tMax.x > maxDist) break;
|
||||||
currentVoxel.x += step.x;
|
currentVoxel.x += step.x;
|
||||||
tMax.x += tDelta.x;
|
tMax.x += tDelta.x;
|
||||||
} else if (tMax.y < tMax.z)
|
} else if (tMax.y < tMax.z) {
|
||||||
{
|
tDist = tDist + tDelta.y;
|
||||||
currentVoxel.y += step.y;
|
currentVoxel.y += step.y;
|
||||||
tMax.y += tDelta.y;
|
tMax.y += tDelta.y;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
tDist = tDist + tDelta.z;
|
||||||
currentVoxel.z += step.z;
|
currentVoxel.z += step.z;
|
||||||
tMax.z += tDelta.z;
|
tMax.z += tDelta.z;
|
||||||
}
|
}
|
||||||
@@ -309,48 +354,117 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t getWidth() const {
|
size_t getWidth() const {
|
||||||
return width;
|
return gridSize.x;
|
||||||
}
|
}
|
||||||
size_t getHeight() const {
|
size_t getHeight() const {
|
||||||
return height;
|
return gridSize.y;
|
||||||
}
|
}
|
||||||
size_t getDepth() const {
|
size_t getDepth() const {
|
||||||
return depth;
|
return gridSize.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame renderFrame(const Vec3f& CamPos, const Vec3f& lookAt, const Vec3f& up, float fov, size_t outW, size_t outH) {
|
||||||
|
TIME_FUNCTION;
|
||||||
|
Vec3f forward = (lookAt - CamPos).normalized();
|
||||||
|
Vec3f right = forward.cross(up).normalized();
|
||||||
|
Vec3f upCor = right.cross(forward).normalized();
|
||||||
|
float aspect = outW / outH;
|
||||||
|
float fovRad = radians(fov);
|
||||||
|
float viewH = 2 * tan(fovRad / 2);
|
||||||
|
float viewW = viewH * aspect;
|
||||||
|
float maxDist = gridSize.lengthSquared() / 2;
|
||||||
|
frame outFrame = frame(outH,outW, frame::colormap::RGB);
|
||||||
|
std::vector<uint8_t> colorBuffer(outW * outH * 3);
|
||||||
|
#pragma omp parallel for
|
||||||
|
for (size_t y = 0; y < outH; y++) {
|
||||||
|
float v = (y + 0.5) / outH - 0.5;
|
||||||
|
for (size_t x = 0; x < outW; x++) {
|
||||||
|
float u = (x + 0.5) / outW - 0.5;
|
||||||
|
Vec3f rayDir = (forward + right * (u + viewW) + upCor * (v * viewH)).normalized();
|
||||||
|
Vec3f hitColor = Vec3f(0,0,0);
|
||||||
|
bool hit = castRay(CamPos, rayDir, maxDist, hitColor);
|
||||||
|
size_t idx = y*outW+x;
|
||||||
|
if (!hit) {
|
||||||
|
hitColor = Vec3f(0.1,0.1,1.0f);
|
||||||
|
} else {
|
||||||
|
std::cout << "hit";
|
||||||
|
}
|
||||||
|
colorBuffer[idx + 0] = static_cast<uint8_t>(hitColor.x * 255);
|
||||||
|
colorBuffer[idx + 1] = static_cast<uint8_t>(hitColor.y * 255);
|
||||||
|
colorBuffer[idx + 2] = static_cast<uint8_t>(hitColor.z * 255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
outFrame.setData(colorBuffer);
|
||||||
|
return outFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderOut(std::vector<uint8_t>& output, size_t& outwidth, size_t& outheight, const Camera& cam) {
|
void renderOut(std::vector<uint8_t>& output, size_t& outwidth, size_t& outheight, const Camera& cam) {
|
||||||
TIME_FUNCTION;
|
TIME_FUNCTION;
|
||||||
output.resize(outwidth * outheight * 3);
|
Vec3f forward = (cam.posfor.direction - cam.posfor.origin).normalized();
|
||||||
Vec3f backgroundColor(0.1f, 0.1f, 1.0f);
|
Vec3f right = forward.cross(cam.up).normalized();
|
||||||
float maxDistance = std::sqrt(width*width + height*height + depth*depth) * 2.0f;
|
Vec3f upCor = right.cross(forward).normalized();
|
||||||
// std::vector<Vec3f> dirs = genPixelDirs(cam.posfor.origin, cam.posfor.direction, outwidth, outheight, cam.fov);
|
float aspect = outwidth / outheight;
|
||||||
|
float fovRad = radians(cam.fov);
|
||||||
|
float viewH = 2 * tan(fovRad / 2);
|
||||||
|
float viewW = viewH * aspect;
|
||||||
|
float maxDist = gridSize.lengthSquared() / 2;
|
||||||
|
//frame outFrame = frame(outH,outW, frame::colormap::RGB);
|
||||||
|
std::vector<uint8_t> colorBuffer(outwidth * outheight * 3);
|
||||||
|
#pragma omp parallel for
|
||||||
for (size_t y = 0; y < outheight; y++) {
|
for (size_t y = 0; y < outheight; y++) {
|
||||||
float yout = y * outwidth;
|
float v = (y + 0.5) / outheight - 0.5;
|
||||||
for (size_t x = 0; x < outwidth; x++) {
|
for (size_t x = 0; x < outwidth; x++) {
|
||||||
// Vec3f rayDir = dirs[y*outwidth + x];
|
float u = (x + 0.5) / outwidth - 0.5;
|
||||||
// Vec3f hitColor = Vec3f(0,0,0);
|
Vec3f rayDir = (forward + right * (u + viewW) + upCor * (v * viewH)).normalized();
|
||||||
Vec3f rayDir = perPixelRayDir(x, y, outwidth, outheight, cam);
|
Vec3f hitColor = Vec3f(0,0,0);
|
||||||
Ray3f ray(cam.posfor.origin, rayDir);
|
bool hit = castRay(cam.posfor.origin, rayDir, maxDist, hitColor);
|
||||||
Vec3f hitPos;
|
size_t idx = y*outwidth+x;
|
||||||
Vec3f hitNorm;
|
|
||||||
Vec3f hitColor;
|
|
||||||
bool hit = rayCast(cam.posfor.origin, rayDir, maxDistance, hitColor);
|
|
||||||
|
|
||||||
Vec3f finalColor;
|
|
||||||
if (!hit) {
|
if (!hit) {
|
||||||
finalColor = backgroundColor;
|
hitColor = Vec3f(0.1,0.1,1.0f);
|
||||||
} else {
|
} else {
|
||||||
finalColor = hitColor;
|
std::cout << "hit";
|
||||||
}
|
}
|
||||||
|
colorBuffer[idx + 0] = static_cast<uint8_t>(hitColor.x * 255);
|
||||||
finalColor = finalColor.clamp(0, 1);
|
colorBuffer[idx + 1] = static_cast<uint8_t>(hitColor.y * 255);
|
||||||
size_t pixelIndex = (yout + x) * 3;
|
colorBuffer[idx + 2] = static_cast<uint8_t>(hitColor.z * 255);
|
||||||
output[pixelIndex + 0] = static_cast<uint8_t>(finalColor.x * 255);
|
|
||||||
output[pixelIndex + 1] = static_cast<uint8_t>(finalColor.y * 255);
|
|
||||||
output[pixelIndex + 2] = static_cast<uint8_t>(finalColor.z * 255);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
output = colorBuffer;
|
||||||
|
// TIME_FUNCTION;
|
||||||
|
// output.resize(outwidth * outheight * 3);
|
||||||
|
// Vec3f backgroundColor(0.1f, 0.1f, 1.0f);
|
||||||
|
// float maxDistance = sqrt(gridSize.lengthSquared()) * 2;
|
||||||
|
// //float maxDistance = std::sqrt(width*width + height*height + depth*depth) * 2.0f;
|
||||||
|
// // std::vector<Vec3f> dirs = genPixelDirs(cam.posfor.origin, cam.posfor.direction, outwidth, outheight, cam.fov);
|
||||||
|
|
||||||
|
// for (size_t y = 0; y < outheight; y++) {
|
||||||
|
// float yout = y * outwidth;
|
||||||
|
// for (size_t x = 0; x < outwidth; x++) {
|
||||||
|
// // Vec3f rayDir = dirs[y*outwidth + x];
|
||||||
|
// // Vec3f hitColor = Vec3f(0,0,0);
|
||||||
|
// Vec3f rayDir = perPixelRayDir(x, y, outwidth, outheight, cam);
|
||||||
|
// Ray3f ray(cam.posfor.origin, rayDir);
|
||||||
|
// Vec3f hitPos;
|
||||||
|
// Vec3f hitNorm;
|
||||||
|
// Vec3f hitColor;
|
||||||
|
// bool hit = castRay(cam.posfor.origin, rayDir, maxDistance, hitColor);
|
||||||
|
|
||||||
|
// Vec3f finalColor;
|
||||||
|
// if (!hit) {
|
||||||
|
// finalColor = backgroundColor;
|
||||||
|
// } else {
|
||||||
|
// finalColor = hitColor;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// finalColor = finalColor.clamp(0, 1);
|
||||||
|
// size_t pixelIndex = (yout + x) * 3;
|
||||||
|
// output[pixelIndex + 0] = static_cast<uint8_t>(finalColor.x * 255);
|
||||||
|
// output[pixelIndex + 1] = static_cast<uint8_t>(finalColor.y * 255);
|
||||||
|
// output[pixelIndex + 2] = static_cast<uint8_t>(finalColor.z * 255);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user