Commit 4b89766a authored by unknown's avatar unknown
Browse files

Angular

parent 76ab130d
......@@ -119,8 +119,9 @@ struct line_hit
struct Line
{
line_hit nearest;
line_hit farthest;
int triangle;
// line_hit nearest;
// line_hit farthest;
};
struct Linespace
......
#ifndef __GL_LINESPACE
#define __GL_LINESPACE
#include <raytracer/basic_structs.glh>
#include <raytracer/buffers.glh>
#include <raytracer/intersections.glh>
#include <raytracer/std.glh>
#include <raytracer/utilities.glh>
const uint face_width_axis[3] = {2, 2, 0};
const uint face_height_axis[3] = {1, 0, 1};
uvec2 getPatch(const in Mesh mesh, vec3 at_position, int axis, int face){
bool flip_indices = face != axis;
return !flip_indices
? uvec2(at_position[face_width_axis[axis]] / mesh.linespace.patch_size, at_position[face_height_axis[axis]] / mesh.linespace.patch_size)
: uvec2(mesh.linespace.resolution[face_width_axis[axis]], mesh.linespace.resolution[face_height_axis[axis]]) -
uvec2(at_position[face_width_axis[axis]] / mesh.linespace.patch_size, at_position[face_height_axis[axis]] / mesh.linespace.patch_size)- 1;
}
float getDistance(const in Ray ray, const in Hit hit, inout uint dir_sign)
{
Mesh mesh = b_meshes[hit.mesh];
Triangle triangle = mesh.triangles[hit.triangle];
Vertex v1 = mesh.vertices[triangle.indices[1]];
Vertex v2 = mesh.vertices[triangle.indices[2]];
Vertex v3 = mesh.vertices[triangle.indices[0]];
vec3 vector = hit__getFromBarycentric(hit.barycentric, triangle, position).xyz - ray.origin;
dir_sign = uint(sign(dot(vector, ray.direction)));
return length(vector);
}
struct PatchInfo
{
int face;
int axis;
uvec2 patch_index;
vec3 position;
float t;
};
const uint m_radial_subdivisions = 1; //TODO: put into ssbo
uint lineIndex(const in Ray ray, const in Mesh mesh, float t, int face, bool reverse)
{
const Linespace linespace = mesh.linespace;
vec3 horizontal = vec3(0);
horizontal[face_width_axis[face % 3]] = face >= 2 ? -1 : 1;
vec3 vertical = vec3(0);
vertical[face_width_axis[face % 3]] = face >= 2 ? -1 : 1;
vec3 direction = reverse ? -ray.direction : ray.direction;
float radial_x = dot(horizontal, direction);
float radial_y = dot(vertical, direction);
const uvec2 entry_patch = getPatch(mesh, ray.origin + t * ray.direction - linespace.bounds.min.xyz, face % 3, face);
const uint n = uint(face);
uint patch_offset = uint(n % 3 >= 1) * (linespace.resolution[face_width_axis[0]] + (uint(n % 3 >= 2) * linespace.resolution[face_width_axis[1]])) * linespace.resolution[face_height_axis[0]];
patch_offset += uint((n / 3) * dot(linespace.resolution.zzx, linespace.resolution.yxy));
const uint radial_diameter = 2 * m_radial_subdivisions - 1;
const uint square_radial_diameter = radial_diameter * radial_diameter;
const uint patch_sub_offset = linespace.resolution[face_width_axis[uint(face) % 3]] * entry_patch.y + entry_patch.x;
radial_x += 1;
radial_x *= float(m_radial_subdivisions) + 1;
radial_x -= 1;
radial_y += 1;
radial_y *= float(m_radial_subdivisions) + 1;
radial_y -= 1;
return patch_offset * square_radial_diameter + patch_sub_offset + uint(radial_y) * radial_diameter + uint(radial_x);
}
bool traverseLineSpace(const in Mesh mesh, const in Ray local_ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min)
{
float tmin;
float tmax;
int face_tmin;
int face_tmax;
float offset = 1e-5;//1000;//mesh.linespace.patch_size;
Ray offset_ray = local_ray;
offset_ray.origin += local_ray.direction * offset;
if(!offset_ray.intersectsBounds(mesh.linespace.bounds, tmin, tmax, face_tmin, face_tmax) || t_min <= tmin-offset || tmin-offset > max_distance)
{
return false;
}
uint line_id = lineIndex(offset_ray, mesh, tmin, face_tmin, false);
Line near_data = mesh.lines[line_id];
Hit nearer;
float t;
if(near_data.triangle != -1)
{
nearer.triangle = near_data.triangle;
nearer.mesh = mesh.id;
if(local_ray.intersectsTrianglePlane(near_data.triangle, mesh, t, nearer.barycentric.x, nearer.barycentric.y))
{
float nearest_distance = t-offset;
if(nearest_distance > 0 && max_distance > nearest_distance){
hit = nearer;
t_min = t;
//Found an intersected shaft. But we don't yet know whether it contains geometry, so look it up as a last step.
return true;
}
}
}
line_id = lineIndex(offset_ray, mesh, tmax, face_tmax, true);
near_data = mesh.lines[line_id];
if(near_data.triangle != -1)
{
nearer.triangle = near_data.triangle;
nearer.mesh = mesh.id;
if(local_ray.intersectsTrianglePlane(near_data.triangle, mesh, t, nearer.barycentric.x, nearer.barycentric.y))
{
float farthest_distance = t-offset;
if(farthest_distance > 0 && max_distance > farthest_distance){
hit = nearer;
t_min = t;
//Found an intersected shaft. But we don't yet know whether it contains geometry, so look it up as a last step.
return true;
}
}
}
return false;
}
#endif //__GL_LINESPACE
\ No newline at end of file
......@@ -2,7 +2,7 @@
#define __GL_MESH_DATASTRUCTURE
#include <raytracer/datastructure/mesh_bvh.glh>
#include <raytracer/datastructure/mesh_linespace.glh>
#include <raytracer/datastructure/mesh_angular_linespace.glh>
uniform bool u_use_ls;
......
#include "AngularLinespace.h"
// --------------- STDLIB ---------------
// --------------- EXTERN ---------------
#include <engine/Time.h>
// --------------- INTERN ---------------
#include <advanced/meshlocal/LocalBVH.h>
namespace glare
{
namespace advanced
{
AngularLinespace::AngularLinespace(const advanced::LocalCollector &collector, int box_subdivisions, int radial_subdivisions, Generator generator)
{
generate(collector, box_subdivisions, radial_subdivisions, generator);
}
void AngularLinespace::generate(const advanced::LocalCollector &collector, int box_subdivisions, int radial_subdivisions, Generator generator)
{
core::ClockMS clock;
m_resolution = math::UniformBoundsSubdivision(collector.bounds(), box_subdivisions);
m_radial_subdivisions = radial_subdivisions;
m_generator = generator;
m_num_lines = unsigned(calculateLineCount());
const size_t memory = sizeof(sample_line_t) * m_num_lines;
m_bounds = collector.bounds();
m_bounds.max = m_bounds.min + glm::vec4(m_resolution.size * glm::vec3(m_resolution.subdivisions), 0);
m_lines.resize(m_num_lines, sample_line_t{ -1 });
const advanced::LocalBVH &line_bvh = static_cast<const advanced::LocalBVH&>(collector.datastructure());
for (Face face = Face::ePosX; unsigned(face) <= unsigned(Face::eNegZ); face = Face(unsigned(face) + 1))
{
const unsigned count = m_resolution.subdivisions[face_width_axises[unsigned(face) % 3]] * m_resolution.subdivisions[face_height_axises[unsigned(face) % 3]];
Log_Info << "Starting at " << unsigned(face);
const unsigned radial_diameter = 2 * radial_subdivisions - 1;
const unsigned count_and_radial = count * radial_diameter * radial_diameter;
#pragma omp parallel for schedule(dynamic)
for (int gid = 0; gid < int(count_and_radial); ++gid)
{
const unsigned width = m_resolution.subdivisions[face_width_axises[unsigned(face) % 3]];
const unsigned id = gid / (radial_diameter * radial_diameter);
const unsigned radial_id = gid % (radial_diameter * radial_diameter);
Patch patch(face);
patch.index_horizontal = id % width;
patch.index_vertical = id / width;
const unsigned radial_x = radial_id % radial_diameter;
const unsigned radial_y = radial_id / radial_diameter;
const float max_radius = 1 - 1 / float(radial_subdivisions);
//relative position maps the id onto a point relative to the patch center with a maximum axial distance of max_radius, mapped to (-1..1)
glm::vec2 relative_position = (glm::vec2(radial_x, radial_y) / (radial_subdivisions - 1)) - glm::vec2(1);
relative_position *= 1 - 1 / float(radial_subdivisions);
//build normalized direction vector
glm::vec3 direction;
direction[face_width_axises[unsigned(face) % 3]] = unsigned(face) <= 2 ? relative_position.x : -relative_position.x;
direction[face_height_axises[unsigned(face) % 3]] = unsigned(face) <= 2 ? relative_position.y : -relative_position.y;
direction[unsigned(face) % 3] = (unsigned(face) <= 2 ? 1 : -1) * ( 1 - glm::abs(relative_position.x) - glm::abs(relative_position.y));
math::Ray test_ray;
test_ray.origin = patchCenter(patch);
test_ray.direction = direction;
math::Hit nearest;
nearest.triangle = -1;
line_bvh.nearestIntersection(test_ray, nearest);
unsigned idx = index(patch, radial_x, radial_y);
m_lines[idx].triangle = (nearest.barycentric.x != -1) ? int(nearest.triangle) : -1;
}
}
m_line_buffer.upload(m_lines, gl::BufferUsage::eStaticDraw);
m_line_buffer.makeResident(gl::Access::eReadOnly);
Log_Info << "[Linespace Data] Generation Time: " << clock.time() << "ms";
Log_Info << "[Linespace Data] Lines: " << m_num_lines;
Log_Info << "[Linespace Data] Memory: " << memory << " Bytes";
Log_Info << "[Linespace Data] Patch Subdivisions: " << m_resolution.subdivisions.x << ", " << m_resolution.subdivisions.y << ", " << m_resolution.subdivisions.z;
Log_Info << "[Linespace Data] Patch Size: " << m_resolution.size;
Log_Info << "[Linespace Data] Radial Subdivisions: " << radial_subdivisions;
Log_Info << "[Linespace Data] Object Bounds: " << collector.bounds();
}
uint32_t AngularLinespace::index(const Patch &patch, unsigned radial_x, unsigned radial_y)
{
/*if (patch.index_horizontal == 3 && patch.index_vertical == 3)
{
Log_Error << "baldnk";
}*/
const unsigned n = unsigned(patch.face);
// patch offset at face 0 is 0
// patch offset at face 1 is x * y
// patch offset at face 2 is (x+z)*y
// patch offsets larger than that have x*y + y*z + x*z added
unsigned patch_offset = unsigned(n % 3 >= 1) * (m_resolution.subdivisions[face_width_axises[0]] + (unsigned(n % 3 >= 2) * m_resolution.subdivisions[face_width_axises[1]])) * m_resolution.subdivisions[face_height_axises[0]];
patch_offset += unsigned((n / 3) * glm::dot(glm::vec3(glm::vec3(m_resolution.subdivisions).zzx), glm::vec3(glm::vec3(m_resolution.subdivisions).yxy)));
const unsigned radial_diameter = 2 * m_radial_subdivisions - 1;
const unsigned square_radial_diameter = radial_diameter * radial_diameter;
const unsigned patch_sub_offset = m_resolution.subdivisions[face_width_axises[unsigned(patch.face) % 3]] * patch.index_vertical + patch.index_horizontal;
return patch_offset * square_radial_diameter + patch_sub_offset * square_radial_diameter + radial_y * radial_diameter + radial_x;
}
glm::vec3 AngularLinespace::patchCenter(const Patch &patch)
{
unsigned face_index = unsigned(patch.face);
unsigned max_factor = 1 - (face_index / 3); // 1 for pos plane, 0 for neg plane
glm::vec3 position;
position[face_index % 3] = m_bounds.min[face_index % 3] + max_factor*m_bounds.size()[face_index % 3];
unsigned axis_width = face_width_axises[face_index % 3];
unsigned axis_height = face_height_axises[face_index % 3];
if (patch.face < Face::eNegX) {
position[axis_width] = m_bounds.min[axis_width] + patch.index_horizontal * m_resolution.size + m_resolution.size / 2;
position[axis_height] = m_bounds.min[axis_height] + patch.index_vertical * m_resolution.size + m_resolution.size / 2;
}
else {
position[axis_width] = m_bounds.max[axis_width] - (patch.index_horizontal * m_resolution.size + m_resolution.size / 2);
position[axis_height] = m_bounds.max[axis_height] - (patch.index_vertical * m_resolution.size + m_resolution.size / 2);
}
return position;
}
size_t AngularLinespace::calculateLineCount() const
{
// Number of start faces times the number of sample rays
return 2 * (m_resolution.subdivisions.x * m_resolution.subdivisions.y +
m_resolution.subdivisions.x * m_resolution.subdivisions.z +
m_resolution.subdivisions.y * m_resolution.subdivisions.z) * (glm::pow2((2 * m_radial_subdivisions) - 1));
}
const core::Buffer<gl::BufferType::eShaderStorage> &AngularLinespace::lineBuffer() const
{
return m_line_buffer;
}
const math::Bounds& AngularLinespace::bounds() const
{
return m_bounds;
}
const math::UniformBoundsSubdivision& AngularLinespace::subdivisions() const
{
return m_resolution;
}
unsigned AngularLinespace::lines() const
{
return m_num_lines;
}
}
}
#ifndef INCLUDE_ANGULARLINESPACE_H
#define INCLUDE_ANGULARLINESPACE_H
// --------------- STDLIB ---------------
// --------------- EXTERN ---------------
#include <engine/Math.h>
// --------------- INTERN ---------------
#include <advanced/meshlocal/LocalCollector.h>
namespace glare
{
namespace advanced
{
struct sample_line_t
{
int32_t triangle;
};
class AngularLinespace
{
public:
enum class Generator
{
eCPU = 0,
eGPU = 1
};
enum class Face : uint32_t
{
ePosX = 0,
ePosY = 1,
ePosZ = 2,
eNegX = 3,
eNegY = 4,
eNegZ = 5
};
struct Patch
{
Patch() : face(Face::ePosX), index(0) {}
Patch(Face face) : face(face), index(0) {}
Patch(Face face, glm::uvec2 index) : face(face), index(index) {}
Patch(Face face, unsigned id_horizontal, unsigned id_vertical) : face(face), index(id_horizontal, id_vertical) {}
Face face;
unsigned padding;
union {
struct {
unsigned index_horizontal;
unsigned index_vertical;
};
glm::uvec2 index;
};
};
const glm::uvec3 face_width_axises = { 2, 2, 0 };
const glm::uvec3 face_height_axises = { 1, 0, 1 };
AngularLinespace(const advanced::LocalCollector &collector, int box_subdivisions, int radial_subdivisions, Generator generator = Generator::eCPU);
AngularLinespace(AngularLinespace& other) = default;
AngularLinespace(AngularLinespace&& other) = default;
AngularLinespace& operator=(AngularLinespace& other) = default;
AngularLinespace& operator=(AngularLinespace&& other) = default;
void generate(const advanced::LocalCollector &collector, int box_subdivisions, int radial_subdivisions, Generator generator = Generator::eCPU);
glm::vec3 patchCenter(const Patch &patch);
size_t calculateLineCount() const;
uint32_t index(const Patch &patch, unsigned radial_x, unsigned radial_y);
const math::Bounds& bounds() const;
const math::UniformBoundsSubdivision& subdivisions() const;
unsigned lines() const;
const core::Buffer<gl::BufferType::eShaderStorage> &lineBuffer() const;
private:
core::Buffer<gl::BufferType::eShaderStorage> m_line_buffer;
std::vector<sample_line_t> m_lines;
math::UniformBoundsSubdivision m_resolution;
unsigned m_num_lines;
math::Bounds m_bounds;
int m_radial_subdivisions;
Generator m_generator;
};
}
}
#endif //INCLUDE_ANGULARLINESPACE_H
......@@ -402,6 +402,7 @@ namespace glare
bool LocalBVH::nearestIntersection(const math::Ray &ray, math::Hit &hit) const
{
hit.barycentric.x = -1;
math::Hit tmp_hit;
float min_t = std::numeric_limits<float>::max();
float tmp;
......
#include "LocalCollector.h"
#include <linespace/LineSpace.h>
#include <advanced/meshlocal/AngularLinespace.h>
namespace glare
{
......@@ -55,14 +56,14 @@ namespace glare
m_vertex_buffer->makeResident(gl::Access::eReadOnly);
m_triangle_buffer->makeResident(gl::Access::eReadOnly);
const unsigned linespace_max_res = -1;
const ls::LineSpace::Generator linespace_generator = ls::LineSpace::Generator::eGPU;
const unsigned linespace_max_res = 4;
const AngularLinespace::Generator linespace_generator = AngularLinespace::Generator::eGPU;
if (!m_linespace) {
m_linespace = std::make_unique<ls::LineSpace>(*this, linespace_max_res, linespace_generator);
m_linespace = std::make_unique<AngularLinespace>(*this, linespace_max_res, 1, linespace_generator);
}
else {
m_linespace->generate(*this, linespace_max_res, linespace_generator);
m_linespace->generate(*this, linespace_max_res, 1, linespace_generator);
}
}
......@@ -109,11 +110,11 @@ namespace glare
mesh.resolution = glm::uvec3(m_linespace->subdivisions().subdivisions);
mesh.lines_buffer = m_linespace->lineBuffer().residentAddress();
for (int i = 0; i < 15; ++i) {
/*for (int i = 0; i < 15; ++i) {
mesh.offsets[i] = glm::uint(m_linespace->offsets()[i]);
}
}*/
mesh.line_count = glm::uint(m_linespace->lines().size());
mesh.line_count = glm::uint(m_linespace->lines());
}
mesh.material = glm::uint(material_index);
return mesh;
......
......@@ -14,7 +14,7 @@ namespace glare
namespace advanced
{
class AngularLinespace;
/**
* @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
......@@ -53,7 +53,8 @@ namespace glare
size_t m_id = 0;
size_t m_material_id = 0; //!< NOT the buffer position of this material!
std::shared_ptr<LocalDatastructure> m_datastructure;
std::shared_ptr<ls::LineSpace> m_linespace;
// std::shared_ptr<ls::LineSpace> m_linespace;
std::shared_ptr<AngularLinespace> m_linespace;
math::Bounds m_bounds;
std::vector<math::Vertex> m_vertices;
std::vector<advanced::Triangle> m_triangles;
......
......@@ -48,8 +48,6 @@ namespace glare
glfwSwapInterval(0);
gl::clampColor(gl::ClampColorTarget::eRead, false);
gl::clampColor(gl::ClampColorTarget::eVertex, false);
gl::clampColor(gl::ClampColorTarget::eFragment, false);
gl::cullFace(gl::Face::eBack);
while (!glfwWindowShouldClose(m_main_window))
......
......@@ -79,7 +79,7 @@ namespace glare
}
else
{
shader.updateUniformUInt("u_background_texture", 0);
shader.updateUniformPointer("u_background_texture", 0);
shader.updateUniformFloat("u_background_texture_scale", 1);
}
});
......
......@@ -7,6 +7,24 @@ namespace gl
return Error(glGetError());
}
debug_callback_t debug_callback = [](DebugSource source, DebugType type, unsigned id, DebugSeverity severity, std::string message)
{
//empty callback on startup
};
static void GLAPIENTRY baseCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam)
{
const auto func = *reinterpret_cast<const debug_callback_t*>(userParam);
if(func)
func(DebugSource(source), DebugType(type), id, DebugSeverity(severity), std::string(message));
}
void debugMessageCallback(debug_callback_t callback)
{
debug_callback = callback;
glDebugMessageCallback(baseCallback, &debug_callback);
}
void clear(ClearBufferBits bits)
{
glClear(GLbitfield(bits));
......@@ -304,7 +322,7 @@ namespace gl
{
glDeleteTextures(count, textures);
}
void getTextureLevelParameteriv(TextureTarget target, int level, TextureLevelParameter parameter, int *data)
{
glGetTexLevelParameteriv(GLenum(target), level, GLenum(parameter), data);
......@@ -630,7 +648,7 @@ namespace gl
glDeleteQueries(count, ids);
}
void beginQuery(QueryTarget target, unsigned id)
void beginQuery(QueryTarget target, unsigned id)
{
glBeginQuery(GLenum(target), id);
}
......
......@@ -659,8 +659,40 @@ namespace gl
eResultAvailable = GL_QUERY_RESULT_AVAILABLE
};
enum class DebugSource
{
eAPI = GL_DEBUG_SOURCE_API,
eApplication = GL_DEBUG_SOURCE_APPLICATION,
eOther = GL_DEBUG_SOURCE_OTHER,
eShaderCompiler = GL_DEBUG_SOURCE_SHADER_COMPILER,
eThirdParty = GL_DEBUG_SOURCE_THIRD_PARTY,
eWindowSystem = GL_DEBUG_SOURCE_WINDOW_SYSTEM,
};
enum class DebugType
{
eError = GL_DEBUG_TYPE_ERROR,
eDeprecatedBehavior = GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR,
eUndefinedBehavior = GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR,
ePortability = GL_DEBUG_TYPE_PORTABILITY,
ePerformance = GL_DEBUG_TYPE_PERFORMANCE,
eOther = GL_DEBUG_TYPE_OTHER,
eMarker = GL_DEBUG_TYPE_MARKER,
};
enum class DebugSeverity
{