Матрица вида-проекции направленного источника
This commit is contained in:
		
							parent
							
								
									b463e0808c
								
							
						
					
					
						commit
						78e7160a4c
					
				| @ -81,7 +81,10 @@ class Sun | |||||||
|          |          | ||||||
|         alignas(16) glm::vec3 direction; // Направление лучей источника
 |         alignas(16) glm::vec3 direction; // Направление лучей источника
 | ||||||
|         alignas(16) glm::vec3 color; // Цвет
 |         alignas(16) glm::vec3 color; // Цвет
 | ||||||
|  |         alignas(16) glm::mat4 vp; // Матрица вида-проекции источника
 | ||||||
| 
 | 
 | ||||||
|  |         void recalcVP(); // Пересчитывает по необходимости матрицу вида-проекции
 | ||||||
|  |          | ||||||
|         static Sun instance; // Экземпляр синглтона
 |         static Sun instance; // Экземпляр синглтона
 | ||||||
|         static bool uploadReq; // Необходимость загрузки в следствии изменений
 |         static bool uploadReq; // Необходимость загрузки в следствии изменений
 | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -264,6 +264,8 @@ Sun& Sun::get() | |||||||
| // Загрузка данных об источнике на шейдер
 | // Загрузка данных об источнике на шейдер
 | ||||||
| void Sun::upload(UBO& sun_data) | void Sun::upload(UBO& sun_data) | ||||||
| { | { | ||||||
|  |     instance.recalcVP(); // Пересчет матрицы вида-проекции источника по необходимости (влияет на флаг uploadReq)
 | ||||||
|  | 
 | ||||||
|     if (uploadReq) |     if (uploadReq) | ||||||
|     { |     { | ||||||
|         sun_data.loadSub(&instance, sizeof(instance)); |         sun_data.loadSub(&instance, sizeof(instance)); | ||||||
| @ -299,3 +301,42 @@ glm::vec3& Sun::e_color() | |||||||
| 
 | 
 | ||||||
|     return instance.color; |     return instance.color; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // Пересчитывает по необходимости матрицу вида-проекции
 | ||||||
|  | void Sun::recalcVP() | ||||||
|  | { | ||||||
|  |     std::pair <bool, const glm::vec4*> camProjCoords = Camera::current().getProjCoords(); | ||||||
|  | 
 | ||||||
|  |     // Есть изменения по источнику или камере
 | ||||||
|  |     if (uploadReq || camProjCoords.first) | ||||||
|  |     { | ||||||
|  |         uploadReq = true; // Требуется загрузка в следствии пересчета матрицы
 | ||||||
|  | 
 | ||||||
|  |         glm::vec3 mean = glm::vec3(0); // Среднее арифметическое
 | ||||||
|  |         glm::vec4 max, min; // макс и мин координаты
 | ||||||
|  |         glm::vec4 point; // Точка приведенная в пространство источника света
 | ||||||
|  | 
 | ||||||
|  |         // Найдем среднее арифметическое от точек для нахождения центра прямоугольника
 | ||||||
|  |         for (int i = 0; i < 8; i++) | ||||||
|  |             mean += glm::vec3(camProjCoords.second[i]); | ||||||
|  |         mean /= 8; | ||||||
|  |         // Используем среднее арифметическое для получения матрицы вида параллельного источника
 | ||||||
|  |         glm::mat4 lightView = glm::lookAt(mean + glm::normalize(direction), mean, CAMERA_UP_VECTOR); | ||||||
|  |          | ||||||
|  |         // Примем первую точку как минимальную и максимальную (приведя в пространство вида источника)
 | ||||||
|  |         min = max = lightView * camProjCoords.second[0]; | ||||||
|  |         // Для оставшихся точек
 | ||||||
|  |         for (int i = 1; i < 8; i++) | ||||||
|  |         { | ||||||
|  |             // Приведем в пространство вида источника
 | ||||||
|  |             point = lightView * camProjCoords.second[i]; | ||||||
|  |             max = glm::max(max, point); | ||||||
|  |             min = glm::min(min, point); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Максимальное значение глубины
 | ||||||
|  |         max.z = std::max(fabs(max.z), fabs(min.z)); | ||||||
|  |         // На основании максимальных и минимальных координат создадим матрицу проекции источника
 | ||||||
|  |         vp = glm::ortho(min.x, max.x, min.y, max.y, min.z, max.z) * lightView; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user