Рей трейсинг,один из методов получения физически правельной картинки,вот представте себе сцену - полоскость и три сферы рандомно раставленые над ней все эти объекты имеют свойство отражать в себе окружающий мир,как вы это сделаете? Чтобы всё было физически правельно веть надо будет отражать не только на плейне все сферы но и чтобы в сферах были отражения других сфер и плейна! Без рей трейсинга здесь однозначно не обойтись! Кстате скоро выйдет RayTrace движок от инвидии который будет ускарятся на их видео карточках.
Я не раскажу вам к сожелению об отражениях в этой статье,но в дальнейших частях думаю реч пойдёт и об отражениях.
И так перва статья об RayTrace будет вводная:
Представте себе такую сцену:
Она разбита не триугольники( но как правело если юзать триугольники то нужно кажый триугольник разбить ещё на 3-4 триугольника а то и больше чтобы достич качества):
И так стрельба лучами от источника к вершине каждого триугольника:
Мы просто берём луч Origin = light position , Dir = vertex position - Origin
И шотим и так с кажой вершиной каждого объекта.
Как же получить тени спросите вы?? Легко при шоте лучём мы проверяем если луч пересёк что либо то значит затеням вершину так как между источником и вершиной стоит какаято преграда!
У себя я это делаю так:
void CMesh::rayTrace()
{
for(int i=0;i<num_surfaces;i++){
CSurface* s = surfaces[i];
for(int j=0;j<s->lightmaps.size();j++){
LightMap* m = &s->lightmaps[j];
for(int y=0;y<m->size;y++){
for(int x=0;x<m->size;x++){
vec3 crd = m->getLumel(x,y)->coord;
for(int k=0;k<CSceneManager::num_lights;k++){
CLight* l = CSceneManager::lights[k];
//if(!l->getMaterial())
// continue;
float dist = 100000;
vec3 p,n;
vec3 start = l->getWorldPosition();
vec3 end = crd;//(l->getWorldPosition() - m->getLumel(x,y)->coord).normalized() * crd.distance(l->getWorldPosition());
IEntity* e = CEngine::scene->rayTrace(start,(end - start).normalized() * 1000 ,p,n);
//glMatrixMode(GL_MODELVIEW);
//glLoadIdentity();
CEngine::scene->begin(CEngine::scene->camera);
glColor3f(1,0,0);
glBegin(GL_LINES);
glVertex3f(start.x,start.y,start.z);
glVertex3f(end.x,end.y,end.z);
glEnd();
if(e && p.distance(end) <= 2.0f ){
float dist = (l->getWorldPosition() - crd).length();
float attenuation = 1 - sqrt(dist) / sqrt(l->getRadius());
float d = dot(m->getLumel(x,y)->normal,(start - end).normalized());
m->getLumel(x,y)->color += l->getMaterial()->getColor() * d * attenuation;
glColor3f(0,1,0);
glBegin(GL_LINES);
glVertex3f(start.x,start.y,start.z);
glVertex3f(p.x,p.y,p.z);
glEnd();
}
CEngine::scene->end();
getEngine()->flip();
}
}
}
}
s->updateLightmap();
}
}
Первая часть закончена,воторая будет как только я разберусь с отражениями)).