Commit af30eccc authored by unknown's avatar unknown
Browse files

Simplified Subroutine usage (one-method-binding)

parent 02866a69
<linespace version="1.0">
<item name="subdivisions" value="30"/>
<item name="radial-subdivision" value="20"/>
<item name="subdivisions" value="10"/>
<item name="radial-subdivision" value="10"/>
<item name="generator" value="gpu"/>
</linespace>
......@@ -136,22 +136,27 @@ bool shade(int id, inout vec3 radiance, uint bounce, out uint bsdf_id)
BufferLight light = b_lights[int(floor(random_sample.x * b_lights.length()))];
//Shadow test
//float light_distance;
Ray shadow_test;// = light.makeShadowRay(vertex, random_sample, light_distance);
vec3 light_color;
float light_distance;
Ray shadow_test = light.makeShadowRay(vertex, random_sample, light_distance);
bool use_bvh = (trace.properties.shadow_importance > (1-u_linespace_properties.shadow_quality))
&& (b_traces[id].getBounceAmount(bsdf_id) < getLSBounceThreshold(bsdf_id))
&& b_traces[id].properties.travelled_distance < u_linespace_properties.distance_threshold;
if (!shadow_test.intersectsAny(light_distance, use_bvh))
bool success = sampleLight(light, vertex, random_sample, shadow_test, light_distance, light_color);
if (success && !shadow_test.intersectsAny(light_distance, use_bvh))
{
float angle = angle(shadow_test, vertex);
float brightness;
vec3 light_color = light.sampleColor(shadow_test, light_distance, brightness);
brightness *= angle;
if(brightness > 1e-5f) {
writeColorStore(ray, light_color * light_influence * radiance * brightness, clamp_color_max);
}
// float angle = angle(shadow_test, vertex, light_color);
// float brightness;
// vec3 light_color = light.sampleColor(shadow_test, light_distance, brightness);
// //brightness *= angle;
//if(brightness > 1e-5f) {
writeColorStore(ray, light_color * light_influence * radiance, clamp_color_max);
// }
}
}
......
......@@ -219,7 +219,7 @@ vec3 sampleEmissive(const in Material material, const in vec2 random, const in V
return vec3(0);
}
subroutine uniform bsdfSampler u_bsdf_sample[9];
subroutine uniform bsdfSampler u_bsdf_sample[8];
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)
{
......
......@@ -5,6 +5,29 @@
#include <raytracer/utilities.glsl>
#include <raytracer/random.glsl>
subroutine bool lightSample(const in BufferLight light, const in Vertex vertex, const in vec2 random_sample, out Ray shadow_ray, out float light_distance, out vec3 light_color);
subroutine(lightSample)
bool samplePoint(const in BufferLight light, const in Vertex vertex, const in vec2 random_sample, out Ray shadow_ray, out float light_distance, out vec3 light_color)
{
vec3 direction = (light.position.xyz + randUniformSphere(random_sample)*light.data[0]) - vertex.position.xyz;
shadow_ray.origin = vertex.position.xyz + 1e-5*vertex.normal.xyz;
shadow_ray.direction = normalize(direction);
light_distance = length(direction);
light_color = light.color.rgb * attenuation(light_distance, light.constant, light.linear, light.quadratic) * angle(shadow_ray, vertex);
return length(light_color) > 0.001f;
}
subroutine uniform lightSample u_light_sample[1];
bool sampleLight(const in BufferLight light, const in Vertex vertex, const in vec2 random_sample, out Ray shadow_ray, out float light_distance, out vec3 light_color)
{
return u_light_sample[0](light, vertex, random_sample, shadow_ray, light_distance, light_color);
}
Ray makeShadowRay(const in BufferLight light, const in Vertex vertex, const in vec2 random_sample, out float distance)
{
Ray to_light;
......
......@@ -96,45 +96,49 @@ bool evaluateColor(const in vec4 color)
return length(color.rgb) > 0.0001f;
}
bool sampleLight(const in LightWithShadowmap light_and_map, const in vec3 position, const in vec3 normal, const in vec3 camera, out vec3 point_to_light, out vec4 color)
subroutine bool lightSample(const in LightWithShadowmap light_and_map, const in vec3 position, const in vec3 normal, const in vec3 camera, out vec3 point_to_light, out vec4 color);
subroutine(lightSample)
bool samplePoint(const in LightWithShadowmap light_and_map, const in vec3 position, const in vec3 normal, const in vec3 camera, out vec3 point_to_light, out vec4 color)
{
const BufferLight light = light_and_map.light;
float attenuation;
float dist;
switch(light.data.light_type)
{
case 0:
//point light
point_to_light = light.position.xyz - position.xyz;
color = vec4(light.fullAttenuation(length(point_to_light))*light.color.rgb, 1);
return evaluateColor(color);
case 1:
//spot light
point_to_light = light.position.xyz - position.xyz;
float angle_dot = max(dot(normalize(-point_to_light), normalize(light.direction.xyz)), 0.0);
float attenuation = (1-smoothstep(cos(light.data.params[0]), cos(light.data.params[1]), angle_dot)) * light.fullAttenuation(length(point_to_light));
color = vec4(attenuation * light.color.rgb, 1);
return evaluateColor(color);
case 2:
//directional light
point_to_light = normalize(-light.direction.xyz);
float darkening = calculateShadowMapDarkening(position, normalize(point_to_light), normal, camera, light_and_map);
color = vec4(darkening * light.color.rgb, 1);
return evaluateColor(color);
case 3:
//ambient light
color = light.color;
return false;
default:
break;
}
point_to_light = light_and_map.light.position.xyz - position.xyz;
color = vec4(light_and_map.light.fullAttenuation(length(point_to_light))*light_and_map.light.color.rgb, 1);
return evaluateColor(color);
}
subroutine(lightSample)
bool sampleSpot(const in LightWithShadowmap light_and_map, const in vec3 position, const in vec3 normal, const in vec3 camera, out vec3 point_to_light, out vec4 color)
{
point_to_light = light_and_map.light.position.xyz - position.xyz;
float angle_dot = max(dot(normalize(-point_to_light), normalize(light_and_map.light.direction.xyz)), 0.0);
float attenuation = (1-smoothstep(cos(light_and_map.light.data.params[0]), cos(light_and_map.light.data.params[1]), angle_dot)) * light_and_map.light.fullAttenuation(length(point_to_light));
color = vec4(attenuation * light_and_map.light.color.rgb, 1);
return evaluateColor(color);
}
subroutine(lightSample)
bool sampleDirectional(const in LightWithShadowmap light_and_map, const in vec3 position, const in vec3 normal, const in vec3 camera, out vec3 point_to_light, out vec4 color)
{
point_to_light = normalize(-light_and_map.light.direction.xyz);
float darkening = calculateShadowMapDarkening(position, normalize(point_to_light), normal, camera, light_and_map);
color = vec4(darkening * light_and_map.light.color.rgb, 1);
return evaluateColor(color);
}
subroutine(lightSample)
bool sampleAmbient(const in LightWithShadowmap light_and_map, const in vec3 position, const in vec3 normal, const in vec3 camera, out vec3 point_to_light, out vec4 color)
{
color = light_and_map.light.color;
return false;
}
subroutine uniform lightSample u_light_sample[4];
bool sampleLight(const in LightWithShadowmap light_and_map, const in vec3 position, const in vec3 normal, const in vec3 camera, out vec3 point_to_light, out vec4 color)
{
return u_light_sample[light_and_map.light.data.light_type % 4](light_and_map, position, normal, camera, point_to_light, color);
}
vec4 phong(const in LightWithShadowmap light_and_map, const in vec3 position, const in vec3 normal, const in vec3 camera, const in vec4 diffuse, const in vec4 specular, float shininess, bool metallic = false)
{
vec4 color = vec4(0, 0, 0, 1);
......
......@@ -54,6 +54,7 @@ namespace glare
for (auto &&shader : shaders)
{
m_shader_stages.push_back(shader->type());
int num_subroutines;
gl::getProgramStageiv(m_handle, shader->type(), gl::ProgramParameter::eActiveSubroutines, &num_subroutines);
int max_length;
......@@ -77,6 +78,8 @@ namespace glare
delete[] name;
}
}
Log_Hint << "SUBROUTINES " << m_subroutines.size();
}
Program::Program(std::shared_ptr<Shader> shader)
......@@ -106,6 +109,17 @@ namespace glare
void Program::use() const
{
gl::useProgram(m_handle);
if (!m_subroutine_bindings.empty())
{
for (const auto& stage_routines : m_subroutine_bindings)
{
if (!stage_routines.second.empty())
{
setSubroutines(stage_routines.first, stage_routines.second);
}
}
}
}
int Program::subroutineIndex(gl::ShaderType shader_stage, const std::string &name) const
......@@ -127,6 +141,17 @@ namespace glare
{
gl::uniformSubroutinesuiv(stage, indices.size(), indices.data());
}
void Program::bindSubroutine(gl::ShaderType stage, const std::string& uniform, const std::string& subroutine)
{
int location = gl::getSubroutineUniformLocation(m_handle, stage, uniform);
if (location >= 0) {
auto &&list = m_subroutine_bindings[stage];
list.resize(glm::max(int(list.size()), location+1));
list[location] = subroutineIndex(stage, subroutine);
}
}
void Program::storageBuffer(const std::string& name, const Buffer<gl::BufferType::eShaderStorage> &buffer) const
{
......
......@@ -57,8 +57,7 @@ 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;
void bindSubroutine(gl::ShaderType stage, const std::string& uniform, const std::string& subroutine);
// buffers
void storageBuffer(const std::string& name, const Buffer<gl::BufferType::eShaderStorage> &buffer) const;
......@@ -76,6 +75,9 @@ namespace glare
private:
int subroutineIndex(gl::ShaderType shader_stage, const std::string &name) const;
void setSubroutines(gl::ShaderType stage, std::vector<unsigned> indices) const;
void uniformUpdate(gl::UniformType type, unsigned location, const void* data) const;
unsigned invocations(unsigned global, unsigned local);
......@@ -85,6 +87,8 @@ 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;
std::vector<gl::ShaderType> m_shader_stages;
std::map<gl::ShaderType, std::vector<unsigned>> m_subroutine_bindings;
};
template<> void Program::uniform<bool>(const std::string &name, const bool& data) const
......
......@@ -44,6 +44,11 @@ namespace glare
m_texture_renderer->shader().uniform("screen.width", m_width);
m_texture_renderer->shader().uniform("screen.height", m_height);
m_texture_renderer->shader().uniform("u_samples", m_gbuffer_framebuffer->samples());
m_texture_renderer->shader().bindSubroutine(gl::ShaderType::eFragment, "u_light_sample[0]", "samplePoint");
m_texture_renderer->shader().bindSubroutine(gl::ShaderType::eFragment, "u_light_sample[1]", "sampleSpot");
m_texture_renderer->shader().bindSubroutine(gl::ShaderType::eFragment, "u_light_sample[2]", "sampleDirectional");
m_texture_renderer->shader().bindSubroutine(gl::ShaderType::eFragment, "u_light_sample[3]", "sampleAmbient");
}
GBuffer::~GBuffer()
......
......@@ -31,7 +31,7 @@ namespace glare
{
}
const Program& TextureRenderer::shader() const
Program& TextureRenderer::shader()
{
return *m_shader;
}
......
......@@ -41,7 +41,7 @@ namespace glare
void draw(unsigned samples = 1) const;
const Program& shader() const;
Program& shader();
void addPreDrawCallback(std::function<void(const Program &shader)> callback)
{
......
......@@ -92,15 +92,6 @@ 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()
......@@ -143,6 +134,16 @@ namespace glare
m_linespace_config.bounce_thresholds |= (m_ls_bounce_count_thresholds[i] & 0xf) << (4 * i);
}
m_render_shader->uniform("u_linespace_properties.bounce_thresholds", m_linespace_config.bounce_thresholds);
m_render_shader->bindSubroutine(gl::ShaderType::eCompute, "u_bsdf_sample[0]", "sampleGlossy");
m_render_shader->bindSubroutine(gl::ShaderType::eCompute, "u_bsdf_sample[1]", "sampleMirror");
m_render_shader->bindSubroutine(gl::ShaderType::eCompute, "u_bsdf_sample[2]", "sampleDiffuse");
m_render_shader->bindSubroutine(gl::ShaderType::eCompute, "u_bsdf_sample[3]", "sampleRoughGlass");
m_render_shader->bindSubroutine(gl::ShaderType::eCompute, "u_bsdf_sample[4]", "sampleGlass");
m_render_shader->bindSubroutine(gl::ShaderType::eCompute, "u_bsdf_sample[5]", "sampleTranslucent");
m_render_shader->bindSubroutine(gl::ShaderType::eCompute, "u_bsdf_sample[6]", "sampleTransparent");
m_render_shader->bindSubroutine(gl::ShaderType::eCompute, "u_bsdf_sample[7]", "sampleEmissive");
m_render_shader->bindSubroutine(gl::ShaderType::eCompute, "u_light_sample[0]", "samplePoint");
}
const core::TextureRGBA_32F &Pathtracer::render(uint32_t width, uint32_t height)
......@@ -171,7 +172,6 @@ namespace glare
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);
......
......@@ -117,7 +117,7 @@ namespace glare
std::array<uint8_t, 8> m_bounce_count_thresholds;
std::array<uint8_t, 8> m_ls_bounce_count_thresholds;
std::vector<unsigned> m_bsdf_subroutines = std::vector<unsigned>(9);
std::vector<unsigned> m_subroutines;
std::shared_ptr<SceneCollector> m_collector;
std::unique_ptr<core::TextureRGBA_32F> m_render_target;
......
......@@ -623,6 +623,11 @@ namespace gl
glUniformSubroutinesuiv(GLenum(stage), int(count), indices);
}
int getSubroutineUniformLocation(unsigned program, ShaderType type, const std::string &name)
{
return glGetSubroutineUniformLocation(program, GLenum(type), name.c_str());
}
void getProgramInfoLog(unsigned program, int max_length, int *length, char *info_log)
{
glGetProgramInfoLog(program, max_length, length, info_log);
......
......@@ -961,6 +961,7 @@ namespace gl
void getActiveSubroutineName(unsigned program, ShaderType stage, unsigned index, int buffer_size, int* length, char* name);
void uniformSubroutinesuiv(ShaderType stage, size_t count, unsigned* indices);
int getSubroutineUniformLocation(unsigned program, ShaderType type, const std::string &name);
void dispatchComputeGroupSize(unsigned count_x, unsigned count_y, unsigned count_z, unsigned local_size_x, unsigned local_size_y, unsigned local_size_z);
......
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