Assorted fixes to UV unwrapping and GPU lightmapper

Various fixes to UV2 unwrapping and the GPU lightmapper. Listed here for
context in case of git blame/bisect:

* Fix UV2 unwrapping on import, also cleaned up the unwrap cache code.
* Fix saving of RGBA images in EXR format.
* Fixes to the GPU lightmapper:
	- Added padding between atlas elements, avoids bleeding.
	- Remove old SDF generation code.
	- Fix baked attenuation for Omni/Spot lights.
	- Fix baking of material properties onto UV2 (wireframe was
	  wrongly used before).
	- Disable statically baked lights for objects that have a
	  lightmap texture to avoid applying the same light twice.
	- Fix lightmap pairing in RendererSceneCull.
	- Fix UV2 array generated from `RenderingServer::mesh_surface_get_arrays()`.
	- Port autoexposure fix for OIDN from 3.x.
	- Save debug textures as EXR when using floating point format.
This commit is contained in:
jfons
2021-04-25 23:36:39 +02:00
parent eb57dcdb90
commit 6995b0429c
21 changed files with 457 additions and 481 deletions

View File

@ -96,15 +96,22 @@ params;
bool ray_hits_triangle(vec3 from, vec3 dir, float max_dist, vec3 p0, vec3 p1, vec3 p2, out float r_distance, out vec3 r_barycentric) {
const vec3 e0 = p1 - p0;
const vec3 e1 = p0 - p2;
vec3 triangleNormal = cross(e1, e0);
vec3 triangle_normal = cross(e1, e0);
const vec3 e2 = (1.0 / dot(triangleNormal, dir)) * (p0 - from);
float n_dot_dir = dot(triangle_normal, dir);
if (abs(n_dot_dir) < 0.01) {
return false;
}
const vec3 e2 = (p0 - from) / n_dot_dir;
const vec3 i = cross(dir, e2);
r_barycentric.y = dot(i, e1);
r_barycentric.z = dot(i, e0);
r_barycentric.x = 1.0 - (r_barycentric.z + r_barycentric.y);
r_distance = dot(triangleNormal, e2);
r_distance = dot(triangle_normal, e2);
return (r_distance > params.bias) && (r_distance < max_dist) && all(greaterThanEqual(r_barycentric, vec3(0.0)));
}
@ -307,8 +314,6 @@ void main() {
continue;
}
d /= lights.data[i].range;
attenuation = get_omni_attenuation(d, 1.0 / lights.data[i].range, lights.data[i].attenuation);
if (lights.data[i].type == LIGHT_TYPE_SPOT) {
@ -410,7 +415,7 @@ void main() {
uint tidx;
vec3 barycentric;
vec3 light;
vec3 light = vec3(0.0);
if (trace_ray(position + ray_dir * params.bias, position + ray_dir * length(params.world_size), tidx, barycentric)) {
//hit a triangle
vec2 uv0 = vertices.data[triangles.data[tidx].indices.x].uv;
@ -419,8 +424,8 @@ void main() {
vec3 uvw = vec3(barycentric.x * uv0 + barycentric.y * uv1 + barycentric.z * uv2, float(triangles.data[tidx].slice));
light = textureLod(sampler2DArray(source_light, linear_sampler), uvw, 0.0).rgb;
} else {
//did not hit a triangle, reach out for the sky
} else if (params.env_transform[0][3] == 0.0) { // Use env_transform[0][3] to indicate when we are computing the first bounce
// Did not hit a triangle, reach out for the sky
vec3 sky_dir = normalize(mat3(params.env_transform) * ray_dir);
vec2 st = vec2(