Skip to content
saittam edited this page Sep 13, 2010 · 6 revisions

Description

trace.sh is a bash script that implements a simple raytracer. I wrote it to pratice my shell scripting skills and to find out what it would feel like to write a program in bash that you would normally not even remotely consider to use shell scripting for. Quite surprisingly it did only take an afternoon to complete a first working version!

Current features:

  • reads geometry files containing a set of triangles. For the format, see the comment at the top of trace.sh. There is also a python script for exporting blender models in the correct format, see the file blender-export.py
  • implements standard phong shading model for lighting calculations
  • trace.sh uses a slave bc process to do the actual calculations. This means we can do raytracing in arbitrary precision!
  • Parallel rendering slave processes can be forked (see the -j option). The main script distributes work to the slaves, waits for them to finish and collects and combines their results then.
  • The output goes to an image file in PNG or JPEG format. NetPBM is used for converting the image data.
  • An aborted rendering run can be resumed at a later time, thereby keeping information for all pixels that have already been calculated.

What is missing:

  • Anti-aliasing (supersampling could be implemented relatively easily)
  • Space partitioning. Implementing this is an interesting task: The triangle lists could be stored in files, and the filesystem be used for a tree data structure.
  • Refractions and reflections

Performance

As you will probably have expected, trace.sh‘s rendering performance is really slow :-) That doesn’t come as a suprise, since for computing each pixel, trace.sh forks some OS processes. To give some numbers: The fdc testing scene took some 50 hours to render at a resolution of 1680 by 1050 pixels on my dual-core machine running 2 parallel rendering threads.

Here is a scaled version of the resulting image (see here for original size):

Issues with bc

When rendering large images, I encountered the situation that bc would slowly eat up all my memory. Taking a closer look at the problem I figured out it was actually caused by a memory leak in the bc code. Below patch fixes the problem for me and keeps @bc@’s memory usage constant:

diff --git a/bc/bc.y b/bc/bc.y
index 14dc4be..bd91c38 100644
--- a/bc/bc.y
+++ b/bc/bc.y
@@ -569,6 +569,7 @@ expression          :  named_expression ASSIGN_OP
                                    generate (">");
                                  break;
                                }
+                             free($2);
                            }
                        | expression '+' expression
                            {
diff --git a/bc/util.c b/bc/util.c
index 30beaf9..26e2e85 100644
--- a/bc/util.c
+++ b/bc/util.c
@@ -602,8 +602,7 @@ lookup (name, namekind)
     case FUNCTDEF:
       if (id->f_name != 0)
        {
-         if (namekind != FUNCT)
-           free(name);
+         free(name);
          /* Check to see if we are redefining a math lib function. */ 
          if (use_math && namekind == FUNCTDEF && id->f_name <= 6)
            id->f_name = next_func++;
Clone this wiki locally