-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathrayTracer.cpp
155 lines (135 loc) · 3.68 KB
/
rayTracer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*************************************************
Copyright(C)2011
项目描述:光线跟踪
文件名:ray.h
作者:wy 日期:
文件描述:光线跟踪器,其中有射线类
函数列表:
**************************************************/
#include "rayTracer.h"
#include "common.h"
#include <iostream>
Tracer::Tracer()
{
m_scn = new Scene();
}
Tracer::~Tracer()
{
delete m_scn;
}
/*跟踪函数,遍历场景中的所有物体,返回交点处的颜色*/
Vector3 Tracer::trace(Ray ray,int depth)
{
float distance = INFINITY;/*初始化无限大距离*/
int dep = depth;/*递归深度*/
Object* aim;/*交点物体*/
Vector3 point;/*交点*/
Vector3 n;/*交点处的法向量*/
Vector3 l;/*交点到光源的方向*/
Vector3 v;/*交点到眼睛的方向*/
Vector3 r;/*光线沿l的入射光线在交点处的出射方向*/
Color hit_color;/*交点处的颜色*/
int res_hit;/*相交情况结果*/
/*遍历场景中的每一个物体,获取其中的一个离眼睛最近的点所在物体*/
for(int k=0;k<m_scn->get_o_num();k++)
{
Object* obj = m_scn->get_objects(k);/*当前物体*/
int res;
if(res = obj->is_intersected(ray,distance))/*判断是否有交点,有交点改变distance*/
{
aim = obj;/*获取目标物体*/
res_hit = res;
}
}
/*有相交物体*/
if(distance != INFINITY)
{
point = ray.get_point(distance);/*获取交点*/
//std::cout<<"here"<<std::endl;
n = aim->get_normal(point);/*交点处的法向量*/
n.normalize();/*单位化*/
/*在物体内与物体相交*/
if(res_hit == INTERSECTED_IN)
{
n = -n;
}
v = m_eye - point;/*交点到眼睛的方向*/
v.normalize();
/*遍历场景中的每一个光源*/
for(int k = 0; k < m_scn->get_l_num(); k++)
{
PointLight pl = m_scn->get_light(k);/*光源*/
l = pl.get_pst() - point;/*交点到光源的方向*/
l.normalize();
Ray l_ray = Ray(point + l*SMALL, l);/**/
float shade = 1.0f;/*阴影,1.0表示交点不在阴影中*/
float distance = INFINITY;/*初始化无限大距离*/
/*测试是否有物体遮挡住光源*/
for(int k=0;k<m_scn->get_o_num();k++)
{
Object* obj = m_scn->get_objects(k);/*当前物体*/
if(obj->is_intersected(l_ray,distance))
{
shade = 0.0f;
break;
}
}
/*漫反射*/
if(aim->get_diffuse() > 0)
{
float cos = DOT(l,n);/*光线与交点处法线的夹角的余弦*/
if(cos > 0)
{
float diffuse = cos*aim->get_diffuse()*shade;
/*将漫反射光加到光线颜色中*/
hit_color = hit_color + diffuse*pl.get_color()*aim->get_color();
}
}
/*镜面反射*/
if(aim->get_spec() > 0)
{
/*Phong高光*/
Vector3 h = 2*DOT(n,l)*n - l;/*反射光线*/
float cos = DOT(h,v);/*反射光线与视线方向的夹角余弦*/
if(cos > 0)
{
float specular = powf(cos,20)*aim->get_spec()*shade;
hit_color = hit_color + specular*pl.get_color();
}
}
}
/*反射光线*/
if(aim->get_refl() > 0 && dep < TOTALDEPTH)
{
Vector3 refl = 2*DOT(n,l)*n - l;/*反射光线*/
hit_color = hit_color + trace(Ray(point + refl*0.0001f, refl), ++dep);
}
}
return hit_color;/*没有相交时,是初始黑色;有相交时,是交点处的颜色*/
}
/*绘制,获取颜色信息*/
void Tracer::render()
{
m_eye.set(0.0f,0.0f,4.0f);/*眼睛位置*/
m_scn->init_scene();/*读入场景*/
/*视窗坐标增量*/
float dx = (float)(VIEW_WIDTH/VIEW_PIXEL_WIDTH);
float dy = (float)(VIEW_HEIGHT/VIEW_PIXEL_HEIGHT);
/*视窗初始坐标*/
float view_x = - VIEW_WIDTH/2.0;
float view_y = - VIEW_HEIGHT/2.0;
/*遍历所有像素点*/
for(int i=0; i<VIEW_PIXEL_HEIGHT; i++)
{
view_x = - VIEW_WIDTH/2.0;
for(int j=0; j<VIEW_PIXEL_WIDTH; j++)
{
Vector3 dir = Vector3(view_x,view_y,0) - m_eye;/*射线方向*/
dir.normalize();
Ray ray(m_eye, dir);/*射线*/
screen_color[i][j] = trace(ray,1);/*遍历场景中的所有物体*/
view_x += dx;
}
view_y += dy;
}
}