main.lua 3.0 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 = vec2(radius, radius):distance(vec2(x, y))
  11. local depth = math.sqrt(radius^2 - distanceFromCenter^2)
  12. puffImage:setPixel(x, y, 1, 1, 1, depth / radius)
  13. lovr.math.drain()
  14. end
  15. end
  16. puffTexture = lovr.graphics.newTexture(puffImage)
  17. puffMaterial = lovr.graphics.newMaterial({ texture = puffTexture })
  18. -- puff positions
  19. redPuffs = {}
  20. for i = 1, 100 do
  21. table.insert(redPuffs, {
  22. position = lovr.math.newVec3(
  23. lovr.math.random() - .5,
  24. lovr.math.random() - .5 + 1.7,
  25. lovr.math.random() - .5
  26. )
  27. })
  28. end
  29. bluePuffs = {}
  30. for i = 1, 100 do
  31. table.insert(bluePuffs, {
  32. position = lovr.math.newVec3(
  33. lovr.math.random() - .5,
  34. lovr.math.random() - .5 + 1.7,
  35. lovr.math.random() - .5
  36. )
  37. })
  38. end
  39. -- red puff billboard shader
  40. redPuffVertex = [[
  41. Constants {
  42. vec3 headPosition;
  43. };
  44. mat4 target(vec3 from, vec3 to, vec3 up) {
  45. mat4 m;
  46. vec3 z = normalize(from - to);
  47. vec3 x = normalize(cross(up, z));
  48. vec3 y = cross(z, x);
  49. m[0] = vec4(x, 0);
  50. m[1] = vec4(y, 0);
  51. m[2] = vec4(z, 0);
  52. m[3] = vec4(from, 1);
  53. return m;
  54. }
  55. vec4 lovrmain() {
  56. vec3 puffPosition = Transform[3].xyz;
  57. vec3 puffScale = vec3(length(Transform[0]), length(Transform[1]), length(Transform[2]));
  58. mat4 billboardModel = target(puffPosition, headPosition, vec3(0, 1, 0));
  59. billboardModel *= mat4(
  60. puffScale.x, 0, 0, 0,
  61. 0, puffScale.y, 0, 0,
  62. 0, 0, puffScale.z, 0,
  63. 0, 0, 0, 1
  64. );
  65. return Projection * View * billboardModel * VertexPosition;
  66. }
  67. ]]
  68. defaultFragment = [[
  69. vec4 lovrmain() {
  70. return DefaultColor;
  71. }
  72. ]]
  73. redPuffShader = lovr.graphics.newShader(redPuffVertex, defaultFragment)
  74. lovr.graphics.setBackgroundColor(0, .5, 1)
  75. end
  76. function lovr.draw(pass)
  77. pass:setSampler('nearest') -- try uncommenting
  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', { lovr.headset.getPosition('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. puff.orientation = quat(mat4():target(puff.position, vec3(lovr.headset.getPosition('head'))))
  92. pass:plane(puff.position, .1, .1, puff.orientation)
  93. end
  94. end