main.lua 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. local glsl = {}
  2. local lightPosition = {}
  3. local headsetPosition = {}
  4. local controller = nil
  5. function lovr.load()
  6. model = lovr.graphics.newModel('helmet/DamagedHelmet.gltf')
  7. shader = lovr.graphics.newShader(unpack(glsl.pbr))
  8. lovr.graphics.setBackgroundColor(.18, .18, .20)
  9. lightPosition = { 75, 60, 20 }
  10. end
  11. function lovr.update(dt)
  12. controller = lovr.headset.getControllers()[1]
  13. if controller then lightPosition = { controller:getPosition() } end
  14. headsetPosition = { lovr.headset.getPosition() }
  15. shader:send('lightPosition', lightPosition)
  16. shader:send('headsetPosition', headsetPosition)
  17. end
  18. function lovr.draw()
  19. lovr.graphics.setShader(shader)
  20. model:draw(0, 1.6, -1.5, .4, lovr.timer.getTime() * .12 + .1)
  21. lovr.graphics.setShader()
  22. if controller then
  23. local x, y, z = unpack(lightPosition)
  24. lovr.graphics.setColor(1, 1, 1)
  25. lovr.graphics.sphere(x, y, z, .01)
  26. end
  27. end
  28. glsl.pbr = {
  29. [[
  30. out vec3 vNormal;
  31. out vec3 vVertex;
  32. vec4 position(mat4 projection, mat4 transform, vec4 vertex) {
  33. vNormal = mat3(lovrModel) * lovrNormal;
  34. vVertex = vec3(lovrModel * vertex);
  35. return projection * lovrView * vec4(vVertex, 1.0);
  36. }
  37. ]],
  38. [[
  39. #define PI 3.141592653
  40. in vec3 vNormal;
  41. in vec3 vVertex;
  42. uniform vec3 headsetPosition;
  43. uniform vec3 lightPosition;
  44. float D_GGX(float NoH, float roughness) {
  45. float alpha = roughness * roughness;
  46. float alpha2 = alpha * alpha;
  47. float denom = (NoH * NoH) * (alpha2 - 1.) + 1.;
  48. return alpha2 / (PI * denom * denom);
  49. }
  50. float G_SmithGGXCorrelated(float NoV, float NoL, float roughness) {
  51. float alpha = roughness * roughness;
  52. float alpha2 = alpha * alpha;
  53. float GGXV = NoL * sqrt(alpha2 + (1. - alpha2) * (NoV * NoV));
  54. float GGXL = NoV * sqrt(alpha2 + (1. - alpha2) * (NoL * NoL));
  55. return .5 / max(GGXV + GGXL, 1e-5);
  56. }
  57. vec3 F_Schlick(vec3 F0, float LoH) {
  58. return F0 + (vec3(1.) - F0) * pow(1. - LoH, 5.);
  59. }
  60. vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) {
  61. vec3 baseColor = texture(lovrDiffuseTexture, uv).rgb;
  62. vec3 emissive = texture(lovrEmissiveTexture, uv).rgb;
  63. float metalness = texture(lovrMetalnessTexture, uv).b * lovrMetalness;
  64. float roughness = max(texture(lovrRoughnessTexture, uv).g * lovrRoughness, .05);
  65. float occlusion = texture(lovrOcclusionTexture, uv).r;
  66. vec3 F0 = mix(vec3(.04), baseColor, metalness);
  67. vec3 N = normalize(vNormal);
  68. vec3 V = normalize(headsetPosition - vVertex);
  69. vec3 L = normalize(lightPosition - vVertex);
  70. vec3 H = normalize(V + L);
  71. float NoV = abs(dot(N, V)) + 1e-5;
  72. float NoL = clamp(dot(N, L), 0., 1.);
  73. float NoH = clamp(dot(N, H), 0., 1.);
  74. float LoH = clamp(dot(L, H), 0., 1.);
  75. float D = D_GGX(NoH, roughness);
  76. float G = G_SmithGGXCorrelated(NoV, NoL, roughness);
  77. vec3 F = F_Schlick(F0, LoH);
  78. vec3 specular = vec3(D * G * F);
  79. vec3 diffuse = (vec3(1.) - F) * (1. - metalness) * baseColor;
  80. vec3 color = (diffuse + specular) * NoL * occlusion + emissive;
  81. ]] ..
  82. (lovr.getOS() == 'Web' and ' color = pow(color, vec3(.4545));\n' or '') ..
  83. [[
  84. return vec4(vec3(color), 1.);
  85. }
  86. ]]
  87. }