Fix energy loss
This commit is contained in:
+73
-25
@@ -595,9 +595,8 @@ Vector3 pixel(float x, float y, float aspect_ratio)
|
|||||||
assert(!isnanv(in_ray.direction));
|
assert(!isnanv(in_ray.direction));
|
||||||
|
|
||||||
//Vector3 sky_color = {0.6, 0.7, 0.9};
|
//Vector3 sky_color = {0.6, 0.7, 0.9};
|
||||||
Vector3 sky_color = {0, 0, 0};
|
//Vector3 sky_color = {0, 0, 0};
|
||||||
//Vector3 sky_color = {1, 1, 1};
|
//Vector3 sky_color = {1, 1, 1};
|
||||||
0;
|
|
||||||
|
|
||||||
Vector3 contrib = {1, 1, 1};
|
Vector3 contrib = {1, 1, 1};
|
||||||
Vector3 result = {0, 0, 0};
|
Vector3 result = {0, 0, 0};
|
||||||
@@ -605,7 +604,7 @@ Vector3 pixel(float x, float y, float aspect_ratio)
|
|||||||
|
|
||||||
HitInfo hit = trace_ray(in_ray);
|
HitInfo hit = trace_ray(in_ray);
|
||||||
if (hit.object == -1) {
|
if (hit.object == -1) {
|
||||||
//Vector3 sky_color = sample_cubemap(&skybox, normalize(in_ray.direction));
|
Vector3 sky_color = sample_cubemap(&skybox, normalize(in_ray.direction));
|
||||||
result = combine(result, mulv(sky_color, contrib), 1, 1);
|
result = combine(result, mulv(sky_color, contrib), 1, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -615,24 +614,25 @@ Vector3 pixel(float x, float y, float aspect_ratio)
|
|||||||
if (objects[j].material.emission_power == 0 || j == hit.object)
|
if (objects[j].material.emission_power == 0 || j == hit.object)
|
||||||
continue;
|
continue;
|
||||||
Vector3 dir_to_light_source = combine(origin_of(objects[j]), hit.point, 1, -1);
|
Vector3 dir_to_light_source = combine(origin_of(objects[j]), hit.point, 1, -1);
|
||||||
|
int samples = 5;
|
||||||
|
float spread = 0.5;
|
||||||
|
for (int k = 0; k < samples; k++) {
|
||||||
// Add some noise based on roughness
|
// Add some noise based on roughness
|
||||||
Vector3 rand_dir = random_direction();
|
Vector3 rand_dir = random_direction();
|
||||||
if (dotv(rand_dir, hit.normal) < 0)
|
if (dotv(rand_dir, hit.normal) < 0)
|
||||||
rand_dir = scale(rand_dir, -1);
|
rand_dir = scale(rand_dir, -1);
|
||||||
dir_to_light_source = normalize(combine(rand_dir, dir_to_light_source, objects[j].material.roughness, 1));
|
Vector3 sample_dir = normalize(combine(rand_dir, dir_to_light_source, spread, 1));
|
||||||
Ray ray_to_light_source = { combine(hit.point, dir_to_light_source, 1, 0.001), dir_to_light_source };
|
Ray sample_ray = { combine(hit.point, sample_dir, 1, 0.001), sample_dir };
|
||||||
HitInfo hit2 = trace_ray(ray_to_light_source);
|
HitInfo hit2 = trace_ray(sample_ray);
|
||||||
if (hit2.object == j) {
|
if (hit2.object != -1)
|
||||||
sampled_light_color = scale(objects[hit2.object].material.emission_color, objects[hit2.object].material.emission_power);
|
sampled_light_color = combine(sampled_light_color, objects[hit2.object].material.emission_color, 1, objects[hit2.object].material.emission_power);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
sampled_light_color = scale(sampled_light_color, 1.0f / samples);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Material material = objects[hit.object].material;
|
Material material = objects[hit.object].material;
|
||||||
|
|
||||||
float perceptualRoughness = maxf(material.roughness, 0.089);
|
|
||||||
float roughness = perceptualRoughness * perceptualRoughness;
|
|
||||||
|
|
||||||
Vector3 v = scale(in_ray.direction, -1);
|
Vector3 v = scale(in_ray.direction, -1);
|
||||||
//Vector3 l = out_dir;
|
//Vector3 l = out_dir;
|
||||||
Vector3 n = hit.normal;
|
Vector3 n = hit.normal;
|
||||||
@@ -654,24 +654,18 @@ Vector3 pixel(float x, float y, float aspect_ratio)
|
|||||||
result = combine(result, mulv(scale(material.emission_color, material.emission_power), contrib), 1, 1);
|
result = combine(result, mulv(scale(material.emission_color, material.emission_power), contrib), 1, 1);
|
||||||
|
|
||||||
Vector3 out_dir;
|
Vector3 out_dir;
|
||||||
if (random_float() < avgv(F)) {
|
if (material.metallic > 0.001 || random_float() <= avgv(F)) {
|
||||||
// Specular ray
|
// Specular ray
|
||||||
Vector3 reflect_dir = reflect(in_ray.direction, scale(hit.normal, -1));
|
Vector3 reflect_dir = reflect(in_ray.direction, scale(hit.normal, -1));
|
||||||
out_dir = normalize(combine(rand_dir, reflect_dir, material.roughness, 1));
|
out_dir = normalize(combine(rand_dir, reflect_dir, material.roughness, 1));
|
||||||
float NoL = dotv(n, out_dir);
|
|
||||||
float specular_contrib = 1.0f / (4.0 * NoV * NoL + 0.0001);
|
|
||||||
contrib = scale(contrib, specular_contrib);
|
|
||||||
} else {
|
} else {
|
||||||
// Diffuse ray
|
// Diffuse ray
|
||||||
Vector3 diffuse_contrib = scale(material.albedo, (1 - material.metallic));
|
|
||||||
out_dir = rand_dir;
|
out_dir = rand_dir;
|
||||||
contrib = mulv(contrib, diffuse_contrib);
|
contrib = mulv(contrib, scale(material.albedo, (1 - material.metallic)));
|
||||||
}
|
}
|
||||||
float NoL = dotv(n, out_dir);
|
|
||||||
contrib = scale(contrib, NoL);
|
|
||||||
Ray out_ray = { combine(hit.point, out_dir, 1, 0.001), out_dir };
|
Ray out_ray = { combine(hit.point, out_dir, 1, 0.001), out_dir };
|
||||||
|
|
||||||
float light_sample_weight = 0.1;
|
float light_sample_weight = 0.05;
|
||||||
if (!iszerov(sampled_light_color)) {
|
if (!iszerov(sampled_light_color)) {
|
||||||
result = combine(result, mulv(sampled_light_color, contrib), 1, light_sample_weight);
|
result = combine(result, mulv(sampled_light_color, contrib), 1, light_sample_weight);
|
||||||
contrib = scale(contrib, 1 - light_sample_weight);
|
contrib = scale(contrib, 1 - light_sample_weight);
|
||||||
@@ -832,6 +826,60 @@ int main(void)
|
|||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
|
add_object(sphere(
|
||||||
|
(Material) {
|
||||||
|
.emission_color={1, 1, 1},
|
||||||
|
.emission_power=1,
|
||||||
|
.metallic=0,
|
||||||
|
.reflectance=0,
|
||||||
|
.roughness=0,
|
||||||
|
.albedo=(Vector3) {0.2, 0.5, 1},
|
||||||
|
},
|
||||||
|
(Vector3) {0, 2, 0},
|
||||||
|
1)
|
||||||
|
);
|
||||||
|
|
||||||
|
add_object(sphere(
|
||||||
|
(Material) {
|
||||||
|
.emission_color={0},
|
||||||
|
.emission_power=0,
|
||||||
|
.metallic=0,
|
||||||
|
.reflectance=0,
|
||||||
|
.roughness=0,
|
||||||
|
.albedo=(Vector3) {0.2, 0.5, 1},
|
||||||
|
},
|
||||||
|
(Vector3) {0, 0, 3},
|
||||||
|
1)
|
||||||
|
);
|
||||||
|
|
||||||
|
add_object(sphere(
|
||||||
|
(Material) {
|
||||||
|
.emission_color={0},
|
||||||
|
.emission_power=0,
|
||||||
|
.metallic=1,
|
||||||
|
.reflectance=0,
|
||||||
|
.roughness=0,
|
||||||
|
.albedo=(Vector3) {0.5, 0.2, 1},
|
||||||
|
},
|
||||||
|
(Vector3) {3, 0, 0},
|
||||||
|
1)
|
||||||
|
);
|
||||||
|
|
||||||
|
#elif 0
|
||||||
|
|
||||||
|
add_object(sphere(
|
||||||
|
(Material) {
|
||||||
|
.emission_color={0},
|
||||||
|
.emission_power=0,
|
||||||
|
.metallic=0,
|
||||||
|
.reflectance=1,
|
||||||
|
.roughness=0,
|
||||||
|
.albedo=(Vector3) {0.2, 0.5, 1},
|
||||||
|
},
|
||||||
|
(Vector3) {-3, 0, 0},
|
||||||
|
1)
|
||||||
|
);
|
||||||
|
|
||||||
add_object(sphere(
|
add_object(sphere(
|
||||||
(Material) {
|
(Material) {
|
||||||
.emission_color={0},
|
.emission_color={0},
|
||||||
@@ -960,7 +1008,7 @@ int main(void)
|
|||||||
add_object(cube(
|
add_object(cube(
|
||||||
(Material) {
|
(Material) {
|
||||||
.emission_color={1, 1, 1},
|
.emission_color={1, 1, 1},
|
||||||
.emission_power=3,
|
.emission_power=1,
|
||||||
.metallic=0,
|
.metallic=0,
|
||||||
.reflectance=0,
|
.reflectance=0,
|
||||||
.roughness=0,
|
.roughness=0,
|
||||||
@@ -976,7 +1024,7 @@ int main(void)
|
|||||||
.emission_power=0,
|
.emission_power=0,
|
||||||
.metallic=1,
|
.metallic=1,
|
||||||
.reflectance=0,
|
.reflectance=0,
|
||||||
.roughness=0,
|
.roughness=0.5,
|
||||||
.albedo=(Vector3) {0, 1, 0}
|
.albedo=(Vector3) {0, 1, 0}
|
||||||
},
|
},
|
||||||
(Vector3) {box_w/2, box_w/3, box_d/2},
|
(Vector3) {box_w/2, box_w/3, box_d/2},
|
||||||
@@ -995,10 +1043,10 @@ int main(void)
|
|||||||
add_object(cube ((Material) {.emission_color={0}, .emission_power=0, .metallic=0, .reflectance=0, .roughness=1, .albedo=(Vector3) {0.4, 0.3, 0.9}}, (Vector3) {0, -0.1, 0}, (Vector3) {9, 0.1, 9}));
|
add_object(cube ((Material) {.emission_color={0}, .emission_power=0, .metallic=0, .reflectance=0, .roughness=1, .albedo=(Vector3) {0.4, 0.3, 0.9}}, (Vector3) {0, -0.1, 0}, (Vector3) {9, 0.1, 9}));
|
||||||
|
|
||||||
add_object(cube ((Material) {.emission_color={0}, .emission_power=0, .metallic=0, .reflectance=0, .roughness=1, .albedo=(Vector3) {1, 0, 0}}, (Vector3) {5, 0, 6}, (Vector3) {1, 1, 1}));
|
add_object(cube ((Material) {.emission_color={0}, .emission_power=0, .metallic=0, .reflectance=0, .roughness=1, .albedo=(Vector3) {1, 0, 0}}, (Vector3) {5, 0, 6}, (Vector3) {1, 1, 1}));
|
||||||
add_object(cube ((Material) {.emission_color={0}, .emission_power=0, .metallic=0, .reflectance=0, .roughness=0, .albedo=(Vector3) {1, 0, 1}}, (Vector3) {4, 0, 5}, (Vector3) {1, 1, 1}));
|
add_object(cube ((Material) {.emission_color={0}, .emission_power=0, .metallic=0, .reflectance=1, .roughness=0, .albedo=(Vector3) {1, 0, 1}}, (Vector3) {4, 0, 5}, (Vector3) {1, 1, 1}));
|
||||||
|
|
||||||
add_object(sphere((Material) {.emission_color={0}, .emission_power=0, .metallic=0, .reflectance=0, .roughness=1, .albedo=(Vector3) {1, 0.4, 0}}, (Vector3) {3, 1, 3}, 1));
|
add_object(sphere((Material) {.emission_color={0}, .emission_power=0, .metallic=0, .reflectance=0, .roughness=1, .albedo=(Vector3) {1, 0.4, 0}}, (Vector3) {3, 1, 3}, 1));
|
||||||
add_object(sphere((Material) {.emission_color={0}, .emission_power=0, .metallic=0, .reflectance=0, .roughness=0, .albedo=(Vector3) {0, 1, 0}}, (Vector3) {5, 1, 3}, 1));
|
add_object(sphere((Material) {.emission_color={0}, .emission_power=0, .metallic=0, .reflectance=1, .roughness=0, .albedo=(Vector3) {0, 1, 0}}, (Vector3) {5, 1, 3}, 1));
|
||||||
add_object(sphere((Material) {.emission_color={1, 0.5, 0.5}, .emission_power=5, .metallic=0, .reflectance=0, .roughness=1, .albedo=(Vector3) {1, 0.4, 0}}, (Vector3) {3, 5, 3}, 1));
|
add_object(sphere((Material) {.emission_color={1, 0.5, 0.5}, .emission_power=5, .metallic=0, .reflectance=0, .roughness=1, .albedo=(Vector3) {1, 0.4, 0}}, (Vector3) {3, 5, 3}, 1));
|
||||||
#elif 1
|
#elif 1
|
||||||
// add_object(cube ((Material) {.emission_color={0}, .emission_power=0, .metallic=0, .reflectance=0, .roughness=0, .albedo=(Vector3) {1, 0.3, 0.3}}, (Vector3) {0, 0, 0}, (Vector3) {10, 5, 0.1}));
|
// add_object(cube ((Material) {.emission_color={0}, .emission_power=0, .metallic=0, .reflectance=0, .roughness=0, .albedo=(Vector3) {1, 0.3, 0.3}}, (Vector3) {0, 0, 0}, (Vector3) {10, 5, 0.1}));
|
||||||
|
|||||||
Reference in New Issue
Block a user