From 5ef07c6af5dbc2509fa12af54158730068ee201f Mon Sep 17 00:00:00 2001 From: yggdrasil75 Date: Wed, 21 Jan 2026 20:25:25 -0500 Subject: [PATCH] made it I think faster --- util/grid/grid3.hpp | 177 +++++++++++++++++++++++++++----------- util/vectorlogic/vec3.hpp | 8 ++ 2 files changed, 136 insertions(+), 49 deletions(-) diff --git a/util/grid/grid3.hpp b/util/grid/grid3.hpp index f8e72b0..8f84900 100644 --- a/util/grid/grid3.hpp +++ b/util/grid/grid3.hpp @@ -17,6 +17,7 @@ #include #include #include "../basicdefines.hpp" +#include //constexpr char magic[4] = {'Y', 'G', 'G', '3'}; static constexpr int CHUNK_THRESHOLD = 16; //at this size, subdivide. @@ -125,6 +126,7 @@ private: std::vector voxels; std::unordered_map chunkList; std::unordered_map activeChunks; + int xyPlane; float radians(float rads) { return rads * (M_PI / 180); @@ -143,6 +145,34 @@ private: } } + // Slab method for AABB intersection + bool intersectRayAABB(const Vec3f& origin, const Vec3f& dir, const Vec3f& boxMin, const Vec3f& boxMax, float& tNear, float& tFar) const { + Vec3f invDir(1.0f / dir.x, 1.0f / dir.y, 1.0f / dir.z); + + float t1 = (boxMin.x - origin.x) * invDir.x; + float t2 = (boxMax.x - origin.x) * invDir.x; + + float tMin = std::min(t1, t2); + float tMax = std::max(t1, t2); + + t1 = (boxMin.y - origin.y) * invDir.y; + t2 = (boxMax.y - origin.y) * invDir.y; + + tMin = std::max(tMin, std::min(t1, t2)); + tMax = std::min(tMax, std::max(t1, t2)); + + t1 = (boxMin.z - origin.z) * invDir.z; + t2 = (boxMax.z - origin.z) * invDir.z; + + tMin = std::max(tMin, std::min(t1, t2)); + tMax = std::min(tMax, std::max(t1, t2)); + + tNear = tMin; + tFar = tMax; + + return tMax >= tMin && tMax >= 0.0f; + } + public: VoxelGrid() : gridSize(0,0,0) { std::cout << "creating empty grid." << std::endl; @@ -157,11 +187,11 @@ public: static std::unique_ptr deserializeFromFile(const std::string& filename); Voxel& get(int x, int y, int z) { - return voxels[z * gridSize.x * gridSize.y + y * gridSize.x + x]; + return voxels[z * xyPlane + y * gridSize.x + x]; } const Voxel& get(int x, int y, int z) const { - return voxels[z * gridSize.x * gridSize.y + y * gridSize.x + x]; + return voxels[z * xyPlane + y * gridSize.x + x]; } Voxel& get(const Vec3i& xyz) { @@ -203,6 +233,7 @@ public: voxels = std::move(newVoxels); activeChunks = std::move(newActiveChunks); gridSize = Vec3i(newW, newH, newD); + xyPlane = gridSize.x * gridSize.y; } void resize(Vec3i newsize) { @@ -252,38 +283,18 @@ public: return voxl.AllGTE(0) && voxl.AllLT(gridSize); } - void voxelTraverse(const Vec3f& origin, const Vec3f& end, Voxel& outVoxel, int maxDist = 10000000) const { + void voxelTraverse(const Vec3f& origin, const Vec3f& end, Voxel& outVoxel, Vec3i& step, const Vec3f& ray, Vec3f& tMax, int maxDist = 10000000) const { Vec3i cv = origin.floorToI(); Vec3i lv = end.floorToI(); - Vec3f ray = end - origin; - Vec3i step = end.mask([](float v, float zero) { return v >= zero; }, 0.0f) * 2 - Vec3i(1); + step = Vec3i(ray.x >= 0 ? 1 : -1, ray.y >= 0 ? 1 : -1, ray.z >= 0 ? 1 : -1); Vec3f tDelta = Vec3f(ray.x != 0 ? std::abs(1.0f / ray.x) : INF, ray.y != 0 ? std::abs(1.0f / ray.y) : INF, ray.z != 0 ? std::abs(1.0f / ray.z) : INF); - Vec3f tMax; - if (ray.x > 0) { - tMax.x = (std::floor(origin.x) + 1.0f - origin.x) / ray.x; - } else if (ray.x < 0) { - tMax.x = (origin.x - std::floor(origin.x)) / -ray.x; - } else tMax.x = INF; - - if (ray.y > 0) { - tMax.y = (std::floor(origin.y) + 1.0f - origin.y) / ray.y; - } else if (ray.y < 0) { - tMax.y = (origin.y - std::floor(origin.y)) / -ray.y; - } else tMax.y = INF; - - if (ray.z > 0) { - tMax.z = (std::floor(origin.z) + 1.0f - origin.z) / ray.z; - } else if (ray.z < 0) { - tMax.z = (origin.z - std::floor(origin.z)) / -ray.z; - } else tMax.z = INF; - float dist = 0.0f; outVoxel.alpha = 0.0; - while (lv != cv && dist < 1.f && inGrid(cv) && outVoxel.alpha < 1.f) { + while (lv != cv && inGrid(cv) && outVoxel.alpha < 1.f) { const Voxel& curv = get(cv); if (curv.active) { @@ -300,27 +311,24 @@ public: } // Step Logic - if (tMax.x < tMax.y) { - if (tMax.x < tMax.z) { - dist = tMax.x; - cv.x += step.x; - tMax.x += tDelta.x; - } else { - dist = tMax.z; - cv.z += step.z; - tMax.z += tDelta.z; + int axis = (tMax.x < tMax.y) ? + ((tMax.x < tMax.z) ? 0 : 2) : + ((tMax.y < tMax.z) ? 1 : 2); + + switch(axis) { + case 0: + tMax.x += tDelta.x; + cv.x += step.x; + break; + case 1: + tMax.y += tDelta.y; + cv.y += step.y; + break; + case 2: + tMax.z += tDelta.z; + cv.z += step.z; + break; } - } else { - if (tMax.y < tMax.z) { - dist = tMax.y; - cv.y += step.y; - tMax.y += tDelta.y; - } else { - dist = tMax.z; - cv.z += step.z; - tMax.z += tDelta.z; - } - } } //outVoxel.color = newC return; @@ -343,11 +351,41 @@ public: Vec3f up = cam.up; float aspect = resolution.aspect(); - float fovRad = cam.fovRad(); float viewH = tan(cam.fov * 0.5f); float viewW = viewH * aspect; float maxDist = std::sqrt(gridSize.lengthSquared()); + Vec3i step; + // Defines the bounds of the grid for AABB checking + Vec3f gridMin(0, 0, 0); + std::array precomputedSteps; + int baseQuadrant = 0; + + baseQuadrant = forward.calculateInvOctantMask(); + + precomputedSteps[0] = Vec3i(1, 1, 1); // +++ + precomputedSteps[1] = Vec3i(-1, 1, 1); // -++ + precomputedSteps[2] = Vec3i(1, -1, 1); // +-+ + precomputedSteps[3] = Vec3i(-1, -1, 1); // --+ + precomputedSteps[4] = Vec3i(1, 1, -1); // ++- + precomputedSteps[5] = Vec3i(-1, 1, -1); // -+- + precomputedSteps[6] = Vec3i(1, -1, -1); // +-- + precomputedSteps[7] = Vec3i(-1, -1, -1);// --- + std::array precomputedTMax; + + Vec3f floored = cam.posfor.origin.floor(); + Vec3f dNext = floored + 1.f - cam.posfor.origin; + Vec3f dPrev = cam.posfor.origin - floored; + + precomputedTMax[0] = Vec3f(dNext.x, dNext.y, dNext.z); + precomputedTMax[1] = Vec3f(dPrev.x, dNext.y, dNext.z); + precomputedTMax[2] = Vec3f(dNext.x, dPrev.y, dNext.z); + precomputedTMax[3] = Vec3f(dPrev.x, dPrev.y, dNext.z); + precomputedTMax[4] = Vec3f(dNext.x, dNext.y, dPrev.z); + precomputedTMax[5] = Vec3f(dPrev.x, dNext.y, dPrev.z); + precomputedTMax[6] = Vec3f(dNext.x, dPrev.y, dPrev.z); + precomputedTMax[7] = Vec3f(dPrev.x, dPrev.y, dPrev.z); + frame outFrame(resolution.x, resolution.y, colorformat); std::vector colorBuffer; if (colorformat == frame::colormap::RGB) { @@ -360,13 +398,54 @@ public: for (int y = 0; y < resolution.y; y++) { float v = (1.f - 2.f * (y+0.5f) / resolution.y) * viewH; Vec3f vup = up * v; + int yQuad = baseQuadrant; + if (v < 0) yQuad ^= 2; for (int x = 0; x < resolution.x; x++) { Voxel outVoxel(0, false, 0.f, Vec3ui8(10, 10, 255)); float u = (2.f * (x+0.5f)/resolution.x - 1.f) * viewW; Vec3f rayDirWorld = (forward + right * u + vup).normalized(); - Vec3f rayStartGrid = cam.posfor.origin; - Vec3f rayEnd = rayStartGrid + rayDirWorld * maxDist; - voxelTraverse(rayStartGrid, rayEnd, outVoxel, maxDist); + float tNear = 0.0f; + float tFar = maxDist; + bool hit = intersectRayAABB(cam.posfor.origin, rayDirWorld, gridMin, gridSize, tNear, tFar); + if (!hit) { + Vec3ui8 hitColor = outVoxel.color; + + // Set pixel color in buffer + switch (colorformat) { + case frame::colormap::BGRA: { + int idx = (y * resolution.y + x) * 4; + colorBuffer[idx + 3] = hitColor.x; + colorBuffer[idx + 2] = hitColor.y; + colorBuffer[idx + 1] = hitColor.z; + colorBuffer[idx + 0] = 255; + break; + } + case frame::colormap::RGB: + default: { + int idx = (y * resolution.y + x) * 3; + colorBuffer[idx] = hitColor.x; + colorBuffer[idx + 1] = hitColor.y; + colorBuffer[idx + 2] = hitColor.z; + break; + } + } + continue; + } + + Vec3f rayStartGrid = cam.posfor.origin; // + rayDirWorld * tNear; + Vec3f rayEnd = rayStartGrid + rayDirWorld * tFar; + int xQuad = yQuad; + if (u < 0) xQuad ^= 1; + step = precomputedSteps[xQuad]; + Vec3f tMaxBase = precomputedTMax[xQuad]; + Vec3f ray = rayEnd - rayStartGrid; + Vec3f tMax( + ray.x != 0 ? tMaxBase.x / std::abs(ray.x) : INF, + ray.y != 0 ? tMaxBase.y / std::abs(ray.y) : INF, + ray.z != 0 ? tMaxBase.z / std::abs(ray.z) : INF + ); + + voxelTraverse(rayStartGrid, rayEnd, outVoxel, step, ray, tMax, maxDist); Vec3ui8 hitColor = outVoxel.color; // Set pixel color in buffer switch (colorformat) { diff --git a/util/vectorlogic/vec3.hpp b/util/vectorlogic/vec3.hpp index 883023b..c9ca5b3 100644 --- a/util/vectorlogic/vec3.hpp +++ b/util/vectorlogic/vec3.hpp @@ -495,6 +495,14 @@ public: if (z > 0.f) mask |= 4; return mask; } + + uint8_t calculateInvOctantMask() const { + uint8_t mask = 0; + if (x < 0.f) mask |= 1; + if (y < 0.f) mask |= 2; + if (z < 0.f) mask |= 4; + return mask; + } T maxComp() const { return std::max({x, y, z});