Commit e7d17b2d authored by Johannes Braun's avatar Johannes Braun
Browse files

Not working yet.

parent 224c559f
<linespace version="1.0">
<item name="subdivisions" value="20"/>
<item name="subdivisions" value="10"/>
<item name="radial-subdivision" value="50"/>
<item name="generator" value="gpu"/>
</linespace>
......@@ -110,27 +110,43 @@ bool shade(int id, inout vec3 radiance, uint bounce, out uint bsdf_id)
vec2 random_sample = vec2(ray.px, ray.py) - ivec2(ray.px, ray.py);
//Sample BSDF
float pdf;
vec3 light_influence;
Ray out_ray;
vec3 reflectance = material.sampleBSDF(random_sample, vertex, ray, out_ray, light_influence, pdf, bsdf_id);
//float pdf;
//vec3 light_influence;
//Ray out_ray;
//vec3 reflectance =
BSDFResult bsdf_result;
bsdf_result.radiance = material.sampleBSDF(random_sample, vertex, ray, bsdf_result.generated_ray, bsdf_result.irradiance, bsdf_result.distribution, bsdf_result.bsdf_id);
b_traces[id].addBounceAmount(bsdf_id, 1);
// reflectance = radiance; light_influence = irradiance; pdf = distribution; out_ray = generated_ray
//BSDFResult bsdf_result = material.computeBSDF(random_sample, vertex, ray);
if(b_traces[id].getBounceAmount(bsdf_id) > getBounceThreshold(bsdf_id))
b_traces[id].addBounceAmount(bsdf_result.bsdf_id, 1);
if(b_traces[id].getBounceAmount(bsdf_result.bsdf_id) > getBounceThreshold(bsdf_result.bsdf_id))
{
b_traces[id].hit.invalidate();
return false;
}
if(out_ray.direction == vec3(0))
if(bsdf_result.generated_ray.direction == vec3(0))
{
// Treat as emissive material.
writeColorStore(ray, radiance * light_influence, clamp_color_max);
//writeColorStore(ray, radiance * bsdf_result.irradiance, clamp_color_max);
writeColorStore(ray, bsdf_result.radiance, clamp_color_max);
b_traces[id].hit.invalidate();
return false;
}
bool use_bvh = (trace.properties.shadow_importance > (1-u_linespace_properties.shadow_quality))
&& (b_traces[id].getBounceAmount(bsdf_result.bsdf_id) < getLSBounceThreshold(bsdf_result.bsdf_id))
&& b_traces[id].properties.travelled_distance < u_linespace_properties.distance_threshold;
// Environment shading for the diffuse part
if(length(bsdf_result.irradiance) > 0.01f && !bsdf_result.diffuse_ray.intersectsAny(FLT_MAX, use_bvh)){
writeColorStore(ray, u_environment.sampleColor(bsdf_result.diffuse_ray.direction.xyz).rgb * bsdf_result.irradiance * radiance, clamp_color_max);
}
if (b_lights.length() > 0) {
//Select random light... well... at least if there are any.
BufferLight light = b_lights[int(floor(random_sample.x * b_lights.length()))];
......@@ -140,38 +156,25 @@ bool shade(int id, inout vec3 radiance, uint bounce, out uint bsdf_id)
Ray shadow_test;// = light.makeShadowRay(vertex, random_sample, light_distance);
vec3 light_color;
float 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;
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, 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);
// }
writeColorStore(ray, light_color * bsdf_result.irradiance * radiance, clamp_color_max);
}
}
//Quit if bounces won't be of any use due to low contributions
if (reflectance == vec3(0) || pdf <= 1e-5f)
if (bsdf_result.radiance == vec3(0) || bsdf_result.distribution <= 1e-5f)
{
b_traces[id].hit.invalidate();
return false;
}
//TODO: Check if caching is helping reducing the overhead of SSBOs here.
b_traces[id].properties.accuracy_importance *= pdf;
b_traces[id].properties.shadow_importance *= pdf;
b_traces[id].ray = out_ray;
radiance *= reflectance * angle(out_ray, vertex) / pdf;
b_traces[id].properties.accuracy_importance *= bsdf_result.distribution;
b_traces[id].properties.shadow_importance *= bsdf_result.distribution;
b_traces[id].ray = bsdf_result.generated_ray;
radiance *= bsdf_result.radiance * angle(bsdf_result.generated_ray, vertex) / bsdf_result.distribution;//
return true;
}
......
......@@ -6,6 +6,177 @@
#include <raytracer/utilities.glsl>
#include <raytracer/properties/ray_transform.glsl>
#include <raytracer/properties/fresnel.glsl>
#include <screenshader/gbuffer/cook_torrance.glsl>
struct BSDFResult
{
// A newly generated ray for shading
Ray generated_ray;
// An environment lighting ray
Ray diffuse_ray;
// How the color coming from the generated ray direction will be tinted
vec3 radiance;
// How the incoming light will be tinted
vec3 irradiance;
// The probability of the generated ray (result of the probability distribution function)
float distribution;
// For effect purposes: set a dedicated id for the type of effect achieved
uint bsdf_id;
};
struct SampledMaterial
{
vec4 diffuse;
vec4 specular;
vec4 transparent;
vec4 emissive;
vec4 ambient;
float roughness; // 0..1
float metallic; // 0..1
float ior; // 0..n
};
vec3 reflectedDirection(vec3 local_hemi_sample, vec3 reflected, float roughness)
{
return normalize(localToWorldNormal(local_hemi_sample * vec3(roughness, roughness, 1), reflected));
}
BSDFResult computeBSDFaaa(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in)
{
SampledMaterial sampled_material;
sampled_material.diffuse = material.getDiffuse(vertex.texcoord);
sampled_material.specular = material.getSpecular(vertex.texcoord);
sampled_material.transparent = material.getTransparent(vertex.texcoord);
sampled_material.emissive = material.getEmissive(vertex.texcoord);
sampled_material.ambient = material.getAmbient(vertex.texcoord);
sampled_material.roughness = material.getRoughness();
sampled_material.metallic = clamp((sampled_material.specular.r + sampled_material.specular.g + sampled_material.specular.b )/3, 0, 1);
sampled_material.ior = 1.56f;//material.ior;
vec3 backwards_direction = normalize(-ray_in.direction);
bool entering = dot(backwards_direction, vertex.normal.xyz) > 0.f;
vec3 hemi = randCosineHemisphere(random.x, random.y) * (entering ? 1 : -1);
vec3 reflected = reflect(-backwards_direction, faceforward(vertex.normal.xyz, -backwards_direction, vertex.normal.xyz));
BSDFResult result;
result.generated_ray = ray_in;
result.generated_ray.direction = reflectedDirection(hemi, reflected, sampled_material.roughness);
result.generated_ray.origin = vertex.position.xyz + 1e-5f * result.generated_ray.direction;
result.diffuse_ray.direction = localToWorldNormal(hemi, vertex.normal.xyz).xyz;
result.diffuse_ray.origin = vertex.position.xyz + 1e-5f*result.diffuse_ray.direction;
vec3 normal_response = normalResponse(sampled_material.diffuse.rgb, sampled_material.ior, sampled_material.metallic);
vec3 half_vector = normalize(result.generated_ray.direction.xyz + backwards_direction);
float cosT = clamp(dot(result.generated_ray.direction.xyz, vertex.normal.xyz), 0, 1);
float sinT = sqrt(1 - cosT * cosT);
vec3 fresnel = fresnelSchlick(clamp(dot(backwards_direction, half_vector), 0, 1), normal_response);
float geometry = ggxPartialGeometry(backwards_direction, vertex.normal.xyz, half_vector, sampled_material.roughness)
* ggxPartialGeometry(result.generated_ray.direction, vertex.normal.xyz, half_vector, sampled_material.roughness);
float denominator = clamp(4 * (clamp(dot(vertex.normal.xyz, backwards_direction), 0, 1) * clamp(dot(half_vector, vertex.normal.xyz), 0, 1)) + 0.05f, 0, 1);
float distribution = ggxDistribution(vertex.normal.xyz, half_vector, sampled_material.roughness);
vec3 k_specular = fresnel;
vec3 one_minus_kspec = (1-k_specular);
result.radiance = fresnel * geometry * sinT / denominator;
result.distribution = cosT * geometry * sinT / denominator;
result.irradiance = (1-k_specular)*(1-sampled_material.metallic)*sampled_material.diffuse.rgb * ONE_OVER_PI;
result.bsdf_id = 0;
return result;
}
BSDFResult computeBSDF(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in)
{
SampledMaterial sampled_material;
sampled_material.diffuse = material.getDiffuse(vertex.texcoord);
sampled_material.specular = material.getSpecular(vertex.texcoord);
sampled_material.transparent = material.getTransparent(vertex.texcoord);
sampled_material.emissive = material.getEmissive(vertex.texcoord);
sampled_material.ambient = material.getAmbient(vertex.texcoord);
sampled_material.roughness = material.getRoughness();
sampled_material.metallic = clamp((sampled_material.specular.r + sampled_material.specular.g + sampled_material.specular.b )/3, 0, 1);
sampled_material.ior = 1.56f;//material.ior;
vec3 backwards_direction = normalize(-ray_in.direction);
vec3 normal_response = normalResponse(sampled_material.diffuse.rgb, sampled_material.ior, sampled_material.metallic);
bool entering = dot(backwards_direction, vertex.normal.xyz) > 0.f;
vec3 hemi = randCosineHemisphere(random.x, random.y) * (entering ? 1 : -1);
vec3 microsurface_normal = reflectedDirection(hemi, vertex.normal.xyz, sampled_material.roughness);
vec3 outgoing = reflect(-backwards_direction, faceforward(microsurface_normal, -backwards_direction, vertex.normal.xyz));
vec3 fresnel = fresnelSchlick(clamp(dot(backwards_direction, microsurface_normal), 0, 1), normal_response);
//float geometry = ggxPartialGeometry(backwards_direction, vertex.normal.xyz, microsurface_normal, sampled_material.roughness)
// * ggxPartialGeometry(outgoing, vertex.normal.xyz, microsurface_normal, sampled_material.roughness);
//float distribution = ggxDistribution(vertex.normal.xyz, microsurface_normal, sampled_material.roughness);
float i_dot_m = clamp(dot(backwards_direction, microsurface_normal), 0, 1);
float i_dot_n = clamp(dot(backwards_direction, vertex.normal.xyz), 0, 1);
float m_dot_n = clamp(dot(vertex.normal.xyz, microsurface_normal), 0, 1);
float o_dot_m = clamp(dot(microsurface_normal, outgoing), 0, 1);
float o_dot_n = clamp(dot(vertex.normal.xyz, outgoing), 0, 1);
float alphaSqr = sampled_material.roughness * sampled_material.roughness * sampled_material.roughness * sampled_material.roughness;
float denom = m_dot_n * m_dot_n * (alphaSqr - 1.0) + 1.0;
float distribution = alphaSqr / (denom * denom);
float geometry = min(1, min((2*m_dot_n*i_dot_n/i_dot_m), (2*m_dot_n*o_dot_n/i_dot_m)));
float out_probability = distribution * m_dot_n;
float weight = i_dot_m * geometry / (i_dot_n * i_dot_m);
vec3 reflection_term = fresnel * geometry * distribution / (4 * i_dot_m * o_dot_m);
BSDFResult result;
result.generated_ray = ray_in;
result.generated_ray.direction = outgoing;
result.generated_ray.origin = vertex.position.xyz + 1e-5 * outgoing;
result.radiance = fresnel * geometry;// * distribution;
result.distribution = geometry;
result.irradiance = (1-fresnel)*(1-sampled_material.metallic)*sampled_material.diffuse.rgb * ONE_OVER_PI;
result.bsdf_id = 0;
return result;
}
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);
......@@ -66,7 +237,6 @@ vec3 sampleTranslucent(const in Material material, const in vec2 random, const i
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
bool entering = dot(-ray_in.direction, vertex.normal.xyz) > 0.f;
float eta_i = entering ? 1.f : material.ior;
float eta_t = entering ? material.ior : 1.f;
......@@ -219,6 +389,45 @@ vec3 sampleEmissive(const in Material material, const in vec2 random, const in V
return vec3(0);
}
subroutine(bsdfSampler)
vec3 sampleGGX(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 = 1-(material.specular_exponent / 100.f);
bool entering = dot(-ray_in.direction.xyz, vertex.normal.xyz) > 0.f;
vec3 hemi = randCosineHemisphere(random.x, random.y);
hemi.xy *= roughness;
vec3 reflected = normalize(reflect(ray_in.direction, faceforward(vertex.normal.xyz, ray_in.direction, vertex.normal.xyz)).xyz);
ray_out.origin = vertex.position.xyz + 1e-5 * -ray_in.direction;
ray_out.direction.xyz = normalize(localToWorldNormal(entering ? hemi : -hemi, reflected.xyz));
vec3 half_view = ggxHalfView(ray_out.direction.xyz, -ray_in.direction.xyz);
vec3 diffuse_color = material.getDiffuse(vertex.texcoord).xyz;
vec3 specular_color = material.getDiffuse(vertex.texcoord).xyz;
bsdf_id = 0;
float metallic = 0.f;
float cosT = clamp(dot(ray_out.direction.xyz, vertex.normal.xyz), 0, 1);
float sinT = sqrt(1 - cosT * cosT);
vec3 fresnel = fresnelSchlick(dot(-ray_in.direction.xyz, half_view), normalResponse(diffuse_color, material.ior, metallic));
float normal_dot_view = dot(vertex.normal.xyz, ray_in.direction.xyz);
float geometry = ggxPartialGeometry(-ray_in.direction.xyz, vertex.normal.xyz, half_view, roughness)
* ggxPartialGeometry(ray_out.direction.xyz, vertex.normal.xyz, half_view, roughness);
float denominator = clamp(4 * (normal_dot_view * dot(half_view, vertex.normal.xyz)) + 0.05f, 0, 1);
pdf = ggxDistribution(vertex.normal.xyz, half_view, roughness);
vec3 specular_factor = fresnel;
vec3 diffuse_factor = (1-specular_factor)*(1-metallic);
light_influence = diffuse_factor * diffuse_color * ONE_OVER_PI;
return diffuse_factor * diffuse_color * ONE_OVER_PI + geometry * fresnel * sinT / denominator;
}
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)
......@@ -238,6 +447,7 @@ vec3 sampleBSDF(const in Material material, const in vec2 random, const in Verte
index = emits ? 7 : index;
//return sampleGGX(material, 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);
}
......
......@@ -34,7 +34,7 @@ vec4 getEmissive(const in Material material, const in vec2 texcoord)
float getRoughness(const in Material material)
{
return pow(1.f - (material.specular_exponent.clamp(1, 100)/100.f), 2);
return pow(1.f - ((material.specular_exponent.clamp(1, 101)-1)/100.f), 2);
}
#endif //__GL_UTILS_MATERIALS
\ No newline at end of file
#endif //__GL_UTILS_MATERIALS
#ifndef INCLUDE_COOK_TORRANCE_GLSL
#define INCLUDE_COOK_TORRANCE_GLSL
#define GGX_PI 3.14159265359
#include <raytracer/random.glsl>
#include <raytracer/properties/ray_transform.glsl>
vec3 ggxHalfView(const in vec3 to_light, const in vec3 to_eye)
{
return normalize(to_light + to_eye);
}
float ggxChi(float v)
{
return v > 0 ? 1 : 0;
}
float ggxDistribution(const in vec3 normal, const in vec3 half_view, float roughness)
{
float normal_dot_half = dot(normal, half_view);
float roughness2 = roughness * roughness;
float normal_dot_half2 = normal_dot_half * normal_dot_half;
float tan2 = (1-normal_dot_half2) / normal_dot_half2;
float denominator = normal_dot_half2 * (roughness2 + tan2);
return (ggxChi(normal_dot_half) * roughness2) / (GGX_PI * denominator * denominator);
}
float ggxPartialGeometry(const in vec3 to_eye, const in vec3 normal, const in vec3 half_view, float roughness)
{
float eye_dot_half2 = clamp(dot(to_eye, half_view), 0, 1);
float chi = ggxChi(eye_dot_half2 / clamp(dot(to_eye, normal), 0, 1));
eye_dot_half2 = eye_dot_half2 * eye_dot_half2;
float tan2 = (1 - eye_dot_half2) / eye_dot_half2;
return (chi*2) / (1 + sqrt(1 + roughness * roughness * tan2));
}
vec3 normalResponse(const in vec3 material_color, float ior, float metallic)
{
vec3 response = vec3(abs((1-ior) / (1+ior)));
response = response * response;
return mix(response, material_color, metallic);
}
vec3 fresnelSchlick(float view_dot_half, const in vec3 normal_response)
{
return normal_response + (1-normal_response) * pow(1 - view_dot_half, 5);
}
vec3 ggxSpecular(samplerCube environment, const in vec3 normal, const in vec3 to_light, const in vec3 to_eye, float roughness, const in vec3 normal_response, out vec3 k_specular)
{
const int sample_count = 1;
vec3 reflection = reflect(-to_eye, normal);
vec3 radiance = vec3(0);
float normal_dot_view = clamp(dot(normal, to_eye), 0, 1);
for(int i=0; i<sample_count; ++i)
{
// vec2 random_sample = rand2D(int(gl_FragCoord.x + 50000 * gl_FragCoord.y));
vec3 random_direction = vec3(0,0,1);//randCosineHemisphere(random_sample.x, random_sample.y);
//random_direction.xy *= roughness;
random_direction = vec3(0, 0, 1);
random_direction = localToWorldNormal(random_direction, reflection);
vec3 half_vector = ggxHalfView(random_direction, to_eye);
float cosT = clamp(dot(random_direction, normal), 0, 1);
float sinT = sqrt(1 - cosT * cosT);
vec3 fresnel = fresnelSchlick(dot(to_eye, half_vector), normal_response);
float geometry = ggxPartialGeometry(to_eye, normal, half_vector, roughness) * ggxPartialGeometry(random_direction, normal, half_vector, roughness);
float denominator = clamp(4 * (normal_dot_view * dot(half_vector, normal)) + 0.05f, 0, 1);
k_specular += fresnel;
radiance += textureLod(environment, random_direction, roughness * 8).rgb * geometry * fresnel * sinT/denominator;
}
k_specular /= sample_count;
k_specular = clamp(k_specular, 0, 1);
return radiance / sample_count;
}
#endif //!INCLUDE_COOK_TORRANCE_GLSL
......@@ -111,7 +111,8 @@ namespace glare
//Create a skybox from cube map.
m_skybox = std::make_shared<core::Skybox>(core::Skybox::collectFilesFrom(files::asset("/textures/ryfjallet/")));
initializeScene(m_current_scene_root / "bunny_fancy.dae", 1.f);
initializeScene(m_current_scene_root / "cbox.dae", 1.f);
//initializeScene(m_current_scene_root / "banni.dae", 1.f);
initializeRenderRequirements();
initializeAdvanced();
......
......@@ -209,9 +209,9 @@ namespace glare
m_node_buffer.upload(m_nodes, gl::BufferUsage::eDynamicRead);
m_node_buffer.makeResident(gl::Access::eReadOnly);
Log_Info << "BVH info: Nodes " << m_node_counter;
Log_Info << "BVH info: Depth " << m_bvh_depth;
Log_Info << "BVH info: Construction took " << timer.time() << " microseconds";
Log_Debug << "BVH info: Nodes " << m_node_counter;
Log_Debug << "BVH info: Depth " << m_bvh_depth;
Log_Debug << "BVH info: Construction took " << timer.time() << " microseconds";
}
template<typename TPrimitive>
......
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