Commit 02866a69 authored by unknown's avatar unknown
Browse files

Added BSFD sampling subroutines

parent f287ffb7
<linespace version="1.0">
<item name="subdivisions" value="100"/>
<item name="subdivisions" value="30"/>
<item name="radial-subdivision" value="20"/>
<item name="generator" value="gpu"/>
</linespace>
......@@ -7,6 +7,9 @@
#include <raytracer/properties/ray_transform.glsl>
#include <raytracer/properties/fresnel.glsl>
subroutine vec3 bsdfSampler(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id);
subroutine(bsdfSampler)
vec3 sampleDiffuse(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
{
bool entering = dot(-ray_in.direction.xyz, vertex.normal.xyz) > 0.f;
......@@ -31,6 +34,7 @@ vec3 sampleDiffuse(const in Material material, const in vec2 random, const in Ve
return diffuse * ONE_OVER_PI;
}
subroutine(bsdfSampler)
vec3 sampleTranslucent(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
{
bool entering = dot(-ray_in.direction, vertex.normal.xyz) > 0.f;
......@@ -59,6 +63,7 @@ vec3 sampleTranslucent(const in Material material, const in vec2 random, const i
return diffuse * ONE_OVER_PI;
}
subroutine(bsdfSampler)
vec3 sampleGlass(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
{
//Needed parameters for refraction and reflection
......@@ -93,6 +98,7 @@ vec3 sampleGlass(const in Material material, const in vec2 random, const in Vert
return fresnel * material.getSpecular(vertex.texcoord).rgb / abs(dot(ray_out.direction, vertex.normal.xyz));
}
subroutine(bsdfSampler)
vec3 sampleRoughGlass(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
{
//Needed parameters for refraction and reflection
......@@ -149,6 +155,7 @@ vec3 sampleRoughGlass(const in Material material, const in vec2 random, const in
return mix(fresnel * material.getSpecular(vertex.texcoord).rgb / abs(dot(ray_out.direction, vertex.normal.xyz)), diffuse * ONE_OVER_PI, roughness);
}
subroutine(bsdfSampler)
vec3 sampleTransparent(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
{
//refract ray.
......@@ -162,6 +169,7 @@ vec3 sampleTransparent(const in Material material, const in vec2 random, const i
return material.getTransparent(vertex.texcoord).xyz / abs(dot(ray_out.direction, vertex.normal.xyz));
}
subroutine(bsdfSampler)
vec3 sampleMirror(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
{
pdf = 1.f;
......@@ -173,6 +181,7 @@ vec3 sampleMirror(const in Material material, const in vec2 random, const in Ver
return material.getSpecular(vertex.texcoord).xyz / abs(dot(ray_out.direction, vertex.normal.xyz));
}
subroutine(bsdfSampler)
vec3 sampleGlossy(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
{
float roughness = material.getRoughness();
......@@ -198,6 +207,7 @@ vec3 sampleGlossy(const in Material material, const in vec2 random, const in Ver
return mix(diffuse*material.getSpecular(vertex.texcoord).xyz / abs(dot(ray_out.direction, vertex.normal.xyz)), diffuse * ONE_OVER_PI, roughness);
}
subroutine(bsdfSampler)
vec3 sampleEmissive(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
{
bsdf_id = 5;
......@@ -209,14 +219,7 @@ vec3 sampleEmissive(const in Material material, const in vec2 random, const in V
return vec3(0);
}
const uint eGlossy = 1 << 0;
const uint eMirror = 1 << 1;
const uint eDiffuse = 1 << 2;
const uint eTransparentGlossy = 1 << 8;
const uint eTransparentMirror = 1 << 9;
const uint eTransparentDiffuse = 1 << 10;
const uint eTransparent = 1 << 11;
const uint eEmissive = 1 << 16;
subroutine uniform bsdfSampler u_bsdf_sample[9];
vec3 sampleBSDF(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
{
......@@ -224,38 +227,18 @@ vec3 sampleBSDF(const in Material material, const in vec2 random, const in Verte
ray_out.px = ray_in.px;
ray_out.py = ray_in.py;
bool rough = material.specular_exponent < 99;
uint bitset = 1; //Glossy by default.
bool transparent = length(material.getTransparent(vertex.texcoord).xyz) >= 0.1;
bool emits = length(material.getEmissive(vertex.texcoord).xyz) >= 0.01;
bitset = 1 << (1 * uint(!rough)); //mirror
bitset = 1 << (2 * uint(material.specular_exponent <= 1)); //glossy;
uint index = rough ? 0 : 1;
index = material.specular_exponent <= 1 ? 2 : index;
bitset = bitset << (8 * uint(length(material.getTransparent(vertex.texcoord).xyz) >= 0.1));
uint mask = uint((bitset & (0x700)) > 0) * uint(material.ior==1);
bitset = mask*(1 << 11) + ((1-mask)*bitset);
index += transparent ? 3 : 0;
index = (transparent && material.ior==1) ? 6 : index;
uint emissive = uint(length(material.getEmissive(vertex.texcoord).xyz) >= 0.01);
bitset = emissive*(1 << 16) + ((1 - emissive)*bitset);
index = emits ? 7 : index;
switch (bitset)
{
default:
case eGlossy:
return material.sampleGlossy(random, vertex, ray_in, ray_out, light_influence, pdf, bsdf_id);
case eMirror:
return material.sampleMirror(random, vertex, ray_in, ray_out, light_influence, pdf, bsdf_id);
case eDiffuse:
return material.sampleDiffuse(random, vertex, ray_in, ray_out, light_influence, pdf, bsdf_id);
case eTransparentGlossy:
return material.sampleRoughGlass(random, vertex, ray_in, ray_out, light_influence, pdf, bsdf_id);
case eTransparentMirror:
return material.sampleGlass(random, vertex, ray_in, ray_out, light_influence, pdf, bsdf_id);
case eTransparentDiffuse:
return material.sampleTranslucent(random, vertex, ray_in, ray_out, light_influence, pdf, bsdf_id);
case eTransparent:
return material.sampleTransparent(random, vertex, ray_in, ray_out, light_influence, pdf, bsdf_id);
case eEmissive:
return material.sampleEmissive(random, vertex, ray_in, ray_out, light_influence, pdf, bsdf_id);
}
return u_bsdf_sample[index](material, random, vertex, ray_in, ray_out, light_influence, pdf, bsdf_id);
}
#endif //!__BDSF_DIFFUSE_GLH
......@@ -114,11 +114,11 @@ namespace glare
//quitPromptDefault(0);
initializeScene(m_current_scene_root / "benchmark_stfd_bunny_diff.dae", 1.f);
//initializeScene(m_current_scene_root / "benchmark_stfd_bunny_diff.dae", 1.f);
//initializeScene(m_current_scene_root / "glass.dae", 1.f);
//initializeScene(m_current_scene_root / "artifact_suzanne_x2_mirror_0r.dae", 1.f);
//initializeScene(m_current_scene_root / "artifact_suzanne_x2_transparent.dae", 1.f);
//initializeScene(m_current_scene_root / "bunny.dae", 1.f);
initializeScene(m_current_scene_root / "bunny.dae", 1.f);
//initializeScene(m_current_scene_root / "kubas.dae", 1.f);
initializeRenderRequirements();
......
......@@ -37,18 +37,46 @@ namespace glare
int num_uniforms;
gl::getProgramiv(m_handle, gl::ProgramParameter::eActiveUniforms, &num_uniforms);
int max_length;
gl::getProgramiv(m_handle, gl::ProgramParameter::eActiveUniformMaxLength, &max_length);
for (int i = 0; i < num_uniforms; ++i) {
UniformInfo data;
int max_length = 200;
char* name = new char[max_length];
gl::getActiveUniform(m_handle, i, max_length, &data.size, &data.type, name);
int length = max_length;
char* name = new char[length];
gl::getActiveUniform(m_handle, i, length, &data.size, &data.type, name);
data.index = i;
data.name = name;
m_uniforms[data.name] = data;
delete[] name;
}
for (auto &&shader : shaders)
{
int num_subroutines;
gl::getProgramStageiv(m_handle, shader->type(), gl::ProgramParameter::eActiveSubroutines, &num_subroutines);
int max_length;
gl::getProgramStageiv(m_handle, shader->type(), gl::ProgramParameter::eActiveSubroutineMaxLength, &max_length);
for (int sr = 0; sr < num_subroutines; ++sr)
{
int length;
char* name = new char[max_length];
gl::getActiveSubroutineName(m_handle, shader->type(), sr, max_length, &length, name);
SubroutineInfo info;
info.index = sr;
info.name = name;
info.shader_type = shader->type();
m_subroutines[info.name].emplace(info.shader_type, info);
Log_Info << "info:name: " << info.name;
delete[] name;
}
}
}
Program::Program(std::shared_ptr<Shader> shader)
......@@ -79,6 +107,26 @@ namespace glare
{
gl::useProgram(m_handle);
}
int Program::subroutineIndex(gl::ShaderType shader_stage, const std::string &name) const
{
if (m_subroutines.count(name) != 0)
{
const auto &map = m_subroutines.at(name);
if (map.count(shader_stage) != 0)
{
return map.at(shader_stage).index;
}
}
return -1;
}
void Program::setSubroutines(gl::ShaderType stage, std::vector<unsigned> indices) const
{
gl::uniformSubroutinesuiv(stage, indices.size(), indices.data());
}
void Program::storageBuffer(const std::string& name, const Buffer<gl::BufferType::eShaderStorage> &buffer) const
{
......
......@@ -24,6 +24,13 @@ namespace glare
gl::UniformType type;
};
struct SubroutineInfo
{
gl::ShaderType shader_type;
std::string name;
unsigned index;
};
const UniformInfo empty_uniform_info{ 0, "", -1 };
class Program
......@@ -50,6 +57,9 @@ namespace glare
template<> void uniform<glm::bvec3>(const std::string &name, const glm::bvec3& data) const;
template<> void uniform<glm::bvec4>(const std::string &name, const glm::bvec4& data) const;
int subroutineIndex(gl::ShaderType shader_stage, const std::string &name) const;
void setSubroutines(gl::ShaderType stage, std::vector<unsigned> indices) const;
// buffers
void storageBuffer(const std::string& name, const Buffer<gl::BufferType::eShaderStorage> &buffer) const;
......@@ -74,6 +84,7 @@ namespace glare
gl::handle::shader_program m_handle;
std::map<std::string, UniformInfo> m_uniforms;
std::map<std::string, std::map<gl::ShaderType, SubroutineInfo>> m_subroutines;
};
template<> void Program::uniform<bool>(const std::string &name, const bool& data) const
......
......@@ -10,7 +10,7 @@ namespace glare
namespace core
{
Shader::Shader(gl::ShaderType type)
: m_handle(std::move(type))
: m_handle(std::move(type)), m_type(type)
{}
Shader::Shader(gl::ShaderType shader_type, const fs::path& path)
......@@ -81,5 +81,9 @@ namespace glare
return m_identifier;
}
const gl::ShaderType Shader::type() const
{
return m_type;
}
}
}
\ No newline at end of file
......@@ -32,10 +32,12 @@ namespace glare
unsigned id() const;
const std::string& identifierName() const;
const gl::ShaderType type() const;
private:
std::string m_identifier;
gl::handle::shader m_handle;
gl::ShaderType m_type;
};
}
}
......
......@@ -92,6 +92,15 @@ namespace glare
m_render_config.clamp_direct = pt_child.find_child_by_attribute("item", "name", "clamp-direct").attribute("value").as_float(8);
m_render_config.clamp_indirect = pt_child.find_child_by_attribute("item", "name", "clamp-indirect").attribute("value").as_float(8);
m_bsdf_subroutines[0] = m_render_shader->subroutineIndex(gl::ShaderType::eCompute, "sampleGlossy");
m_bsdf_subroutines[1] = m_render_shader->subroutineIndex(gl::ShaderType::eCompute, "sampleMirror");
m_bsdf_subroutines[2] = m_render_shader->subroutineIndex(gl::ShaderType::eCompute, "sampleDiffuse");
m_bsdf_subroutines[3] = m_render_shader->subroutineIndex(gl::ShaderType::eCompute, "sampleRoughGlass");
m_bsdf_subroutines[4] = m_render_shader->subroutineIndex(gl::ShaderType::eCompute, "sampleGlass");
m_bsdf_subroutines[5] = m_render_shader->subroutineIndex(gl::ShaderType::eCompute, "sampleTranslucent");
m_bsdf_subroutines[6] = m_render_shader->subroutineIndex(gl::ShaderType::eCompute, "sampleTransparent");
m_bsdf_subroutines[7] = m_render_shader->subroutineIndex(gl::ShaderType::eCompute, "sampleEmissive");
}
void Pathtracer::reset()
......@@ -147,6 +156,7 @@ namespace glare
m_trace_buffer->reserve<Trace>(width * height, gl::BufferUsage::eDynamicCopy);
m_render_target = std::make_unique<core::TextureRGBA_32F>(width, height);
m_color_store = std::make_unique<core::TextureRGBA_32F>(width, height);
m_render_shader->uniform("u_render_target", m_render_target->makeImageResident(gl::Access::eReadWrite));
m_render_shader->uniform("u_color_store", m_color_store->makeImageResident(gl::Access::eReadWrite));
m_render_shader->storageBuffer("trace_buffer", *m_trace_buffer);
......@@ -159,8 +169,9 @@ namespace glare
return *m_render_target;
m_ray_generator->generate(*this);
m_render_shader->use();
m_render_shader->setSubroutines(gl::ShaderType::eCompute, m_bsdf_subroutines);
m_render_shader->uniform("u_render_config.current_sample", m_render_config.current_sample);
m_render_shader->dispatch2d(width, 4, height, 4);
......
......@@ -115,7 +115,9 @@ namespace glare
} m_linespace_config;
std::array<uint8_t, 8> m_bounce_count_thresholds;
std::array<uint8_t, 8> m_ls_bounce_count_thresholds;
std::array<uint8_t, 8> m_ls_bounce_count_thresholds;
std::vector<unsigned> m_bsdf_subroutines = std::vector<unsigned>(9);
std::shared_ptr<SceneCollector> m_collector;
std::unique_ptr<core::TextureRGBA_32F> m_render_target;
......
......@@ -608,6 +608,21 @@ namespace gl
glGetProgramiv(program, GLenum(parameter), out);
}
void getProgramStageiv(unsigned program, ShaderType stage, ProgramParameter parameter, int* out)
{
glGetProgramStageiv(program, GLenum(stage), GLenum(parameter), out);
}
void getActiveSubroutineName(unsigned program, ShaderType stage, unsigned index, int buffer_size, int* length, char* name)
{
glGetActiveSubroutineName(program, GLenum(stage), index, buffer_size, length, name);
}
void uniformSubroutinesuiv(ShaderType stage, size_t count, unsigned* indices)
{
glUniformSubroutinesuiv(GLenum(stage), int(count), indices);
}
void getProgramInfoLog(unsigned program, int max_length, int *length, char *info_log)
{
glGetProgramInfoLog(program, max_length, length, info_log);
......
......@@ -713,7 +713,10 @@ namespace gl
eActiveAttributes = GL_ACTIVE_ATTRIBUTES,
eActiveAttributeMaxLength = GL_ACTIVE_ATTRIBUTE_MAX_LENGTH,
eActiveUniforms = GL_ACTIVE_UNIFORMS,
eActiveUniformMaxLength = GL_ACTIVE_UNIFORM_MAX_LENGTH
eActiveUniformMaxLength = GL_ACTIVE_UNIFORM_MAX_LENGTH,
eActiveSubroutines = GL_ACTIVE_SUBROUTINES,
eActiveSubroutineUniforms = GL_ACTIVE_SUBROUTINE_UNIFORMS,
eActiveSubroutineMaxLength = GL_ACTIVE_SUBROUTINE_MAX_LENGTH,
};
enum class ProgramInterface
......@@ -953,8 +956,12 @@ namespace gl
void attachShader(unsigned program, unsigned shader);
void getProgramiv(unsigned program, ProgramParameter parameter, int* out);
void getProgramStageiv(unsigned program, ShaderType stage, ProgramParameter parameter, int* out);
void getProgramInfoLog(unsigned program, int max_length, int *length, char *info_log);
void getActiveSubroutineName(unsigned program, ShaderType stage, unsigned index, int buffer_size, int* length, char* name);
void uniformSubroutinesuiv(ShaderType stage, size_t count, unsigned* indices);
void dispatchComputeGroupSize(unsigned count_x, unsigned count_y, unsigned count_z, unsigned local_size_x, unsigned local_size_y, unsigned local_size_z);
int getUniformLocation(unsigned program, std::string name);
......
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