Code Toy - A Naive Implementation of Ray Tracer

Link: https://informationalmind.appspot.com/2011/12/3/CodeToy_ANaiveImplementationOfRayTracer.html


Several weeks ago, as an exercise of Computer Graphics, DD and I managed to implement a Ray Tracer using C++. We both have no experience of implementing a rendering algorithm before, and this is our first move toward this direction. About two weeks ago, the code have reached it’s first “milestone” - it just works!

The basic idea of our Ray Tracer is simple. As the title wrote, this code toy is a naive implementation with almost no optimization and coded really straight forward.

I have some other thing to be mentioned, that is: this is my first time using SVN... We use Google code as code server, TortoiseSVN as client.  Thank DD that leading me into SVN world and set up this project on Google code.

This is the project page on Google code: http://code.google.com/p/simpleraytracer/

A result of our Ray Tracer:

Traced

(About the image: In the scene, there are three light source. The sphere in the middle is almost transparent, top left sphere is half transparent, remaining three have different levels of reflectivity.)

By the way, 用JavaScript玩转计算机图形学(一)光线追踪入门(Chinese) is a great article about how to implementing ray tracer by Milo Yip(@Google+), we’ve got some idea from this post.

First glance

Code structure

The structure of this code toy is not good because of our lack of experience in this field. So I will not dive into detail of this little mass. Just outline it.

RayTraceMgr – Manage the parameters used in Tracer, control the tracing process and the image generating process.

Tracer – Implement the tracing detail.

Scene – Manage the objects to be traced.

GeometricTools – Extract the geometric algorithms used in Tracer and Scene.

RenderableObject – Abstract object represents the object to be traced in Scene.

And lots of other classes.

Features

We have implemented some basic features that can be easily achieved.  Features including basic Phong shading model, recursive reflection, recursive refraction, a simple approximation of Fresnel reflectivity and transparency(Fresnel Equation), and a simple shadowing, a naive and straight forward 4x anti-aliasing.

We still have a lot of things can do. For example, we only have done the sphere object now, triangle mesh will be the next move if we continue; scene management, we brute forced the intersection calculation for each pair of objects currently...

Tracing process

Ray emitted from camera

The basic idea of ray tracing is emitting rays from the camera through each pixel into the scene, color the pixel by some calculation at intersection point with objects. This is some sorts of trigonometry similar to Ray Casting and this part was not written by me, so I won’t go into detail of this. But this does not mean it is extremely easy to implement, of course. You can get more detail about this in the link of Wikipedia above or in the blog post mentioned above.

This part was implemented by DD. (Wish DD can write something about this so we can get more exact idea of this part~)

One of the rays goes into the scene

Let’s focus on one ray emitted from the camera.

The ray goes into the scene, and intersects with some objects. At the intersection point on the object, we can calculate the color using Phong shading model(the ambient light is not considered in this tracer). And here, as we use ray tracing, we can get basic shadow effects easily. We check the segments between intersection point and each light source if they are intersecting other objects. If one intersected, just ignore this color calculation of this light source. Now we have a color, but the surface of that object may have specular reflection and refraction lights. So we have to calculate the color contributed by them recursively.

Recursively color calculation is simple and straight forward, if we have the information of reflection ray and refraction ray. Suppose we already have these information, what to do is call the tracing function again with corresponding parameters of reflection ray and refraction ray.

Reflection and Refraction

Now the problem is how to calculate reflection and refraction ray. Reflection is easy to get, and the blog post mentioned above have given the solution. What about refraction ray?

We know the incident vector “I”(suppose pointing out of the surface), the surface normal “N”, now we want to get the refraction vector “R”(pointing out of the surface at other side). Let “i” be the incident angle and “r” be the refraction angle. First we know R is in the same plane as I and N, second we know sin(i) * n1 = sin(r) * n2(n1 and n2 is the refractive index of the two materials), so we can get:

1. a * I + b * N = R

// a and b are two unknown coefficients, R can be linearly represented by I and N.

2. n1 * (I × N) = n2 * (R × -N)

// “×” is cross product, as I, N and R is in the same plane, I × N and R × –N are two vector in the same direction, the magnitude of these vectors are sin(i) and sin(r).

3. ||R|| = 1

// R is a unit vector.

Using above three equations, replace R in 2 and 3 with 1, we can get a and b, so the R followed.

But I haven’t used this approach... Instead, I use the method provided by GLSL man page directly...

Weight of color contributions

Then, how to decide the color contribution of these reflection and refraction?

As mentioned above, the surface of the intersecting object has many properties, including reflectivity(range: [0.0, 1.0]), transparency(range: [0.0, 1.0])(which often be called alpha). The more specular the surface is, the higher reflectivity it has. So we set some weight to indicate the reflection and refraction ray color contribution. Reflection ray weight is just the reflectivity, and (1 – reflectivity) can indicate the weight of diffuse color.

But there is the transparency. A fully transparent object cannot be seen because it does not reflect any light, what you can see there are the lights emitted behind it. So we have to consider the transparency, or alpha. The reflection weight become (1 – alpha) * (reflectivity) and the diffuse weight become (1 – alpha) * (1 - reflectivity). For the transparent part, we consider the back surface, similar to the front surface while doing reflection and diffusion. It immediately comes out that the transparency, or the refraction ray contribution weight is (alpha) * (reflectivity), and the diffuse color weight of the back surface is (alpha) * (1 – reflectivity).

More about transparency

Object that is transparent makes things much harder to handle. There is a thing called Fresnel reflection and refraction. The basic idea of it is when you look at a translucent surface, the larger incident angle, the more reflectivity. So the alpha mentioned above have to be calculated dynamically. I used (1 – cos(incident angle)) to map alpha to [original alpha, 1] here to approximate and simplify the computation. The effect can be directly seen in the image above(the sphere at the center).

Anti-aliasing

We have implemented a naive 4x AA here, that is: each pixel tracing four evenly distributed rays instead of one, then using the mean color value as the pixel color. That’s all of it.

What can be done in the future

As said in the beginning, this is a really simple and naive ray tracer and almost has no optimization, there is still a lot of work can be done.

We only implemented the sphere object, triangle and triangle mesh can be the next move.

Scene management is not optimized. We check each pair of spheres to do the intersection test, not using any kind of space partitioning algorithms.

Objects are hard coded in the program, no model importing facilities.

In the tracer, no texture is implemented. We just left an interface to add this feature.

Shadows in this tracer can only handle opaque objects correctly. Translucent objects are treated as opaque objects, so there is no light influence behind translucent objects.

we only implemented the point light, no other kind of lights implemented.

...

All listed above are things we can do. But this code toy may not be developed any more. We keep learning, knowledge in our mind keep growing, there must be better ways to do this, and one of them may be our choice in the future if we want to continue doing this~

Closing

Coding with some others can bring lots of benefits such as better idea catching, faster code generating, quicker bug locating, etc...

I wrote this post after two more weeks of the “milestone” because I have to pass a math exam few days ago...

Writing in English is still uncomfortable for me currently... More practices are needed...

转载于:https://www.cnblogs.com/ylqcnblogsylq/archive/2011/12/04/CodeToy_ANaiveImplementationOfRayTracer.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值