main.lua 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. -- red puffs are billboards oriented in GLSL
  2. -- blue puffs are billboards oriented in Lua
  3. function lovr.load()
  4. -- puff texture
  5. puffImageSize = 128 -- try 16
  6. puffImage = lovr.data.newImage(puffImageSize, puffImageSize)
  7. for x = 0, puffImageSize - 1 do
  8. for y = 0, puffImageSize - 1 do
  9. local radius = puffImageSize / 2 - 1
  10. local distanceFromCenter = vector(radius, radius, 0):distance(vector(x, y, 0))
  11. local depth = math.sqrt(radius^2 - distanceFromCenter^2)
  12. puffImage:setPixel(x, y, 1, 1, 1, depth / radius)
  13. end
  14. end
  15. puffTexture = lovr.graphics.newTexture(puffImage)
  16. puffMaterial = lovr.graphics.newMaterial({ texture = puffTexture })
  17. -- puff positions
  18. redPuffs = {}
  19. for i = 1, 100 do
  20. table.insert(redPuffs, {
  21. position = vector(
  22. lovr.math.random() - .5,
  23. lovr.math.random() - .5 + 1.7,
  24. lovr.math.random() - .5
  25. )
  26. })
  27. end
  28. bluePuffs = {}
  29. for i = 1, 100 do
  30. table.insert(bluePuffs, {
  31. position = vector(
  32. lovr.math.random() - .5,
  33. lovr.math.random() - .5 + 1.7,
  34. lovr.math.random() - .5
  35. )
  36. })
  37. end
  38. -- red puff billboard shader
  39. redPuffVertex = [[
  40. Constants {
  41. vec3 headPosition;
  42. };
  43. mat4 target(vec3 from, vec3 to, vec3 up) {
  44. mat4 m;
  45. vec3 z = normalize(from - to);
  46. vec3 x = normalize(cross(up, z));
  47. vec3 y = cross(z, x);
  48. m[0] = vec4(x, 0);
  49. m[1] = vec4(y, 0);
  50. m[2] = vec4(z, 0);
  51. m[3] = vec4(from, 1);
  52. return m;
  53. }
  54. vec4 lovrmain() {
  55. vec3 puffPosition = Transform[3].xyz;
  56. vec3 puffScale = vec3(length(Transform[0]), length(Transform[1]), length(Transform[2]));
  57. mat4 billboardModel = target(puffPosition, headPosition, vec3(0, 1, 0));
  58. billboardModel *= mat4(
  59. puffScale.x, 0, 0, 0,
  60. 0, puffScale.y, 0, 0,
  61. 0, 0, puffScale.z, 0,
  62. 0, 0, 0, 1
  63. );
  64. return Projection * View * billboardModel * VertexPosition;
  65. }
  66. ]]
  67. defaultFragment = [[
  68. vec4 lovrmain() {
  69. return DefaultColor;
  70. }
  71. ]]
  72. redPuffShader = lovr.graphics.newShader(redPuffVertex, defaultFragment)
  73. lovr.graphics.setBackgroundColor(0, .5, 1)
  74. end
  75. function lovr.draw(pass)
  76. pass:setSampler('nearest') -- try uncommenting
  77. local head = vector(lovr.headset.getPosition())
  78. -- red puffs
  79. pass:setColor(1, .9, .9)
  80. pass:setMaterial(puffMaterial)
  81. pass:setDepthWrite(false)
  82. pass:setShader(redPuffShader)
  83. pass:send('headPosition', head)
  84. for _, puff in pairs(redPuffs) do
  85. pass:plane(puff.position, .1)
  86. end
  87. pass:setShader()
  88. -- blue puffs
  89. pass:setColor(.9, 1, 1)
  90. for _, puff in pairs(bluePuffs) do
  91. pass:plane(puff.position, .1, .1, quaternion.lookdir(head - puff.position))
  92. end
  93. end