← Back to team overview

kicad-developers team mailing list archive

Raytracer light diffuseness

 

Some scenes (in particular, boards with a lot of tallish through-hole components) seem to suffer pretty badly from the low diffuseness of the light sources the raytracer uses:

https://misc.c4757p.com/way-too-shadowy.png

Currently, this is directly coded, but it can be parameterized really easily. I've attached a patch to enable this and bump up the number of light sources from 8 to 64. The tradeoff here is that the render time scales roughly linearly, so obviously this can't just be increased all the time.

Here's an example with 64 sources, roughly the same scene. It looks significantly better to my eye:

https://misc.c4757p.com/8x-sources-with-intensity-comp.png

I don't really have time to contribute a full patch, but I really would like to see this added as a runtime configurable option in the GUI. Is that something that somebody would be interested in doing?

(Resent as the first mail seems to have gotten lost, apologies if two come through)

-Alexis
diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp
index 2910ccdf7e..3f610e42c0 100644
--- a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp
+++ b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp
@@ -877,32 +877,30 @@ void C3D_RENDER_RAYTRACING::reload( REPORTER *aStatusTextReporter )
                                          SFVEC3F( light_top_bottom ) ) );
     */
 
-    m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 1.0f / 8.0f,
-                                                               glm::pi<float>() * 1 / 4.0f ),
-                                         SFVEC3F( light_directional_intensity ) ) );
-    m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 1.0f / 8.0f,
-                                                               glm::pi<float>() * 3 / 4.0f ),
-                                         SFVEC3F( light_directional_intensity ) ) );
-    m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 1.0f / 8.0f,
-                                                               glm::pi<float>() * 5 / 4.0f ),
-                                         SFVEC3F( light_directional_intensity ) ) );
-    m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 1.0f / 8.0f,
-                                                               glm::pi<float>() * 7 / 4.0f ),
-                                         SFVEC3F( light_directional_intensity ) ) );
-
-
-    m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 7.0f / 8.0f,
-                                                               glm::pi<float>() * 1 / 4.0f ),
-                                         SFVEC3F( light_directional_intensity ) ) );
-    m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 7.0f / 8.0f,
-                                                               glm::pi<float>() * 3 / 4.0f ),
-                                         SFVEC3F( light_directional_intensity ) ) );
-    m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 7.0f / 8.0f,
-                                                               glm::pi<float>() * 5 / 4.0f ),
-                                         SFVEC3F( light_directional_intensity ) ) );
-    m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 7.0f / 8.0f,
-                                                               glm::pi<float>() * 7 / 4.0f ),
-                                         SFVEC3F( light_directional_intensity ) ) );
+    const int num_sources = 64;
+    const float intensity_factor = 1.f / sqrtf(num_sources / 8.f);
+    const float light_dir_intensity_compensated = light_directional_intensity * intensity_factor;
+
+    for (int i = 0; i < num_sources / 2; i += 2) {
+        m_lights.Add(
+            new CDIRECTIONALLIGHT(
+                SphericalToCartesian(
+                    glm::pi<float>() * 1.0f / 8.0f,
+                    glm::pi<float>() * (1 + i) / ((float) (num_sources / 2))
+                ),
+                SFVEC3F( light_dir_intensity_compensated )
+            )
+        );
+        m_lights.Add(
+            new CDIRECTIONALLIGHT(
+                SphericalToCartesian(
+                    glm::pi<float>() * 7.0f / 8.0f,
+                    glm::pi<float>() * (1 + i) / ((float) (num_sources / 2))
+                ),
+                SFVEC3F( light_dir_intensity_compensated )
+            )
+        );
+    }
 
 
     // Create an accelerator

Follow ups