@@ -177,7 +177,7 @@ vec3 get_normal()
177177#ifdef NORMAL_LOC
178178 vec3 ng = normalize (frag_normal);
179179#else
180- vec3 = cross (pos_dx, pos_dy);
180+ vec3 ng = cross (pos_dx, pos_dy);
181181#endif
182182
183183 t = normalize (t - ng * dot (ng, t));
@@ -262,6 +262,25 @@ vec3 compute_brdf(vec3 n, vec3 v, vec3 l,
262262 return color;
263263}
264264
265+
266+ vec3 compute_blinn_phong_brdf(vec3 n, vec3 v, vec3 l, float glossiness,
267+ vec3 diffuse, vec3 specular, vec3 radiance)
268+ {
269+ vec3 h = normalize (l+ v);
270+ float nl = clamp (dot (n, l), 0.001 , 1.0 );
271+ float nv = clamp (abs (dot (n, v)), 0.001 , 1.0 );
272+ float nh = clamp (dot (n, h), 0.0 , 1.0 );
273+ float lh = clamp (dot (l, h), 0.0 , 1.0 );
274+ float vh = clamp (dot (v, h), 0.0 , 1.0 );
275+
276+ vec3 diffuse_contrib = diffuse * nl / PI;
277+ vec3 spec_contrib = specular * pow (nh, glossiness);
278+
279+ vec3 color = radiance * (diffuse_contrib + spec_contrib);
280+ return color;
281+ }
282+
283+
265284float texture2DCompare(sampler2D depths, vec2 uv, float compare) {
266285 return compare > texture(depths, uv.xy).r ? 1.0 : 0.0 ;
267286}
@@ -308,36 +327,29 @@ float shadow_calc(mat4 light_matrix, sampler2D shadow_map, float nl)
308327 return shadow;
309328}
310329
311- // /////////////////////////////////////////////////////////////////////////////
312- // MAIN
313- // /////////////////////////////////////////////////////////////////////////////
314- void main()
315- {
316330
317- vec4 color = vec4 (vec3 (0.0 ), 1.0 );
318- // /////////////////////////////////////////////////////////////////////////////
319- // Handle Metallic Materials
320- // /////////////////////////////////////////////////////////////////////////////
321331#ifdef USE_METALLIC_MATERIAL
332+ vec4 compute_metallic_color() {
333+ vec4 color = vec4 (vec3 (0.0 ), 1.0 );
322334
323335 // Compute metallic/roughness factors
324336 float roughness = material.roughness_factor;
325337 float metallic = material.metallic_factor;
326- #ifdef HAS_METALLIC_ROUGHNESS_TEX
338+ #ifdef HAS_METALLIC_ROUGHNESS_TEX
327339 vec2 mr = texture(material.metallic_roughness_texture, uv_0).rg;
328340 roughness = roughness * mr.r;
329341 metallic = metallic * mr.g;
330- #endif
342+ #endif
331343 roughness = clamp (roughness, min_roughness, 1.0 );
332344 metallic = clamp (metallic, 0.0 , 1.0 );
333345 // In convention, material roughness is perceputal roughness ^ 2
334346 float alpha_roughness = roughness * roughness;
335347
336348 // Compute albedo
337349 vec4 base_color = material.base_color_factor;
338- #ifdef HAS_BASE_COLOR_TEX
350+ #ifdef HAS_BASE_COLOR_TEX
339351 base_color = base_color * srgb_to_linear(texture(material.base_color_texture, uv_0));
340- #endif
352+ #endif
341353
342354 // Compute specular and diffuse colors
343355 vec3 dialectric_spec = vec3 (min_roughness);
@@ -359,18 +371,18 @@ void main()
359371
360372 // Compute outbound color
361373 vec3 res = compute_brdf(n, v, l, roughness, metallic,
362- f0, c_diff, base_color.rgb, radiance);
374+ f0, c_diff, base_color.rgb, radiance);
363375
364376 // Compute shadow
365- #ifdef DIRECTIONAL_LIGHT_SHADOWS
377+ #ifdef DIRECTIONAL_LIGHT_SHADOWS
366378 float nl = clamp (dot (n,l), 0.0 , 1.0 );
367379 float shadow = shadow_calc(
368- directional_lights[i].light_matrix,
369- directional_lights[i].shadow_map,
370- nl
380+ directional_lights[i].light_matrix,
381+ directional_lights[i].shadow_map,
382+ nl
371383 );
372384 res = res * (1.0 - shadow);
373- #endif
385+ #endif
374386 color.xyz += res;
375387 }
376388
@@ -386,7 +398,7 @@ void main()
386398
387399 // Compute outbound color
388400 vec3 res = compute_brdf(n, v, l, roughness, metallic,
389- f0, c_diff, base_color.rgb, radiance);
401+ f0, c_diff, base_color.rgb, radiance);
390402 color.xyz += res;
391403 }
392404 for (int i = 0 ; i < n_spot_lights; i++ ) {
@@ -407,50 +419,168 @@ void main()
407419
408420 // Compute outbound color
409421 vec3 res = compute_brdf(n, v, l, roughness, metallic,
410- f0, c_diff, base_color.rgb, radiance);
411- #ifdef SPOT_LIGHT_SHADOWS
422+ f0, c_diff, base_color.rgb, radiance);
423+ #ifdef SPOT_LIGHT_SHADOWS
412424 float nl = clamp (dot (n,l), 0.0 , 1.0 );
413425 float shadow = shadow_calc(
414426 spot_lights[i].light_matrix,
415427 spot_lights[i].shadow_map,
416- nl
417- );
428+ nl);
418429 res = res * (1.0 - shadow);
419- #endif
430+ #endif
420431 color.xyz += res;
421432 }
422433 color.xyz += base_color.xyz * ambient_light;
423434
424435 // Calculate lighting from environment
425- #ifdef USE_IBL
436+ #ifdef USE_IBL
426437 // TODO
427- #endif
438+ #endif
428439
429440 // Apply occlusion
430- #ifdef HAS_OCCLUSION_TEX
441+ #ifdef HAS_OCCLUSION_TEX
431442 float ao = texture(material.occlusion_texture, uv_0).r;
432443 color.xyz *= ao;
433- #endif
444+ #endif
434445
435446 // Apply emissive map
436447 vec3 emissive = material.emissive_factor;
437- #ifdef HAS_EMISSIVE_TEX
448+ #ifdef HAS_EMISSIVE_TEX
438449 emissive *= srgb_to_linear(texture(material.emissive_texture, uv_0)).rgb;
439- #endif
450+ #endif
440451 color.xyz += emissive * material.emissive_factor;
441452
442- #ifdef COLOR_0_LOC
453+ #ifdef COLOR_0_LOC
443454 color *= color_multiplier;
455+ #endif
456+
457+ return clamp (vec4 (pow (color.xyz, vec3 (1.0 / 2.2 )), color.a * base_color.a), 0.0 , 1.0 );
458+ }
444459#endif
445460
446- frag_color = clamp (vec4 (pow (color.xyz, vec3 (1.0 / 2.2 )), color.a * base_color.a), 0.0 , 1.0 );
461+ #ifdef USE_GLOSSY_MATERIAL
462+ vec4 compute_glossy_color() {
463+ vec4 color = vec4 (vec3 (0.0 ), 1.0 );
447464
448- #else
449- // TODO GLOSSY MATERIAL BRDF
465+ // Compute metallic/roughness factors
466+ float glossiness = material.glossiness_factor;
467+ #ifdef HAS_SPECULAR_GLOSSINESS_TEX
468+ glossiness = glossiness * texture(material.specular_glossiness, uv_0).r;
469+ #endif
470+
471+ // Compute albedo
472+ vec4 diffuse_color = material.diffuse_factor;
473+ vec4 specular_color = vec4 (material.specular_factor, 1.0 );
474+ #ifdef HAS_DIFFUSE_TEX
475+ diffuse_color = diffuse_color * srgb_to_linear(texture(material.diffuse_texture, uv_0));
476+ #endif
477+
478+ // Compute normal
479+ vec3 n = normalize (get_normal());
480+
481+ // Loop over lights
482+ for (int i = 0 ; i < n_directional_lights; i++ ) {
483+ vec3 direction = directional_lights[i].direction;
484+ vec3 v = normalize (cam_pos - frag_position); // Vector towards camera
485+ vec3 l = normalize (- 1.0 * direction); // Vector towards light
486+
487+ // Compute attenuation and radiance
488+ float attenuation = directional_lights[i].intensity;
489+ vec3 radiance = attenuation * directional_lights[i].color;
490+
491+ // Compute outbound color
492+ vec3 res = compute_blinn_phong_brdf(
493+ n, v, l, glossiness, diffuse_color.rgb, specular_color.rgb, radiance);
494+
495+ // Compute shadow
496+ #ifdef DIRECTIONAL_LIGHT_SHADOWS
497+ float nl = clamp (dot (n,l), 0.0 , 1.0 );
498+ float shadow = shadow_calc(
499+ directional_lights[i].light_matrix,
500+ directional_lights[i].shadow_map,
501+ nl);
502+ res = res * (1.0 - shadow);
503+ #endif
504+ color.xyz += res;
505+ }
506+
507+ for (int i = 0 ; i < n_point_lights; i++ ) {
508+ vec3 position = point_lights[i].position;
509+ vec3 v = normalize (cam_pos - frag_position); // Vector towards camera
510+ vec3 l = normalize (position - frag_position); // Vector towards light
511+
512+ // Compute attenuation and radiance
513+ float dist = length (position - frag_position);
514+ float attenuation = point_lights[i].intensity / (dist * dist);
515+ vec3 radiance = attenuation * point_lights[i].color;
516+
517+ // Compute outbound color
518+ vec3 res = compute_blinn_phong_brdf(
519+ n, v, l, glossiness, diffuse_color.rgb, specular_color.rgb, radiance);
520+ color.xyz += res;
521+ }
522+ for (int i = 0 ; i < n_spot_lights; i++ ) {
523+ vec3 position = spot_lights[i].position;
524+ vec3 v = normalize (cam_pos - frag_position); // Vector towards camera
525+ vec3 l = normalize (position - frag_position); // Vector towards light
526+
527+ // Compute attenuation and radiance
528+ vec3 direction = spot_lights[i].direction;
529+ float las = spot_lights[i].light_angle_scale;
530+ float lao = spot_lights[i].light_angle_offset;
531+ float dist = length (position - frag_position);
532+ float cd = clamp (dot (direction, - l), 0.0 , 1.0 );
533+ float attenuation = clamp (cd * las + lao, 0.0 , 1.0 );
534+ attenuation = attenuation * attenuation * spot_lights[i].intensity;
535+ attenuation = attenuation / (dist * dist);
536+ vec3 radiance = attenuation * spot_lights[i].color;
537+
538+ // Compute outbound color
539+ vec3 res = compute_blinn_phong_brdf(
540+ n, v, l, glossiness, diffuse_color.rgb, specular_color.rgb, radiance);
541+ #ifdef SPOT_LIGHT_SHADOWS
542+ float nl = clamp (dot (n,l), 0.0 , 1.0 );
543+ float shadow = shadow_calc(
544+ spot_lights[i].light_matrix,
545+ spot_lights[i].shadow_map,
546+ nl);
547+ res = res * (1.0 - shadow);
548+ #endif
549+ color.xyz += res;
550+ }
551+
552+ // Apply occlusion
553+ #ifdef HAS_OCCLUSION_TEX
554+ float ao = texture(material.occlusion_texture, uv_0).r;
555+ color.xyz *= ao;
556+ #endif
557+
558+ // Apply emissive map
559+ vec3 emissive = material.emissive_factor;
560+ #ifdef HAS_EMISSIVE_TEX
561+ emissive *= srgb_to_linear(texture(material.emissive_texture, uv_0)).rgb;
562+ #endif
563+ color.xyz += emissive * material.emissive_factor;
564+
565+ #ifdef COLOR_0_LOC
566+ color *= color_multiplier;
567+ #endif
568+
569+ return clamp (vec4 (pow (color.xyz, vec3 (1.0 / 2.2 )), color.a), 0.0 , 1.0 );
570+ }
450571#endif
451572
452573// /////////////////////////////////////////////////////////////////////////////
453- // Handle Glossy Materials
574+ // MAIN
454575// /////////////////////////////////////////////////////////////////////////////
455-
576+ void main()
577+ {
578+ #ifdef USE_METALLIC_MATERIAL
579+ frag_color = compute_metallic_color();
580+ #elif USE_GLOSSY_MATERIAL
581+ // TODO GLOSSY MATERIAL BRDF
582+ frag_color = compute_glossy_color();
583+ #else
584+ frag_color = vec4 (1.0 , 0.0 , 1.0 , 1.0 );
585+ #endif
456586}
0 commit comments