pbr.lua 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. return function()
  2. return lovr.graphics.newShader([[
  3. out vec3 vPosition;
  4. out vec3 vNormal;
  5. out vec3 vTangent;
  6. out vec3 vLight;
  7. uniform vec3 lightDirection = vec3(0., 1., 1.);
  8. vec4 position(mat4 projection, mat4 transform, vec4 vertex) {
  9. vec4 position = lovrTransform * vertex;
  10. vNormal = lovrNormalMatrix * lovrNormal;
  11. vTangent = (lovrView * vec4(lovrTangent, 0.)).xyz;
  12. vPosition = position.xyz / position.w;
  13. vLight = (lovrView * vec4(lightDirection, 0.)).xyz;
  14. return projection * transform * vertex;
  15. }
  16. ]], [[
  17. in vec3 vPosition;
  18. in vec3 vNormal;
  19. in vec3 vTangent;
  20. in vec3 vLight;
  21. #define M_PI 3.141592653589
  22. vec3 computeN(vec3 vertexNormal, vec3 vertexTangent, sampler2D normalTexture, vec2 uv) {
  23. vec3 sample = normalize(texture(normalTexture, uv).rgb * 2. - 1.);
  24. vec3 N = normalize(vertexNormal);
  25. vec3 T = normalize(vertexTangent);
  26. vec3 B = cross(N, T);
  27. mat3 TBN = mat3(T, B, N);
  28. return normalize(TBN * sample);
  29. }
  30. float computeD(vec3 H, vec3 N, float roughness) {
  31. float alpha = roughness * roughness;
  32. float alpha2 = alpha * alpha;
  33. float NdotH = clamp(dot(N, H), 0., 1.);
  34. float x = (NdotH * NdotH) * (alpha2 - 1.) + 1.;
  35. return alpha2 / (M_PI * x * x);
  36. }
  37. vec3 computeF(vec4 baseColor, float metalness, vec3 H, vec3 V) {
  38. vec3 x = baseColor.rgb * metalness;
  39. return x + (1. - x) * pow(clamp(1. - dot(V, H), 0., 1.), 5.);
  40. }
  41. float computeG(float roughness, float NdotL, float NdotV) {
  42. float r = roughness * roughness;
  43. float GL = 2. * NdotL / (NdotL + sqrt(r * r + (1. - r * r) * (NdotL * NdotL)));
  44. float GV = 2. * NdotV / (NdotV + sqrt(r * r + (1. - r * r) * (NdotV * NdotV)));
  45. return GL * GV;
  46. }
  47. vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) {
  48. vec4 baseColor = texture(lovrDiffuseTexture, uv) * lovrDiffuseColor;
  49. float ao = texture(lovrOcclusionTexture, uv).r;
  50. float metalness = texture(lovrMetalnessTexture, uv).b * lovrMetalness;
  51. float roughness = texture(lovrRoughnessTexture, uv).g * lovrRoughness;
  52. vec4 emissive = texture(lovrEmissiveTexture, uv) * lovrEmissiveColor;
  53. vec3 N = computeN(vNormal, vTangent, lovrNormalTexture, uv);
  54. vec3 V = normalize(-vPosition);
  55. vec3 L = normalize(vLight);
  56. vec3 H = normalize(L + V);
  57. float NdotL = clamp(dot(N, L), .001, 1.);
  58. float NdotV = abs(dot(N, V)) + .001;
  59. vec3 diffuse = baseColor.rgb * (1. - metalness) * dot(N, L);
  60. vec3 specularColor = baseColor.rgb * metalness;
  61. float D = computeD(H, N, roughness);
  62. vec3 F = computeF(baseColor, metalness, H, V);
  63. float G = computeG(roughness, NdotL, NdotV);
  64. vec3 brdf = (D * F * G) / (4. * NdotL * NdotV);
  65. vec3 specular = specularColor * brdf;
  66. vec3 main = clamp((diffuse + specular) * ao, 0., 1.);
  67. return graphicsColor * vertexColor * vec4(clamp(main + emissive.rgb, 0., 1.), 1.);
  68. }
  69. ]])
  70. end