Commit 1f0c5485 authored by Johannes Braun's avatar Johannes Braun
Browse files

Cleaned it all up a bit.

parent 2cb137cd
<linespace version="1.0">
<item name="subdivisions" value="10"/>
<item name="grid-subdivision" value="4"/>
<item name="grid-subdivisions" value="5"/>
<item name="radial-subdivision" value="50"/>
<item name="generator" value="gpu"/>
</linespace>
......@@ -75,12 +75,12 @@ bool traverseObjects(const in Ray ray, const in bool use_first, const in float m
if(local_ray.intersectsBounds(mesh_bounds, current_t))
{
vec3 voxel_size = mesh_bounds.size().xyz / vec3(mesh.grid_resolution);
vec3 voxel_size = mesh_bounds.size().xyz / vec3(mesh.grid_linespace.grid_resolution);
vec3 step = sign(local_ray.direction);
vec3 delta = step / local_ray.direction * voxel_size;
vec3 position = (local_ray.origin - mesh_bounds.min.xyz) / voxel_size;
ivec3 index = clamp(ivec3(position), ivec3(0), mesh.grid_resolution-1);
ivec3 index = clamp(ivec3(position), ivec3(0), mesh.grid_linespace.grid_resolution-1);
ivec3 totalStepSign = ivec3(greaterThan(step, ivec3(0)));
//bool x;
......@@ -92,7 +92,7 @@ bool traverseObjects(const in Ray ray, const in bool use_first, const in float m
for(;;)
{
int ls_index = index.x + index.y * mesh.grid_resolution.x + index.z * mesh.grid_resolution.y * mesh.grid_resolution.z;
int ls_index = index.x + index.y * mesh.grid_linespace.grid_resolution.x + index.z * mesh.grid_linespace.grid_resolution.y * mesh.grid_linespace.grid_resolution.z;
int axis = smallestAxis(tnext);
......@@ -107,7 +107,7 @@ bool traverseObjects(const in Ray ray, const in bool use_first, const in float m
}
temp_t_min = tnext[axis];
index[axis] += int( step[axis] );
if ((index[axis] < 0) || (index[axis] >= mesh.grid_resolution[axis]))
if ((index[axis] < 0) || (index[axis] >= mesh.grid_linespace.grid_resolution[axis]))
{
break;
}
......@@ -200,12 +200,12 @@ bool traverseObjects(const in Ray ray, const in bool use_first, const in float m
if(local_ray.intersectsBounds(mesh_bounds, current_t))
{
vec3 voxel_size = mesh_bounds.size().xyz / vec3(mesh.grid_resolution);
vec3 voxel_size = mesh_bounds.size().xyz / vec3(mesh.grid_linespace.grid_resolution);
vec3 step = sign(local_ray.direction);
vec3 delta = step / local_ray.direction * voxel_size;
vec3 position = (local_ray.origin - mesh_bounds.min.xyz) / voxel_size;
ivec3 index = clamp(ivec3(position), ivec3(0), mesh.grid_resolution-1);
ivec3 index = clamp(ivec3(position), ivec3(0), mesh.grid_linespace.grid_resolution-1);
ivec3 totalStepSign = ivec3(greaterThan(step, ivec3(0)));
//bool x;
......@@ -217,7 +217,7 @@ bool traverseObjects(const in Ray ray, const in bool use_first, const in float m
for(;;)
{
int ls_index = index.x + index.y * mesh.grid_resolution.x + index.z * mesh.grid_resolution.y * mesh.grid_resolution.z;
int ls_index = index.x + index.y * mesh.grid_linespace.grid_resolution.x + index.z * mesh.grid_linespace.grid_resolution.y * mesh.grid_linespace.grid_resolution.z;
int axis = smallestAxis(tnext);
......@@ -232,7 +232,7 @@ bool traverseObjects(const in Ray ray, const in bool use_first, const in float m
}
temp_t_min = tnext[axis];
index[axis] += int( step[axis] );
if ((index[axis] < 0) || (index[axis] >= mesh.grid_resolution[axis]))
if ((index[axis] < 0) || (index[axis] >= mesh.grid_linespace.grid_resolution[axis]))
{
break;
}
......
......@@ -86,7 +86,7 @@ struct PatchInfo
uint lineIndex(const in Ray ray, const in Mesh mesh, int ls_index, float tmin, float tmax, int face_in, int face_out, inout bool direction_swapped)
{
Linespace linespace = mesh.linespaces[ls_index];
Linespace linespace = mesh.grid_linespace.linespaces[ls_index];
PatchInfo entry_info;
PatchInfo exit_info;
......@@ -135,12 +135,12 @@ bool traverseLineSpace(const in Mesh mesh, int index, const in Ray local_ray, co
int face_tmax;
// LS can be empty.
if (mesh.linespaces[index].line_count == 0) return false;
if (mesh.grid_linespace.linespaces[index].line_count == 0) return false;
Ray loc = local_ray;
loc.origin += 0.05f * loc.direction;
if(!loc.intersectsBounds(mesh.linespaces[index].bounds, tmin, tmax, face_tmin, face_tmax) || t_min <= tmin || tmin > max_distance)
if(!loc.intersectsBounds(mesh.grid_linespace.linespaces[index].bounds, tmin, tmax, face_tmin, face_tmax) || t_min <= tmin || tmin > max_distance)
{
return false;
}
......@@ -148,8 +148,8 @@ bool traverseLineSpace(const in Mesh mesh, int index, const in Ray local_ray, co
bool swapped = false;
uint line_id = lineIndex(loc, mesh, index, tmin, tmax, face_tmin, face_tmax, swapped);
Line line_near = mesh.linespaces[index].lines[line_id * 2];
Line line_far = mesh.linespaces[index].lines[line_id * 2 + 1];
Line line_near = mesh.grid_linespace.linespaces[index].lines[line_id * 2];
Line line_far = mesh.grid_linespace.linespaces[index].lines[line_id * 2 + 1];
int near_data = swapped ? line_far.triangle : line_near.triangle;
Hit nearer;
......
......@@ -31,5 +31,5 @@ void main()
vec2 random = settings.u_random_subpixel ? vec2(0, 0) : rand2D(random_seed + id, target_size.x*target_size.y);
traces_data[id].ray = u_camera.getRayFromPixel(vec2(gl_GlobalInvocationID.xy), random, vec2(target_size));
traces_data[id].hit.invalidate();
traces_data[id].ray.nearestIntersection(traces_data[id].hit, true);
traces_data[id].ray.nearestIntersection(traces_data[id].hit, false);
}
......@@ -21,10 +21,9 @@ struct Mesh
Vertex* vertices;
Triangle* triangles;
BVHNode* nodes;
Linespace* linespaces;
ivec3 grid_resolution;
int num_linespaces;
int p1[2];
GridLinespaceData grid_linespace;
uint material;
uint id;
......
......@@ -37,4 +37,12 @@ struct Linespace
int padding2;
};
struct GridLinespaceData
{
Linespace* linespaces;
int p[2];
ivec3 grid_resolution;
int num_linespaces;
};
#endif //!INCLUDE_UTIL_LINESPACE_GLSL
#include "grid_linespace.h"
namespace glare::raytrace
{
void GridLinespace::generate(const LocalCollector& collector, const core::Preferences& preferences)
{
Config config;
config.generator = preferences["generator"].as_string("gpu") == "cpu" ? Platform::eCPU : Platform::eGPU;
config.grid_subdivision = preferences["grid-subdivisions"].as_int(1);
config.linespace_subdivisions = preferences["subdivisions"].as_int(4);
generate(collector, config);
}
void GridLinespace::generate(const LocalCollector& collector, const Config& config)
{
core::ClockMS clock;
m_finished = false;
m_grid_subdivision = collector.bounds().computeSubdivision(config.grid_subdivision);
Log_Info << "Building " << m_grid_subdivision.resolution.x << "x" << m_grid_subdivision.resolution.y << "x" << m_grid_subdivision.resolution.z << " Grid Line Space";
int count = static_cast<int>(m_grid_subdivision.children());
m_linespaces.resize(count);
m_linespaces_data.resize(count);
for (int i = 0; i < count; ++i)
{
m_linespaces[i] = std::make_shared<Linespace>();
m_linespaces[i]->generate(collector, m_grid_subdivision, i, config.linespace_subdivisions, config.generator);
m_linespaces_data[i] = m_linespaces[i]->data();
}
m_linespaces_buffer.upload(m_linespaces_data, gl::BufferUsage::eDynamicDraw);
m_finished = true;
Log_Info << "Grid Linespace generation took " << clock.time() << "ms";
}
GridLinespaceData GridLinespace::data() const
{
GridLinespaceData result;
result.linespaces_buffer_ptr = m_linespaces_buffer.makeResident(gl::Access::eReadOnly);
result.grid_resolution = glm::ivec3(m_grid_subdivision.resolution);
result.num_linespaces = static_cast<int>(m_linespaces_data.size());
return result;
}
bool GridLinespace::finished() const
{
return m_finished;
}
}
\ No newline at end of file
#ifndef INCLUDE_GRID_LINESPACE_H
#define INCLUDE_GRID_LINESPACE_H
#include <core/numeric/geometry.h>
#include "core/res/preferences.h"
#include "linespace.h"
namespace glare::raytrace
{
inline int patchCount(const math::Subdivision& subdivision, Face face)
{
return subdivision.resolution[FaceAxises::get(face).horizontal] * subdivision.resolution[FaceAxises::get(face).vertical];
}
inline int lineCount(const math::Subdivision& subdivision)
class GridLinespace
{
const unsigned patches_x = patchCount(subdivision, Face::ePosX);
const unsigned patches_y = patchCount(subdivision, Face::ePosY);
const unsigned patches_z = patchCount(subdivision, Face::ePosZ);
return 2 * (2 * patches_x * (patches_y + patches_z) + patches_x * patches_x
+ 2 * patches_y * (patches_x + patches_z) + patches_y * patches_y
+ 2 * patches_z * (patches_x + patches_y) + patches_z * patches_z);
}
inline int compute(math::Bounds bounds, int res_voxels, int res_linespace)
{
auto subdiv = bounds.computeSubdivision(res_voxels);
math::Bounds sub_bounds_sample{ {0,0,0,1}, glm::vec4(subdiv.size, 1) };
auto subsubdiv = sub_bounds_sample.computeSubdivision(res_linespace);
glm::vec3 effective_resolution = subdiv.resolution * subsubdiv.resolution;
int count = subdiv.resolution.x * subdiv.resolution.y * subdiv.resolution.z * lineCount(subsubdiv);
int memory = count * sizeof(Line);
return 0;
}
public:
struct Config
{
int grid_subdivision;
int linespace_subdivisions;
Platform generator;
};
GridLinespace() = default;
template<typename... Params>
GridLinespace(Params&&... params) { generate(params); }
void generate(const LocalCollector& collector, const core::Preferences& preferences);
void generate(const LocalCollector& collector, const Config& config);
GridLinespaceData data() const;
bool finished() const;
private:
math::Subdivision m_grid_subdivision;
std::vector<std::shared_ptr<Linespace>> m_linespaces;
std::vector<LinespaceData> m_linespaces_data;
core::Buffer m_linespaces_buffer;
bool m_finished = false;
};
}
#endif // !INCLUDE_GRID_LINESPACE_H
#endif //!INCLUDE_GRID_LINESPACE_H
\ No newline at end of file
......@@ -9,19 +9,12 @@
namespace glare::raytrace
{
Linespace::Linespace()
{
}
Linespace::Linespace(const LocalCollector &collector, int max_subdivisions, const Platform generator)
: Linespace()
{
generate(collector, max_subdivisions, generator);
}
Linespace::~Linespace() {}
void Linespace::generate(const LocalCollector &collector, const fs::path &settings_file)
{
pugi::xml_document doc;
......@@ -38,30 +31,30 @@ namespace glare::raytrace
void Linespace::generate(const LocalCollector &collector, int max_subdivisions, const Platform generator)
{
generate(collector, 1, 0, max_subdivisions, generator);
generate(collector, collector.bounds().computeSubdivision(1), 0, max_subdivisions, generator);
}
void Linespace::generate(const LocalCollector &collector, int uniform_grid_subdivision, int uniform_grid_index, int max_subdivisions, const Platform generator)
void Linespace::generate(const LocalCollector &collector, const math::Subdivision& uniform_grid, int uniform_grid_index, int max_subdivisions, const Platform generator)
{
//Log_Info << "Building Line Space for collector id " << collector.id() << "...";
core::ClockGL::instance().start();
m_bounds = collector.bounds();
auto grid = m_bounds.computeSubdivision(uniform_grid_subdivision);
int grid_index = uniform_grid_index;
glm::vec3 grid_index_3d;
grid_index_3d.x = static_cast<float>(grid_index % grid.resolution.x);
grid_index /= grid.resolution.x;
grid_index_3d.y = static_cast<float>(grid_index % grid.resolution.y);
grid_index_3d.z = static_cast<float>(grid_index / grid.resolution.y);
grid_index_3d.x = static_cast<float>(grid_index % uniform_grid.resolution.x);
grid_index /= uniform_grid.resolution.x;
grid_index_3d.y = static_cast<float>(grid_index % uniform_grid.resolution.y);
grid_index_3d.z = static_cast<float>(grid_index / uniform_grid.resolution.y);
math::Bounds replacement;
replacement.min = m_bounds.min + glm::vec4(grid_index_3d * grid.size, 0);
replacement.max = replacement.min + glm::vec4(grid.size, 0);
replacement.min = m_bounds.min + glm::vec4(grid_index_3d * uniform_grid.size, 0);
replacement.max = replacement.min + glm::vec4(uniform_grid.size, 0);
m_bounds = replacement;
m_subdivision = m_bounds.subdivide(max_subdivisions);
Log_Info << "Building " << m_subdivision.resolution.x << "x" << m_subdivision.resolution.y << "x"<<m_subdivision.resolution.z<< " Line Space";
m_filled = collector.triangles().cend() != std::find_if(collector.triangles().cbegin(), collector.triangles().cend(), [this, &collector](const TriangleIDs& tri)
{
math::Triangle triangle;
......@@ -158,8 +151,7 @@ namespace glare::raytrace
void Linespace::generateGPU(const LocalCollector &collector) const
{
// construct once, use it for all further generators.
const static std::unique_ptr<core::Program> construction_shader
= std::make_unique<core::Program>(files::shader("/pathtracer/linespace_build/linespace_generate.comp"));
const static auto construction_shader = std::make_unique<core::Program>(files::shader("/pathtracer/linespace_build/linespace_generate.comp"));
construction_shader->use();
// Reserve the needed buffer memory
......
......@@ -89,12 +89,12 @@ namespace glare::raytrace
{
public:
Linespace();
~Linespace();
Linespace() = default;
~Linespace() = default;
Linespace(const LocalCollector &collector, int max_subdivisions, const Platform generator = Platform::eCPU);
void generate(const LocalCollector &collector, const fs::path &settings_file);
void generate(const LocalCollector &collector, int max_subdivisions, const Platform generator = Platform::eCPU);
void generate(const LocalCollector &collector, int uniform_grid_subdivision, int uniform_grid_index, int max_subdivisions, const Platform generator = Platform::eCPU);
void generate(const LocalCollector &collector, const math::Subdivision& uniform_grid, int uniform_grid_index, int max_subdivisions, const Platform generator = Platform::eCPU);
LinespaceData data() const;
const core::Buffer &lineBuffer() const;
......@@ -116,6 +116,7 @@ namespace glare::raytrace
math::Bounds m_bounds;
math::Subdivision m_subdivision;
core::Buffer m_line_buffer;
bool m_filled = false;
......
......@@ -3,90 +3,53 @@
#include <raytrace/data/linespace.h>
#include <core/rendering/batch_renderer.h>
#include <pugixml/pugixml.hpp>
#include "grid_linespace.h"
namespace glare::raytrace
{
LocalCollector::LocalCollector()
: m_grid_linespace(std::make_unique<GridLinespace>())
{
}
LocalCollector::LocalCollector(const core::MeshDrawable &mesh, std::shared_ptr<LocalBVH> datastructure)
: LocalCollector()
{
collect(mesh, datastructure);
}
void LocalCollector::collect(const core::MeshDrawable &mesh, std::shared_ptr<LocalBVH> datastructure)
{
Log_Info << std::string(14, '#') << " CURRENTLY PROCESSED MESH NAME: " << mesh.renderer()->owner()->name() << " " << std::string(14, '#');
Log_Info << "Processing Mesh: " << mesh.renderer()->owner()->name();
m_mesh_id = mesh.mesh->id();
m_id = static_cast<size_t>(mesh.renderer()->id());
m_material_id = mesh.material->id();
m_bvh = datastructure;
m_bounds = math::Bounds();
m_vertices = std::vector<math::Vertex>(mesh.mesh->getVertices());
m_vertices = mesh.mesh->getVertices();
m_triangles.resize(mesh.mesh->getIndices().size() / 3);
const auto& indices = mesh.mesh->getIndices();
#pragma omp parallel for
for (int i = 0; i < static_cast<int>(mesh.mesh->getIndices().size()); i += 3)
for (int i = 0; i < static_cast<int>(indices.size()); i += 3)
{
TriangleIDs triangle;
for (int index = 0; index < 3; index++) {
triangle.indices[index] = mesh.mesh->getIndices()[i + index];
m_bounds.expand(mesh.mesh->getVertices()[mesh.mesh->getIndices()[i + index]].position);
for (int index = 0; index < 3; ++index) {
triangle.indices[index] = indices[i + index];
m_bounds.expand(m_vertices[indices[i+index]].position);
}
triangle.material_id = 0;
m_triangles[i / 3] = triangle;
}
m_bvh->apply(m_vertices, m_triangles);
if (!m_triangle_buffer)
m_triangle_buffer = std::make_shared<core::Buffer>();
if (!m_vertex_buffer)
m_vertex_buffer = std::make_shared<core::Buffer>();
m_triangle_buffer->upload(m_triangles, gl::BufferUsage::eDynamicRead);
m_vertex_buffer->upload(m_vertices, gl::BufferUsage::eDynamicRead);
m_vertex_buffer->makeResident(gl::Access::eReadOnly);
m_triangle_buffer->makeResident(gl::Access::eReadOnly);
pugi::xml_document doc;
doc.load_file(files::asset("preferences/linespace_default.xml").c_str());
const auto& linespace_tag = doc.child("linespace");
const int subdiv_grid = linespace_tag.find_child_by_attribute("item", "name", "grid-subdivisions").attribute("value").as_int(16);
const int max_subdivisions = linespace_tag.find_child_by_attribute("item", "name", "subdivisions").attribute("value").as_int(16);
const std::string gen = linespace_tag.find_child_by_attribute("item", "name", "generator").attribute("value").as_string("cpu");
const Platform generator = gen == "gpu" ? Platform::eGPU : Platform::eCPU;
m_triangle_buffer.upload(m_triangles, gl::BufferUsage::eDynamicRead);
m_vertex_buffer.upload(m_vertices, gl::BufferUsage::eDynamicRead);
auto subdiv = m_bounds.computeSubdivision(subdiv_grid);
m_grid_resolution = glm::ivec3(subdiv.resolution);
int count = m_grid_resolution.x * m_grid_resolution.y * m_grid_resolution.z;
m_linespaces.resize(count);
for (int i = 0; i < count; ++i)
{
m_linespaces[i] = std::make_shared<Linespace>();
m_linespaces[i]->generate(*this, subdiv_grid, i, max_subdivisions, generator);
}
m_linespace_data.resize(count);
for (int i = 0; i < count; ++i)
{
m_linespace_data[i] = m_linespaces[i]->data();
}
m_linespace_buffer.upload(m_linespace_data, gl::BufferUsage::eDynamicDraw);
m_grid_linespace->generate(*this, core::Preferences(files::asset("preferences/linespace_default.xml")));
}
int64_t LocalCollector::meshID() const
......@@ -122,15 +85,12 @@ namespace glare::raytrace
mesh.transformation = transform;
mesh.inverse_transformation = glm::inverse(transform);
mesh.normal_matrix = glm::mat4(glm::mat3(glm::transpose(glm::inverse(transform))));
mesh.vertex_buffer_ptr = m_vertex_buffer->residentAddress();
mesh.triangle_buffer_ptr = m_triangle_buffer->residentAddress();
mesh.vertex_buffer_ptr = m_vertex_buffer.makeResident(gl::Access::eReadOnly);
mesh.triangle_buffer_ptr = m_triangle_buffer.makeResident(gl::Access::eReadOnly);
if(!m_linespaces.empty() && !m_linespace_data.empty())
{
mesh.linespaces = static_cast<int>(m_linespace_data.size());
mesh.linespace_buffer_ptr = m_linespace_buffer.makeResident(gl::Access::eReadOnly);
mesh.grid_resolution = m_grid_resolution;
}
// Need to check for grid LS finished, because LS generation requires a makeMesh call.
if (m_grid_linespace->finished())
mesh.grid_linespace = m_grid_linespace->data();
mesh.material = material_index;
return mesh;
......
......@@ -12,7 +12,8 @@
namespace glare::raytrace
{
class Linespace;
class AngularLinespace;
//class AngularLinespace;
class GridLinespace;
/**
* @brief The LocalCollector is used to apply a datastructure to any given mesh and provide buffers for raytracing.
* A management for transformations and the mesh material is also included
......@@ -52,19 +53,15 @@ namespace glare::raytrace
int64_t m_mesh_id = 0;
math::Bounds m_bounds;
//glm::mat4 m_transform;
std::shared_ptr<LocalBVH> m_bvh;
glm::ivec3 m_grid_resolution;
std::vector<std::shared_ptr<Linespace>> m_linespaces;
std::vector<LinespaceData> m_linespace_data;
std::shared_ptr<GridLinespace> m_grid_linespace;
std::vector<math::Vertex> m_vertices;
std::vector<TriangleIDs> m_triangles;
std::shared_ptr<core::Buffer> m_triangle_buffer;
std::shared_ptr<core::Buffer> m_vertex_buffer;
core::Buffer m_linespace_buffer;
core::Buffer m_triangle_buffer;
core::Buffer m_vertex_buffer;
};
struct InstancedCollector
......
......@@ -98,6 +98,14 @@ namespace glare::raytrace
void uniformUpdate(const core::Program &program, std::string var_name) const;
};
struct GridLinespaceData
{
uint64_t linespaces_buffer_ptr;
int p[2];
glm::ivec3 grid_resolution;
int num_linespaces;
};
struct LinespaceData
{
uint64_t lines;
......@@ -115,17 +123,14 @@ namespace glare::raytrace
uint64_t vertex_buffer_ptr;
uint64_t triangle_buffer_ptr;
uint64_t datastructure_buffer_ptr;
uint64_t linespace_buffer_ptr;
int p1[2];
glm::ivec3 grid_resolution;
int linespaces;
GridLinespaceData grid_linespace;
glm::uint material;
glm::uint id;
int p[2];
//LinespaceData linespace;
glm::mat4 transformation;
glm::mat4 inverse_transformation;
glm::mat4 normal_matrix;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment