ABAP Ray Tracer – Part 5 – The Sample
Recap
I am writing a ray tracer with ABAP by studying the book “Ray Tracing from the Ground Up“.
A ray tracer is able to create computer generated imagery.
If you like to know more about my motivation behind this endeavour, check out my first blog.
In my fourth blog I improved my ray tracer to render any number of objects and studied how C++ method parameters translate to the ABAP world.
The project can be found on gitHub.
Objectives
In this fifth blog I am updating my ray tracer to use different sampling algorithms to tackle the problem of aliasing(1).
I will demonstrate the aliasing effect by showing images created by my ray tracer and allow you to compare different sampling algorithms to minimize the aliasing effect.
Aliasing & Antialiasing
The aliasing effect, in the context of computer generated images, describes artefacts, which are often unpleasant to look at.
Aliasing is an inherent problem of ray tracing, which can never be fully overcome.
This problem results from the fact, that the mathematical definition of the objects allows for infinite detail.
But to make these details visible to our eyes, we have to map them to the finite area of a pixel.
We are squeezing more information into a pixel, which only can hold a single color, this in return leads to a loss of details/information and creates patterns/artifacts in the rendered image.
The following image shows my very first rendering.
Sphere with one ray per pixel.
Magnified border of the sphere
The jagged border line is a very common artefact caused by aliasing.
When shooting a ray from the center of each pixel, it either hits the object surface or misses it. In the end the pixel gets the full opaque color of the object or the background.
Suffern, (2007). Figure04.01. [EPS image]
Available at: raytracegroundup.com (2) [Accessed 28. Jan. 2018]
One solution to this problem is to cast more than one ray for a single pixel and to average the colors to define the visible pixel color. This is called sampling. So, one could also say, using more than one sample helps to have a better approximation of the world being rendered.
The following figure 04.03 shows the top left pixel from the figure 04.01.
25 samples are cast (left) and each returns either yellow or grey (center). The color values are then averaged so that the final color is a desaturated yellow. (right)
Suffern, (2007). Figure04.03. [EPS image]
Available at: raytracegroundup.com (2) [Accessed 28. Jan. 2018]
Subdividing a pixel evenly and shooting rays from the center of each individual subpixel is also called uniform or regular sampling.
The following images have regular sampling applied to perform antialiasing on the sphere’s edge. Each pixel is determined by using 16 samples.
Sphere with regular sampling (16 samples)
Magnified border of the sphere, which got antialiased.
Another example to illustrate the problem of aliasing is the sinusoid function (3), which is a mathematical representation describing continuously shrinking waves.
The following image got rendered in the range (x,y) = [0, 3.79]²
. The smallest wave gets represented by around 5 pixel. No artifacts are present.
Sinusoid function
If the same resolution is used to display a larger range ((x,y) = [0, 10.83]²
), a pattern unfolds, which is also known as moiré (4), which results from the waves getting so small that they cannot be represented by a single pixel.
Moiré pattern
Now I am applying regular sampling with 16 samples per pixel, as a result the strength of the pattern decreases, but it’s still visible. In fact, if the contrast of this image would be highly increased the same pattern unfolds again, as you can also see in the following picture.
This pattern results from the fact that the samples are all evenly and uniformly spaced from each other, which shifts the problem, but doesn’t solve it.
Regular sampling applied (16 samples)
As you can see in the next image: An alternative solution is to implement another sampling algorithm, where the samples are randomly distributed within the area a pixel spans. This will create a noise pattern to which the human eye is much more forgiving compared to a distinct pattern.
Random sampling applied (16 samples)
But random sampling can result in sample gaps or clusters, which cause under- or oversampling. Another algorithm called Jittered sampling randomizes the rays only inside the area of each subpixel, which causes more evenly spaced samples.
Suffern, (2007). Figure04.07. [EPS image]
Available at: raytracegroundup.com (2) [Accessed 28. Jan. 2018]
(left) 25 random samples
(center) 25 Jittered samples
(right) Like the center, but with subpixels displayed
The following rendering has Jittered sampling applied.
Jittered Sampling (16 samples)
There are many more sampling algorithms, like Multi-Jittered, Hammersley, N-Rooks, which are covered in the book but not covered in my blog as this would again make the length of the article awfully long and I try to learn from my mistakes ;).
Bottom line: Sampling helps to get a better approximation, like finer details, smoother edges, sharper textures at the cost of performance. Various algorithms exist which have different characteristics.
Sampling will be used in several occasions during ray tracing, not only when I fight jagged edges, but also when area lights and soft shadows are going to be implemented in later chapters.
Language Differences
Integer division
What caused me some serious headaches during the conversion of the C++ sampling algorithms to ABAP is the difference how both languages handle integer division. Look for yourself:
// C++
int val = 1;
val = val / 2;
// val is zero
"ABAP
DATA val TYPE int4 VALUE 1.
val = val / 2.
"val is one
I ended up using trunc
and a float value:
"ABAP
DATA val TYPE int4 VALUE 1.
val = trunc( val / '2.0' ).
"val is zero
Conclusion
This blog concludes chapter 4 and 5 of the book.
By casting additional samples per pixel, my ray tracer can solve alias effects like jagged edges or moiré patterns.
I implemented several sampling algorithms to study their characteristics.
And I also learned that integer division is handled differently by ABAP compared to C++, which I solved by using trunc
and float division.
What’s Next
The implementation of perspective viewing to my ray tracer will be the follow-up topic to this blog.
Thanks,
André
Hello André Schaarschmidt,
I can see that you have invested good time and efforts for achieving this. But how this helps in an ERP software like SAP or how can some one get some added information/knowledge on the ABAP he can use for business purpose. If you have a got an interesting program design which runs behind for this, may be others can benefit.
B.R.
There is a link to github (see top of the blog), so I'm guessing you can find the actual ABAP code (design and all) there?
It is a valid question though. We mostly use ABAP for business stuff, so how exactly an academic blog about rendering and aliasing (yawn!) can help anyone with their sales orders and journal entries? Well, I can answer that with a story.
Last week I checked out several books from a library. Among them was a cookbook titled something like "Easy skillet dinners" and another cookbook called Crossroads. At home, I looked through them and marked a few recipes from the "Easy" book to make later. The Crossroads book is based on a restaurant and, even though it had rave reviews, I was mostly irritated by it. It just seemed too frou-frou and unrealistic. E.g. it had a recipe that included frying expensive Marcona almonds with rosemary just to put them on top of a dish. Or another recipe was for "smoked corn" that involved disabling your smoke alarm and, well, actual smoking. Now who even does this kind of stuff at home? This is nuts!
So I just put it away to return to the library. But then later I was looking again at the "Easy" recipes and thought: "Hm, what if instead of a plain corn I used smoked corn here? Could be much more interesting flavor..."
Blogs like this are rather "artisanal ABAP". Instead of just providing "step-by-step with screenshots", they can inspire us to write better code. I might not be making any Crossroads recipes as is but I certainly learned a couple of new things from that book. There are different cookbooks for different purposes, just like there are different kinds of ABAP blogs.
Hi Jelena.
Thanks a lot for taking the lead in answering P D comment. You gave a good example.
When being raised by my parents, I was given the words: "You don't know what you need it for".
Holds true to you story I say.
Happy cooking Jelena.
André
Hi P D.
Thanks for the effort of reading this article and I am sorry you came to the conclusion, that you don't see any benefit for yourself. And yeah, it's not the coffee table blog series to make you straight forward solve problem X in the ERP realm. The problem domain I tapped into with this ray tracing is really very different.
Cause of my background in the VFX industry, this is still a topic which interests me and solving it with a toolset so different is a challenge and a learning experience for me. These experiences I try to transform into these articles to let others participate in this little journey I am on.
Have you read my first blog? It might give you a better view on what's in this series for you and for myself.
To give you some examples of things I learnt:
Best regards,
André
I enjoyed this blog and the first one you wrote. C++ to ABAP is cool. This is just plain fun. When I get a chance it will be a great download for me!
Thank you so much!
Michelle
Hi Michelle.
You are such a positive influencer in this community. Thank you very much fo your ongoing effort to spark the light with your positive comments and blogs here.
So the thanks is all on you for making the effort and leaving a comment here.
Thank you!
André
Thank you!
Michelle