in vec2 vertex_uv; in vec3 vertex_normal; in vec4 vertex_tangent; in vec3 vertex_pos; #include "drive/common/brdf.glsl" // written from a presentation slide, modified slightly float valveSpecularAA(vec3 geometricNormal, float roughness) { vec3 dnx = dFdx(geometricNormal); vec3 dny = dFdy(geometricNormal); float roughFactor = pow(clamp(max(dot(dnx, dnx), dot(dny, dny)) ,0.0, 1.0), 1.0/4.0); return max(roughness, roughFactor); } void main() { // sample textures vec4 tex_albedo = texture(t_base_color, vertex_uv); vec4 tex_normal = texture(t_normal, vertex_uv) * 2.0 - 1.0; vec4 tex_orm = texture(t_metallic_roughness, vertex_uv); // derive attributes vec3 albedo = tex_albedo.rgb; float metallic = tex_orm.z; float roughness = tex_orm.y; float occlusion = tex_orm.x; // normal mapping vec3 n = normalize(vertex_normal); vec3 t = normalize(vertex_tangent.xyz); vec3 b = vertex_tangent.w * cross(n, t); vec3 worldNormal = normalize(tex_normal.x * t + tex_normal.y * b + tex_normal.z * n); roughness = valveSpecularAA(n, roughness); // build surface state vec3 viewVector = -normalize(vertex_pos - (inverse(u_view) * vec4(0.0, 0.0, 0.0, 1.0)).xyz); SurfaceState surf = GetSurfaceState(albedo, metallic, roughness, worldNormal, viewVector, vec4(vertex_pos, 1.0), occlusion); vec3 color = vec3(0.0, 0.0, 0.0); // apply hardcoded PBR directional lights vec3 lightDirs[2] = vec3[]( normalize(vec3(1.0, 0.0, 0.0)), normalize(vec3(-1.0, 0.0, 0.0)) ); vec3 lightCols[2] = vec3[]( vec3(1.0, 0.57, 0.37), vec3(0.37, 0.57, 1.0) ); float lightStr[2] = float[]( 3.0, 2.0 ); for(int i = 0; i < 2; i++) { LightState light = GetLightState(surf, lightDirs[i], lightCols[i], lightStr[i]); color += DirectLighting(surf, light); } // Apply IBL color += ImageLighting(t_brdf, t_irradiance, t_radiance, surf) * 1.0; out_color0 = vec4(color, 1.0); }