Commit 969f57dd authored by Johannes Braun's avatar Johannes Braun
Browse files

Several fixes

parent 3c5c9e1a
...@@ -4,12 +4,12 @@ Size=353,64 ...@@ -4,12 +4,12 @@ Size=353,64
Collapsed=0 Collapsed=0
[Scene] [Scene]
Pos=0,72 Pos=-2,66
Size=352,837 Size=352,837
Collapsed=0 Collapsed=0
[Settings] [Settings]
Pos=1128,-2 Pos=1125,0
Size=311,899 Size=311,899
Collapsed=0 Collapsed=0
<linespace version="1.0"> <linespace version="1.0">
<item name="subdivisions" value="10"/> <item name="subdivisions" value="20"/>
<item name="grid-subdivisions" value="10"/> <item name="grid-subdivisions" value="2"/>
<item name="radial-subdivision" value="50"/> <item name="radial-subdivision" value="50"/>
<item name="generator" value="gpu"/> <item name="generator" value="gpu"/>
</linespace> </linespace>
...@@ -73,6 +73,7 @@ Mesh getMesh(const in Scene scene, int index) ...@@ -73,6 +73,7 @@ Mesh getMesh(const in Scene scene, int index)
bool traverseObjects(const in Scene scene, const in Ray ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min, bool force_bvh = false) bool traverseObjects(const in Scene scene, const in Ray ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min, bool force_bvh = false)
{ {
hit.invalidate();
if(!use_global_bvh) if(!use_global_bvh)
{ {
float current_t = t_min; float current_t = t_min;
...@@ -119,7 +120,7 @@ bool traverseObjects(const in Scene scene, const in Ray ray, const in bool use_f ...@@ -119,7 +120,7 @@ bool traverseObjects(const in Scene scene, const in Ray ray, const in bool use_f
for(;;) for(;;)
{ {
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 ls_index = index.x + index.y * mesh.grid_linespace.grid_resolution.x + index.z * mesh.grid_linespace.grid_resolution.x * mesh.grid_linespace.grid_resolution.y;
int axis = smallestAxis(tnext); int axis = smallestAxis(tnext);
......
...@@ -138,7 +138,7 @@ bool traverseLineSpace(const in Mesh mesh, int index, const in Ray local_ray, co ...@@ -138,7 +138,7 @@ bool traverseLineSpace(const in Mesh mesh, int index, const in Ray local_ray, co
if (mesh.grid_linespace.linespaces[index].line_count == 0) return false; if (mesh.grid_linespace.linespaces[index].line_count == 0) return false;
Ray loc = local_ray; Ray loc = local_ray;
loc.origin += 0.05f * loc.direction; loc.origin += 1e-4f * loc.direction;
if(!loc.intersectsBounds(mesh.grid_linespace.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)
{ {
......
...@@ -10,9 +10,10 @@ ...@@ -10,9 +10,10 @@
layout(local_size_variable) in; layout(local_size_variable) in;
layout(rgba32f) uniform image2D u_render_target; layout(rgba32f) uniform image2D render_target;
uniform int random_seed; uniform int random_seed;
uniform bool use_linespace = false; uniform bool use_linespace = false;
uniform bool random_subpixel = false;
uniform Scene scene; uniform Scene scene;
layout(std430) buffer trace_buffer layout(std430) buffer trace_buffer
...@@ -20,20 +21,15 @@ layout(std430) buffer trace_buffer ...@@ -20,20 +21,15 @@ layout(std430) buffer trace_buffer
Trace traces_data[]; Trace traces_data[];
}; };
uniform struct
{
bool u_random_subpixel; //defaults to false.
} settings;
void main() void main()
{ {
ivec2 target_size = u_render_target.imageSize(); ivec2 target_size = render_target.imageSize();
if (!(int(gl_GlobalInvocationID.x) < target_size.x && int(gl_GlobalInvocationID.y) < target_size.y)) if (!(int(gl_GlobalInvocationID.x) < target_size.x && int(gl_GlobalInvocationID.y) < target_size.y))
return; return;
int id = target_size.x * int(gl_GlobalInvocationID.y) + int(gl_GlobalInvocationID.x); int id = target_size.x * int(gl_GlobalInvocationID.y) + int(gl_GlobalInvocationID.x);
vec2 random = settings.u_random_subpixel ? vec2(0, 0) : rand2D(random_seed + id, target_size.x*target_size.y); vec2 random = random_subpixel ? rand2D(random_seed + id, target_size.x*target_size.y) : vec2(0, 0);
traces_data[id].ray = scene.camera.getRayFromPixel(vec2(gl_GlobalInvocationID.xy), random, vec2(target_size)); traces_data[id].ray = scene.camera.getRayFromPixel(vec2(gl_GlobalInvocationID.xy), random, vec2(target_size));
traces_data[id].hit.invalidate(); traces_data[id].hit.invalidate();
scene.nearestIntersection(traces_data[id].ray, traces_data[id].hit, !use_linespace); scene.nearestIntersection(traces_data[id].ray, traces_data[id].hit, !use_linespace);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <util/tracing/scene.glsl> #include <util/tracing/scene.glsl>
#include <util/math/random.glsl> #include <util/math/random.glsl>
layout(rgba32f) uniform image2DMS u_gbuffer_texture_01; layout(rgba32f) uniform image2D u_gbuffer_texture_01;
layout(rgba32f) uniform image2D u_render_target; layout(rgba32f) uniform image2D u_render_target;
uniform int random_seed; uniform int random_seed;
uniform int samples; uniform int samples;
...@@ -28,7 +28,7 @@ void main() ...@@ -28,7 +28,7 @@ void main()
ivec2 target_size = u_render_target.imageSize(); ivec2 target_size = u_render_target.imageSize();
vec2 random = rand2D(random_seed + int(id), target_size.x * target_size.y); vec2 random = rand2D(random_seed + int(id), target_size.x * target_size.y);
vec2 pixel = vec2(id%target_size.x, id/target_size.x) + random; vec2 pixel = vec2(id%target_size.x, id/target_size.x) + random;
vec4 texel_01 = u_gbuffer_texture_01.imageLoad(ivec2(pixel), int(random.x * samples)); vec4 texel_01 = u_gbuffer_texture_01.imageLoad(ivec2(pixel));
traces_data[id].ray = scene.camera.getRayFromPixel(pixel, random, vec2(target_size)); traces_data[id].ray = scene.camera.getRayFromPixel(pixel, random, vec2(target_size));
traces_data[id].hit.invalidate(); traces_data[id].hit.invalidate();
......
...@@ -7,9 +7,9 @@ layout(triangle_strip, max_vertices = 3) out; ...@@ -7,9 +7,9 @@ layout(triangle_strip, max_vertices = 3) out;
#include <util/scene/mesh.glsl> #include <util/scene/mesh.glsl>
#include <util/math/geometry.glsl> #include <util/math/geometry.glsl>
#include <util/tracing/scene.glsl>
#include <pathtracer/buffers.glsl> Scene scene;
uniform mat4 u_mvp; uniform mat4 u_mvp;
uniform uint u_mesh_id; uniform uint u_mesh_id;
...@@ -21,7 +21,7 @@ void main() ...@@ -21,7 +21,7 @@ void main()
{ {
triangle_id = int(gl_in[0].gl_Position.x); triangle_id = int(gl_in[0].gl_Position.x);
Mesh mesh = meshes_data[u_mesh_id]; Mesh mesh = scene.meshes[u_mesh_id];
Triangle current = mesh.triangles[triangle_id]; Triangle current = mesh.triangles[triangle_id];
......
...@@ -36,7 +36,6 @@ uniform int sampels_max = 80000; ...@@ -36,7 +36,6 @@ uniform int sampels_max = 80000;
uniform int samples_per_frame = 1; uniform int samples_per_frame = 1;
layout(rgba32f) uniform image2D render_target; layout(rgba32f) uniform image2D render_target;
layout(std430) buffer trace_buffer layout(std430) buffer trace_buffer
{ {
Trace traces_data[]; Trace traces_data[];
...@@ -76,20 +75,6 @@ struct Bounce ...@@ -76,20 +75,6 @@ struct Bounce
//// ////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
int iArray(const in int array[num_effects], int index)
{
for(int i=0; i<num_effects; ++i)
if(i==index)
return array[i];
}
int iArrayComp(const in int array1[num_effects], const in int array2[num_effects], int index)
{
for(int i=0; i<num_effects; ++i)
if(i==index)
return array1[i] < array2[i] ? 1 : (array1[i] > array2[i] ? -1 : 0);
}
subroutine uniform lightSample sampleLightRoutines[4]; subroutine uniform lightSample sampleLightRoutines[4];
LightData sampleLight(const in Light light, const in Vertex vertex, const in vec2 random_sample) LightData sampleLight(const in Light light, const in Vertex vertex, const in vec2 random_sample)
{ {
...@@ -108,6 +93,13 @@ LightData sampleLight(const in Light light, const in Vertex vertex, const in vec ...@@ -108,6 +93,13 @@ LightData sampleLight(const in Light light, const in Vertex vertex, const in vec
return result; return result;
} }
int iArrayComp(const in int array1[num_effects], const in int array2[num_effects], int index)
{
for(int i=0; i<num_effects; ++i)
if(i==index)
return array1[i] < array2[i] ? 1 : (array1[i] > array2[i] ? -1 : 0);
}
bool shouldUseBvh(const in Bounce bounce) bool shouldUseBvh(const in Bounce bounce)
{ {
return (bounce.pdf_accumulation > (1-linespace_accuracy)) return (bounce.pdf_accumulation > (1-linespace_accuracy))
...@@ -153,8 +145,6 @@ bool shade(inout Bounce bounce) ...@@ -153,8 +145,6 @@ bool shade(inout Bounce bounce)
BSDFResult bsdf_result = material.computeBSDF(random_sample, vertex, bounce.ray); BSDFResult bsdf_result = material.computeBSDF(random_sample, vertex, bounce.ray);
bounce.path_distance += distance(bounce.ray.origin, vertex.position.xyz);
bool exceeds_bounces = false; bool exceeds_bounces = false;
for(int i=0; i<num_effects; ++i) for(int i=0; i<num_effects; ++i)
{ {
...@@ -166,6 +156,7 @@ bool shade(inout Bounce bounce) ...@@ -166,6 +156,7 @@ bool shade(inout Bounce bounce)
} }
} }
bounce.path_distance += distance(bounce.ray.origin, vertex.position.xyz);
bounce.bsdf_id = int(bsdf_result.bsdf_id); bounce.bsdf_id = int(bsdf_result.bsdf_id);
bounce.pdf_accumulation *= bsdf_result.probability_density; bounce.pdf_accumulation *= bsdf_result.probability_density;
bounce.ray = bsdf_result.generated_ray; bounce.ray = bsdf_result.generated_ray;
...@@ -199,13 +190,6 @@ bool shade(inout Bounce bounce) ...@@ -199,13 +190,6 @@ bool shade(inout Bounce bounce)
return true; return true;
} }
void trace(inout Bounce bounce)
{
//Invalidate before intersection test so that we don't have to conditionally invalidate afterwards
bounce.hit.invalidate();
scene.nearestIntersection(bounce.ray, bounce.hit, shouldUseBvh(bounce));
}
void main() void main()
{ {
ivec2 target_size = render_target.imageSize(); ivec2 target_size = render_target.imageSize();
...@@ -215,12 +199,9 @@ void main() ...@@ -215,12 +199,9 @@ void main()
if (!(int(gl_GlobalInvocationID.x) < target_size.x && int(gl_GlobalInvocationID.y) < target_size.y)) if (!(int(gl_GlobalInvocationID.x) < target_size.x && int(gl_GlobalInvocationID.y) < target_size.y))
return; return;
// Get the trace generated by the external primary-ray-generator and initialize the Bounce struct.
Trace current = traces_data[id];
Bounce bounce; Bounce bounce;
bounce.hit = current.hit; bounce.hit = traces_data[id].hit;
bounce.ray = current.ray; bounce.ray = traces_data[id].ray;
bounce.path_distance = 0; bounce.path_distance = 0;
bounce.pdf_accumulation = 1.f; bounce.pdf_accumulation = 1.f;
bounce.bounce_amount = int[num_effects](0,0,0,0); bounce.bounce_amount = int[num_effects](0,0,0,0);
...@@ -232,7 +213,7 @@ void main() ...@@ -232,7 +213,7 @@ void main()
// continue with first-trace-then-shade until either shade returns false (not hitting something or constribution too low) // continue with first-trace-then-shade until either shade returns false (not hitting something or constribution too low)
// or we exceed the global bounce limit. // or we exceed the global bounce limit.
for (bounce.count = 1; bounce.shade() && bounce.count <= bounce_count; ++bounce.count) { for (bounce.count = 1; bounce.shade() && bounce.count <= bounce_count; ++bounce.count) {
bounce.trace(); scene.nearestIntersection(bounce.ray, bounce.hit, shouldUseBvh(bounce));
} }
ivec2 pixel = ivec2(bounce.ray.px, bounce.ray.py); ivec2 pixel = ivec2(bounce.ray.px, bounce.ray.py);
......
...@@ -529,7 +529,7 @@ void drawSettingsWindow() ...@@ -529,7 +529,7 @@ void drawSettingsWindow()
static auto effectBounces = [](const std::string &label, raytrace::Effect effect) static auto effectBounces = [](const std::string &label, raytrace::Effect effect)
{ {
if (int val = pathtracer->getBounceThreshold(effect); ImGui::DragInt(label.c_str(), &val, 0.1f, 0, 255)) if (int val = pathtracer->getBounceThreshold(effect); ImGui::DragInt(label.c_str(), &val, 0.1f, 0, 255))
pathtracer->setBounceThreshold(effect, static_cast<uint8_t>(val)); pathtracer->setBounceThreshold(effect, val);
}; };
effectBounces("Diffusion", raytrace::Effect::eDiffusion); effectBounces("Diffusion", raytrace::Effect::eDiffusion);
...@@ -577,7 +577,7 @@ void drawSettingsWindow() ...@@ -577,7 +577,7 @@ void drawSettingsWindow()
static auto bounceControl = [](const std::string &label, raytrace::Effect effect) static auto bounceControl = [](const std::string &label, raytrace::Effect effect)
{ {
if (int val = pathtracer->getLinespaceBounces(effect); ImGui::DragInt(label.c_str(), &val, 0.1f, 0, pathtracer->getLinespaceBounces(effect))) if (int val = pathtracer->getLinespaceBounces(effect); ImGui::DragInt(label.c_str(), &val, 0.1f, 0, pathtracer->getLinespaceBounces(effect)))
pathtracer->setLinespaceBounces(effect, static_cast<uint8_t>(val)); pathtracer->setLinespaceBounces(effect, val);
}; };
bounceControl("Diffusion", raytrace::Effect::eDiffusion); bounceControl("Diffusion", raytrace::Effect::eDiffusion);
......
...@@ -12,15 +12,6 @@ ...@@ -12,15 +12,6 @@
namespace glare::raytrace namespace glare::raytrace
{ {
CameraCollector::CameraCollector()
{
}
CameraCollector::~CameraCollector()
{
}
void CameraCollector::clear(const math::Flags &flags) void CameraCollector::clear(const math::Flags &flags)
{ {
...@@ -50,9 +41,9 @@ namespace glare::raytrace ...@@ -50,9 +41,9 @@ namespace glare::raytrace
} }
void CameraCollector::apply(core::Program &program) void CameraCollector::apply(core::Program &program, const std::string& uniform_name)
{ {
if(!m_cameras.empty()) if(!m_cameras.empty())
program.uniformStruct("scene.camera", m_cameras[m_active_camera]); program.uniformStruct(uniform_name + ".camera", m_cameras[m_active_camera]);
} }
} }
...@@ -16,19 +16,17 @@ namespace glare::raytrace ...@@ -16,19 +16,17 @@ namespace glare::raytrace
class CameraCollector : public CollectorUnit class CameraCollector : public CollectorUnit
{ {
public: public:
CameraCollector(); CameraCollector() = default;
CameraCollector(CameraCollector& other) = default; CameraCollector(CameraCollector& other) = default;
CameraCollector(CameraCollector&& other) = default; CameraCollector(CameraCollector&& other) = default;
CameraCollector& operator=(CameraCollector& other) = default; CameraCollector& operator=(CameraCollector& other) = default;
CameraCollector& operator=(CameraCollector&& other) = default; CameraCollector& operator=(CameraCollector&& other) = default;
~CameraCollector() override;
void clear(const math::Flags &flags) override; void clear(const math::Flags &flags) override;
void collect(const math::Flags &flags, const core::SceneNode &node) override; void collect(const math::Flags &flags, const core::SceneNode &node) override;
void build(const math::Flags &flags) override; void build(const math::Flags &flags) override;
void apply(core::Program &program) override; void apply(core::Program &program, const std::string& uniform_name) override;
private: private:
unsigned m_active_camera = 0; unsigned m_active_camera = 0;
......
...@@ -11,9 +11,6 @@ ...@@ -11,9 +11,6 @@
namespace glare::raytrace namespace glare::raytrace
{ {
LightCollector::LightCollector() {}
LightCollector::~LightCollector() {}
void LightCollector::clear(const math::Flags &flags) void LightCollector::clear(const math::Flags &flags)
{ {
if (flags & DirtyFlags::eLight) if (flags & DirtyFlags::eLight)
...@@ -39,9 +36,9 @@ namespace glare::raytrace ...@@ -39,9 +36,9 @@ namespace glare::raytrace
} }
} }
void LightCollector::apply(core::Program &program) void LightCollector::apply(core::Program &program, const std::string& uniform_name)
{ {
program.uniform("scene.lights", m_lights.empty() ? 0 : m_light_buffer.makeResident(gl::Access::eReadOnly)); program.uniform(uniform_name + ".lights", m_lights.empty() ? 0 : m_light_buffer.makeResident(gl::Access::eReadOnly));
program.uniform("scene.num_lights", static_cast<int>(m_lights.size())); program.uniform(uniform_name + ".num_lights", static_cast<int>(m_lights.size()));
} }
} }
\ No newline at end of file
...@@ -17,19 +17,17 @@ namespace glare::raytrace ...@@ -17,19 +17,17 @@ namespace glare::raytrace
class LightCollector : public CollectorUnit class LightCollector : public CollectorUnit
{ {
public: public:
LightCollector(); LightCollector() = default;
LightCollector(LightCollector& other) = default; LightCollector(LightCollector& other) = default;
LightCollector(LightCollector&& other) = default; LightCollector(LightCollector&& other) = default;
LightCollector& operator=(LightCollector& other) = default; LightCollector& operator=(LightCollector& other) = default;
LightCollector& operator=(LightCollector&& other) = default; LightCollector& operator=(LightCollector&& other) = default;
~LightCollector() override;
void clear(const math::Flags &flags) override; void clear(const math::Flags &flags) override;
void collect(const math::Flags &flags, const core::SceneNode &node) override; void collect(const math::Flags &flags, const core::SceneNode &node) override;
void build(const math::Flags &flags) override; void build(const math::Flags &flags) override;
void apply(core::Program &program) override; void apply(core::Program &program, const std::string& uniform_name) override;
private: private:
core::Buffer m_light_buffer; core::Buffer m_light_buffer;
......
...@@ -79,12 +79,12 @@ namespace glare::raytrace ...@@ -79,12 +79,12 @@ namespace glare::raytrace
return m_use_bvh; return m_use_bvh;
} }
void MeshCollector::apply(core::Program &program) void MeshCollector::apply(core::Program &program, const std::string& uniform_name)
{ {
program.uniform("scene.meshes", m_meshes.empty() ? 0 : m_mesh_buffer.makeResident(gl::Access::eReadOnly)); program.uniform(uniform_name + ".meshes", m_meshes.empty() ? 0 : m_mesh_buffer.makeResident(gl::Access::eReadOnly));
program.uniform("scene.bvh_nodes", m_global_bvh.nodes().empty() ? 0 : m_global_bvh.buffer().makeResident(gl::Access::eReadOnly)); program.uniform(uniform_name + ".bvh_nodes", m_global_bvh.nodes().empty() ? 0 : m_global_bvh.buffer().makeResident(gl::Access::eReadOnly));
program.uniform("scene.num_meshes", static_cast<int>(m_meshes.size())); program.uniform(uniform_name + ".num_meshes", static_cast<int>(m_meshes.size()));
program.uniform("scene.global_bvh", m_use_bvh); program.uniform(uniform_name + ".global_bvh", m_use_bvh);
} }
void MeshCollector::collectMeshRenderer(std::shared_ptr<core::MeshDrawable> mesh_renderer) void MeshCollector::collectMeshRenderer(std::shared_ptr<core::MeshDrawable> mesh_renderer)
...@@ -157,7 +157,7 @@ namespace glare::raytrace ...@@ -157,7 +157,7 @@ namespace glare::raytrace
size_t id = mesh_ids[i]; size_t id = mesh_ids[i];
m_id_mapping[id] = i; m_id_mapping[id] = i;
const auto &collector = m_local_collectors[id]; const auto &collector = m_local_collectors[id];
m_meshes[i] = collector.collector->makeMesh(m_material_buffer.makeResident(gl::Access::eReadOnly) + static_cast<uint64_t>(m_material_filter[collector.collector->materialID()]), collector.transform); m_meshes[i] = collector.collector->makeMesh(m_material_buffer.makeResident(gl::Access::eReadOnly) + sizeof(Material) * static_cast<uint64_t>(m_material_filter[collector.collector->materialID()]), collector.transform);
m_meshes[i].id = i; m_meshes[i].id = i;
mesh_ids[i] = i; mesh_ids[i] = i;
} }
......
...@@ -24,13 +24,12 @@ namespace glare::raytrace ...@@ -24,13 +24,12 @@ namespace glare::raytrace
MeshCollector(MeshCollector&& other) = default; MeshCollector(MeshCollector&& other) = default;
MeshCollector& operator=(MeshCollector& other) = default; MeshCollector& operator=(MeshCollector& other) = default;
MeshCollector& operator=(MeshCollector&& other) = default; MeshCollector& operator=(MeshCollector&& other) = default;
~MeshCollector() override = default;
void clear(const math::Flags &flags) override; void clear(const math::Flags &flags) override;
void collect(const math::Flags &flags, const core::SceneNode &node) override; void collect(const math::Flags &flags, const core::SceneNode &node) override;
void build(const math::Flags &flags) override; void build(const math::Flags &flags) override;
void apply(core::Program &program) override; void apply(core::Program &program, const std::string& uniform_name) override;
const std::map<size_t, InstancedCollector>& localCollectors() const; const std::map<size_t, InstancedCollector>& localCollectors() const;
const std::map<size_t, size_t>& idMapping() const; const std::map<size_t, size_t>& idMapping() const;
......
...@@ -10,9 +10,6 @@ ...@@ -10,9 +10,6 @@
namespace glare::raytrace namespace glare::raytrace
{ {
SkyboxCollector::SkyboxCollector() {}
SkyboxCollector::~SkyboxCollector() {}
void SkyboxCollector::collect(const math::Flags &flags, const core::SceneNode &node) void SkyboxCollector::collect(const math::Flags &flags, const core::SceneNode &node)
{ {
if (flags & DirtyFlags::eSkybox) if (flags & DirtyFlags::eSkybox)
...@@ -23,16 +20,16 @@ namespace glare::raytrace ...@@ -23,16 +20,16 @@ namespace glare::raytrace
} }
} }
void SkyboxCollector::apply(core::Program &program) void SkyboxCollector::apply(core::Program &program, const std::string& uniform_name)
{ {
if (m_skybox) if (m_skybox)
{ {
program.uniformStruct("scene.environment", *m_skybox); program.uniformStruct(uniform_name + ".environment", *m_skybox);
} }
else else
{ {
program.uniform("scene.environment.color", glm::vec4(0.7f, 0.9f, 0.97f, 1)); program.uniform(uniform_name + ".environment.color", glm::vec4(0.7f, 0.9f, 0.97f, 1));
program.uniform("scene.environment.has_cubemap", 0); program.uniform(uniform_name + ".environment.has_cubemap", 0);
} }
} }