Показать сообщение отдельно
Старый 23.09.2009, 00:00   #1
Genius
Знающий
 
Аватар для Genius
 
Регистрация: 02.11.2007
Сообщений: 255
Написано 27 полезных сообщений
(для 43 пользователей)
Статья: RayTrace(Part 1)



Рей трейсинг,один из методов получения физически правельной картинки,вот представте себе сцену - полоскость и три сферы рандомно раставленые над ней все эти объекты имеют свойство отражать в себе окружающий мир,как вы это сделаете? Чтобы всё было физически правельно веть надо будет отражать не только на плейне все сферы но и чтобы в сферах были отражения других сфер и плейна! Без рей трейсинга здесь однозначно не обойтись! Кстате скоро выйдет 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();
	}
}
Первая часть закончена,воторая будет как только я разберусь с отражениями)).


(Offline)
 
Ответить с цитированием