some improvements
This commit is contained in:
@@ -38,7 +38,7 @@ void generateNoiseGrid(VoxelGrid& grid, PNoise2& noise) {
|
|||||||
|
|
||||||
// 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.01;
|
||||||
float active = (noiseVal > threshold) ? noiseVal : 0.0f;
|
float active = (noiseVal > threshold) ? noiseVal : 0.0f;
|
||||||
|
|
||||||
// Create grayscale color based on noise value
|
// Create grayscale color based on noise value
|
||||||
@@ -80,7 +80,17 @@ 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 rotateX(const Vec3f& vec, float angle) {
|
||||||
|
TIME_FUNCTION;
|
||||||
|
float cosA = cos(angle);
|
||||||
|
float sinA = sin(angle);
|
||||||
|
return Vec3f(
|
||||||
|
vec.x,
|
||||||
|
vec.y * cosA - vec.z * sinA,
|
||||||
|
vec.y * sinA + vec.z * cosA
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Vec3f rotateY(const Vec3f& vec, float angle) {
|
Vec3f rotateY(const Vec3f& vec, float angle) {
|
||||||
TIME_FUNCTION;
|
TIME_FUNCTION;
|
||||||
float cosA = cos(angle);
|
float cosA = cos(angle);
|
||||||
@@ -92,6 +102,17 @@ Vec3f rotateY(const Vec3f& vec, float angle) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec3f rotateZ(const Vec3f& vec, float angle) {
|
||||||
|
TIME_FUNCTION;
|
||||||
|
float cosA = cos(angle);
|
||||||
|
float sinA = sin(angle);
|
||||||
|
return Vec3f(
|
||||||
|
vec.x * cosA - vec.y * sinA,
|
||||||
|
vec.x * sinA + vec.y * cosA,
|
||||||
|
vec.z
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
TIME_FUNCTION;
|
TIME_FUNCTION;
|
||||||
std::cout << "=== Noise Grid Generator and Renderer ===" << std::endl;
|
std::cout << "=== Noise Grid Generator and Renderer ===" << std::endl;
|
||||||
@@ -113,8 +134,7 @@ 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;
|
||||||
|
|
||||||
// Create 180-degree rotation around the Y axis
|
int numFrames = 360;
|
||||||
int numFrames = 2;
|
|
||||||
|
|
||||||
// Base camera position (looking from front)
|
// Base camera position (looking from front)
|
||||||
Vec3f basePosition(0, 0, cameraDistance);
|
Vec3f basePosition(0, 0, cameraDistance);
|
||||||
@@ -133,7 +153,45 @@ int main() {
|
|||||||
|
|
||||||
// Create filename with frame number
|
// Create filename with frame number
|
||||||
char filename[256];
|
char filename[256];
|
||||||
snprintf(filename, sizeof(filename), "output/frame_%03d.bmp", i);
|
snprintf(filename, sizeof(filename), "output/framey_%03d.bmp", i);
|
||||||
|
|
||||||
|
std::cout << "Rendering frame " << i << "/" << numFrames
|
||||||
|
<< " (angle: " << (angle * 360.0f / M_PI) << " degrees)" << std::endl;
|
||||||
|
|
||||||
|
renderView(filename, grid, finalPos, rotatedDir, up);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i <= numFrames; i++) {
|
||||||
|
float angle = (float)i / numFrames * M_PI; // 0 to π (180 degrees)
|
||||||
|
|
||||||
|
// Rotate camera position around Y axis
|
||||||
|
Vec3f rotatedPos = rotateZ(basePosition, angle);
|
||||||
|
Vec3f finalPos = gridCenter + rotatedPos;
|
||||||
|
//Vec3f rotatedDir = rotateY(baseDirection, angle);
|
||||||
|
Vec3f rotatedDir = (gridCenter - finalPos).normalized();
|
||||||
|
|
||||||
|
// Create filename with frame number
|
||||||
|
char filename[256];
|
||||||
|
snprintf(filename, sizeof(filename), "output/framez_%03d.bmp", i);
|
||||||
|
|
||||||
|
std::cout << "Rendering frame " << i << "/" << numFrames
|
||||||
|
<< " (angle: " << (angle * 360.0f / M_PI) << " degrees)" << std::endl;
|
||||||
|
|
||||||
|
renderView(filename, grid, finalPos, rotatedDir, up);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i <= numFrames; i++) {
|
||||||
|
float angle = (float)i / numFrames * M_PI; // 0 to π (180 degrees)
|
||||||
|
|
||||||
|
// Rotate camera position around Y axis
|
||||||
|
Vec3f rotatedPos = rotateX(basePosition, angle);
|
||||||
|
Vec3f finalPos = gridCenter + rotatedPos;
|
||||||
|
//Vec3f rotatedDir = rotateY(baseDirection, angle);
|
||||||
|
Vec3f rotatedDir = (gridCenter - finalPos).normalized();
|
||||||
|
|
||||||
|
// Create filename with frame number
|
||||||
|
char filename[256];
|
||||||
|
snprintf(filename, sizeof(filename), "output/framex_%03d.bmp", i);
|
||||||
|
|
||||||
std::cout << "Rendering frame " << i << "/" << numFrames
|
std::cout << "Rendering frame " << i << "/" << numFrames
|
||||||
<< " (angle: " << (angle * 360.0f / M_PI) << " degrees)" << std::endl;
|
<< " (angle: " << (angle * 360.0f / M_PI) << " degrees)" << std::endl;
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
|
#include <limits>
|
||||||
#ifndef M_PI
|
#ifndef M_PI
|
||||||
#define M_PI 3.14159265358979323846f
|
#define M_PI 3.14159265358979323846f
|
||||||
#endif
|
#endif
|
||||||
#ifndef EPSILON
|
#ifndef EPSILON
|
||||||
#define EPSILON 0.0000000000000000000000001f
|
#define EPSILON 0.0000000000000000000000001f
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef INF
|
||||||
|
#define INF 2^31-1
|
||||||
|
#endif
|
||||||
@@ -64,6 +64,47 @@ private:
|
|||||||
Result(3,2) = -(zfar * zNear) / (zfar - zNear);
|
Result(3,2) = -(zfar * zNear) / (zfar - zNear);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<float,float> rayBoxIntersect(Vec3f origin, Vec3f direction) {
|
||||||
|
Vec3f tBMin = Vec3f(0,0,0);
|
||||||
|
Vec3f tBMax = Vec3f(width, height, depth);
|
||||||
|
float tmin = 0;
|
||||||
|
float tmax = INF;
|
||||||
|
Vec3f invDir = direction.safeInverse();
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
if (abs(direction[i] < EPSILON)) {
|
||||||
|
if (origin[i] < tBMin[i] || origin[i] > tBMax[i]) return std::make_pair(0.0f, 0.0f);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::make_pair(tmin, tmax);
|
||||||
|
}
|
||||||
|
|
||||||
|
//used to prevent division by 0 issues
|
||||||
|
bool specialCases(Vec3f origin, Vec3f direction, float maxDist, Vec3f hitColor) {
|
||||||
|
float stepSize = 0.5;
|
||||||
|
int maxSteps = maxDist/stepSize;
|
||||||
|
for (int step = 0; step < maxSteps; ++step) {
|
||||||
|
float t = step * stepSize;
|
||||||
|
Vec3f pos = Vec3f(origin + direction * t);
|
||||||
|
Vec3T voxelCoords = pos.floorToT();
|
||||||
|
if (inGrid(voxelCoords)) {
|
||||||
|
Voxel cv = get(voxelCoords);
|
||||||
|
if (cv.active > EPSILON) {
|
||||||
|
hitColor = cv.color.toFloat();
|
||||||
|
std::cout << "hit in special case at: " << voxelCoords << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
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) : width(w), height(h), depth(d) {
|
||||||
voxels.resize(w * h * d);
|
voxels.resize(w * h * d);
|
||||||
@@ -125,6 +166,19 @@ public:
|
|||||||
float aspect = static_cast<float>(imgWidth) / static_cast<float>(imgHeight);
|
float aspect = static_cast<float>(imgWidth) / static_cast<float>(imgHeight);
|
||||||
Vec3f worldUp(0, 1, 0);
|
Vec3f worldUp(0, 1, 0);
|
||||||
Vec3f camRight = worldUp.cross(dir).normalized();
|
Vec3f camRight = worldUp.cross(dir).normalized();
|
||||||
|
Vec3f camUp = dir.cross(camRight).normalized();
|
||||||
|
|
||||||
|
for (int y = 0; y < height; ++y) {
|
||||||
|
float ndcY = 1 - (2 * y / (height - 1));
|
||||||
|
float screenY = ndcY * tanFov;
|
||||||
|
for (int x = 0; x < width; ++x) {
|
||||||
|
float ndcX = (2 * x / (width - 1)) - 1;
|
||||||
|
float screenX = ndcX * aspect*tanFov;
|
||||||
|
Vec3f dir = (camRight * screenX + camUp * screenY + dir).normalized();
|
||||||
|
dirs[y*width+x] = dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dirs;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
@@ -143,234 +197,68 @@ public:
|
|||||||
return rayDirWorld.normalized();
|
return rayDirWorld.normalized();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rayCast(const Ray3f& ray, float maxDistance, Vec3f hitPos, Vec3f hitNormal, Vec3f& hitColor) {
|
bool rayCast(Vec3f origin, Vec3f direction, float maxDist, Vec3f hitColor) {
|
||||||
hitColor = Vec3f(0,0,0);
|
TIME_FUNCTION;
|
||||||
Vec3f rayDir = ray.direction;
|
direction.normalized();
|
||||||
Vec3f rayOrigin = ray.origin;
|
if (abs(direction.length()) < EPSILON) return false;
|
||||||
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);
|
Vec3f invDir = direction.safeInverse();
|
||||||
tDelta.y = std::abs(1.0 / rayDir.y);
|
Vec3T currentVoxel = origin.floorToT();
|
||||||
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)) {
|
if (direction.x == 0 || direction.y == 0 || direction.z == 0) {
|
||||||
startOut = true;
|
return specialCases(origin, direction, maxDist, hitColor);
|
||||||
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)) {
|
if (!inGrid(currentVoxel)) {
|
||||||
// std::cout << "grid edge not found. " << currentVoxel << std::endl;
|
std::pair<float,float> re = rayBoxIntersect(origin, direction);
|
||||||
// }
|
float tEntry = re.first;
|
||||||
|
float tExit = re.second;
|
||||||
float tDist = 0.0;
|
if (tEntry < EPSILON || tExit < EPSILON) return false;
|
||||||
|
float tStart = std::max(0.0f, tEntry);
|
||||||
// Main DDA loop
|
if (tStart > maxDist) return false;
|
||||||
while (inGrid(currentVoxel) && tDist < maxDistance) {
|
Vec3f gridOrig = Vec3f(origin+direction*tStart);
|
||||||
Voxel& voxel = get(currentVoxel);
|
currentVoxel = gridOrig.floorToT();
|
||||||
|
|
||||||
// Ignore alpha - treat any voxel with active > 0 as solid
|
|
||||||
if (voxel.active > EPSILON) {
|
|
||||||
// Convert color from 0-255 to 0-1 range
|
|
||||||
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)
|
|
||||||
);
|
|
||||||
|
|
||||||
// No alpha blending - just take the first solid voxel's color
|
|
||||||
hitColor = voxelColor;
|
|
||||||
hitPos = rayOrigin + rayDir * tDist;
|
|
||||||
|
|
||||||
// Determine which face was hit
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true; // Return immediately on first solid hit
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move to next voxel
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
Vec3i8 step = Vec3i8(direction.x >= 0 ? 1 : -1, direction.y >= 0 ? 1 : -1, direction.z >= 0 ? 1 : -1);
|
||||||
|
Vec3f nextVoxel = Vec3f(currentVoxel.x + (step.x>0 ? 1 : 0) - origin.x,
|
||||||
|
currentVoxel.y + (step.y>0 ? 1 : 0) - origin.y,
|
||||||
|
currentVoxel.z + (step.z>0 ? 1 : 0) - origin.z);
|
||||||
|
Vec3f tMax = nextVoxel*invDir;
|
||||||
|
Vec3f tDelta = invDir.abs();
|
||||||
|
|
||||||
|
float aalpha = 0;
|
||||||
|
|
||||||
|
while (inGrid(currentVoxel)) {
|
||||||
|
Voxel cv = get(currentVoxel);
|
||||||
|
if (cv.active > EPSILON) {
|
||||||
|
hitColor = (hitColor * aalpha) + (cv.color * cv.active);
|
||||||
|
aalpha += cv.active;
|
||||||
|
}
|
||||||
|
if (aalpha >= 1 ) {
|
||||||
|
//std::cout << "hit in normal case at: " << currentVoxel << " due to alpha overload" << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tMax.x < tMax.y && tMax.x < tMax.z) {
|
||||||
|
if (tMax.x > maxDist) break;
|
||||||
|
currentVoxel = (currentVoxel.x + step.x, currentVoxel.y, currentVoxel.z);
|
||||||
|
tMax.x += tDelta.x;
|
||||||
|
} else if (tMax.y < tMax.z)
|
||||||
|
{
|
||||||
|
currentVoxel = (currentVoxel.x, currentVoxel.y + step.y, currentVoxel.z);
|
||||||
|
tMax.y += tDelta.y;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
currentVoxel = (currentVoxel.x, currentVoxel.y, currentVoxel.z + step.z);
|
||||||
|
tMax.z += tDelta.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (aalpha > EPSILON) {
|
||||||
|
//std::cout << "hit in normal case " << " due to any alpha" << std::endl;
|
||||||
|
return true;
|
||||||
|
} else return false;
|
||||||
}
|
}
|
||||||
// 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;
|
||||||
@@ -384,9 +272,9 @@ public:
|
|||||||
|
|
||||||
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) {
|
||||||
output.resize(outwidth * outheight * 3);
|
output.resize(outwidth * outheight * 3);
|
||||||
Vec3f backgroundColor(0.1f, 0.1f, 0.1f);
|
Vec3f backgroundColor(0.1f, 0.1f, 1.0f);
|
||||||
float maxDistance = std::sqrt(width*width + height*height + depth*depth) * 2.0f;
|
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++) {
|
for (size_t y = 0; y < outheight; y++) {
|
||||||
for (size_t x = 0; x < outwidth; x++) {
|
for (size_t x = 0; x < outwidth; x++) {
|
||||||
Vec3f rayDir = perPixelRayDir(x, y, outwidth, outheight, cam);
|
Vec3f rayDir = perPixelRayDir(x, y, outwidth, outheight, cam);
|
||||||
@@ -394,7 +282,7 @@ public:
|
|||||||
Vec3f hitPos;
|
Vec3f hitPos;
|
||||||
Vec3f hitNorm;
|
Vec3f hitNorm;
|
||||||
Vec3f hitColor;
|
Vec3f hitColor;
|
||||||
bool hit = rayCast(ray, maxDistance, hitPos, hitNorm, hitColor);
|
bool hit = rayCast(cam.posfor.origin, rayDir, maxDistance, hitColor);
|
||||||
|
|
||||||
Vec3f finalColor;
|
Vec3f finalColor;
|
||||||
if (!hit) {
|
if (!hit) {
|
||||||
|
|||||||
@@ -458,6 +458,7 @@ using Vec3i = Vec3<int>;
|
|||||||
using Vec3i8 = Vec3<int8_t>;
|
using Vec3i8 = Vec3<int8_t>;
|
||||||
using Vec3ui8 = Vec3<uint8_t>;
|
using Vec3ui8 = Vec3<uint8_t>;
|
||||||
using Vec3T = Vec3<size_t>;
|
using Vec3T = Vec3<size_t>;
|
||||||
|
using Vec3b = Vec3<bool>;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline std::ostream& operator<<(std::ostream& os, const Vec3<T>& vec) {
|
inline std::ostream& operator<<(std::ostream& os, const Vec3<T>& vec) {
|
||||||
|
|||||||
Reference in New Issue
Block a user