Add light sampling
This commit is contained in:
@@ -1 +1,2 @@
|
|||||||
*.exe
|
*.exe
|
||||||
|
*.exr
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
"""
|
||||||
|
# Import the library using the alias "mi"
|
||||||
|
import mitsuba as mi
|
||||||
|
# Set the variant of the renderer
|
||||||
|
mi.set_variant('scalar_rgb')
|
||||||
|
# Load a scene
|
||||||
|
scene = mi.load_dict(mi.cornell_box())
|
||||||
|
# Render the scene
|
||||||
|
img = mi.render(scene)
|
||||||
|
# Write the rendered image to an EXR file
|
||||||
|
mi.Bitmap(img).write('cbox.exr')
|
||||||
|
"""
|
||||||
|
import mitsuba as mi
|
||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
mi.set_variant('scalar_rgb')
|
||||||
|
|
||||||
|
# Define a scene with a sphere and a cube
|
||||||
|
scene_dict = {
|
||||||
|
'type': 'scene',
|
||||||
|
'integrator': {
|
||||||
|
'type': 'path'
|
||||||
|
},
|
||||||
|
'sensor': {
|
||||||
|
'type': 'perspective',
|
||||||
|
'film': {
|
||||||
|
'type': 'hdrfilm',
|
||||||
|
'width': 800,
|
||||||
|
'height': 600,
|
||||||
|
},
|
||||||
|
'sampler': {
|
||||||
|
'type': 'independent',
|
||||||
|
'sample_count': 64
|
||||||
|
},
|
||||||
|
'to_world': mi.ScalarTransform4f.look_at(
|
||||||
|
origin=[10, 10, 10], # Camera position
|
||||||
|
target=[0, 0, 0], # Camera looks at the origin
|
||||||
|
up=[0, 1, 0] # Up direction for the camera
|
||||||
|
)
|
||||||
|
},
|
||||||
|
'light': {
|
||||||
|
'type': 'point',
|
||||||
|
'position': [0, 5, 0],
|
||||||
|
'intensity': {'type': 'spectrum', 'value': 30.0}
|
||||||
|
},
|
||||||
|
'sphere': {
|
||||||
|
'type': 'sphere',
|
||||||
|
'center': [0, 0, 0],
|
||||||
|
'radius': 1,
|
||||||
|
'bsdf': {
|
||||||
|
'type': 'diffuse',
|
||||||
|
'reflectance': {'type': 'rgb', 'value': [0.8, 0.3, 0.3]}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'cube': {
|
||||||
|
'type': 'cube',
|
||||||
|
'to_world': mi.ScalarTransform4f.translate([2, 0, 0]).scale(1),
|
||||||
|
'bsdf': {
|
||||||
|
'type': 'diffuse',
|
||||||
|
'reflectance': {'type': 'rgb', 'value': [0.3, 0.8, 0.3]}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'floor': {
|
||||||
|
'type': 'cube',
|
||||||
|
'to_world': mi.ScalarTransform4f.translate([0, -0.5, 0]).scale([5, 0.01, 5]),
|
||||||
|
'bsdf': {
|
||||||
|
'type': 'diffuse',
|
||||||
|
'reflectance': {'type': 'rgb', 'value': [0.8, 0.8, 0.8]} # Light grey floor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Load and render the scene
|
||||||
|
scene = mi.load_dict(scene_dict)
|
||||||
|
img = mi.render(scene)
|
||||||
|
|
||||||
|
# Convert the rendered image to a numpy array
|
||||||
|
bitmap = mi.Bitmap(img)
|
||||||
|
image_np = np.array(bitmap.convert(mi.Bitmap.PixelFormat.RGB, mi.Struct.Type.UInt8))
|
||||||
|
|
||||||
|
# Display the image using OpenCV
|
||||||
|
cv2.imshow('Rendered Image', image_np)
|
||||||
|
cv2.waitKey(0) # Press any key to close the window
|
||||||
|
cv2.destroyAllWindows()
|
||||||
+56
-19
@@ -553,6 +553,13 @@ HitInfo trace_ray(Ray ray)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector3 origin_of(Object o)
|
||||||
|
{
|
||||||
|
if (o.type == OBJECT_SPHERE)
|
||||||
|
return o.sphere.center;
|
||||||
|
return combine(o.cube.origin, o.cube.size, 1, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
Cubemap skybox;
|
Cubemap skybox;
|
||||||
|
|
||||||
Vector3 pixel(float x, float y, float aspect_ratio)
|
Vector3 pixel(float x, float y, float aspect_ratio)
|
||||||
@@ -570,8 +577,6 @@ Vector3 pixel(float x, float y, float aspect_ratio)
|
|||||||
Vector3 result = {0, 0, 0};
|
Vector3 result = {0, 0, 0};
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
|
|
||||||
assert(!isnanv(in_ray.direction));
|
|
||||||
|
|
||||||
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));
|
||||||
@@ -581,19 +586,14 @@ Vector3 pixel(float x, float y, float aspect_ratio)
|
|||||||
Material material = objects[hit.object].material;
|
Material material = objects[hit.object].material;
|
||||||
|
|
||||||
Vector3 reflect_dir = reflect(in_ray.direction, scale(hit.normal, -1));
|
Vector3 reflect_dir = reflect(in_ray.direction, scale(hit.normal, -1));
|
||||||
assert(!isnanv(reflect_dir));
|
|
||||||
|
|
||||||
Vector3 rand_dir = random_direction();
|
Vector3 rand_dir = random_direction();
|
||||||
assert(!isnanv(rand_dir));
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
Vector3 out_dir = normalize(combine(rand_dir, reflect_dir, material.roughness, 1));
|
Vector3 out_dir = normalize(combine(rand_dir, reflect_dir, material.roughness, 1));
|
||||||
assert(!isnanv(out_dir));
|
Ray out_ray = { combine(hit.point, out_dir, 1, 0.001), out_dir };
|
||||||
|
|
||||||
Ray out_ray = (Ray) { combine(hit.point, out_dir, 1, 0.001), out_dir };
|
|
||||||
|
|
||||||
|
Vector3 diffuse_contrib;
|
||||||
|
Vector3 emitted_light;
|
||||||
{
|
{
|
||||||
float perceptualRoughness = maxf(material.roughness, 0.089);
|
float perceptualRoughness = maxf(material.roughness, 0.089);
|
||||||
float roughness = perceptualRoughness * perceptualRoughness;
|
float roughness = perceptualRoughness * perceptualRoughness;
|
||||||
@@ -615,10 +615,37 @@ Vector3 pixel(float x, float y, float aspect_ratio)
|
|||||||
|
|
||||||
Vector3 specular = scale(F, (D * V) / (4.0 * NoV * NoL + 0.0001));
|
Vector3 specular = scale(F, (D * V) / (4.0 * NoV * NoL + 0.0001));
|
||||||
Vector3 diffuse = mulv(combine((Vector3) {1, 1, 1}, F, 1, -1), scale(material.albedo, 1 - material.metallic));
|
Vector3 diffuse = mulv(combine((Vector3) {1, 1, 1}, F, 1, -1), scale(material.albedo, 1 - material.metallic));
|
||||||
Vector3 combined = combine(diffuse, specular, 1, 1);
|
diffuse_contrib = scale(combine(diffuse, specular, 1, 1), NoL);
|
||||||
|
emitted_light = scale(material.emission_color, material.emission_power);
|
||||||
|
}
|
||||||
|
|
||||||
result = combine(result, mulv(contrib, material.emission_color), 1, material.emission_power);
|
bool sampled_light = false;
|
||||||
contrib = mulv(contrib, scale(combined, NoL));
|
Vector3 sampled_light_color;
|
||||||
|
{
|
||||||
|
for (int j = 0; j < num_objects; j++) {
|
||||||
|
if (objects[j].material.emission_power == 0 || j == hit.object)
|
||||||
|
continue;
|
||||||
|
Vector3 dir_to_light_source = combine(origin_of(objects[j]), hit.point, 1, -1);
|
||||||
|
// Add some noise based on roughness
|
||||||
|
Vector3 rand_dir = random_direction();
|
||||||
|
if (dotv(rand_dir, hit.normal) < 0)
|
||||||
|
rand_dir = scale(rand_dir, -1);
|
||||||
|
dir_to_light_source = normalize(combine(rand_dir, dir_to_light_source, material.roughness, 1));
|
||||||
|
Ray ray_to_light_source = { combine(hit.point, dir_to_light_source, 1, 0.001), dir_to_light_source };
|
||||||
|
HitInfo hit2 = trace_ray(ray_to_light_source);
|
||||||
|
if (hit2.object == j) {
|
||||||
|
sampled_light = true;
|
||||||
|
sampled_light_color = scale(objects[hit2.object].material.emission_color, objects[hit2.object].material.emission_power);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = combine(result, mulv(emitted_light, contrib), 1, 1);
|
||||||
|
contrib = mulv(contrib, diffuse_contrib);
|
||||||
|
if (sampled_light) {
|
||||||
|
contrib = scale(contrib, 0.5);
|
||||||
|
result = combine(result, mulv(sampled_light_color, contrib), 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
in_ray = out_ray;
|
in_ray = out_ray;
|
||||||
@@ -812,7 +839,7 @@ int main(void)
|
|||||||
.emission_power=0,
|
.emission_power=0,
|
||||||
.metallic=0,
|
.metallic=0,
|
||||||
.reflectance=0,
|
.reflectance=0,
|
||||||
.roughness=0,
|
.roughness=1,
|
||||||
.albedo=(Vector3) {1, 1, 1}
|
.albedo=(Vector3) {1, 1, 1}
|
||||||
},
|
},
|
||||||
(Vector3) {0, 0, 0},
|
(Vector3) {0, 0, 0},
|
||||||
@@ -825,7 +852,7 @@ int main(void)
|
|||||||
.emission_power=0,
|
.emission_power=0,
|
||||||
.metallic=0,
|
.metallic=0,
|
||||||
.reflectance=0,
|
.reflectance=0,
|
||||||
.roughness=0,
|
.roughness=1,
|
||||||
.albedo=(Vector3) {1, 1, 1}
|
.albedo=(Vector3) {1, 1, 1}
|
||||||
},
|
},
|
||||||
(Vector3) {box_w, 0, 0},
|
(Vector3) {box_w, 0, 0},
|
||||||
@@ -847,8 +874,8 @@ int main(void)
|
|||||||
|
|
||||||
add_object(cube(
|
add_object(cube(
|
||||||
(Material) {
|
(Material) {
|
||||||
.emission_color={1, 1, 1},
|
.emission_color={0.5, 0.5, 0.5},
|
||||||
.emission_power=2,
|
.emission_power=1,
|
||||||
.metallic=0,
|
.metallic=0,
|
||||||
.reflectance=0,
|
.reflectance=0,
|
||||||
.roughness=1,
|
.roughness=1,
|
||||||
@@ -871,7 +898,7 @@ int main(void)
|
|||||||
box_w/3
|
box_w/3
|
||||||
));
|
));
|
||||||
|
|
||||||
#elif 0
|
#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}));
|
||||||
add_object(cube ((Material) {.emission_color={0}, .emission_power=0, .metallic=0, .reflectance=0, .roughness=0.6, .albedo=(Vector3) {0.3, 1, 0.3}}, (Vector3) {0, 0, 0}, (Vector3) {0.1, 5, 10}));
|
add_object(cube ((Material) {.emission_color={0}, .emission_power=0, .metallic=0, .reflectance=0, .roughness=0.6, .albedo=(Vector3) {0.3, 1, 0.3}}, (Vector3) {0, 0, 0}, (Vector3) {0.1, 5, 10}));
|
||||||
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) {10, 0.1, 10}));
|
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) {10, 0.1, 10}));
|
||||||
@@ -879,9 +906,19 @@ int main(void)
|
|||||||
add_object(cube ((Material) {.emission_color={0}, .emission_power=0, .metallic=0, .reflectance=0, .roughness=0, .albedo=(Vector3) {1, 0, 1}}, (Vector3) {6, 0, 7}, (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) {6, 0, 7}, (Vector3) {1, 1, 1}));
|
||||||
add_object(sphere((Material) {.emission_color={0}, .emission_power=0, .metallic=0, .reflectance=0, .roughness=0.5, .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.5, .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=0, .roughness=0, .albedo=(Vector3) {0, 1, 0}}, (Vector3) {5, 1, 3}, 1));
|
||||||
add_object(sphere((Material) {.emission_color={1, 0.4, 0.2}, .emission_power=3, .metallic=0, .reflectance=0, .roughness=1, .albedo=(Vector3) {1, 0.4, 0}}, (Vector3) {3, 5, 3}, 1));
|
add_object(sphere((Material) {.emission_color={1, 1, 1}, .emission_power=1, .metallic=0, .reflectance=0, .roughness=1, .albedo=(Vector3) {1, 0.4, 0}}, (Vector3) {3, 5, 3}, 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.6, .albedo=(Vector3) {0.3, 1, 0.3}}, (Vector3) {0, 0, 0}, (Vector3) {0.1, 5, 10}));
|
||||||
|
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) {10, 0.1, 10}));
|
||||||
|
// add_object(cube ((Material) {.emission_color={0}, .emission_power=0, .metallic=0, .reflectance=0, .roughness=1, .albedo=(Vector3) {1, 0, 0}}, (Vector3) {7, 0, 8}, (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) {6, 0, 7}, (Vector3) {1, 1, 1}));
|
||||||
|
// add_object(sphere((Material) {.emission_color={0}, .emission_power=0, .metallic=0, .reflectance=0, .roughness=0.5, .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={1, 1, 1}, .emission_power=1, .metallic=0, .reflectance=0, .roughness=1, .albedo=(Vector3) {1, 0.4, 0}}, (Vector3) {3, 5, 3}, 1));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const char *faces[] = {
|
const char *faces[] = {
|
||||||
[CF_RIGHT] = "assets/skybox/right.jpg",
|
[CF_RIGHT] = "assets/skybox/right.jpg",
|
||||||
|
|||||||
Reference in New Issue
Block a user