rtx: improve emissive surface sampling
Sample a single triangle not in a loop.
This commit is contained in:
parent
e4aea1486f
commit
8cf040f9be
|
@ -1,8 +1,8 @@
|
|||
## 2021-09-01, E132
|
||||
- [x] rtx: ingest brdfs from ray tracing gems 2
|
||||
- [x] rtx: directly select a triangle for light sampling
|
||||
|
||||
# Next
|
||||
- [ ] rtx: directly select a triangle for light sampling
|
||||
- [ ] rtx: pass alpha for transparency
|
||||
- [ ] rtx: remove additive/refractive flags in favor or probability of ray continuing further instead of bouncing off
|
||||
- [ ] rtx: experiment with refraction index and "refraction roughness"
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
const float dlight_attenuation_const = 10000.;
|
||||
const float shadow_offset_fudge = .5;
|
||||
const float normal_offset_fudge = .1;
|
||||
const float brightness_fudge = 30.;
|
||||
|
||||
layout (constant_id = 0) const uint MAX_DLIGHTS = 32;
|
||||
layout (constant_id = 1) const uint MAX_EMISSIVE_KUSOCHKI = 256;
|
||||
|
@ -97,6 +98,50 @@ bool shadowed(vec3 pos, vec3 dir, float dist) {
|
|||
return shadow;
|
||||
}
|
||||
|
||||
vec3 sampleSurfaceTriangle(vec3 view_dir, MaterialProperties material, mat4x3 emissive_transform, mat3 emissive_transform_normal, uint triangle_index, uint index_offset, uint vertex_offset) {
|
||||
const uint first_index_offset = index_offset + triangle_index * 3;
|
||||
|
||||
// TODO this is not entirely correct -- need to mix between all normals, or have this normal precomputed
|
||||
const uint vi1 = uint(indices[first_index_offset+0]) + vertex_offset;
|
||||
const vec3 n1 = normalize(emissive_transform_normal * vertices[vi1].normal);
|
||||
// if (dot(n1, normal) >= 0. /* TODO epsilon */ )
|
||||
// continue;
|
||||
|
||||
// TODO random sample point on the entire geometry ?
|
||||
const uint vi2 = uint(indices[first_index_offset+1]) + vertex_offset;
|
||||
const uint vi3 = uint(indices[first_index_offset+2]) + vertex_offset;
|
||||
|
||||
const vec3 v1 = (emissive_transform * vec4(vertices[vi1].pos, 1.)).xyz;
|
||||
const vec3 v2 = (emissive_transform * vec4(vertices[vi2].pos, 1.)).xyz;
|
||||
const vec3 v3 = (emissive_transform * vec4(vertices[vi3].pos, 1.)).xyz;
|
||||
|
||||
// TODO projected uniform sampling
|
||||
const vec3 sample_pos = mix(mix(v1, v2, rand01()), v3, rand01());
|
||||
//const vec3 sample_pos = vertices[vi1].pos;
|
||||
|
||||
// const vec3 n2 = vertices[vi2].normal;
|
||||
// const vec3 n3 = vertices[vi3].normal;
|
||||
|
||||
vec3 light_dir = sample_pos - payload.hit_pos_t.xyz;
|
||||
float light_dot = -dot(light_dir, n1);
|
||||
if (light_dot <= 0.)
|
||||
return vec3(0.);
|
||||
|
||||
const float light_dist = length(light_dir);
|
||||
light_dot /= light_dist;
|
||||
light_dir /= light_dist;
|
||||
|
||||
const float light_dir_normal_dot = dot(light_dir, payload.normal);
|
||||
if (light_dir_normal_dot <= 0.)
|
||||
return vec3(0.);
|
||||
|
||||
if (shadowed(payload.hit_pos_t.xyz, light_dir, light_dist - shadow_offset_fudge))
|
||||
return vec3(0.);
|
||||
|
||||
// TODO sample emissive texture
|
||||
return brightness_fudge * evalCombinedBRDF(payload.normal, light_dir, view_dir, material) / (light_dist * light_dist);
|
||||
}
|
||||
|
||||
vec3 computeLighting(vec3 view_dir, MaterialProperties material) {
|
||||
vec3 C = vec3(0.);
|
||||
const ivec3 light_cell = ivec3(floor(payload.hit_pos_t.xyz / LIGHT_GRID_CELL_SIZE)) - light_grid.grid_min;
|
||||
|
@ -114,8 +159,6 @@ vec3 computeLighting(vec3 view_dir, MaterialProperties material) {
|
|||
//C += .3 * fract(vec3(light_cell) / 4.);
|
||||
|
||||
const uint num_emissive_kusochki = uint(light_grid.clusters[cluster_index].num_emissive_surfaces);
|
||||
//const uint num_emissive_kusochki = emissive_kusochki.num_kusochki;
|
||||
|
||||
float sampling_light_scale = 1.;
|
||||
#if 0
|
||||
const uint max_lights_per_frame = 4;
|
||||
|
@ -145,80 +188,17 @@ vec3 computeLighting(vec3 view_dir, MaterialProperties material) {
|
|||
|
||||
const mat3 emissive_transform_normal = transpose(inverse(mat3(emissive_transform)));
|
||||
|
||||
// if (i != picked_light) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
if (emissive_kusok_index == uint(payload.kusok_index)) {
|
||||
// TODO do we need to do this when we have textures?
|
||||
//C += throughput * vec3(hash(float(kusok_index)), hash(float(kusok_index)+15.43), hash(float(kusok_index)+34.));//kusok.emissive.rgb;
|
||||
//C = vec3(1., 0., 1.);
|
||||
if (emissive_kusok_index == uint(payload.kusok_index))
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint picked_tri = rand_range(ekusok.triangles);
|
||||
for (uint ti = 0; ti < ekusok.triangles; ++ti) {
|
||||
const uint first_index_offset = ekusok.index_offset + ti * 3;
|
||||
|
||||
// TODO this is not entirely correct -- need to mix between all normals, or have this normal precomputed
|
||||
const uint vi1 = uint(indices[first_index_offset+0]) + ekusok.vertex_offset;
|
||||
const vec3 n1 = normalize(emissive_transform_normal * vertices[vi1].normal);
|
||||
// if (dot(n1, normal) >= 0. /* TODO epsilon */ )
|
||||
// continue;
|
||||
|
||||
if (picked_tri > ti)
|
||||
continue;
|
||||
|
||||
// TODO random sample point on the entire ekusok geometry
|
||||
const uint vi2 = uint(indices[first_index_offset+1]) + ekusok.vertex_offset;
|
||||
const uint vi3 = uint(indices[first_index_offset+2]) + ekusok.vertex_offset;
|
||||
|
||||
const vec3 v1 = (emissive_transform * vec4(vertices[vi1].pos, 1.)).xyz;
|
||||
const vec3 v2 = (emissive_transform * vec4(vertices[vi2].pos, 1.)).xyz;
|
||||
const vec3 v3 = (emissive_transform * vec4(vertices[vi3].pos, 1.)).xyz;
|
||||
|
||||
const vec3 sample_pos = mix(mix(v1, v2, rand01()), v3, rand01());
|
||||
//const vec3 sample_pos = vertices[vi1].pos;
|
||||
|
||||
// const vec3 n2 = vertices[vi2].normal;
|
||||
// const vec3 n3 = vertices[vi3].normal;
|
||||
|
||||
vec3 light_dir = sample_pos - payload.hit_pos_t.xyz;
|
||||
float light_dot = -dot(light_dir, n1);
|
||||
if (light_dot <= 0.) {
|
||||
//C = vec3(1., 0., 1.);
|
||||
continue;
|
||||
}
|
||||
|
||||
const float light_dist = length(light_dir);
|
||||
light_dot /= light_dist;
|
||||
light_dir /= light_dist;
|
||||
|
||||
const float light_dir_normal_dot = dot(light_dir, payload.normal);
|
||||
if (light_dir_normal_dot <= 0.)
|
||||
continue;
|
||||
|
||||
if (shadowed(payload.hit_pos_t.xyz, light_dir, light_dist - shadow_offset_fudge)) {
|
||||
//C = vec3(0., 1., 0.);
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO
|
||||
const float brightness_fudge = 30.;
|
||||
C += sampling_light_scale * brightness_fudge * emissive * evalCombinedBRDF(payload.normal, light_dir, view_dir, material) / (light_dist * light_dist);
|
||||
|
||||
// Sample just one triangle
|
||||
break;
|
||||
} // for emissive kusok triangles
|
||||
const uint triangle_index = rand_range(ekusok.triangles);
|
||||
C += sampling_light_scale * emissive * sampleSurfaceTriangle(view_dir, material, emissive_transform, emissive_transform_normal, triangle_index, ekusok.index_offset, ekusok.vertex_offset);
|
||||
} // for all emissive kusochki
|
||||
|
||||
for (uint i = 0; i < num_lights; ++i) {
|
||||
const vec4 light_pos_r = lights[i].pos_r;
|
||||
const vec3 light_color = lights[i].color.rgb;
|
||||
|
||||
//rand01_state = fract((pos.x + pos.y + pos.z)/100.) + uv.x + uv.y + fract(pc.t) + i;
|
||||
//rand01_state += fract(fract(pc.t) + i + (light_pos_r.x + light_pos_r.y + light_pos_r.z)/1000.);
|
||||
|
||||
// Find random point on a sphere
|
||||
// TODO proper BRDF importance sampling and correct random point distribution
|
||||
vec3 rnd = normalize(vec3(rand01(), rand01(), rand01())*2.-1.);
|
||||
|
|
Loading…
Reference in New Issue