資源簡介
使用光線光線算法實現的光線跟蹤效果圖
有陰影和反射效果,采用Phong光照模型

代碼片段和文件信息
#include?“raytracer.h“
#include?“scene.h“
#include?“common.h“
#include?“windows.h“
#include?“winbase.h“
namespace?Raytracer?{
Ray::Ray(?vector3&?a_Origin?vector3&?a_Dir?)?:?
m_Origin(?a_Origin?)?
m_Direction(?a_Dir?)
{
}
Engine::Engine()
{
m_Scene?=?new?Scene();
}
Engine::~Engine()
{
delete?m_Scene;
}
/*************注釋*************
作用:設置渲染目標
******************************/
void?Engine::SetTarget(?Pixel*?a_Dest?int?a_Width?int?a_Height?)
{
//?設置像素緩沖區的地址和大小
m_Dest?=?a_Dest;
m_Width?=?a_Width;
m_Height?=?a_Height;
}
/*************注釋*************
作用:初始化渲染器,跳過標題欄,并預先計算一些值
******************************/
void?Engine::InitRender()
{
//?越過窗口欄的20個像素,即跳過標題欄
m_CurrLine?=?20;
//?設置像素緩沖區的第一個像素地址
m_PPos?=?20?*?m_Width;
//?屏幕平面在世界坐標系的位置
m_WX1?=?-6?m_WX2?=?6?m_WY1?=?m_SY?=?4.5?m_WY2?=?-4.5;
//計算插值△x△y
m_DX?=?(m_WX2?-?m_WX1)?/?m_Width;
m_DY?=?(m_WY2?-?m_WY1)?/?m_Height;
m_SY?+=?20?*?m_DY;
//為前面行分配空間存儲指向圖元的指針
m_LastRow?=?new?Primitive*[m_Width];
memset(?m_LastRow?0?m_Width?*?4?);
}
/*************注釋*************
作用:從左至右發射屏幕的掃描的光線,渲染場景的物體
******************************/
bool?Engine::Render()
{
//渲染場景的起始點
vector3?o(?0?0?-5?);
//初始化時鐘
int?msecs?=?GetTickCount();
//重置上一個找到的圖元指針
Primitive*?lastprim?=?0;
//?渲染剩余的行
for?(?int?y?=?m_CurrLine;?y?(m_Height?-?20);?y++?)
{
m_SX?=?m_WX1;
//渲染當前行像素
for?(?int?x?=?0;?x? {
//發射跟蹤光線
Color?acc(?0?0?0?);?
vector3?dir?=?vector3(?m_SX?m_SY?0?)?-?o;
NORMALIZE(?dir?);
Ray?r(?o?dir?);?//跟蹤光線
float?dist;
Primitive*?prim?=?Raytrace(?r?acc?1?1.0f?dist?);
int?red?=?(int)(acc.r?*?256);
int?green?=?(int)(acc.g?*?256);
int?blue?=?(int)(acc.b?*?256);
if?(red?>?255)?red?=?255;
if?(green?>?255)?green?=?255;
if?(blue?>?255)?blue?=?255;
m_Dest[m_PPos++]?=?(red?<16)?+?(green?<8)?+?blue;
m_SX?+=?m_DX;
}
m_SY?+=?m_DY;
//渲染世界場景是否超過0.1s
if?((GetTickCount()?-?msecs)?>?100)?
{
//更新屏幕,把控制權交給windows
m_CurrLine?=?y?+?1;
return?false;
}
}
return?true;
}
Primitive*?Engine::Raytrace(?Ray&?a_Ray?Color&?a_Acc?int?a_Depth?float?a_RIndex?float&?a_Dist?)
{
if?(a_Depth?>?TRACEDEPTH)?return?0;?//大于設置的追蹤深度返回
a_Dist?=?1000000.0f; //?追蹤光線最大長度
vector3?pi;
Primitive*?prim?=?0;
int?result;
for?(?int?s?=?0;?s?GetNrPrimitives();?s++?) //?找到最近相交的圖元
{
Primitive*?pr?=?m_Scene->GetPrimitive(?s?);//當前圖元
int?res;
if?(res?=?pr->Intersect(?a_Ray?a_Dist?))?
{
prim?=?pr;
result?=?res;?//?0?=?miss?1?=?hit?-1?=?hit在圖元內部檢測到相交
}
}
//沒有相交,結束光線
if?(!prim)?return?0;?
//處理光線與圖元相交
if?(prim->IsLight())
{
//?碰到光源,結束光線
a_Acc?=?Color(?1?1?1?);?//為白色光源
}
else
/*
計算從相交點(pi)到光源(L)的向量,并用這個向量和相交點的單位向量的叉積來計算
出光源的亮度。這個計算出的亮度是元素朝向光源的那一點被光源照亮,而其他點就是
陰暗的了。叉積大于0為了防止面與光源反向
*/
{
????//?決定相交點的顏色
pi?=?a_Ray.GetOrigin()?+?a_Ray.GetDirection()?*?a_Dist;?//相交點?a_Dist的長
?屬性????????????大小?????日期????時間???名稱
-----------?---------??----------?-----??----
?????文件???????4176??2010-06-20?19:13??RayTracer\raytracer.dsp
?????文件????????541??2004-07-08?16:04??RayTracer\raytracer.dsw
?????文件??????99328??2010-06-23?18:47??RayTracer\raytracer.ncb
?????文件???????1392??2010-06-23?18:47??RayTracer\raytracer.plg
?????文件????????478??2010-06-23?18:47??RayTracer\raytracer.positions
?????文件???????2911??2010-06-20?20:37??RayTracer\scene.h
?????文件????????235??2010-06-20?12:04??RayTracer\testbyOGL.cpp
?????文件?????237633??2010-06-23?18:47??RayTracer\Debug\raytracer.exe
?????文件????????478??2010-06-20?22:42??RayTracer\surface.cpp
?????文件????????517??2010-06-20?22:42??RayTracer\surface.h
?????文件???????5863??2010-06-20?22:42??RayTracer\raytracer.cpp
?????文件???????1265??2010-06-20?22:43??RayTracer\raytracer.h
?????文件???????4728??2010-06-20?22:43??RayTracer\scene.cpp
?????文件???????3666??2010-06-20?22:44??RayTracer\common.h
?????文件???????3538??2010-06-23?18:47??RayTracer\testapp.cpp
?????文件??????49664??2010-06-23?18:47??RayTracer\raytracer.opt
?????文件?????237633??2010-06-23?18:47??RayTracer\raytracer.exe
?????文件??????52732??2010-06-23?18:47??RayTracer\效果圖.jpg
?????目錄??????????0??2010-06-20?22:40??RayTracer\Debug
?????目錄??????????0??2010-06-20?22:40??RayTracer
-----------?---------??----------?-----??----
???????????????706778????????????????????20
評論
共有 條評論