Blender(cycles) fails to render correct values in some pixels. Fails to hit correct triangle. Why? And how to avoid this problem?
Open, Needs TriagePublic

Description

I do some rendering in blender(cycles). I render with the help of cycles nodes .exr images, where in each pixel instead of rgba-channels I store xyzObjectIndex-channels. Everything works fine up to several pixels.

For example, on the image above you can see visualization of the object ids. Each pixel has information onto which object it looks now. You can see that blender failed to recognize building in one blue pixel, blender suggested that this part of the building is the sky and has rendered sky there.

As I can see this happens for degenerate triangles, triangles which are almost in parallel to the ray, which is shoot from pixel. It means that blender(cycles) raytracing algorithm fails to detect correct triangle when shooting ray.

Material setup:

This nodes help me to render .exr image, where instead of RGB I have XYZ - 3D position of the surface seen by pixel and instead of alpha - Object Index. Rendered image is correct up to a few pixels.

Geometry of the mesh: As far as I know my mesh consists from triangles.

Rendering machine: I use SVM.

Samples: one ray.

How to avoid this problem?

Here is test scene for testing:

P.S.: Also noticed that function ray_triangle_intersect() in file "\cycles\util\util_math_intersect.h" returns sometimes wrong barycentric coordinates (u + v > 1, which is wrong), hence it renders incorrect 3D position for current pixel. Wrong barycentric coordinates are there due to fact that in line 182 (const float inv_den = 1.0f / den;) happens division by zero.

Details

Type
Bug
Philipp Oeser (lichtwerk) triaged this task as Incomplete priority.Apr 23 2018, 12:25 PM

Thanx for investigating.
Could you please attach a .blend as well so someone can reproduce with your geometry?

Thanx for investigating.
Could you please attach a .blend as well so someone can reproduce with your geometry?

I have attached a test scene.

Not really sure this is the solution to all issues in question (havent checked any code and your first example pic seems unrelated to the example scene?)

BUT: in the provided scene, there is a gap between faces (right where you get black pixels).
If I close this gap (by slightly moving one edge up in Z and merge vertices), those black pixels are gone...

Not sure this is a bug?
If this is unrelated, please provide another example (without gaps in the geometry, where this issue also shows...)

Marking as incomplete for the time being...

Dear @Philipp Oeser (lichtwerk) , thanks for your answer. Yes, you are right in some places I have gaps in the mesh, that's why positions were wrong. But in most cases 3D positions are almost correct, I get deviations from correct positions in ~cm or ~mm range. After careful debugging, I have noticed, this happens due to place in file "blender/intern/cycles/kernel/geom/geom_triangle_intersect.h", line 221:

if(det != 0.0f) {

		/* If determinant is zero it means ray lies in the plane of
		 * the triangle. It is possible in theory due to watertight
		 * nature of triangle intersection. For such cases we simply
		 * don't refine intersection hoping it'll go all fine.
		 */
		float rt = dot(edge2, qvec) / det;
		P = P + D*rt;

}

Mainly, I am interested in sentence:

For such cases we simply don't refine intersection hoping it'll go all fine.

In my case it doesnt go fine. And I am getting wrong(almost correct) 3D positions with wrong barycentric coordinates.

Noticed that function ray_triangle_intersect() in file "\cycles\util\util_math_intersect.h" returns sometimes wrong barycentric coordinates (u + v > 1, which is wrong), hence it renders incorrect 3D position for current pixel. Wrong barycentric coordinates are there due to fact that in line 182 (const float inv_den = 1.0f / den;) happens division by very small number.

Question:
• It is clear that in function ray_triangle_intersect() you are getting sometimes not really correct values, due to division on very small number, that's why you use function triangle_refine() to shoot ray second time to refine position. But it is not clear why it is not refined completely? Division on very small numbers still is not handled properly.
• How one can get correct barycentric coordinates?

Philipp Oeser (lichtwerk) raised the priority of this task from Incomplete to Needs Triage.May 2 2018, 3:23 PM

Thanx for investigating. In that case, I'll pass this on to @Brecht Van Lommel (brecht) or @Sergey Sharybin (sergey) for judgement.