PBR
This commit is contained in:
		
							parent
							
								
									7ea3476e98
								
							
						
					
					
						commit
						66574fa6b1
					
				| @ -34,8 +34,9 @@ uniform float camera_cascade_distances[4]; // Размер массива дол | ||||
| 
 | ||||
| uniform sampler2D gPosition; | ||||
| uniform sampler2D gNormal; | ||||
| uniform sampler2D gDiffuseP; | ||||
| uniform sampler2D gAmbientSpecular; | ||||
| uniform sampler2D gBaseColor; | ||||
| uniform sampler2D gRMS; | ||||
| uniform sampler2D gEmittedColor; | ||||
| uniform sampler2DArray sunShadowDepth; | ||||
| uniform samplerCubeArray pointShadowDepth; | ||||
| uniform sampler2D ssao; | ||||
| @ -50,24 +51,50 @@ layout(std140, binding = 4) uniform gamma | ||||
| 
 | ||||
| out vec4 color;  | ||||
| 
 | ||||
| const float PI = 3.14159265359; | ||||
| 
 | ||||
| float D(vec3 H, vec3 N, float a) | ||||
| { | ||||
|     float tmp = max(dot(N, H), 0); | ||||
|     tmp = tmp*tmp*(a*a-1)+1; | ||||
|     return a*a/(PI * tmp*tmp); | ||||
| } | ||||
| 
 | ||||
| float G_Sclick_Beckmann(float NDotDir, float a) | ||||
| { | ||||
|     float tmp = (a+1)*(a+1) / 8; | ||||
|     return 1 / (NDotDir * (1 - tmp) + tmp); | ||||
| } | ||||
| 
 | ||||
| float G_Smith(float LDotN, float CamDotN, float a) | ||||
| { | ||||
|     return G_Sclick_Beckmann(LDotN, a) * G_Sclick_Beckmann(CamDotN, a); | ||||
| } | ||||
| 
 | ||||
| vec3 F(vec3 H, vec3 Cam_vertex, float metallic, float specular, vec3 base_color) | ||||
| { | ||||
|     vec3 F0 = mix(vec3(0.08 * specular), base_color, metallic); | ||||
|     return F0 + (1 - F0) * pow(1 - max(dot(H, Cam_vertex),0), 5); | ||||
| } | ||||
| 
 | ||||
