From c6038722e5fc6f9c81c52fc74e9580d0e43cda59 Mon Sep 17 00:00:00 2001 From: Yggdrasil75 Date: Thu, 29 Jan 2026 14:50:40 -0500 Subject: [PATCH] some attempts at speed improvements --- tests/g3etest.cpp | 4 +- util/grid/grid3eigen.hpp | 163 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 153 insertions(+), 14 deletions(-) diff --git a/tests/g3etest.cpp b/tests/g3etest.cpp index a937689..92beb9e 100644 --- a/tests/g3etest.cpp +++ b/tests/g3etest.cpp @@ -39,7 +39,7 @@ struct spheredefaults { float reflection = 0.0f; float refraction = 0.0f; bool fillInside = false; - float voxelSize = 0.1f; + float voxelSize = 2.f; int numPoints = 15000; }; @@ -170,7 +170,7 @@ void livePreview(Octree& grid, defaults& config, const Camera& cam) { // Measure render time auto renderStart = std::chrono::high_resolution_clock::now(); - frame currentPreviewFrame = grid.renderFrame(cam, config.outWidth, config.outHeight, frame::colormap::RGB, 3, 1, true); + frame currentPreviewFrame = grid.fastRenderFrame(cam, config.outWidth, config.outHeight, frame::colormap::RGB); auto renderEnd = std::chrono::high_resolution_clock::now(); renderFrameTime = std::chrono::duration(renderEnd - renderStart).count(); diff --git a/util/grid/grid3eigen.hpp b/util/grid/grid3eigen.hpp index 3366e27..0127202 100644 --- a/util/grid/grid3eigen.hpp +++ b/util/grid/grid3eigen.hpp @@ -102,6 +102,9 @@ private: size_t maxDepth; size_t size; size_t maxPointsPerNode; + + Eigen::Vector3f skylight_ = {0.1f, 0.1f, 0.1f}; + Eigen::Vector3f backgroundColor_ = {0.53f, 0.81f, 0.92f}; uint8_t getOctant(const PointType& point, const PointType& center) const { int octant = 0; @@ -427,6 +430,22 @@ public: Octree() : root_(nullptr), maxPointsPerNode(16), maxDepth(16), size(0) {} + void setSkylight(const Eigen::Vector3f& skylight) { + skylight_ = skylight; + } + + Eigen::Vector3f getSkylight() const { + return skylight_; + } + + void setBackgroundColor(const Eigen::Vector3f& color) { + backgroundColor_ = color; + } + + Eigen::Vector3f getBackgroundColor() const { + return backgroundColor_; + } + bool set(const T& data, const PointType& pos, bool visible, Eigen::Vector3f color, float size, bool active, int objectId = -1, bool light = false, float emittance = 0.0f, float refraction = 0.0f, float reflection = 0.0f, Shape shape = Shape::SPHERE) { @@ -450,6 +469,10 @@ public: writeVal(out, maxPointsPerNode); writeVal(out, size); + // Save global settings + writeVec3(out, skylight_); + writeVec3(out, backgroundColor_); + writeVec3(out, root_->bounds.first); writeVec3(out, root_->bounds.second); @@ -474,6 +497,10 @@ public: readVal(in, maxDepth); readVal(in, maxPointsPerNode); readVal(in, size); + + // Load global settings + readVec3(in, skylight_); + readVec3(in, backgroundColor_); PointType minBound, maxBound; readVec3(in, minBound); @@ -823,21 +850,18 @@ public: float tanHalfFov = tan(fovRad * 0.5f); float tanfovy = tanHalfFov; float tanfovx = tanHalfFov * aspect; - PointType space(0,0,0); - if (globalIllumination) space = {0.1f, 0.1f, 0.1f}; - const Eigen::Vector3f defaultColor(0.01f, 0.01f, 0.01f); - float rayLength = std::numeric_limits::max(); std::function traceRay = [&](const PointType& rayOrig, const PointType& rayDir, int bounces, uint32_t& rngState) -> Eigen::Vector3f { - if (bounces > maxBounces) return space; + if (bounces > maxBounces) return globalIllumination ? skylight_ : Eigen::Vector3f::Zero(); - auto hits = voxelTraverse(rayOrig, rayDir, rayLength, true); - if (hits.empty() && bounces == 0) { - return defaultColor; - } else if (hits.empty()) { - return space; + auto hits = voxelTraverse(rayOrig, rayDir, std::numeric_limits::max(), true); + if (hits.empty()) { + if (bounces == 0) { + return backgroundColor_; + } + return globalIllumination ? skylight_ : Eigen::Vector3f::Zero(); } auto obj = hits[0]; @@ -868,11 +892,11 @@ public: // Cube intersection PointType cubeNormal; if (!rayCubeIntersect(rayOrig, rayDir, obj.get(), t, normal, hitPoint)) { - return space; + return globalIllumination ? skylight_ : Eigen::Vector3f::Zero(); } } - Eigen::Vector3f finalColor = space; + Eigen::Vector3f finalColor = globalIllumination ? skylight_ : Eigen::Vector3f::Zero(); if (obj->light) { return obj->color * obj->emittance; @@ -978,6 +1002,121 @@ public: return outFrame; } + frame fastRenderFrame(const Camera& cam, int height, int width, frame::colormap colorformat = frame::colormap::RGB) { + + PointType origin = cam.origin; + PointType dir = cam.direction.normalized(); + PointType up = cam.up.normalized(); + PointType right = cam.right(); + + frame outFrame(width, height, colorformat); + std::vector colorBuffer; + int channels; + if (colorformat == frame::colormap::B) { + channels = 1; + } else if (colorformat == frame::colormap::RGB || colorformat == frame::colormap::BGR) { + channels = 3; + } else { //BGRA and RGBA + channels = 4; + } + colorBuffer.resize(width * height * channels); + + float aspect = static_cast(width) / height; + float fovRad = cam.fovRad(); + float tanHalfFov = tan(fovRad * 0.5f); + float tanfovy = tanHalfFov; + float tanfovx = tanHalfFov * aspect; + + #pragma omp parallel for schedule(dynamic) collapse(2) + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + int pidx = (y * width + x); + int idx = pidx * channels; + + float px = (2.0f * (x + 0.5f) / width - 1.0f) * tanfovx; + float py = (1.0f - 2.0f * (y + 0.5f) / height) * tanfovy; + + PointType rayDir = dir + (right * px) + (up * py); + rayDir.normalize(); + + Eigen::Vector3f color = backgroundColor_; // Start with background color + + auto hits = voxelTraverse(origin, rayDir, std::numeric_limits::max(), true); + if (!hits.empty()) { + auto obj = hits[0]; + + // Simple shading: use object color directly + color = obj->color; + + // If it's a light, add emittance + if (obj->light) { + color = color * obj->emittance; + } + + // Simple lighting based on ray direction (fake diffuse) + PointType normal; + if (obj->shape == Shape::SPHERE) { + PointType center = obj->position; + float radius = obj->size; + PointType L_vec = center - origin; + float tca = L_vec.dot(rayDir); + float d2 = L_vec.dot(L_vec) - tca * tca; + float radius2 = radius * radius; + + if (d2 <= radius2) { + float thc = std::sqrt(radius2 - d2); + float t = tca - thc; + if (t < 0.001f) t = tca + thc; + + PointType hitPoint = origin + rayDir * t; + normal = (hitPoint - center).normalized(); + } + } else { + // For cubes, use a simple approximation + normal = -rayDir; // Face the camera + } + + // Simple directional lighting + float lightDot = std::max(0.2f, normal.dot(-rayDir)); + color = color * lightDot; + } + + color = color.cwiseMax(0.0f).cwiseMin(1.0f); + + switch(colorformat) { + case frame::colormap::B: + colorBuffer[idx ] = static_cast(rgbToGrayscale(color) * 255.0f); + break; + case frame::colormap::RGB: + colorBuffer[idx ] = static_cast(color[0] * 255.0f); + colorBuffer[idx + 1] = static_cast(color[1] * 255.0f); + colorBuffer[idx + 2] = static_cast(color[2] * 255.0f); + break; + case frame::colormap::BGR: + colorBuffer[idx ] = static_cast(color[2] * 255.0f); + colorBuffer[idx + 1] = static_cast(color[1] * 255.0f); + colorBuffer[idx + 2] = static_cast(color[0] * 255.0f); + break; + case frame::colormap::RGBA: + colorBuffer[idx ] = static_cast(color[0] * 255.0f); + colorBuffer[idx + 1] = static_cast(color[1] * 255.0f); + colorBuffer[idx + 2] = static_cast(color[2] * 255.0f); + colorBuffer[idx + 3] = 255; + break; + case frame::colormap::BGRA: + colorBuffer[idx ] = static_cast(color[2] * 255.0f); + colorBuffer[idx + 1] = static_cast(color[1] * 255.0f); + colorBuffer[idx + 2] = static_cast(color[0] * 255.0f); + colorBuffer[idx + 3] = 255; + break; + } + } + } + + outFrame.setData(colorBuffer); + return outFrame; + } + void printStats(std::ostream& os = std::cout) const { if (!root_) { os << "[Octree Stats] Tree is null/empty." << std::endl;