Merge branch 'sample-emissive-lights-textures' into E177

Also do not multiply emissive textures by emissive color. similar to how
original lighting works.
qrad lighting treats emissive surfaces as constant color w/o paying
attention to texture contents. And then the rederer just draws textures
w/o lightmaps.

We need to figure out what to do with pbr path tracer.
This commit is contained in:
Ivan Avdeev 2021-12-08 10:43:11 -08:00
commit 4becafc02c
3 changed files with 52 additions and 16 deletions

View File

@ -157,7 +157,15 @@ void main() {
payload.transmissiveness = (1. - tex_color.a * kusok.color.a);
payload.normal = normal;
payload.geometry_normal = geom_normal;
payload.emissive = kusok.emissive * base_color; // TODO emissive should have a special texture
payload.emissive = vec3(0.);
if (any(greaterThan(kusok.emissive, vec3(0.)))) {
const vec3 emissive_color = base_color;
//const vec3 emissive_color = pow(base_color, vec3(2.2));
//const float max_color = max(max(emissive_color.r, emissive_color.g), emissive_color.b);
payload.emissive = emissive_color;// * mix(vec3(1.), kusok.emissive, smoothstep(.3, .6, max_color));
}
payload.kusok_index = kusok_index;
payload.roughness = (kusok.tex_roughness > 0) ? sampleTexture(kusok.tex_roughness, texture_uv, uv_lods).r : kusok.roughness;

View File

@ -1,4 +1,5 @@
#version 460 core
#extension GL_EXT_nonuniform_qualifier : enable
#extension GL_GOOGLE_include_directive : require
#include "ray_common.glsl"
#include "ray_kusochki.glsl"
@ -16,6 +17,7 @@ const float throughput_threshold = 1e-3;
layout (constant_id = 4) const float LIGHT_GRID_CELL_SIZE = 256.;
layout (constant_id = 5) const uint MAX_LIGHT_CLUSTERS = 32768;
layout (constant_id = 6) const uint MAX_TEXTURES = 4096;
layout (constant_id = 7) const uint SBT_RECORD_SIZE = 64;
//const uint LIGHT_CLUSTER_SIZE = 2 + MAX_VISIBLE_POINT_LIGHTS + MAX_VISIBLE_SURFACE_LIGHTS;
@ -25,6 +27,7 @@ layout (constant_id = 7) const uint SBT_RECORD_SIZE = 64;
//const uint LIGHT_CLUSTER_EMISSIVE_SURFACES_DATA_OFFSET = 3 + MAX_VISIBLE_DLIGHTS;
layout(set = 0, binding = 0, rgba8) uniform image2D out_image_base_color;
layout(set = 0, binding = 6) uniform sampler2D textures[MAX_TEXTURES];
layout(set = 0, binding = 9, rgba16f) uniform image2D out_image_diffuse_gi;
layout(set = 0, binding = 10, rgba16f) uniform image2D out_image_specular;
layout(set = 0, binding = 11, rgba16f) uniform image2D out_image_additive;
@ -113,10 +116,19 @@ float triangleSolidAngle(vec3 p, vec3 a, vec3 b, vec3 c) {
return atan(tanHalfOmega) * 2.;
}
vec3 baryMix(vec3 v1, vec3 v2, vec3 v3, vec2 bary) {
return v1 * (1. - bary.x - bary.y) + v2 * bary.x + v3 * bary.y;
}
vec2 baryMix(vec2 v1, vec2 v2, vec2 v3, vec2 bary) {
return v1 * (1. - bary.x - bary.y) + v2 * bary.x + v3 * bary.y;
}
void sampleSurfaceTriangle(
vec3 color, vec3 view_dir, MaterialProperties material /* TODO BrdfData instead is supposedly more efficient */,
mat4x3 emissive_transform, mat3 emissive_transform_normal,
uint triangle_index, uint index_offset, uint vertex_offset,
uint kusok_index,
out vec3 diffuse, out vec3 specular)
{
diffuse = specular = vec3(0.);
@ -132,7 +144,9 @@ void sampleSurfaceTriangle(
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());
vec2 bary = vec2(rand01(), rand01());
bary.y *= (1. - bary.x);
const vec3 sample_pos = baryMix(v1, v2, v3, bary);
vec3 light_dir = sample_pos - payload_opaque.hit_pos_t.xyz;
const float light_dir_normal_dot = dot(light_dir, payload_opaque.normal);
@ -167,6 +181,20 @@ void sampleSurfaceTriangle(
return;
#endif
#if 0
{
const uint tex_index = kusochki[kusok_index].tex_base_color;
if ((KUSOK_MATERIAL_FLAG_SKYBOX & tex_index) == 0) {
const vec2 uv1 = vertices[vi1].gl_tc;
const vec2 uv2 = vertices[vi2].gl_tc;
const vec2 uv3 = vertices[vi3].gl_tc;
const vec2 uv = baryMix(uv1, uv2, uv3, bary);
color *= texture(textures[nonuniformEXT(tex_index)], uv).rgb;
}
}
#endif
color /= pdf;
if (dot(color,color) < color_culling_threshold)
@ -342,7 +370,7 @@ void computeLighting(vec3 throughput, vec3 view_dir, MaterialProperties material
const uint triangle_index = rand_range(ekusok.triangles);
vec3 ldiffuse, lspecular;
sampleSurfaceTriangle(throughput * ek.emissive, view_dir, material, emissive_transform, emissive_transform_normal, triangle_index, ekusok.index_offset, ekusok.vertex_offset, ldiffuse, lspecular);
sampleSurfaceTriangle(throughput * ek.emissive, view_dir, material, emissive_transform, emissive_transform_normal, triangle_index, ekusok.index_offset, ekusok.vertex_offset, emissive_kusok_index, ldiffuse, lspecular);
diffuse += ldiffuse * sampling_light_scale;
specular += lspecular * sampling_light_scale;
} // for all emissive kusochki
@ -407,23 +435,23 @@ void main() {
vec3 additive = traceAdditive(origin, direction, payload_opaque.hit_pos_t.w <= 0. ? L : payload_opaque.hit_pos_t.w);
// Sky/envmap
if (payload_opaque.kusok_index < 0) {
// Sky/envmap/emissive
if ((payload_opaque.kusok_index < 0) || any(greaterThan(payload_opaque.emissive, vec3(0.)))) {
if (bounce == 0) {
out_additive += payload_opaque.emissive * color_factor + additive;
} else {
out_accumulated += throughput * (payload_opaque.emissive * color_factor + additive);
out_accumulated += throughput * (/*payload_opaque.emissive * color_factor +*/ additive);
}
break;
}
#ifdef DEBUG_LIGHT_CULLING
#if 0 //def DEBUG_LIGHT_CULLING
// light clusters debugging
{
const ivec3 light_cell = ivec3(floor(payload_opaque.hit_pos_t.xyz / LIGHT_GRID_CELL_SIZE)) - light_grid.grid_min;
const uint cluster_index = uint(dot(light_cell, ivec3(1, light_grid.grid_size.x, light_grid.grid_size.x * light_grid.grid_size.y)));
if (any(greaterThanEqual(light_cell, light_grid.grid_size)) || cluster_index >= MAX_LIGHT_CLUSTERS) {
C = vec3(1., 0., 0.) * color_factor;
out_additive = vec3(1., 0., 0.) * color_factor;
break;
}
@ -436,15 +464,15 @@ void main() {
continue;
}
C = vec3(0., 0., 1.) * color_factor;
out_additive = vec3(0., 0., 1.) * color_factor;
}
/* const uvec3 cellrand = pcg3d(uvec3(light_cell)); */
/* C = .02 * color_factor * vec3( */
/* uintToFloat01(cellrand.r), */
/* uintToFloat01(cellrand.g), */
/* uintToFloat01(cellrand.b)); */
//break;
const uvec3 cellrand = pcg3d(uvec3(light_cell));
out_additive = .2 * color_factor * vec3(
uintToFloat01(cellrand.r),
uintToFloat01(cellrand.g),
uintToFloat01(cellrand.b));
break;
}
#endif

View File

@ -1170,7 +1170,7 @@ static void createLayouts( void ) {
.binding = RayDescBinding_Textures,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = MAX_TEXTURES,
.stageFlags = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR,
.stageFlags = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR | VK_SHADER_STAGE_RAYGEN_BIT_KHR,
// FIXME on AMD using immutable samplers leads to nearest filtering ???!
.pImmutableSamplers = NULL, //samplers,
};