| void main()  | ||||
| {  | ||||
|     // Получим данные из текстур буфера | ||||
|     vec3 fragPos = texture(gPosition, texCoord).rgb; | ||||
|     vec3 N = texture(gNormal, texCoord).rgb; | ||||
|     vec3 kd = texture(gDiffuseP, texCoord).rgb; | ||||
|     vec3 ka = texture(gAmbientSpecular, texCoord).rgb; | ||||
|     float ks = texture(gAmbientSpecular, texCoord).a; | ||||
|     float p = texture(gDiffuseP, texCoord).a; | ||||
|     vec3 N = normalize(texture(gNormal, texCoord).rgb); | ||||
|     vec3 base_color = texture(gBaseColor, texCoord).rgb; | ||||
|     float roughness = texture(gRMS, texCoord).r; | ||||
|     float metallic = texture(gRMS, texCoord).g; | ||||
|     float specular = texture(gRMS, texCoord).b; | ||||
|     float ssao_value = texture(ssao, texCoord).r; | ||||
|      | ||||
|     // Переменные используемые в цикле: | ||||
|     vec3 L_vertex; // Расположение источника относительно фрагмента | ||||
|     float L_distance; // Расстояние от поверхности до источника | ||||
|     vec3 Cam_vertex = normalize(camera.position - fragPos); // Расположение камеры относительно фрагмента | ||||
|     float diffuse; // Диффузная составляющая | ||||
|     vec3 ks; // Интенсивность зеркального отражения | ||||
|     vec3 fd, fs; // Диффузное и зеркальное отражения | ||||
|     vec3 H; // Вектор половины пути | ||||
|     float specular; // Зеркальная составляющая | ||||
|     float attenuation; // Угасание с учетом расстояния | ||||
|     float acosA; // Косинус между вектором от поверхности к источнику и обратным направлением источника | ||||
|     float intensity; // Интенсивность для прожектора | ||||
| @ -81,14 +108,19 @@ void main() | ||||
|     float cubemap_offset = 0.05f; // Отступ в текстурных координатах для PCF | ||||
|     float cubemap_depth; // Дистанция между фрагментом и источником в диапазоне [0;1] | ||||
| 
 | ||||
|     float CamDotN = dot(Cam_vertex,N); // Скалярное произведение вектора на камеру и нормали | ||||
|     float LDotN; // Скалярное произведение вектора на источник и нормали | ||||
| 
 | ||||
|     // Определение индекса каскада в который попадает фрагмент (цикл на 1 меньше чем кол-во каскадов) | ||||
|     for (cascade_index = 0; cascade_index < 3; cascade_index++) | ||||
|         if (abs(fragPosCamSpace.z) < camera_cascade_distances[cascade_index]) | ||||
|             break; | ||||
| 
 | ||||
|     // Фоновая освещенность | ||||
|     color = vec4(ka, 1) * ssao_value; | ||||
|     color = vec4(texture(gEmittedColor, texCoord).rgb, 1); | ||||
|      | ||||
|     if (length(N) > 0) | ||||
|     { | ||||
|         // Расчет солнца, если его цвет не черный | ||||
|         if (length(Sun_color) > 0) | ||||
|         { | ||||
| @ -115,16 +147,22 @@ void main() | ||||
|             { | ||||
|                 // Данные об источнике относительно фрагмента | ||||
|                 L_vertex = normalize(Sun_direction); | ||||
|             // Диффузная составляющая | ||||
|             diffuse = max(dot(L_vertex, N), 0.0); // скалярное произведение с отсеканием значений < 0 | ||||
|              | ||||
|                 LDotN = dot(L_vertex,N); | ||||
|                 if (LDotN > 0) | ||||
|                 { | ||||
|                     // Вектор половины пути | ||||
|                     H = normalize(L_vertex + Cam_vertex); | ||||
|             // Зеркальная составляющая | ||||
|             specular = pow(max(dot(H, N), 0.0), p*4); // скалярное произведение с отсеканием значений < 0 в степени p | ||||
| 
 | ||||
|                     // Зеркальное отражение | ||||
|                     ks = F(H, Cam_vertex, metallic, specular, base_color); | ||||
|                     fs = ks * min(D(H, N, roughness*roughness) / 4, 1) * G_Smith(LDotN, CamDotN, roughness*roughness); | ||||
| 
 | ||||
|                     // Диффузное отражение | ||||
|                     fd = (1 - length(ks)/length(base_color)) * base_color; | ||||
| 
 | ||||
|                     // Результирующий цвет с учетом солнца | ||||
|             color += (  vec4(Sun_color*kd*diffuse,  1)   | ||||
|                       + vec4(Sun_color*ks*specular, 1) ) * (1.0 - shadowValue); | ||||
|                     color.rgb += (fd + fs) * Sun_color * LDotN * (1.0 - shadowValue); | ||||
|                 } | ||||
|             } | ||||
|         }  | ||||
| 
 | ||||
| @ -171,34 +209,40 @@ void main() | ||||
|                     // Если угол меньше угла источника или угол источника минимален, то считаем освещенность | ||||
|                     if(acosA <= light_f.data[i].angle)  | ||||
|                     { | ||||
|                     // Диффузная составляющая | ||||
|                     diffuse = max(dot(L_vertex, N), 0.0); // скалярное произведение с отсеканием значений < 0 | ||||
|                  | ||||
|                         LDotN = dot(L_vertex,N); | ||||
|                         if (LDotN > 0) | ||||
|                         { | ||||
|                             // Вектор половины пути | ||||
|                             H = normalize(L_vertex + Cam_vertex); | ||||
|                     // Зеркальная составляющая | ||||
|                     specular = pow(max(dot(H, N), 0.0), p*4); // скалярное произведение с отсеканием значений < 0 в степени p | ||||
| 
 | ||||
|                             // Угасание с учетом расстояния | ||||
|                             attenuation = 1 / (1 + light_f.data[i].K[0] * L_distance + light_f.data[i].K[1] * L_distance * L_distance); | ||||
| 
 | ||||
|                             // Зеркальное отражение | ||||
|                             ks = F(H, Cam_vertex, metallic, specular, base_color); | ||||
|                             fs = ks * min(D(H, N, roughness*roughness) / 4, 1) * G_Smith(LDotN, CamDotN, roughness*roughness); | ||||
| 
 | ||||
|                             // Диффузное отражение | ||||
|                             fd = (1 - length(ks)/length(base_color)) * base_color; | ||||
| 
 | ||||
|                             // Если источник - прожектор, то добавим смягчение | ||||
|                             if (light_f.data[i].angle < 180) | ||||
|                             { | ||||
|                                 intensity = clamp((light_f.data[i].angle - acosA) / 5, 0.0, 1.0);   | ||||
|                         diffuse  *= intensity; | ||||
|                         specular *= intensity; | ||||
|                                 fd *= intensity; | ||||
|                                 fs *= intensity; | ||||
|                             } | ||||
| 
 | ||||
|                     color += ( vec4(light_f.data[i].color*kd*diffuse  * attenuation, 1)  | ||||
|                               + vec4(light_f.data[i].color*ks*specular * attenuation, 1) )  * (1.0 - shadowValue); | ||||
|                             color.rgb += (fd + fs) * light_f.data[i].color * attenuation * LDotN * (1.0 - shadowValue); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // Применение гамма-коррекции | ||||
|     color.rgb = pow(color.rgb, vec3(inv_gamma)); | ||||
|     color.rgb = pow(color.rgb * ssao_value, vec3(inv_gamma)); | ||||
| 
 | ||||
| 
 | ||||
|     // Обводка выбранного объекта | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user