<p>Consider two cases:</p>
<p>You usually don't cull those back faces in camera space (faces are facing away from the <strong>camera</strong>). This will lead to incorrect will lead to incorrect indirect lighting and some times ray termination, if you are not using two-sided BSDF (check Mitsuba renderer, two-sided BSDF). For example, you are rendering Cornell Box scene, and the back faces of the boxes are removed. Your ray penetrates into the boxes and queries the BSDF with 0 path throughput (since the BSDF is one-sided), and it will be terminated immediately.</p>
<p>However, if you opt for extreme performance, and slight bias for indirect illumination is acceptable, then back face culling (for opaque objects) can be applied.</p>
<hr />
<p>For back face culling in ray space, i.e. we check whether the ray incident direction <span class="math-container">$\pmb{w}$</span> and surface normal (consider simple cases, geometry normal) <span class="math-container">$\pmb{n}$</span> can have a negative dot product, if not, the surface is culled. So:</p>
<ul>
<li>Reflective material (<em>purely reflective (opaque, but can reflect)</em>): If you are hitting surfaces that has normals pointing inside, and if you are not using two-sided BSDF, then usually the BSDF model will set the path throughput to be 0, by clipping the foreshortening term by <code>max(0, dot(w, n))</code>, so the radiance returned will be zero. If it is visible, it will be some pleasant visual artifact which you want to avoid. Normally, you should fix these normals first (flip the direction during modeling). However, if the scene is too complex to edit, you can either use two-sided BSDF, or cull these back facing surfaces (but might lead to other artifacts, like a hole on the object).</li>
<li>Material that does not reflect (<em>diffuse (opaque, do not reflect)</em>): ... Emmm, what's for? If there is a surface that does not reflect light, there are mainly two cases this is useful: (1) you place it here intentionally to absorb light (and terminate the path), so why would you cull it? (2) this is an emitter (sometimes we only want emitting surfaces to emit radiance), then why would you cull it?</li>
<li>Refractive material: no, instead, you need the orientation of the normal to judge whether your ray is penetrating into or out-of the object, since in the refraction cases, index-of-refraction on the two sides of the medium interface is determined this way. So, no, it is undesirable to remove transparent surfaces.</li>
</ul>
<p>There are indeed some cases you should cull a surface (not only the back facing surfaces), but rare. An example is the scattering medium boundary: we sometimes use a mesh to represent the boundary of a volumetric medium, but we don't want the mesh to affect the ray direction and radiance. Therefore, the culling can be applied to these surfaces, during visibility testing.</p>
<p>DirectX and HLSL do support culling: there are enumerations like <code>RAY_FLAG_CULL_BACK_FACING_TRIANGLES</code>, <code>RAY_FLAG_CULL_FRONT_FACING_TRIANGLES</code> for function <code>TraceRay</code>, but so far I don't find them useful. I could say this is because ray tracing is fundamentally different from rasterization in whether the shading process depends on the concept of <em>ray</em>. If I recall it correctly, since ray-space culling cannot be pre-processed (for camera space culling, it is easy to know what to cull, given the scene),  it is computed on-the-fly (by checking the ordering of vertices) and the hit on the culled faces are simply ignored. So basically, you are not alleviating the workload for intersection acceleration structure.</p>

