pushing some stuff home
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <vector>
|
||||||
#include "../util/grid/grid3.hpp"
|
#include "../util/grid/grid3.hpp"
|
||||||
#include "../util/output/bmpwriter.hpp"
|
#include "../util/output/bmpwriter.hpp"
|
||||||
#include "../util/noise/pnoise2.hpp"
|
#include "../util/noise/pnoise2.hpp"
|
||||||
@@ -24,30 +25,28 @@ void generateNoiseGrid(VoxelGrid& grid, PNoise2& noise) {
|
|||||||
std::cout << "Processing layer " << z << " of " << GRID_SIZE << std::endl;
|
std::cout << "Processing layer " << z << " of " << GRID_SIZE << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma omp parallel for
|
//#pragma omp parallel for
|
||||||
for (size_t y = 0; y < GRID_SIZE; ++y) {
|
for (size_t y = 0; y < GRID_SIZE; ++y) {
|
||||||
#pragma omp parallel for
|
//#pragma omp parallel for
|
||||||
for (size_t x = 0; x < GRID_SIZE; ++x) {
|
for (size_t x = 0; x < GRID_SIZE; ++x) {
|
||||||
// Create 3D noise coordinates (scaled for better frequency)
|
// Create 3D noise coordinates (scaled for better frequency)
|
||||||
float scale = 0.05f; // Controls noise frequency
|
float scale = 0.05f; // Controls noise frequency
|
||||||
float noiseVal = noise.permute(Vec3f(x * scale, y * scale, z * scale));
|
float noiseVal = noise.permute(Vec3f(x * scale, y * scale, z * scale));
|
||||||
|
|
||||||
// Convert from [-1, 1] to [0, 1] range
|
// Convert from [-1, 1] to [0, 1] range
|
||||||
float normalizedNoise = (noiseVal + 1.0f) * 0.5f;
|
//float normalizedNoise = (noiseVal + 1.0f) * 0.5f;
|
||||||
|
|
||||||
// Apply threshold to make some voxels "active"
|
// Apply threshold to make some voxels "active"
|
||||||
// Higher threshold = sparser voxels
|
// Higher threshold = sparser voxels
|
||||||
float threshold = 0.3f;
|
float threshold = 0.3f;
|
||||||
float active = (normalizedNoise > threshold) ? normalizedNoise : 0.0f;
|
float active = (noiseVal > threshold) ? noiseVal : 0.0f;
|
||||||
//float active = 1;
|
|
||||||
|
|
||||||
// Create grayscale color based on noise value
|
// Create grayscale color based on noise value
|
||||||
uint8_t grayValue = static_cast<uint8_t>(normalizedNoise * 255);
|
uint8_t grayValue = static_cast<uint8_t>(noiseVal * 255);
|
||||||
Vec3ui8 color(grayValue, grayValue, grayValue);
|
Vec3ui8 color(grayValue, grayValue, grayValue);
|
||||||
#pragma omp critical
|
#pragma omp critical
|
||||||
if (active > threshold) {
|
if (active > threshold) {
|
||||||
grid.set(x, y, z, active, color);
|
grid.set(x, y, z, active, color);
|
||||||
//std::cout << "setting a voxel to color: " << color << " with alpha of " << active << std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -60,7 +59,7 @@ void generateNoiseGrid(VoxelGrid& grid, PNoise2& noise) {
|
|||||||
bool renderView(const std::string& filename, VoxelGrid& grid, const Vec3f& position,
|
bool renderView(const std::string& filename, VoxelGrid& grid, const Vec3f& position,
|
||||||
const Vec3f& direction, const Vec3f& up = Vec3f(0, 1, 0)) {
|
const Vec3f& direction, const Vec3f& up = Vec3f(0, 1, 0)) {
|
||||||
TIME_FUNCTION;
|
TIME_FUNCTION;
|
||||||
Camera cam(position, direction, up);
|
Camera cam(position, direction, up, 40);
|
||||||
|
|
||||||
std::vector<uint8_t> renderBuffer;
|
std::vector<uint8_t> renderBuffer;
|
||||||
size_t width = RENDER_WIDTH;
|
size_t width = RENDER_WIDTH;
|
||||||
@@ -81,8 +80,20 @@ bool renderView(const std::string& filename, VoxelGrid& grid, const Vec3f& posit
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to rotate a vector around the Y axis
|
||||||
|
Vec3f rotateY(const Vec3f& vec, float angle) {
|
||||||
|
TIME_FUNCTION;
|
||||||
|
float cosA = cos(angle);
|
||||||
|
float sinA = sin(angle);
|
||||||
|
return Vec3f(
|
||||||
|
vec.x * cosA + vec.z * sinA,
|
||||||
|
vec.y,
|
||||||
|
-vec.x * sinA + vec.z * cosA
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
try {
|
TIME_FUNCTION;
|
||||||
std::cout << "=== Noise Grid Generator and Renderer ===" << std::endl;
|
std::cout << "=== Noise Grid Generator and Renderer ===" << std::endl;
|
||||||
std::cout << "Grid Size: 1024x1024x1024 voxels" << std::endl;
|
std::cout << "Grid Size: 1024x1024x1024 voxels" << std::endl;
|
||||||
std::cout << "Render Size: 512x512 pixels" << std::endl;
|
std::cout << "Render Size: 512x512 pixels" << std::endl;
|
||||||
@@ -101,32 +112,35 @@ int main() {
|
|||||||
|
|
||||||
// Camera distance from center (outside the grid)
|
// Camera distance from center (outside the grid)
|
||||||
float cameraDistance = GRID_SIZE * 2.0f;
|
float cameraDistance = GRID_SIZE * 2.0f;
|
||||||
float cameraDir = GRID_SIZE * 0.5f;
|
|
||||||
|
|
||||||
// Render from 4 cardinal directions (looking at center)
|
// Create 180-degree rotation around the Y axis
|
||||||
std::cout << "\nRendering cardinal views..." << std::endl;
|
int numFrames = 2;
|
||||||
|
|
||||||
// North view (looking from positive Z towards center)
|
// Base camera position (looking from front)
|
||||||
renderView("output/north_view.bmp", grid,
|
Vec3f basePosition(0, 0, cameraDistance);
|
||||||
gridCenter + Vec3f(0, 0, cameraDistance),
|
Vec3f baseDirection(0, 0, -1); // Looking towards negative Z (towards center)
|
||||||
Vec3f(0, 0, -1)); // Look towards negative Z
|
Vec3f up(0, 1, 0);
|
||||||
|
|
||||||
// South view (looking from negative Z towards center)
|
// Render frames around 180 degrees
|
||||||
renderView("output/south_view.bmp", grid,
|
for (int i = 0; i <= numFrames; i++) {
|
||||||
gridCenter + Vec3f(0, 0, -cameraDistance),
|
float angle = (float)i / numFrames * M_PI; // 0 to π (180 degrees)
|
||||||
Vec3f(0, 0, 1)); // Look towards positive Z
|
|
||||||
|
|
||||||
// East view (looking from positive X towards center)
|
// Rotate camera position around Y axis
|
||||||
renderView("output/east_view.bmp", grid,
|
Vec3f rotatedPos = rotateY(basePosition, angle);
|
||||||
gridCenter + Vec3f(cameraDistance, 0, 0),
|
Vec3f finalPos = gridCenter + rotatedPos;
|
||||||
Vec3f(-1, 0, 0)); // Look towards negative X
|
//Vec3f rotatedDir = rotateY(baseDirection, angle);
|
||||||
|
Vec3f rotatedDir = (gridCenter - finalPos).normalized();
|
||||||
|
|
||||||
// West view (looking from negative X towards center)
|
// Create filename with frame number
|
||||||
renderView("output/west_view.bmp", grid,
|
char filename[256];
|
||||||
gridCenter + Vec3f(-cameraDistance, 0, 0),
|
snprintf(filename, sizeof(filename), "output/frame_%03d.bmp", i);
|
||||||
Vec3f(1, 0, 0)); // Look towards positive X
|
|
||||||
|
std::cout << "Rendering frame " << i << "/" << numFrames
|
||||||
|
<< " (angle: " << (angle * 360.0f / M_PI) << " degrees)" << std::endl;
|
||||||
|
|
||||||
|
renderView(filename, grid, finalPos, rotatedDir, up);
|
||||||
|
}
|
||||||
|
|
||||||
// Zenith view (looking from above)
|
|
||||||
std::cout << "\nRendering zenith and nadir views..." << std::endl;
|
std::cout << "\nRendering zenith and nadir views..." << std::endl;
|
||||||
renderView("output/zenith_view.bmp", grid,
|
renderView("output/zenith_view.bmp", grid,
|
||||||
gridCenter + Vec3f(0, cameraDistance, 0),
|
gridCenter + Vec3f(0, cameraDistance, 0),
|
||||||
@@ -139,27 +153,8 @@ int main() {
|
|||||||
Vec3f(0, 1, 0), // Look up
|
Vec3f(0, 1, 0), // Look up
|
||||||
Vec3f(0, 0, 1)); // Adjust up vector
|
Vec3f(0, 0, 1)); // Adjust up vector
|
||||||
|
|
||||||
// Optional: Create a front view (alternative to north)
|
|
||||||
renderView("output/front_view.bmp", grid,
|
|
||||||
gridCenter + Vec3f(0, 0, cameraDistance),
|
|
||||||
Vec3f(0, 0, -1),
|
|
||||||
Vec3f(0, 1, 0));
|
|
||||||
|
|
||||||
std::cout << "\n=== All renders complete! ===" << std::endl;
|
std::cout << "\n=== All renders complete! ===" << std::endl;
|
||||||
std::cout << "Generated BMP files:" << std::endl;
|
|
||||||
std::cout << "1. north_view.bmp - Looking from positive Z" << std::endl;
|
|
||||||
std::cout << "2. south_view.bmp - Looking from negative Z" << std::endl;
|
|
||||||
std::cout << "3. east_view.bmp - Looking from positive X" << std::endl;
|
|
||||||
std::cout << "4. west_view.bmp - Looking from negative X" << std::endl;
|
|
||||||
std::cout << "5. zenith_view.bmp - Looking from above" << std::endl;
|
|
||||||
std::cout << "6. nadir_view.bmp - Looking from below" << std::endl;
|
|
||||||
std::cout << "7. front_view.bmp - Alternative front view" << std::endl;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
std::cerr << "Error: " << e.what() << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
FunctionTimer::printStats(FunctionTimer::Mode::ENHANCED);
|
FunctionTimer::printStats(FunctionTimer::Mode::ENHANCED);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -29,6 +29,9 @@ class VoxelGrid {
|
|||||||
private:
|
private:
|
||||||
size_t width, height, depth;
|
size_t width, height, depth;
|
||||||
std::vector<Voxel> voxels;
|
std::vector<Voxel> voxels;
|
||||||
|
float radians(float rads) {
|
||||||
|
return rads * (M_PI / 180);
|
||||||
|
}
|
||||||
|
|
||||||
static Mat4f lookAt(Vec3f const& eye, Vec3f const& center, Vec3f const& up) {
|
static Mat4f lookAt(Vec3f const& eye, Vec3f const& center, Vec3f const& up) {
|
||||||
Vec3f const f = (center - eye).normalized();
|
Vec3f const f = (center - eye).normalized();
|
||||||
@@ -115,6 +118,15 @@ public:
|
|||||||
return (voxl >= 0 && voxl.x < width && voxl.y < height && voxl.z < depth);
|
return (voxl >= 0 && voxl.x < width && voxl.y < height && voxl.z < depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Vec3f> genPixelDirs(Vec3f pos, Vec3f dir, size_t imgWidth, size_t imgHeight, float fov) {
|
||||||
|
std::vector<Vec3f> dirs(imgWidth * imgHeight);
|
||||||
|
float fovRad = radians(fov);
|
||||||
|
float tanFov = tan(fovRad * 0.5);
|
||||||
|
float aspect = static_cast<float>(imgWidth) / static_cast<float>(imgHeight);
|
||||||
|
Vec3f worldUp(0, 1, 0);
|
||||||
|
Vec3f camRight = worldUp.cross(dir).normalized();
|
||||||
|
}
|
||||||
|
|
||||||
Vec3f perPixelRayDir(size_t x, size_t y, size_t imgWidth, size_t imgHeight, const Camera& cam) const {
|
Vec3f perPixelRayDir(size_t x, size_t y, size_t imgWidth, size_t imgHeight, const Camera& cam) const {
|
||||||
float normedX = (x + 0.5) / imgWidth * 2 - 1;
|
float normedX = (x + 0.5) / imgWidth * 2 - 1;
|
||||||
float normedY = 1 - (y+0.5) / imgHeight * 2;
|
float normedY = 1 - (y+0.5) / imgHeight * 2;
|
||||||
@@ -142,68 +154,71 @@ public:
|
|||||||
step.z = (rayDir.z > 0) ? 1 : -1;
|
step.z = (rayDir.z > 0) ? 1 : -1;
|
||||||
Vec3f tMax;
|
Vec3f tMax;
|
||||||
Vec3f tDelta;
|
Vec3f tDelta;
|
||||||
|
bool startOut = false;
|
||||||
|
|
||||||
//initialization
|
|
||||||
tDelta.x = std::abs(1.0 / rayDir.x);
|
tDelta.x = std::abs(1.0 / rayDir.x);
|
||||||
tDelta.y = std::abs(1.0 / rayDir.y);
|
tDelta.y = std::abs(1.0 / rayDir.y);
|
||||||
tDelta.z = std::abs(1.0 / rayDir.z);
|
tDelta.z = std::abs(1.0 / rayDir.z);
|
||||||
tMax = mix(((rayOrigin - currentVoxel.toFloat()) / -rayDir).toFloat(), (((currentVoxel.toFloat() + 1) - rayOrigin) / rayDir).toFloat(), rayDir.mask([](float x, float value) { return x > 0; }, 0));
|
tMax = mix(((rayOrigin - currentVoxel.toFloat()) / -rayDir).toFloat(),
|
||||||
if (!inGrid(rayOrigin)) {
|
(((currentVoxel.toFloat() + 1) - rayOrigin) / rayDir).toFloat(),
|
||||||
/*
|
rayDir.mask([](float x, float value) { return x > 0; }, 0));
|
||||||
The initialization phase begins by identifying the voxel in which the ray origin, →
|
|
||||||
u, is found. If the ray origin is outside the grid, we find the point in which the ray enters the grid and take the adjacent voxel. The integer
|
|
||||||
variables X and Y are initialized to the starting voxel coordinates. In addition, the variables stepX and
|
|
||||||
stepY are initialized to either 1 or -1 indicating whether X and Y are incremented or decremented as the
|
|
||||||
ray crosses voxel boundaries (this is determined by the sign of the x and y components of →
|
|
||||||
v).
|
|
||||||
Next, we determine the value of t at which the ray crosses the first vertical voxel boundary and
|
|
||||||
store it in variable tMaxX. We perform a similar computation in y and store the result in tMaxY. The
|
|
||||||
minimum of these two values will indicate how much we can travel along the ray and still remain in the
|
|
||||||
current voxel.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
if (!inGrid(rayOrigin)) {
|
||||||
|
startOut = true;
|
||||||
Vec3f tBMin;
|
Vec3f tBMin;
|
||||||
Vec3f tBMax;
|
Vec3f tBMax;
|
||||||
|
|
||||||
tBMin.x = (0.0 - rayOrigin.x) / rayDir.x;
|
tBMin.x = (0.0 - rayOrigin.x) / rayDir.x;
|
||||||
tBMax.x = (width - rayOrigin.x) / rayDir.x;
|
tBMax.x = (width - rayOrigin.x) / rayDir.x;
|
||||||
if (tBMin.x > tBMax.x) std::swap(tBMin.x, tBMax.x);
|
if (tBMin.x > tBMax.x) std::swap(tBMin.x, tBMax.x);
|
||||||
|
|
||||||
tBMin.y = (0.0 - rayOrigin.y) / rayDir.y;
|
tBMin.y = (0.0 - rayOrigin.y) / rayDir.y;
|
||||||
tBMax.y = (height - rayOrigin.y) / rayDir.y;
|
tBMax.y = (height - rayOrigin.y) / rayDir.y;
|
||||||
if (tBMin.y > tBMax.y) std::swap(tBMin.y, tBMax.y);
|
if (tBMin.y > tBMax.y) std::swap(tBMin.y, tBMax.y);
|
||||||
|
|
||||||
tBMin.z = (0.0 - rayOrigin.z) / rayDir.z;
|
tBMin.z = (0.0 - rayOrigin.z) / rayDir.z;
|
||||||
tBMax.z = (depth - rayOrigin.z) / rayDir.z;
|
tBMax.z = (depth - rayOrigin.z) / rayDir.z;
|
||||||
if (tBMin.z > tBMax.z) std::swap(tBMin.z, tBMax.z);
|
if (tBMin.z > tBMax.z) std::swap(tBMin.z, tBMax.z);
|
||||||
|
|
||||||
float tEntry = tBMin.maxComp();
|
float tEntry = tBMin.maxComp();
|
||||||
float tExit = tBMax.minComp();
|
float tExit = tBMax.minComp();
|
||||||
|
|
||||||
if (tEntry > tExit || tExit < 0.0) return false;
|
if (tEntry > tExit || tExit < 0.0) return false;
|
||||||
if (tEntry < 0.0) tEntry = 0.0;
|
if (tEntry < 0.0) tEntry = 0.0;
|
||||||
|
|
||||||
if (tEntry > 0.0) {
|
if (tEntry > 0.0) {
|
||||||
rayOrigin = rayOrigin + rayDir * tEntry;
|
rayOrigin = rayOrigin + rayDir * tEntry;
|
||||||
currentVoxel = rayOrigin.floorToT();
|
currentVoxel = rayOrigin.floorToT();
|
||||||
tMax = mix(((currentVoxel.toFloat() + 1) - rayOrigin) / rayDir, (rayOrigin - currentVoxel) / -rayDir, rayDir.mask([](float x, float value) { return x > 0; }, 0) );
|
tMax = mix(((currentVoxel.toFloat() + 1) - rayOrigin) / rayDir,
|
||||||
|
(rayOrigin - currentVoxel) / -rayDir,
|
||||||
|
rayDir.mask([](float x, float value) { return x > 0; }, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float aalpha = 0.0;
|
// if (startOut && !inGrid(currentVoxel)) {
|
||||||
bool hit = false;
|
// std::cout << "grid edge not found. " << currentVoxel << std::endl;
|
||||||
|
// }
|
||||||
|
|
||||||
float tDist = 0.0;
|
float tDist = 0.0;
|
||||||
|
|
||||||
/*
|
// Main DDA loop
|
||||||
Finally, we compute tDeltaX and tDeltaY. TDeltaX indicates how far along the ray we must move
|
|
||||||
(in units of t) for the horizontal component of such a movement to equal the width of a voxel. Similarly,
|
|
||||||
we store in tDeltaY the amount of movement along the ray which has a vertical component equal to the
|
|
||||||
height of a voxel.
|
|
||||||
*/
|
|
||||||
while (inGrid(currentVoxel) && tDist < maxDistance) {
|
while (inGrid(currentVoxel) && tDist < maxDistance) {
|
||||||
Voxel& voxel = get(currentVoxel);
|
Voxel& voxel = get(currentVoxel);
|
||||||
|
|
||||||
|
// Ignore alpha - treat any voxel with active > 0 as solid
|
||||||
if (voxel.active > EPSILON) {
|
if (voxel.active > EPSILON) {
|
||||||
Vec3f voxelColor(static_cast<float>(voxel.color.x / 255.0), static_cast<float>(voxel.color.y / 255.0), static_cast<float>(voxel.color.z / 255.0));
|
// Convert color from 0-255 to 0-1 range
|
||||||
float contribution = voxel.active * (1.0 - aalpha);
|
Vec3f voxelColor(
|
||||||
hitColor = hitColor + voxelColor * contribution;
|
static_cast<float>(voxel.color.x / 255.0),
|
||||||
aalpha += contribution;
|
static_cast<float>(voxel.color.y / 255.0),
|
||||||
|
static_cast<float>(voxel.color.z / 255.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
// No alpha blending - just take the first solid voxel's color
|
||||||
|
hitColor = voxelColor;
|
||||||
hitPos = rayOrigin + rayDir * tDist;
|
hitPos = rayOrigin + rayDir * tDist;
|
||||||
|
|
||||||
|
// Determine which face was hit
|
||||||
if (tMax.x <= tMax.y && tMax.x <= tMax.z) {
|
if (tMax.x <= tMax.y && tMax.x <= tMax.z) {
|
||||||
hitNormal = Vec3f(-step.x, 0.0, 0.0);
|
hitNormal = Vec3f(-step.x, 0.0, 0.0);
|
||||||
} else if (tMax.y <= tMax.x && tMax.y <= tMax.z) {
|
} else if (tMax.y <= tMax.x && tMax.y <= tMax.z) {
|
||||||
@@ -211,11 +226,11 @@ public:
|
|||||||
} else {
|
} else {
|
||||||
hitNormal = Vec3f(0.0, 0.0, -step.z);
|
hitNormal = Vec3f(0.0, 0.0, -step.z);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (aalpha > EPSILON) {
|
return true; // Return immediately on first solid hit
|
||||||
hit = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move to next voxel
|
||||||
if (tMax.x < tMax.y) {
|
if (tMax.x < tMax.y) {
|
||||||
if (tMax.x < tMax.z) {
|
if (tMax.x < tMax.z) {
|
||||||
tDist = tMax.x;
|
tDist = tMax.x;
|
||||||
@@ -238,11 +253,124 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (aalpha > EPSILON) {
|
|
||||||
std::cout << "hit at: " << currentVoxel << " with value of " << aalpha << std::endl;
|
return false;
|
||||||
}
|
|
||||||
return hit;
|
|
||||||
}
|
}
|
||||||
|
// bool rayCast(const Ray3f& ray, float maxDistance, Vec3f hitPos, Vec3f hitNormal, Vec3f& hitColor) {
|
||||||
|
// hitColor = Vec3f(0,0,0);
|
||||||
|
// Vec3f rayDir = ray.direction;
|
||||||
|
// Vec3f rayOrigin = ray.origin;
|
||||||
|
// Vec3T currentVoxel = rayOrigin.floorToT();
|
||||||
|
// Vec3i step;
|
||||||
|
// step.x = (rayDir.x > 0) ? 1 : -1;
|
||||||
|
// step.y = (rayDir.y > 0) ? 1 : -1;
|
||||||
|
// step.z = (rayDir.z > 0) ? 1 : -1;
|
||||||
|
// Vec3f tMax;
|
||||||
|
// Vec3f tDelta;
|
||||||
|
// bool startOut = false;
|
||||||
|
|
||||||
|
// tDelta.x = std::abs(1.0 / rayDir.x);
|
||||||
|
// tDelta.y = std::abs(1.0 / rayDir.y);
|
||||||
|
// tDelta.z = std::abs(1.0 / rayDir.z);
|
||||||
|
// tMax = mix(((rayOrigin - currentVoxel.toFloat()) / -rayDir).toFloat(), (((currentVoxel.toFloat() + 1) - rayOrigin) / rayDir).toFloat(), rayDir.mask([](float x, float value) { return x > 0; }, 0));
|
||||||
|
// if (!inGrid(rayOrigin)) {
|
||||||
|
// startOut = true;
|
||||||
|
// /*
|
||||||
|
// The initialization phase begins by identifying the voxel in which the ray origin, →
|
||||||
|
// u, is found. If the ray origin is outside the grid, we find the point in which the ray enters the grid and take the adjacent voxel. The integer
|
||||||
|
// variables X and Y are initialized to the starting voxel coordinates. In addition, the variables stepX and
|
||||||
|
// stepY are initialized to either 1 or -1 indicating whether X and Y are incremented or decremented as the
|
||||||
|
// ray crosses voxel boundaries (this is determined by the sign of the x and y components of →
|
||||||
|
// v).
|
||||||
|
// Next, we determine the value of t at which the ray crosses the first vertical voxel boundary and
|
||||||
|
// store it in variable tMaxX. We perform a similar computation in y and store the result in tMaxY. The
|
||||||
|
// minimum of these two values will indicate how much we can travel along the ray and still remain in the
|
||||||
|
// current voxel.
|
||||||
|
// */
|
||||||
|
|
||||||
|
// Vec3f tBMin;
|
||||||
|
// Vec3f tBMax;
|
||||||
|
// tBMin.x = (0.0 - rayOrigin.x) / rayDir.x;
|
||||||
|
// tBMax.x = (width - rayOrigin.x) / rayDir.x;
|
||||||
|
// if (tBMin.x > tBMax.x) std::swap(tBMin.x, tBMax.x);
|
||||||
|
// tBMin.y = (0.0 - rayOrigin.y) / rayDir.y;
|
||||||
|
// tBMax.y = (height - rayOrigin.y) / rayDir.y;
|
||||||
|
// if (tBMin.y > tBMax.y) std::swap(tBMin.y, tBMax.y);
|
||||||
|
// tBMin.z = (0.0 - rayOrigin.z) / rayDir.z;
|
||||||
|
// tBMax.z = (depth - rayOrigin.z) / rayDir.z;
|
||||||
|
// if (tBMin.z > tBMax.z) std::swap(tBMin.z, tBMax.z);
|
||||||
|
// float tEntry = tBMin.maxComp();
|
||||||
|
// float tExit = tBMax.minComp();
|
||||||
|
// if (tEntry > tExit || tExit < 0.0) return false;
|
||||||
|
// if (tEntry < 0.0) tEntry = 0.0;
|
||||||
|
|
||||||
|
// if (tEntry > 0.0) {
|
||||||
|
// rayOrigin = rayOrigin + rayDir * tEntry;
|
||||||
|
// currentVoxel = rayOrigin.floorToT();
|
||||||
|
// tMax = mix(((currentVoxel.toFloat() + 1) - rayOrigin) / rayDir, (rayOrigin - currentVoxel) / -rayDir, rayDir.mask([](float x, float value) { return x > 0; }, 0) );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
// if (startOut && !inGrid(currentVoxel)) std::cout << "grid edge not found. " << currentVoxel << std::endl;
|
||||||
|
|
||||||
|
// float aalpha = 0.0;
|
||||||
|
// bool hit = false;
|
||||||
|
// float tDist = 0.0;
|
||||||
|
|
||||||
|
// /*
|
||||||
|
// Finally, we compute tDeltaX and tDeltaY. TDeltaX indicates how far along the ray we must move
|
||||||
|
// (in units of t) for the horizontal component of such a movement to equal the width of a voxel. Similarly,
|
||||||
|
// we store in tDeltaY the amount of movement along the ray which has a vertical component equal to the
|
||||||
|
// height of a voxel.
|
||||||
|
// */
|
||||||
|
// while (inGrid(currentVoxel) && tDist < maxDistance) {
|
||||||
|
// Voxel& voxel = get(currentVoxel);
|
||||||
|
|
||||||
|
// if (voxel.active > EPSILON) {
|
||||||
|
// Vec3f voxelColor(static_cast<float>(voxel.color.x / 255.0), static_cast<float>(voxel.color.y / 255.0), static_cast<float>(voxel.color.z / 255.0));
|
||||||
|
// float contribution = voxel.active * (1.0 - aalpha);
|
||||||
|
// hitColor = hitColor + voxelColor * contribution;
|
||||||
|
// aalpha += contribution;
|
||||||
|
// hitPos = rayOrigin + rayDir * tDist;
|
||||||
|
// if (tMax.x <= tMax.y && tMax.x <= tMax.z) {
|
||||||
|
// hitNormal = Vec3f(-step.x, 0.0, 0.0);
|
||||||
|
// } else if (tMax.y <= tMax.x && tMax.y <= tMax.z) {
|
||||||
|
// hitNormal = Vec3f(0.0, -step.y, 0.0);
|
||||||
|
// } else {
|
||||||
|
// hitNormal = Vec3f(0.0, 0.0, -step.z);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (aalpha > EPSILON) {
|
||||||
|
// hit = true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (tMax.x < tMax.y) {
|
||||||
|
// if (tMax.x < tMax.z) {
|
||||||
|
// tDist = tMax.x;
|
||||||
|
// tMax.x += tDelta.x;
|
||||||
|
// currentVoxel.x += step.x;
|
||||||
|
// } else {
|
||||||
|
// tDist = tMax.z;
|
||||||
|
// tMax.z += tDelta.z;
|
||||||
|
// currentVoxel.z += step.z;
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// if (tMax.y < tMax.z) {
|
||||||
|
// tDist = tMax.y;
|
||||||
|
// tMax.y += tDelta.y;
|
||||||
|
// currentVoxel.y += step.y;
|
||||||
|
// } else {
|
||||||
|
// tDist = tMax.z;
|
||||||
|
// tMax.z += tDelta.z;
|
||||||
|
// currentVoxel.z += step.z;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // if (aalpha > EPSILON) {
|
||||||
|
// // std::cout << "hit at: " << currentVoxel << " with value of " << aalpha << std::endl;
|
||||||
|
// // }
|
||||||
|
// return hit;
|
||||||
|
// }
|
||||||
|
|
||||||
size_t getWidth() const {
|
size_t getWidth() const {
|
||||||
return width;
|
return width;
|
||||||
|
|||||||
Reference in New Issue
Block a user