Commit a89c0234 authored by unknown's avatar unknown
Browse files

Added preferences for ls bounce thresholds

parent 35bccd7c
#ifndef __BSDF_DIFFUSE_GLH
#define __BDSF_DIFFUSE_GLH
#include <raytracer/basic_structs.glh>
#include <raytracer/random.glh>
#include <raytracer/utilities.glh>
#include <bsdf/ray_transform.glh>
#include <bsdf/fresnel.glh>
vec3 bsdf__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)
{
bool entering = dot(-ray_in.direction.xyz, vertex.normal.xyz) > 0.f;
vec3 hemi = randCosineHemisphere(random.x, random.y);
ray_out.direction.xyz = normalize(localToWorldNormal(entering ? hemi : -hemi, vertex.normal.xyz));
pdf = abs(dot(ray_out.direction, vertex.normal)) * ONE_OVER_PI;
if (pdf == 0.f)
{
return vec3(0.f);
}
ray_out.origin = vertex.position + 1e-5 * -ray_in.direction;
vec3 diffuse = material__getDiffuse(material, vertex.texcoord).xyz;
light_influence = diffuse * ONE_OVER_PI;
return diffuse * ONE_OVER_PI;
}
vec3 bsdf__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)
{
bool entering = dot(-ray_in.direction, vertex.normal) > 0.f;
vec3 hemi = randCosineHemisphere(random.x, random.y);
/*if (entering) {
light_influence = vec3(1, 0, 0);
}*/
ray_out.direction.xyz =localToWorldNormal(hemi, (entering ? -1 : 1) * vertex.normal.xyz);
pdf = abs(dot(ray_out.direction, vertex.normal)) * ONE_OVER_PI;
ray_out.origin = vertex.position + 1e-5f * ray_in.direction;
if (pdf == 0.f)
{
return vec3(0.f);
}
vec3 diffuse = material__getDiffuse(material, vertex.texcoord).xyz;
light_influence = diffuse * ONE_OVER_PI;
return diffuse * ONE_OVER_PI;
}
vec3 bsdf__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)
{
//Needed parameters for refraction and reflection
bool entering = dot(-ray_in.direction, vertex.normal) > 0.f;
float eta_i = entering ? 1.f : material.ior;
float eta_t = entering ? material.ior : 1.f;
float fresnel = dialectricFresnel(abs(dot(-ray_in.direction, vertex.normal)), eta_i, eta_t);
//refract ray.
ray_out.direction = refract(ray_in.direction, faceforward(vertex.normal, ray_in.direction, vertex.normal), eta_i / eta_t);
light_influence = vec3(0);
// Choose whether to sample refractive or reflective BSDF
if ((ray_out.direction.xyz != vec3(0)) && (random.x > fresnel) && (!isnan(ray_out.direction.x)))
{
ray_out.origin = vertex.position + 1e-5 * ray_out.direction;
pdf = 1.0f - fresnel;
vec3 ft = material__getTransparent(material, vertex.texcoord).xyz * (1.0f - fresnel);
return ft / abs(dot(ray_out.direction, vertex.normal));
}
ray_out.direction = reflect(ray_in.direction, faceforward(vertex.normal, ray_in.direction, vertex.normal));
ray_out.origin = vertex.position + 1e-5 * ray_out.direction;
pdf = fresnel;
return fresnel * material__getSpecular(material, vertex.texcoord).xyz / abs(dot(ray_out.direction, vertex.normal));
}
vec3 bsdf__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)
{
//Needed parameters for refraction and reflection
bool entering = dot(-ray_in.direction, vertex.normal) > 0.f;
float eta_i = entering ? 1.f : material.ior;
float eta_t = entering ? material.ior : 1.f;
float fresnel = dialectricFresnel(abs(dot(-ray_in.direction, vertex.normal)), eta_i, eta_t);
float roughness = clamp(1.f - (sqrt(material.specular_exponent) / 10.f), 0, 1);
vec3 diffuse = material__getDiffuse(material, vertex.texcoord).xyz;
light_influence = mix(vec3(0), diffuse * ONE_OVER_PI, roughness);
//refract ray.
vec3 refracted = refract(ray_in.direction, faceforward(vertex.normal, ray_in.direction, vertex.normal), eta_i / eta_t).xyz;
// Choose whether to sample refractive or reflective BSDF
if ((refracted != vec3(0)) && (random.x > fresnel) && (!isnan(refracted.x)))
{
float rad = radians(180.0f - (1.0f - roughness) * 180.0f);
vec3 sampledPoint = randAngle(random.x, random.y, rad);
ray_out.direction.xyz = localToWorldNormal(sampledPoint, refracted);
if (dot(ray_out.direction, faceforward(vertex.normal, ray_in.direction, vertex.normal)) > 0.0f)
{
ray_out.direction.xyz = localToWorldNormal(sampledPoint * vec3(-1, -1, 1), refracted);
}
pdf = mix(1.0f - fresnel, abs(dot(ray_out.direction, vertex.normal)) * ONE_OVER_PI, roughness);
vec3 ft = material__getTransparent(material, vertex.texcoord).xyz * (1.0f - fresnel);
ray_out.origin = vertex.position + 1e-5 * ray_out.direction;
return mix(ft / abs(dot(ray_out.direction, vertex.normal)), diffuse * ONE_OVER_PI, roughness);
}
float rad = radians(180.0f - (1.0f - roughness) * 180.0f);
vec3 reflected = reflect(ray_in.direction, faceforward(vertex.normal, ray_in.direction, vertex.normal)).xyz;
vec3 sampledPoint = randAngle(random.x, random.y, rad);
ray_out.direction.xyz = localToWorldNormal(sampledPoint, reflected);
if (dot(ray_out.direction, faceforward(vertex.normal, ray_in.direction, vertex.normal)) < 0.0f)
{
ray_out.direction.xyz = localToWorldNormal(sampledPoint * vec3(-1, -1, 1), reflected);
}
pdf = mix(fresnel, abs(dot(ray_out.direction, vertex.normal)) * ONE_OVER_PI, roughness);
ray_out.origin = vertex.position + 1e-5 * ray_out.direction;
return mix(fresnel * material__getSpecular(material, vertex.texcoord).xyz / abs(dot(ray_out.direction, vertex.normal)), diffuse * ONE_OVER_PI, roughness);
}
vec3 bsdf__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)
{
//refract ray.
ray_out.direction = ray_in.direction;
ray_out.origin = vertex.position + 1e-5 * ray_out.direction;
pdf = 1;
light_influence = vec3(0);
return material__getTransparent(material, vertex.texcoord).xyz / abs(dot(ray_out.direction, vertex.normal));
}
vec3 bsdf__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)
{
pdf = 1.f;
ray_out.direction = reflect(ray_in.direction, faceforward(vertex.normal, ray_in.direction, vertex.normal));
light_influence = vec3(0);
ray_out.origin = vertex.position + 1e-5 * ray_out.direction;
return material__getSpecular(material, vertex.texcoord).xyz / abs(dot(ray_out.direction, vertex.normal));
}
vec3 bsdf__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)
{
float roughness = clamp(1.f - (sqrt(material.specular_exponent) / 10.f), 0, 1);
float rad = radians(180.0f - (1.0f - roughness) * 180.0f);
vec3 reflected = normalize(reflect(ray_in.direction, faceforward(vertex.normal, ray_in.direction, vertex.normal)).xyz);
vec3 sampledPoint = normalize(randAngle(random.x, random.y, rad));
vec3 diffuse = material__getDiffuse(material, vertex.texcoord).xyz;
light_influence = roughness * diffuse * ONE_OVER_PI;
ray_out.direction.xyz = normalize(localToWorldNormal(sampledPoint, reflected));
if (dot(ray_out.direction, faceforward(vertex.normal, ray_in.direction, vertex.normal)) < 0.0f)
{
ray_out.direction.xyz = normalize(localToWorldNormal(sampledPoint * vec3(-1, -1, 1), reflected));
}
ray_out.origin = vertex.position + 1e-5 * ray_out.direction;
pdf = 1.f - roughness * abs(dot(ray_out.direction, vertex.normal)) * ONE_OVER_PI;
return mix(material__getSpecular(material, vertex.texcoord).xyz / abs(dot(ray_out.direction, vertex.normal)), diffuse * ONE_OVER_PI, roughness);
}
vec3 bsdf__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)
{
pdf = 1.f;
ray_out.direction = vec4(0);
light_influence = material__getEmissive(material, vertex.texcoord).xyz;
ray_out.origin = vertex.position + 1e-5 * ray_out.direction;
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;
vec3 bsdf__sample(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)
{
//Kind of crude but also kind of well functional bsdf selector.
ray_out.pixel = ray_in.pixel;
bool rough = material.specular_exponent < 100;
uint bitset = 1; //Glossy by default.
bitset = 1 << (1 * uint(!rough)); //mirror
bitset = 1 << (2 * uint(material.specular_exponent <= 1)); //glossy;
bitset = bitset << (8 * uint(length(material__getTransparent(material, vertex.texcoord).xyz) >= 0.1));
uint mask = uint((bitset & (0x700)) > 0) * uint(material.ior==1);
bitset = mask*(1 << 11) + ((1-mask)*bitset);
uint emissive = uint(length(material__getEmissive(material, vertex.texcoord).xyz) >= 0.01);
bitset = emissive*(1 << 16) + ((1 - emissive)*bitset);
switch (bitset)
{
default:
case eGlossy:
return bsdf__sampleGlossy(material, random, vertex, ray_in, ray_out, light_influence, pdf);
case eMirror:
return bsdf__sampleMirror(material, random, vertex, ray_in, ray_out, light_influence, pdf);
case eDiffuse:
return bsdf__sampleDiffuse(material, random, vertex, ray_in, ray_out, light_influence, pdf);
case eTransparentGlossy:
return bsdf__sampleRoughGlass(material, random, vertex, ray_in, ray_out, light_influence, pdf);
case eTransparentMirror:
return bsdf__sampleGlass(material, random, vertex, ray_in, ray_out, light_influence, pdf);
case eTransparentDiffuse:
return bsdf__sampleTranslucent(material, random, vertex, ray_in, ray_out, light_influence, pdf);
case eTransparent:
return bsdf__sampleTransparent(material, random, vertex, ray_in, ray_out, light_influence, pdf);
case eEmissive:
return bsdf__sampleEmissive(material, random, vertex, ray_in, ray_out, light_influence, pdf);
}
}
#endif //!__BDSF_DIFFUSE_GLH
\ No newline at end of file
#ifndef __FRESNEL_GLH
#define __FRESNEL_GLH
float dialectricFresnel(const in float cos_theta, in float eta_i, in float eta_t) {
float cos_theta_i = clamp(cos_theta, -1.f, 1.f);
// If we are not entering, we have to swap the indices of refraction:
if (cos_theta_i <= 0) {
float tmp = eta_i;
eta_i = eta_t;
eta_t = tmp;
cos_theta_i = abs(cos_theta_i);
}
// Snell's law
float sin_theta_i = sqrt(max(0.f, 1 - cos_theta_i * cos_theta_i));
float sin_theta_t = eta_i / eta_t * sin_theta_i;
if (sin_theta_t >= 1) {
return 1;
}
float cos_theta_t = sqrt(max(0.f, 1 - sin_theta_t * sin_theta_t));
float rparl = ((eta_t * cos_theta_i) - (eta_i * cos_theta_t)) /
((eta_t * cos_theta_i) + (eta_i * cos_theta_t));
float rperp = ((eta_i * cos_theta_i) - (eta_t * cos_theta_t)) /
((eta_i * cos_theta_i) + (eta_t * cos_theta_t));
// Valid only for unpolarised light, which is what we assume here.
return (rparl * rparl + rperp * rperp) / 2;
}
#endif
\ No newline at end of file
#ifndef __RAY_TRANSFORM_GLH
#define __RAY_TRANSFORM_GLH
vec3 worldToLocal(const in vec3 v, const in vec3 ss, const in vec3 ts, const in vec3 ns)
{
return vec3(dot(v, ss), dot(v, ts), dot(v, ns));
}
vec3 localToWorld(const in vec3 v, const in vec3 ss, const in vec3 ts, const in vec3 ns)
{
return v.x * ss + v.y * ts + v.z * ns;
}
vec3 localToWorldNormal(const in vec3 v, const in vec3 normal) {
vec3 perpendicular = normalize(
max(
max(
cross(normal, vec3(0.0, 1.0, 0.0)),
cross(normal, vec3(0.0, 0.0, 1.0))
),
cross(normal, vec3(1.0, 0.0, 0.0))
)
);
vec3 secondary_perpendicular = cross(normal, perpendicular);
perpendicular = cross(normal, secondary_perpendicular);
return localToWorld(v, perpendicular, secondary_perpendicular, normal); // bring vectors to local shading space
}
#endif // !__RAY_TRANSFORM_GLH
\ No newline at end of file
......@@ -12,6 +12,7 @@ uniform struct
uint max_samples;
float clamp_direct;
float clamp_indirect;
uint bounce_thresholds;
} u_render_config;
#endif
......@@ -34,13 +35,18 @@ uniform struct LinespaceProperties
{
float accuracy_quality;
float shadow_quality;
uint bounce_count_thresholds;
uint bounce_thresholds;
} u_linespace_properties;
uint getLSBounceThreshold(uint id)
{
return (u_linespace_properties.bounce_thresholds >> (4*id)) & 0xF;
}
uint getBounceThreshold(uint id)
{
return (u_linespace_properties.bounce_count_thresholds >> (4*id)) & 0xF;
return (u_render_config.bounce_thresholds >> (4*id)) & 0xF;
}
//In this texture, the colors will all just be added up. The final render target color is then the
......@@ -76,7 +82,7 @@ vec4 loadColorStore(int id)
////
//////////////////////////////////////////////////////////////////////////
bool shade(int id, inout vec3 radiance, uint bounce)
bool shade(int id, inout vec3 radiance, uint bounce, out uint bsdf_id)
{
Trace trace = b_traces[id];
Hit hit = trace.hit;
......@@ -105,7 +111,6 @@ bool shade(int id, inout vec3 radiance, uint bounce)
float pdf;
vec3 light_influence;
Ray out_ray;
uint bsdf_id;
vec3 reflectance = material.sampleBSDF(random_sample, vertex, ray, out_ray, light_influence, pdf, bsdf_id);
b_traces[id].addBounceAmount(bsdf_id, 1);
......@@ -132,7 +137,8 @@ bool shade(int id, inout vec3 radiance, uint bounce)
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);
bool use_bvh = (trace.properties.shadow_importance > (1-u_linespace_properties.shadow_quality))
&& (b_traces[id].getBounceAmount(bsdf_id) < getLSBounceThreshold(bsdf_id));
if (!shadow_test.intersectsAny(light_distance, use_bvh))
{
float angle = angle(shadow_test, vertex);
......@@ -161,13 +167,14 @@ bool shade(int id, inout vec3 radiance, uint bounce)
return true;
}
bool trace(int id)
bool trace(int id, uint last_bsdf_id)
{
//Invalidate before intersection test so that we don't have to conditionally invalidate afterwards
b_traces[id].hit.invalidate();
//Use a BVH if accuracy is important
bool use_bvh = b_traces[id].properties.accuracy_importance > (1-u_linespace_properties.accuracy_quality);
bool use_bvh = (b_traces[id].properties.accuracy_importance > (1-u_linespace_properties.accuracy_quality))
&& (b_traces[id].getBounceAmount(last_bsdf_id) < getLSBounceThreshold(last_bsdf_id));
bool intersects = b_traces[id].ray.nearestIntersection(b_traces[id].hit, use_bvh);
return intersects;
}
......@@ -184,12 +191,13 @@ void main()
vec3 radiance = vec3(1);
//Shade the primary ray hit which was generated by the RayGenerator before the render dispatch call.
bool success = shade(id, radiance, 0);
uint last_bsdf_id;
bool success = shade(id, radiance, 0, last_bsdf_id);
//Then shade all valid hits as long as they bounce around happily in the scene.
for (int bounce = 0; bounce <= u_render_config.num_bounces && success; ++bounce) {
success = trace(id);
success = bool(uint(success) & uint(shade(id, radiance, bounce + 1)));
success = trace(id, last_bsdf_id);
success = bool(uint(success) & uint(shade(id, radiance, bounce + 1, last_bsdf_id)));
}
//Divide color storage by sample count to retrieve the final color.
......
......@@ -17,6 +17,8 @@
<item name="pathtrace_shadow_quality">0.04</item>
<item name="pathtrace_clamp_direct">8</item>
<item name="pathtrace_clamp_indirect">8</item>
<!-- Bounce limits -->
<item name="pathtrace_bounces_diffuse">2</item>
<item name="pathtrace_bounces_translucent">4</item>
<item name="pathtrace_bounces_reflect">4</item>
......@@ -24,6 +26,14 @@
<item name="pathtrace_bounces_transparent">8</item>
<item name="pathtrace_bounces_emissive">0</item>
<!-- Line space bounce count thresholds -->
<item name="pathtrace_ls_thresh_bounces_diffuse">0</item>
<item name="pathtrace_ls_thresh_bounces_translucent">2</item>
<item name="pathtrace_ls_thresh_bounces_reflect">3</item>
<item name="pathtrace_ls_thresh_bounces_refract">5</item>
<item name="pathtrace_ls_thresh_bounces_transparent">7</item>
<item name="pathtrace_ls_thresh_bounces_emissive">0</item>
<!-- Line Space settings -->
<item name="linespace_max_resolution">16</item>
</settings>
\ No newline at end of file
......@@ -15,17 +15,13 @@ namespace glare
void Application::onKeyDown(controls::Key key, controls::KeyMods mods)
{
switch (key) {
case controls::Key::e0:
{
m_render_state = AppRenderState::eGLLines;
} break;
case controls::Key::e1:
{
m_render_state = AppRenderState::eGLDefault;
m_render_state = AppRenderState::eGLLines;
} break;
case controls::Key::e2:
{
m_render_state = AppRenderState::eLineSpace;
m_render_state = AppRenderState::eGLDefault;
} break;
case controls::Key::e3:
{
......@@ -59,6 +55,18 @@ namespace glare
uint8_t effect_bounces_transparent = m_default_preferences->get("pathtrace_bounces_transparent", 8);
uint8_t effect_bounces_emissive = m_default_preferences->get("pathtrace_bounces_emissive", 0);
uint8_t effect_thresh_ls_bounces_diffuse = m_default_preferences->get("pathtrace_ls_thresh_bounces_diffuse", 1);
uint8_t effect_thresh_ls_bounces_translucent = m_default_preferences->get("pathtrace_ls_thresh_bounces_translucent", 2);
uint8_t effect_thresh_ls_bounces_reflect = m_default_preferences->get("pathtrace_ls_thresh_bounces_reflect", 2);
uint8_t effect_thresh_ls_bounces_refract = m_default_preferences->get("pathtrace_ls_thresh_bounces_refract", 4);
uint8_t effect_thresh_ls_bounces_transparent = m_default_preferences->get("pathtrace_ls_thresh_bounces_transparent", 4);
uint8_t effect_thresh_ls_bounces_emissive = m_default_preferences->get("pathtrace_ls_thresh_bounces_emissive", 0);
float accuracy_threshold = m_default_preferences->get<float>("pathtrace_quality", 0.5f);
float shadow_threshold = m_default_preferences->get<float>("pathtrace_shadow_quality", 0.5f);
float clamp_direct = m_default_preferences->get<float>("pathtrace_clamp_direct", 8.f);
float clamp_indirect = m_default_preferences->get<float>("pathtrace_clamp_indirect", 8.f);
core::EngineState::initialize(m_config.window_width, m_config.window_height, m_config.window_title);
core::Callbacks::addKeyDownCallback("main_application", std::bind(&Application::onKeyDown, this, std::placeholders::_1, std::placeholders::_2));
core::SplashScreen splash_screen(splash_image, splash_sound, splash_background, splash_duration);
......@@ -78,11 +86,11 @@ namespace glare
//initializeScene(m_current_scene_root / "benchmark_single_quad_diff.dae", 1.f);
//initializeScene(m_current_scene_root / "benchmark_single_cube_diff.dae", 1.f);
//initializeScene(m_current_scene_root / "benchmark_suzanne_x1_diff.dae", 1.f);
//initializeScene(m_current_scene_root / "benchmark_suzanne_x2_diff.dae", 1.f);
initializeScene(m_current_scene_root / "benchmark_suzanne_x2_diff.dae", 1.f);
//initializeScene(m_current_scene_root / "benchmark_teapot_diff.dae", 1.f);
//initializeScene(m_current_scene_root / "benchmark_stfd_bunny_diff.dae", 1.f);
//initializeScene(m_current_scene_root / "benchmark_stfd_armadillo_diff.dae", 1.f);
initializeScene(m_current_scene_root / "benchmark_stfd_dragon_diff.dae", 1.f);
//initializeScene(m_current_scene_root / "benchmark_stfd_dragon_diff.dae", 1.f);
//initializeScene(m_current_scene_root / "benchmark_stfd_asian_dragon_diff.dae", 1.f);
// ARTIFACT CHECK (GLASS)
......@@ -103,7 +111,7 @@ namespace glare
//initializeScene(m_current_scene_root / "artifact_suzanne_x2_emissive.dae", 1.f);
//initializeScene(m_current_scene_root / "artifact_suzanne_x2_transparent.dae", 1.f);
initializeScene(m_current_scene_root / "block_of_rock.dae", 1.f);
//initializeScene(m_current_scene_root / "block_of_rock.dae", 1.f);
initializeRenderRequirements();
initializeAdvanced();
initializeGUI();
......@@ -114,10 +122,18 @@ namespace glare
m_raytracer->setEffectBounces(advanced::EffectType::eRefraction, effect_bounces_refract);
m_raytracer->setEffectBounces(advanced::EffectType::eTransparent, effect_bounces_transparent);
m_raytracer->setEffectBounces(advanced::EffectType::eEmissive, effect_bounces_emissive);
m_raytracer->setAccuracyThreshold(m_default_preferences->get<float>("pathtrace_quality", 0.5f));
m_raytracer->setShadowThreshold(m_default_preferences->get<float>("pathtrace_shadow_quality", 0.5f));
m_raytracer->setClampDirect(m_default_preferences->get<float>("pathtrace_clamp_direct", 8.f));
m_raytracer->setClampIndirect(m_default_preferences->get<float>("pathtrace_clamp_indirect", 8.f));
m_raytracer->setLinespaceBounceThresholds(advanced::EffectType::eDiffuse, effect_thresh_ls_bounces_diffuse);
m_raytracer->setLinespaceBounceThresholds(advanced::EffectType::eTranslucent, effect_thresh_ls_bounces_translucent);
m_raytracer->setLinespaceBounceThresholds(advanced::EffectType::eReflection, effect_thresh_ls_bounces_reflect);
m_raytracer->setLinespaceBounceThresholds(advanced::EffectType::eRefraction, effect_thresh_ls_bounces_refract);
m_raytracer->setLinespaceBounceThresholds(advanced::EffectType::eTransparent, effect_thresh_ls_bounces_transparent);
m_raytracer->setLinespaceBounceThresholds(advanced::EffectType::eEmissive, effect_thresh_ls_bounces_emissive);
m_raytracer->setAccuracyThreshold(accuracy_threshold);
m_raytracer->setShadowThreshold(shadow_threshold);
m_raytracer->setClampDirect(clamp_direct);
m_raytracer->setClampIndirect(clamp_indirect);
gl::setEnabled(gl::EnableParameter::eMultisample, true);
......@@ -155,7 +171,6 @@ namespace glare
m_gbuffer->draw();
}
break;
case AppRenderState::eLineSpace:
case AppRenderState::ePathtracer:
{
auto &&rt_texture = m_raytracer->render(m_config.window_width, m_config.window_height);
......@@ -270,9 +285,8 @@ namespace glare
render_state = int(m_render_state);
ImGui::Title("Render Mode");
ImGui::RadioButton("[OpenGL] Lines", &render_state, 0);
ImGui::RadioButton("[OpenGL] GBuffer", &render_state, 1);
//ImGui::RadioButton("Line Space", &render_state, 2);
ImGui::RadioButton("Pathtracer", &render_state, 3);
ImGui::RadioButton("[OpenGL] Shaded", &render_state, 1);
ImGui::RadioButton("Pathtracer", &render_state, 2);
if (m_render_state != AppRenderState(render_state)) {
glFinish();
......
......@@ -19,8 +19,7 @@ namespace glare
{
eGLLines = 0,
eGLDefault = 1,
eLineSpace = 2,
ePathtracer = 3
ePathtracer = 2
};
enum class AppRayGenState
......
#include <glare_core>
#include <glare_advanced>
#include <glare_io>
using namespace glare;
int main(int argc, char* argv[])
{
io::Arguments arguments(argc, argv);
std::string mask_asset_path = arguments.get("o", 0, std::string(""));
advanced::LineSpaceMaskMode mask_mode = arguments.has("ns") ? advanced::LineSpaceMaskMode::eNonSymmetrical : advanced::LineSpaceMaskMode::eSymmetrical;
unsigned mask_resolution_min = arguments.get("r", 0, 1);
unsigned mask_resolution_max = arguments.get("r", 1, 16);
bool check_after = arguments.get("check", 0, false);
advanced::LineSpaceMaskGenerator::generate(mask_mode, math::Range<unsigned>(mask_resolution_min, mask_resolution_max), mask_asset_path, check_after);
quitPromptDefault(0);
return 0;
}
\ No newline at end of file
......@@ -32,7 +32,15 @@ namespace glare
m_bounce_count_thresholds[unsigned(EffectType::eTransparent)] = 12;
m_bounce_count_thresholds[unsigned(EffectType::eEmissive)] = 0;
m_render_config.bounces = 8;
m_ls_bounce_count_thresholds[unsigned(EffectType::eDiffuse)] = 1;
m_ls_bounce_count_thresholds[unsigned(EffectType::eTranslucent)] = 3;
m_ls_bounce_count_thresholds[unsigned(EffectType::eReflection)] = 3;
m_ls_bounce_count_thresholds[unsigned(EffectType::eRefraction)] = 6;
m_ls_bounce_count_thresholds[unsigned(EffectType::eTransparent)] = 8;
m_ls_bounce_count_thresholds[unsigned(EffectType::eEmissive)] = 0;
m_render_config.bounces = 16;
m_render_shader = core::ShaderProgram::makeUnique("/raytracer/pathtracer.compute");
m_ray_generator = ray_generator;
m_trace_buffer = std::make_unique<core::Buffer<gl::BufferType::eShaderStorage>>();
......@@ -58,6 +66,18 @@ namespace glare
m_bounce_count_thresholds[unsigned(type)] = clamped;
}
void Raytracer::setLinespaceBounceThresholds(EffectType type, uint8_t bounces)
{
uint8_t clamped = bounces & 0xf;
if (clamped != bounces)
{
Log_Warn << bounces << " - value larger than 15 (0xf). Result of " << clamped << " may be unintended.";
}
m_ls_bounce_count_thresholds[unsigned(type)] = clamped;
}
void Raytracer::reset()
{
m_render_config.current_sample = 0;
......@@ -123,7 +143,13 @@ namespace glare
{
bounce_thresholds |= (m_bounce_count_thresholds[i] & 0xf) << (4 * i);
}
m_render_shader->updateUniformUInt("u_linespace_properties.bounce_count_thresholds", bounce_thresholds);
m_render_shader->updateUniformUInt("u_render_config.bounce_thresholds", bounce_thresholds);
for (int i = 0; i < 8; ++i)
{
m_linespace_config.bounce_thresholds |= (m_ls_bounce_count_thresholds[i] & 0xf) << (4 * i);
}
m_render_shader->updateUniformUInt("u_linespace_properties.bounce_thresholds", m_linespace_config.bounce_thresholds);
m_render_shader->dispatchCompute2D(width, 4, height, 4);
......
......@@ -41,6 +41,7 @@ namespace glare
void saveRender(fs::path target) const;
void setEffectBounces(EffectType type, uint8_t bounces);
void setLinespaceBounceThresholds(EffectType type, uint8_t bounces);
//template<typename DataStruct>
void setGenerator(std::shared_ptr<RayGeneratorBase> generator);
......@@ -128,10 +129,11 @@ namespace glare
struct {
float accuracy_threshold;
float shadow_threshold;
uint32_t bounce_thresholds;
} m_linespace_config;
std::array<uint8_t, 8> m_bounce_count_thresholds;
std::array<uint8_t, 8> m_ls_bounce_count_thresholds;
std::shared_ptr<SceneCollector> m_collector;
std::unique_ptr<core::TextureRGBA_32F> m_render_target;
......
Supports Markdown
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