CC BY-SA 4.0
2024-07-20T06:01:25.070Z
Thanks for the extensive information. To be honest, I find it kind of complicated, since although I have all these different kinds of materials and rays, I haven't dug down into things such as BSDF. This is something that I should have mentioned and it's entirely my fault for failing to do so. To put it simply, the role of the diffuse non-reflective material is indeed to absorb light. As for the backface culling, I really implied it in the ray space context only, i.e. discarding intersections with dot product between the incident ray and the surface normal greater than or equal to zero.
Kotaka Danski
CC BY-SA 4.0
2024-07-20T06:04:15.623Z
The surface and vertex normals I calculate in runtime.
Kotaka Danski
CC BY-SA 4.0
2024-07-20T10:39:06.773Z
The problem for me is that without culling, the rendering is not accurate and I get some huge black spots in my image. If I keep the culling, there is almost no refraction.
Kotaka Danski
CC BY-SA 4.0
2024-07-20T11:06:50.813Z
@KotakaDanski Don't feel bad about not being clear. Edit the post any time you want and I will update mine, too.
Enigmatisms
CC BY-SA 4.0
2024-07-20T11:09:13.177Z
Actually, the problem 'discarding intersections with dot product between the incident ray and the surface normal greater than or equal to zero' resembles that of [this post](https://computergraphics.stackexchange.com/questions/14123/lots-of-bad-samples-below-the-hemisphere-when-sampling-the-ggx-vndf). Since you will can barely come across invalid dot product, if the geometries are properly set.
Enigmatisms
CC BY-SA 4.0
2024-07-20T11:11:31.380Z
One thing to note is that you should avoid self-intersection caused by insufficient floating point accuracy. For example, you have an intersection on a surface, but the calculation is not completely accurate and the ray origin is slightly below the surface, then you can have black dots (or stripes) for the rendering result. Generally, culling is not a good way to avoid abnormal samples.
Enigmatisms
CC BY-SA 4.0
2024-07-20T02:39:02.217Z
2024-07-20T02:39:02.217Z
Enigmatisms
<p>I am currently implementing a ray tracer, which supports reflection and refraction.
I have the following types of rays:</p>
<ul>
<li>camera rays</li>
<li>shadow rays</li>
<li>reflection rays</li>
<li>refraction rays</li>
</ul>
<p>I have the following types of materials:</p>
<ul>
<li>diffuse (opaque, do not reflect)</li>
<li>purely reflective (opaque, but can reflect)</li>
<li>reflective and refractive (semi-transparent objects such as bodies of water, which can reflect part of the light ray and refract the rest).</li>
</ul>
<p>For which combinations of ray type and material type of object being hit should I perform backface culling, when determining the hit point of a ray on a triangle?</p>
<p>EDIT:
From what I stated above, it might seem like my renderer is physically accurate, but it really isn't all that much. Here are some implementation details I failed to mention:</p>
<ul>
<li>I calculate the surface and vertex normals in runtime, when parsing the scene. I don't read them from the scene.</li>
<li>By <code>backface culling</code>, I implied the check if the dot product of the incident ray and the surface normal is greater than or equal to zero. Right now, as long as it's not a shadow ray and the dot product is greater than or equal to zero, I return that there is no intersection.</li>
<li>The different types of rays are used mainly for debugging purposes so far. The shadow rays are an exception and I use them as stated in the previous point.</li>
<li>the non-reflective diffuse material is used to represent a material, which absorbs light. When a ray intersects an object of such a material, I calculate the contribution of each light.</li>
<li>the reflective material causes the incident ray to be reflected. The final color is the color, returned by the reflected ray, multiplied by the albedo of the reflective material, in order to avoid total reflection (perfectly mirrored surface).</li>
<li>the refractive material causes either a reflection ray, or a reflection and a refraction ray to be traced (based on Snell's law) and the final color is calculated using the <code>fresnel</code> formula.</li>
</ul>

<raytracing><rendering><ray>
When to apply backface culling, depending on the ray and material type?
Kotaka Danski
# When to apply backface culling, depending on the ray and material type?

(Asked by: username_0 on 2024-07-19)

I am currently implementing a ray tracer, which supports reflection and refraction.
I have the following types of rays:

* camera rays
* shadow rays
* reflection rays
* refraction rays

I have the following types of materials:

* diffuse (opaque, do not reflect)
* purely reflective (opaque, but can reflect)
* reflective and refractive (semi-transparent objects such as bodies of water, which can reflect part of the light ray and refract the rest).

For which combinations of ray type and material type of object being hit should I perform backface culling, when determining the hit point of a ray on a triangle?

EDIT:
From what I stated above, it might seem like my renderer is physically accurate, but it really isn't all that much. Here are some implementation details I failed to mention:

* I calculate the surface and vertex normals in runtime, when parsing the scene. I don't read them from the scene.
* By `backface culling`, I implied the check if the dot product of the incident ray and the surface normal is greater than or equal to zero. Right now, as long as it's not a shadow ray and the dot product is greater than or equal to zero, I return that there is no intersection.
* The different types of rays are used mainly for debugging purposes so far. The shadow rays are an exception and I use them as stated in the previous point.
* the non-reflective diffuse material is used to represent a material, which absorbs light. When a ray intersects an object of such a material, I calculate the contribution of each light.
* the reflective material causes the incident ray to be reflected. The final color is the color, returned by the reflected ray, multiplied by the albedo of the reflective material, in order to avoid total reflection (perfectly mirrored surface).
* the refractive material causes either a reflection ray, or a reflection and a refraction ray to be traced (based on Snell's law) and the final color is calculated using the `fresnel` formula.

**Tags:** raytracing, rendering, ray


---

## 1 answers

### Answer by username_1 on 2024-07-20. Score: 1 | Accepted answer

Consider two cases:

You usually don't cull those back faces in camera space (faces are facing away from the **camera**). This will lead to incorrect will lead to incorrect indirect lighting and some times ray termination, if you are not using two-sided BSDF (check Mitsuba renderer, two-sided BSDF). For example, you are rendering Cornell Box scene, and the back faces of the boxes are removed. Your ray penetrates into the boxes and queries the BSDF with 0 path throughput (since the BSDF is one-sided), and it will be terminated immediately.

However, if you opt for extreme performance, and slight bias for indirect illumination is acceptable, then back face culling (for opaque objects) can be applied.

---

For back face culling in ray space, i.e. we check whether the ray incident direction $\pmb{w}$ and surface normal (consider simple cases, geometry normal) $\pmb{n}$ can have a negative dot product, if not, the surface is culled. So:

* Reflective material (*purely reflective (opaque, but can reflect)*): If you are hitting surfaces that has normals pointing inside, and if you are not using two-sided BSDF, then usually the BSDF model will set the path throughput to be 0, by clipping the foreshortening term by `max(0, dot(w, n))`, so the radiance returned will be zero. If it is visible, it will be some pleasant visual artifact which you want to avoid. Normally, you should fix these normals first (flip the direction during modeling). However, if the scene is too complex to edit, you can either use two-sided BSDF, or cull these back facing surfaces (but might lead to other artifacts, like a hole on the object).
* Material that does not reflect (*diffuse (opaque, do not reflect)*): ... Emmm, what's for? If there is a surface that does not reflect light, there are mainly two cases this is useful: (1) you place it here intentionally to absorb light (and terminate the path), so why would you cull it? (2) this is an emitter (sometimes we only want emitting surfaces to emit radiance), then why would you cull it?
* Refractive material: no, instead, you need the orientation of the normal to judge whether your ray is penetrating into or out-of the object, since in the refraction cases, index-of-refraction on the two sides of the medium interface is determined this way. So, no, it is undesirable to remove transparent surfaces.

There are indeed some cases you should cull a surface (not only the back facing surfaces), but rare. An example is the scattering medium boundary: we sometimes use a mesh to represent the boundary of a volumetric medium, but we don't want the mesh to affect the ray direction and radiance. Therefore, the culling can be applied to these surfaces, during visibility testing.

DirectX and HLSL do support culling: there are enumerations like `RAY_FLAG_CULL_BACK_FACING_TRIANGLES`, `RAY_FLAG_CULL_FRONT_FACING_TRIANGLES` for function `TraceRay`, but so far I don't find them useful. I could say this is because ray tracing is fundamentally different from rasterization in whether the shading process depends on the concept of *ray*. If I recall it correctly, since ray-space culling cannot be pre-processed (for camera space culling, it is easy to know what to cull, given the scene), it is computed on-the-fly (by checking the ordering of vertices) and the hit on the culled faces are simply ignored. So basically, you are not alleviating the workload for intersection acceleration structure.

> **Comments:**
> **username_0**: Thanks for the extensive information. To be honest, I find it kind of complicated, since although I have all these different kinds of materials and rays, I haven't dug down into things such as BSDF. This is something that I should have mentioned and it's entirely my fault for failing to do so. To put it simply, the role of the diffuse non-reflective material is indeed to absorb light. As for the backface culling, I really implied it in the ray space context only, i.e. discarding intersections with dot product between the incident ray and the surface normal greater than or equal to zero.  
> **username_0**: The surface and vertex normals I calculate in runtime.  
> **username_0**: The problem for me is that without culling, the rendering is not accurate and I get some huge black spots in my image. If I keep the culling, there is almost no refraction.  
> **username_1**: @username_0 Don't feel bad about not being clear. Edit the post any time you want and I will update mine, too.  
> **username_1**: Actually, the problem 'discarding intersections with dot product between the incident ray and the surface normal greater than or equal to zero' resembles that of [this post](https://computergraphics.stackexchange.com/questions/14123/lots-of-bad-samples-below-the-hemisphere-when-sampling-the-ggx-vndf). Since you will can barely come across invalid dot product, if the geometries are properly set.  
> **username_1**: One thing to note is that you should avoid self-intersection caused by insufficient floating point accuracy. For example, you have an intersection on a surface, but the calculation is not completely accurate and the ray origin is slightly below the surface, then you can have black dots (or stripes) for the rendering result. Generally, culling is not a good way to avoid abnormal samples.  

---

