Raytracing topics & techniques-
Part 1-Introduction
Original Author: jacco bikker
Original article address:
Http://www.flipcode.com/archives/Raytracing_Topics_Techniques-Part_1_Introduction.shtml
Basic
Raytracing is a way to simulate the real world: the colors you see are the rays of light produced by the Sun (in most cases ).
Light) scattering in natural scenarios will eventually reach your eyes. If we do not care about Narrow relativity for the moment, then all
Some light is straight.
Consider the following illustration:
Figure 1: light from the sun to the observer
I drew some light in this figure. The yellow light goes directly from the sun to the camera. After the red light is reflected in the scene
Arrive at the camera. The blue light is reflected by the glass sphere and then reached the camera.
The rays that have not arrived at the camera are not shown in this figure. This is why a light tracker is not powered by light
The body traces the observer, but starts with the observer. If you think carefully about the above figure, you will find that this is a good solution,
In this way, you do not need to consider the direction of light.
This means that we can do this: We don't have to wait for the sun to emit a ray of light, just to reach the camera, which has not yet been captured.
The pixel. We can emit a Ray from each pixel of the camera to track where they arrive.
CodeImplementation
In this articleArticleYou can find a connection to download files. This file contains a small ray tracingProgram(VC
6.0 Project files ). It contains some basic things that I didn't mention here (winmain displays some things to the screen
On-screen, a class is used to control Pixel Buffer and font rendering) and light tracker. The light tracker is included in
Raytracer. CPP/. h and scene. CPP/. h. Vector computing, PI, and screen resolution are defined in common. h.
Ray generation
In raytracer. H, you can find the following Ray class definition.
ClassRay {Public: Ray (): m_origin (vector3 (0,0,0), M_direction (vector3 (0,0,0) {}; Ray (vector3& A_origin, vector3 &A_dir );Private: Vector3 m_origin; vector3 m_direction ;};
A Ray has a starting point and a direction. When rays are emitted from the camera, the starting point of all rays is usually a fixed point,
Rays are emitted at this point and pass through the plane of the screen, as shown in.
Figure 2: the plane in which rays are generated from the camera and pass through the screen
Let's take a look at the code produced by rays in the render method of raytracer. cpp:
Vector3 O (0,0,-5); Vector3 dir= Vector3 (m_sx, m_sy,0)-O; normalize (DIR); Ray R (O, DIR );
In this Code, rays start from the start point 'O' and are directed to a pixel position in the plane of the screen. The direction of transmission is standardized
Unit vector. The last line of code creates this Ray.
Note: "The plane where the screen is located" is actually a rectangular plane placed in the virtual world, representing the screen. Here
In a simple light tracker, It is aligned with the origin center. It has 8 world units and 6 World units, which is suitable
800x600 resolution PC screen. Through this plane, you can do a lot of interesting things: If you keep the plane away
Camera, the laser harness will narrow, and the object will become larger on the screen (see figure 2 ). If you rotate this plane (camera point
), You will see different perspectives. This is very interesting. Different viewing angles and career things,
Is only a by-product of logic.
Scenario
Next, we need a scenario for ray tracing. The scenario consists of objects (primitive): geometric objects (such as balls)
Body and plane ). You can also use triangles to construct all other objects ).
Let's take a look at the class declaration in scene. h. The entity "sphere" and "planeprim" inherit from "primitive ". Each object
(Primitive) all have material attributes, and some implementation methods such as intersect and getnormal.
The entire scenario is listed in the scene class. We can see it in the initscene method:
Void Scene: initscene () {m_primitive = New Primitive *[ 100 ]; // Ground plane M_primitive [ 0 ] = New Planeprim (vector3 ( 0 , 1 , 0 ), 4.4f ); M_primitive [ 0 ]-> Setname ( " Plane " ); M_primitive [ 0 ]-> Getmaterial ()-> setreflection ( 0 ); M_primitive [ 0 ]-> Getmaterial ()-> setdiffuse ( 1.0f ); M_primitive [ 0 ]-> Getmaterial ()-> setcolor (color ( 0.4f , 0.3f , 0.3f )); // Big sphere M_primitive [ 1 ] =New Sphere (vector3 ( 1 ,- 0.8f , 3 ), 2.5f ); M_primitive [ 1 ]-> Setname ( " Big sphere " ); M_primitive [ 1 ]-> Getmaterial ()-> setreflection ( 0.6f ); M_primitive [ 1 ]-> Getmaterial ()-> setcolor (color ( 0.7f , 0.7f , 0.7f )); // Small sphere M_primitive [ 2 ] = New Sphere (vector3 (- 5.5f ,- 0.5 , 7 ), 2 ); M_primitive [ 2 ]-> Setname ( " Small sphere " ); M_primitive [ 2 ]-> Getmaterial ()-> setreflection ( 1.0f ); M_primitive [ 2 ]-> Getmaterial ()-> setdiffuse ( 0.1f ); M_primitive [ 2 ]-> Getmaterial ()-> setcolor (color (0.7f , 0.7f , 1.0f )); // Light source 1 M_primitive [ 3 ] = New Sphere (vector3 ( 0 , 5 , 5 ), 0.1f ); M_primitive [ 3 ]-> Light (True ); M_primitive [ 3 ]-> Getmaterial ()-> setcolor (color ( 0.6f , 0.6f , 0.6f )); // Light source 2 M_primitive [ 4 ] = New Sphere (vector3 ( 2 , 5 , 1 ), 0.1f ); M_primitive [ 4 ]-> Light ( True ); M_primitive [ 4 ]-> Getmaterial ()-> setcolor (color ( 0.7f , 0.7f , 0.9f )); // Set number of primitives M_primitives = 5 ;}
This method adds a ground and two sphere to the scene, and a light source (actually two ). The light source is
The Sphere marked as "light.
Ray Tracing
So far, all preparations have been completed. Next, let's take a look at the pseudocode that describes the ray tracing process.
For each pixel
{
Creates a ray through which the camera passes through the pixel.
Find the first object (primitive) This ray hits)
Measure the color at the intersection of rays and objects.
Draw colors to pixels
}
We test all the objects to find the objects closest to the intersection of the rays. This operation is performed
The raytrace method is complete.
Intersection calculation code
After some initialization work, the following code starts to be executed:
//Find the nearest intersectionFor(IntS =0; S <m_scene-> getnrprimitives (); s ++) {Primitive* Pr = m_scene->Getprimitive (s );IntRes;If(RES = Pr->Intersect (a_ray, a_dist) {prim=PR; Result= Res;//0 = Miss, 1 = hit,-1 = hit from inside primitive}}
This loop processes objects in each scenario and calls the intersect method to calculate the intersection of each object ).
This method returns an integer Based on the given rays to indicate whether there is any intersection with the rays and the distance from the intersection to the ray origin.
This cycle is always stored at the intersection nearest to the current position.
Color
When we confirm that the ray has reached a definite object, the color of this Ray can be calculated. Use this
The color of the object is too simple; this will lead to the accumulation of color without any gradient. As an alternative, the pipeline eventually passes through
Two light sources are used to calculate a diffuse shadow. The color of each light source affects the final color of the object.
Environment Implementation:
// Determine color at point of intersection Pi = a_ray.getorigin () + a_ray.getdirection ()* A_dist; // Trace lights For ( Int L =0 ; L <m_scene-> getnrprimitives (); L ++ ) {Primitive * P = m_scene-> getprimitive (L ); If (P-> Islight () {primitive * Light = P; // Calculate diffuse Shading Vector3 L = (sphere *) light)-> getcentre ()- Pi; normalize (l); vector3 n = Prim-> Getnormal (PI ); If (Prim-> getmaterial ()-> getdiffuse ()>0 ){ Float Dot = DOT (n, L ); If (DOT> 0 ){ Float Diff = dot * prim-> getmaterial ()-> Getdiffuse (); // Add diffuse component to ray color A_acc + = diff * prim-> getmaterial ()-> getcolor ()* Light -> Getmaterial ()->Getcolor ();}}}}
This Code calculates a vector from the intersection to the light source, and then calculates the normal of this vector and the intersection object.
Point product to determine this intensity. This intensity is the illuminance of the light source.
The larger the angle between the line and the light source, the darker it is ." Dot> 0 "is used to correct the surface of the backlight.
End
This is all about this article. In the next article, we will add some interesting lights and explain how to add
Shadow.
The following are some of the light trackers in this article.
Attachment
Simple light tracker code:
Http://115.com/file/dpjyandx#raytracer1.zip