A 2D tile-based sandbox game.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

shaders.cc 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #include "shaders.h"
  2. namespace Cygnet::Shaders {
  3. const char *chunkVx = R"glsl(
  4. precision mediump float;
  5. uniform mat3 camera;
  6. uniform vec2 pos;
  7. attribute vec2 vertex;
  8. varying vec2 v_tileCoord;
  9. void main() {
  10. vec3 pos = camera * vec3(pos + vertex, 1);
  11. gl_Position = vec4(pos.xy, 0, 1);
  12. v_tileCoord = vertex;
  13. }
  14. )glsl";
  15. const char *chunkFr = R"glsl(
  16. precision mediump float;
  17. #define TILE_SIZE 32.0
  18. #define CHUNK_WIDTH 64
  19. #define CHUNK_HEIGHT 64
  20. varying vec2 v_tileCoord;
  21. uniform sampler2D tileAtlas;
  22. uniform vec2 tileAtlasSize;
  23. uniform sampler2D tiles;
  24. void main() {
  25. vec2 tilePos = floor(vec2(v_tileCoord.x, v_tileCoord.y));
  26. vec4 tileColor = texture2D(tiles, tilePos / vec2(CHUNK_WIDTH, CHUNK_HEIGHT));
  27. float tileID = floor((tileColor.r * 256.0 + tileColor.a) * 256.0);
  28. // 1/(TILE_SIZE*16) plays the same role here as in the sprite vertex shader.
  29. vec2 offset = v_tileCoord - tilePos;
  30. vec2 pixoffset = (1.0 - offset * 2.0) / (TILE_SIZE * 16.0);
  31. vec2 atlasPos = vec2(
  32. pixoffset.x + tileID + offset.x,
  33. pixoffset.y + floor(tileID / tileAtlasSize.x) + offset.y);
  34. gl_FragColor = texture2D(tileAtlas, atlasPos / tileAtlasSize);
  35. }
  36. )glsl";
  37. const char *lightingVx = R"glsl(
  38. precision mediump float;
  39. uniform mat3 inverseCamera;
  40. attribute vec2 vertex;
  41. varying vec2 v_pos;
  42. void main() {
  43. v_pos = (inverseCamera * vec3(vertex, 1)).xy;
  44. gl_Position = vec4(vertex.xy, 0, 1);
  45. }
  46. )glsl";
  47. const char *lightingFr = R"glsl(
  48. precision mediump float;
  49. varying vec2 v_pos;
  50. uniform vec2 lightPos;
  51. uniform float lightLevel;
  52. void main() {
  53. vec2 diff = lightPos - v_pos;
  54. float squareDist = diff.x * diff.x + diff.y * diff.y;
  55. float dist = sqrt(squareDist);
  56. float attenuated = 1.0 / (1.0 + 1.0 * dist + 0.2 * squareDist);
  57. float light = lightLevel * attenuated;
  58. gl_FragColor = vec4(light, light, light, light);
  59. }
  60. )glsl";
  61. const char *tileVx = R"glsl(
  62. precision mediump float;
  63. uniform mat3 camera;
  64. uniform mat3 transform;
  65. attribute vec2 vertex;
  66. varying vec2 v_tileCoord;
  67. void main() {
  68. vec3 pos = camera * transform * vec3(vertex, 1);
  69. gl_Position = vec4(pos.xy, 0, 1);
  70. v_tileCoord = vertex;
  71. }
  72. )glsl";
  73. const char *blendLightingVx = R"glsl(
  74. precision mediump float;
  75. attribute vec2 vertex;
  76. attribute vec2 texCoord;
  77. varying vec2 v_texCoord;
  78. void main() {
  79. gl_Position = vec4(vertex.xy, 0, 1);
  80. v_texCoord = texCoord;
  81. }
  82. )glsl";
  83. const char *blendLightingFr = R"glsl(
  84. precision mediump float;
  85. varying vec2 v_texCoord;
  86. uniform sampler2D tex;
  87. const float power = 1.0 / 2.4;
  88. void main() {
  89. vec4 linear = texture2D(tex, v_texCoord);
  90. vec4 srgb = 1.055 * pow(linear, vec4(power, power, power, power)) - 0.055;
  91. gl_FragColor = srgb;
  92. }
  93. )glsl";
  94. const char *tileFr = R"glsl(
  95. precision mediump float;
  96. #define TILE_SIZE 32.0
  97. varying vec2 v_tileCoord;
  98. uniform sampler2D tileAtlas;
  99. uniform vec2 tileAtlasSize;
  100. uniform float tileID;
  101. void main() {
  102. // 1/(TILE_SIZE*16) plays the same role here as in the sprite vertex shader.
  103. vec2 offset = v_tileCoord;
  104. vec2 pixoffset = (1.0 - offset * 2.0) / (TILE_SIZE * 16.0);
  105. vec2 atlasPos = vec2(
  106. pixoffset.x + tileID + offset.x,
  107. pixoffset.y + floor(tileID / tileAtlasSize.x) + offset.y);
  108. gl_FragColor = texture2D(tileAtlas, atlasPos / tileAtlasSize);
  109. }
  110. )glsl";
  111. const char *spriteVx = R"glsl(
  112. precision mediump float;
  113. #define TILE_SIZE 32.0
  114. uniform mat3 camera;
  115. uniform mat3 transform;
  116. uniform vec2 frameSize;
  117. uniform vec2 frameInfo; // frame count, frame index
  118. attribute vec2 vertex;
  119. varying vec2 v_texCoord;
  120. void main() {
  121. // Here, I'm basically treating 1/(TILE_SIZE*16) as half the size of a "pixel".
  122. // It's just an arbitrary small number, but it works as an offset to make sure
  123. // neighbouring parts of the atlas don't bleed into the frame we actually
  124. // want to draw due to (nearest neighbour) interpolation.
  125. float pixoffset = (1.0 - vertex.y * 2.0) / (frameSize.y * TILE_SIZE * 16.0);
  126. v_texCoord = vec2(
  127. vertex.x,
  128. (frameSize.y * frameInfo.y + (frameSize.y * vertex.y)) /
  129. (frameSize.y * frameInfo.x) + pixoffset);
  130. vec3 pos = camera * transform * vec3(vertex * frameSize, 1);
  131. gl_Position = vec4(pos.xy, 0, 1);
  132. }
  133. )glsl";
  134. const char *spriteFr = R"glsl(
  135. precision mediump float;
  136. varying vec2 v_texCoord;
  137. uniform sampler2D tex;
  138. void main() {
  139. gl_FragColor = texture2D(tex, v_texCoord);
  140. }
  141. )glsl";
  142. const char *rectVx = R"glsl(
  143. precision mediump float;
  144. uniform mat3 camera;
  145. uniform vec2 pos;
  146. uniform vec2 size;
  147. attribute vec2 vertex;
  148. varying vec2 v_coord;
  149. void main() {
  150. vec3 pos = camera * vec3(pos + vertex * size, 1);
  151. gl_Position = vec4(pos.xy, 0, 1);
  152. v_coord = vertex * size;
  153. }
  154. )glsl";
  155. const char *rectFr = R"glsl(
  156. precision mediump float;
  157. #define THICKNESS 0.02
  158. varying vec2 v_coord;
  159. uniform vec2 size;
  160. void main() {
  161. vec2 invCoord = size - v_coord;
  162. float minDist = min(v_coord.x, min(v_coord.y, min(invCoord.x, invCoord.y)));
  163. gl_FragColor = vec4(0.6, 0.6, 0.6, 0.8) * float(minDist < THICKNESS);
  164. }
  165. )glsl";
  166. }