mirror of
https://github.com/w23/xash3d-fwgs
synced 2024-12-17 06:30:44 +01:00
rtx: implement more of that solid angle sampling
also tweak tonemapping and exposure a bit
This commit is contained in:
parent
74e9401e56
commit
14176f147f
@ -56,11 +56,20 @@ void main() {
|
||||
return;
|
||||
}
|
||||
|
||||
/* if (pix.y < res.y / 3) { */
|
||||
/* imageStore(dest, pix, vec4(pow(float(pix.x) / res.x, 2.2))); return; */
|
||||
/* } else if (pix.y < res.y * 2 / 3) { */
|
||||
/* imageStore(dest, pix, vec4(float(pix.x) / res.x)); return; */
|
||||
/* } else { */
|
||||
/* imageStore(dest, pix, vec4(sqrt(float(pix.x) / res.x))); return; */
|
||||
/* } */
|
||||
|
||||
const vec4 base_color = imageLoad(src_base_color, pix);
|
||||
const float material_index = imageLoad(src_diffuse_gi, pix).a;
|
||||
|
||||
//imageStore(dest, pix, vec4(aces_tonemap(base_color.rgb), 0.)); return;
|
||||
//imageStore(dest, pix, vec4((base_color.rgb), 0.)); return;
|
||||
//imageStore(dest, pix, vec4((imageLoad(src_diffuse_gi, pix).rgb), 0.)); return;
|
||||
//imageStore(dest, pix, vec4(aces_tonemap(imageLoad(src_diffuse_gi, pix).rgb), 0.)); return;
|
||||
//imageStore(dest, pix, vec4(aces_tonemap(imageLoad(src_specular, pix).rgb), 0.)); return;
|
||||
|
||||
@ -128,10 +137,26 @@ void main() {
|
||||
|
||||
// HACK: exposure
|
||||
// TODO: should be dynamic based on previous frames brightness
|
||||
colour *= 4.;
|
||||
#if 0
|
||||
if (pix.x >= res.x / 2) {
|
||||
colour *= 8.;
|
||||
}
|
||||
#else
|
||||
colour *= .25;
|
||||
#endif
|
||||
|
||||
//colour = aces_tonemap(colour);
|
||||
colour = reinhard02(colour, vec3(400.));
|
||||
colour = aces_tonemap(colour);
|
||||
//colour = reinhard02(colour, vec3(400.));
|
||||
//colour = reinhard02(colour, vec3(1.));
|
||||
|
||||
#if 0
|
||||
if (pix.x < res.x / 2) {
|
||||
#endif
|
||||
//colour *= .25;
|
||||
colour = pow(colour, vec3(1. / 2.2));
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
imageStore(dest, pix, vec4(colour, 0.));
|
||||
//imageStore(dest, pix, imageLoad(src_diffuse_gi, pix));
|
||||
|
@ -150,9 +150,21 @@ void sampleSurfaceTriangle(
|
||||
void sampleEmissiveSurface(vec3 throughput, vec3 view_dir, MaterialProperties material, SampleContext ctx, uint ekusok_index, out vec3 out_diffuse, out vec3 out_specular) {
|
||||
const EmissiveKusok ek = lights.kusochki[ekusok_index];
|
||||
const uint emissive_kusok_index = lights.kusochki[ekusok_index].kusok_index;
|
||||
if (emissive_kusok_index == uint(payload_opaque.kusok_index))
|
||||
return;
|
||||
|
||||
out_diffuse = out_specular = vec3(0.);
|
||||
|
||||
const Kusok kusok = kusochki[emissive_kusok_index];
|
||||
|
||||
// TODO streamline matrices layouts
|
||||
const mat4x3 to_world = mat4x3(
|
||||
vec3(ek.tx_row_x.x, ek.tx_row_y.x, ek.tx_row_z.x),
|
||||
vec3(ek.tx_row_x.y, ek.tx_row_y.y, ek.tx_row_z.y),
|
||||
vec3(ek.tx_row_x.z, ek.tx_row_y.z, ek.tx_row_z.z),
|
||||
vec3(ek.tx_row_x.w, ek.tx_row_y.w, ek.tx_row_z.w)
|
||||
);
|
||||
|
||||
const mat4x3 to_shading = ctx.world_to_shading * mat4(
|
||||
vec4(ek.tx_row_x.x, ek.tx_row_y.x, ek.tx_row_z.x, 0),
|
||||
vec4(ek.tx_row_x.y, ek.tx_row_y.y, ek.tx_row_z.y, 0),
|
||||
@ -160,24 +172,13 @@ void sampleEmissiveSurface(vec3 throughput, vec3 view_dir, MaterialProperties ma
|
||||
vec4(ek.tx_row_x.w, ek.tx_row_y.w, ek.tx_row_z.w, 1)
|
||||
);
|
||||
|
||||
const mat4x3 emissive_transform = mat4x3(
|
||||
vec3(ek.tx_row_x.x, ek.tx_row_y.x, ek.tx_row_z.x),
|
||||
vec3(ek.tx_row_x.y, ek.tx_row_y.y, ek.tx_row_z.y),
|
||||
vec3(ek.tx_row_x.z, ek.tx_row_y.z, ek.tx_row_z.z),
|
||||
vec3(ek.tx_row_x.w, ek.tx_row_y.w, ek.tx_row_z.w)
|
||||
);
|
||||
|
||||
|
||||
if (emissive_kusok_index == uint(payload_opaque.kusok_index))
|
||||
return;
|
||||
|
||||
// Taken from Ray Tracing Gems II, ch.47, p.776, listing 47-2
|
||||
// Picking a triangle is taken from Ray Tracing Gems II, ch.47, p.776, listing 47-2
|
||||
int selected = -1;
|
||||
float selected_contrib = 0.;
|
||||
float total_contrib = 0.;
|
||||
float eps1 = rand01();
|
||||
|
||||
solid_angle_polygon_t poly_angle;
|
||||
solid_angle_polygon_t selected_angle;
|
||||
vec4 selected_plane;
|
||||
for (uint i = 0; i < kusok.triangles; ++i) {
|
||||
const uint first_index_offset = kusok.index_offset + i * 3;
|
||||
const uint vi1 = uint(indices[first_index_offset+0]) + kusok.vertex_offset;
|
||||
@ -186,16 +187,20 @@ void sampleEmissiveSurface(vec3 throughput, vec3 view_dir, MaterialProperties ma
|
||||
|
||||
// Transform to shading space
|
||||
vec3 v[MAX_POLYGON_VERTEX_COUNT];
|
||||
v[0] = to_shading * vec4(vertices[vi1].pos, 1.);
|
||||
v[1] = to_shading * vec4(vertices[vi2].pos, 1.);
|
||||
v[2] = to_shading * vec4(vertices[vi3].pos, 1.);
|
||||
v[0] = to_world * vec4(vertices[vi1].pos, 1.);
|
||||
v[1] = to_world * vec4(vertices[vi2].pos, 1.);
|
||||
v[2] = to_world * vec4(vertices[vi3].pos, 1.);
|
||||
|
||||
// TODO cull by normal
|
||||
|
||||
// Clip
|
||||
const uint vertex_count = clip_polygon(3, v);
|
||||
/* const uint vertex_count = clip_polygon(3, v); */
|
||||
/* if (vertex_count == 0) */
|
||||
/* continue; */
|
||||
|
||||
// poly_angle
|
||||
poly_angle = prepare_solid_angle_polygon_sampling(vertex_count, v, payload_opaque.hit_pos_t.xyz);
|
||||
const float tri_contrib = poly_angle.solid_angle;
|
||||
const solid_angle_polygon_t sap = prepare_solid_angle_polygon_sampling(3, v, payload_opaque.hit_pos_t.xyz);
|
||||
const float tri_contrib = sap.solid_angle;
|
||||
|
||||
if (tri_contrib <= 0.)
|
||||
continue;
|
||||
@ -203,25 +208,64 @@ void sampleEmissiveSurface(vec3 throughput, vec3 view_dir, MaterialProperties ma
|
||||
const float tau = total_contrib / (total_contrib + tri_contrib);
|
||||
total_contrib += tri_contrib;
|
||||
|
||||
#if 0
|
||||
if (false) {
|
||||
#else
|
||||
if (eps1 < tau) {
|
||||
#endif
|
||||
eps1 /= tau;
|
||||
} else {
|
||||
selected = int(i);
|
||||
selected_contrib = tri_contrib;
|
||||
eps1 = (eps1 - tau) / (1. - tau);
|
||||
selected_angle = sap;
|
||||
|
||||
selected_plane.xyz = cross(v[1] - v[0], v[2] - v[0]);
|
||||
selected_plane.w = -dot(v[0], selected_plane.xyz);
|
||||
}
|
||||
|
||||
#define MAX_BELOW_ONE .99999 // FIXME what's the correct way to do this
|
||||
eps1 = clamp(eps1, 0., MAX_BELOW_ONE); // Numerical stability (?)
|
||||
}
|
||||
|
||||
if (selected >= 0) {
|
||||
sampleSurfaceTriangle(throughput * ek.emissive, view_dir, material, emissive_transform, selected, kusok.index_offset, kusok.vertex_offset, emissive_kusok_index, out_diffuse, out_specular);
|
||||
if (selected < 0 || selected_angle.solid_angle <= 0.)
|
||||
return;
|
||||
|
||||
const float tri_factor = total_contrib / selected_contrib;
|
||||
out_diffuse *= tri_factor;
|
||||
out_specular *= tri_factor;
|
||||
//sampleSurfaceTriangle(throughput * ek.emissive, view_dir, material, emissive_transform, selected, kusok.index_offset, kusok.vertex_offset, emissive_kusok_index, out_diffuse, out_specular);
|
||||
|
||||
vec2 rnd = vec2(rand01(), rand01());
|
||||
//const vec3 light_dir = normalize(inverse(mat3(ctx.world_to_shading)) * sample_solid_angle_polygon(poly_angle, rnd));
|
||||
const vec3 light_dir = sample_solid_angle_polygon(selected_angle, rnd);
|
||||
|
||||
vec3 tri_diffuse = vec3(0.), tri_specular = vec3(0.);
|
||||
#if 1
|
||||
evalSplitBRDF(payload_opaque.normal, light_dir, view_dir, material, tri_diffuse, tri_specular);
|
||||
tri_diffuse *= throughput * ek.emissive;
|
||||
tri_specular *= throughput * ek.emissive;
|
||||
#else
|
||||
tri_diffuse = vec3(selected_angle.solid_angle);
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
vec3 combined = tri_diffuse + tri_specular;
|
||||
if (dot(combined,combined) > color_culling_threshold) {
|
||||
const float dist = -dot(vec4(payload_opaque.hit_pos_t.xyz, 1.f), selected_plane) / dot(light_dir, selected_plane.xyz);
|
||||
if (!shadowed(payload_opaque.hit_pos_t.xyz, light_dir, dist)) {
|
||||
const float tri_factor = total_contrib; // selected_angle.solid_angle;
|
||||
out_diffuse += tri_diffuse * tri_factor;
|
||||
out_specular += tri_specular * tri_factor;
|
||||
}
|
||||
} else {
|
||||
#ifdef DEBUG_LIGHT_CULLING
|
||||
return vec3(1., 1., 0.) * color_factor;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
//const float tri_factor = total_contrib / selected_angle.solid_angle;
|
||||
out_diffuse += tri_diffuse * tri_factor;
|
||||
out_specular += tri_specular * tri_factor;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sampleEmissiveSurfaces(vec3 throughput, vec3 view_dir, MaterialProperties material, uint cluster_index, inout vec3 diffuse, inout vec3 specular) {
|
||||
@ -230,7 +274,7 @@ void sampleEmissiveSurfaces(vec3 throughput, vec3 view_dir, MaterialProperties m
|
||||
|
||||
const uint num_emissive_kusochki = uint(light_grid.clusters[cluster_index].num_emissive_surfaces);
|
||||
float sampling_light_scale = 1.;
|
||||
#if 1
|
||||
#if 0
|
||||
const uint max_lights_per_frame = 4;
|
||||
uint begin_i = 0, end_i = num_emissive_kusochki;
|
||||
if (end_i > max_lights_per_frame) {
|
||||
|
Loading…
Reference in New Issue
Block a user