-
I need to simulate a complex optical setup in which there is a small gap (~1um) between two surfaces. I noticed that when two surfaces are too close to one another, only one of them interacts with light. Below is what I think is a minimum example that reproduces what I mean: I have a camera observing two planes, separated by a gap. The first is transparent to R and G light, the other is transparent to G and B light. In the overlapping part, as seen from the camera, I get a green rectangle, as expected. However, when reducing the gap below 0.5mm, only the surface closest to the camera is taken into account and the result is a yellow square. I'm using Mitsuba 3.6.0, compiled from source. Minimum example code: import mitsuba as mi
mi.set_variant("cuda_rgb")
gap_m = 0.0005 # --> Works (green square).
# gap_m = 0.0004 # --> Breaks (no green square).
# Scene definition.
scene_dict = {
"type": "scene",
"integrator": {
"type": "path",
"max_depth": 12,
},
"emitter": {
"type": "constant",
"radiance": {
"type": "d65",
"scale": 1.0,
},
},
"camera": {
"type": "perspective",
"fov": 45,
"sampler": {"type": "multijitter", "sample_count": 64},
"film": {"type": "hdrfilm", "width": 640, "height": 480},
},
"shape_1": {
"type": "rectangle",
"to_world": mi.ScalarTransform4f.translate([0, 0, 4 - gap_m]),
"material": {
"type": "dielectric",
"int_ior": 1.0,
"ext_ior": 1.0,
#
"specular_transmittance": {"type": "rgb", "value": [1.0, 1.0, 0.0]},
},
},
"shape_2": {
"type": "rectangle",
"to_world": mi.ScalarTransform4f.translate([0, 0, 4]),
"material": {
"type": "dielectric",
"int_ior": 1.0,
"ext_ior": 1.0,
"specular_transmittance": {"type": "rgb", "value": [0.0, 1.0, 1.0]},
},
},
}
# Render and save.
scene = mi.load_dict(scene_dict)
img = mi.render(scene, spp=1024)
bmp = mi.Bitmap(img)
bmp = bmp.convert(mi.Bitmap.PixelFormat.RGB, mi.Struct.Type.UInt8)
bmp.write("debug_thin_gaps.png") I understand that for meshes that are too close to one another, floating point precision can make it difficult to compute ray/surface intersections right, which can lead to artifacts, but 5e-4 doesn't seem that small for a float32. Also, with the same scene in Blender/Cycles, I can go down to 1um gap without problem (and maybe it's more a limitation of the GUI not allowing too many decimals), which makes me think this can be some sort of feature in Mitsuba to avoid close meshes to interfere. I thought that a workaround could be just to scale the scene, to make everything, say, 1000x bigger and then the surfaces 1000x farther apart, but this doesn't work... |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Hi @cvejarano After an intersection has been found we offset the ray origin by a small amount to avoid self-intersections, you can find the relevant code here: https://github.com/mitsuba-renderer/mitsuba3/blob/master/include/mitsuba/render/interaction.h#L160-L169. I believe the issue you're running into is that this value is simply too large. You could try modifying that method directly, by reducing |
Beta Was this translation helpful? Give feedback.
Hi @cvejarano
After an intersection has been found we offset the ray origin by a small amount to avoid self-intersections, you can find the relevant code here: https://github.com/mitsuba-renderer/mitsuba3/blob/master/include/mitsuba/render/interaction.h#L160-L169. I believe the issue you're running into is that this value is simply too large. You could try modifying that method directly, by reducing
RayEpsilon
or completely changing that logic.The reason this value is a bit too aggressive is that the various shape types we have implemented in Mitsuba all have different numerical tolerances/precision, it's therefore set for the worst case scenario.