__BulbRendererDefineLight.gml 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // Feather disable all
  2. function __BulbRendererDefineLight()
  3. {
  4. //Screen-space surface for final accumulation of lights
  5. //In HDR mode, this is a per-channel 64-bit RGBA surface
  6. __lightSurface = undefined;
  7. __lightsArray = [];
  8. __sunlightArray = [];
  9. GetLightSurface = function()
  10. {
  11. if ((__surfaceWidth <= 0) || (__surfaceHeight <= 0)) return undefined;
  12. var _surfaceWidth = floor(__surfaceWidth);
  13. var _surfaceHeight = floor(__surfaceHeight);
  14. if ((__lightSurface != undefined) && ((surface_get_width(__lightSurface) != _surfaceWidth) || (surface_get_height(__lightSurface) != _surfaceHeight)))
  15. {
  16. surface_free(__lightSurface);
  17. __lightSurface = undefined;
  18. }
  19. if ((__lightSurface == undefined) || !surface_exists(__lightSurface))
  20. {
  21. //Only try to create an HDR surface if floating point surfaces are available
  22. if (_system.__hdrAvailable)
  23. {
  24. //Work around compile error in LTS
  25. var _surface_create = surface_create;
  26. __lightSurface = _surface_create(_surfaceWidth, _surfaceHeight, hdr? surface_rgba16float : surface_rgba8unorm);
  27. }
  28. else
  29. {
  30. __lightSurface = surface_create(_surfaceWidth, _surfaceHeight);
  31. }
  32. surface_set_target(__lightSurface);
  33. draw_clear_alpha(c_black, 1.0);
  34. surface_reset_target();
  35. }
  36. return __lightSurface;
  37. }
  38. __FreeLightSurface = function()
  39. {
  40. if ((__lightSurface != undefined) && surface_exists(__lightSurface))
  41. {
  42. surface_free(__lightSurface);
  43. __lightSurface = undefined;
  44. }
  45. }
  46. GetLightValue = function(_worldX, _worldY)
  47. {
  48. var _surface = GetLightSurface();
  49. //Deploy PROPER MATHS in case the dev is using matrices
  50. var _viewMatrix = camera_get_view_mat(__camera);
  51. var _projMatrix = camera_get_proj_mat(__camera);
  52. var _cameraW = round(abs(2/_projMatrix[0]));
  53. var _cameraH = round(abs(2/_projMatrix[5]));
  54. var _vector = matrix_transform_vertex(matrix_multiply(_viewMatrix, _projMatrix), _worldX, _worldY, 0);
  55. var _x = _cameraW * (0.5 + 0.5*_vector[0]);
  56. var _y = _cameraH * (0.5 - 0.5*_vector[1]); //Silly GM matrix quirk
  57. var _result = surface_getpixel_ext(_surface, _x, _y);
  58. if (not is_array(_result))
  59. {
  60. //Unpack 32-bit colour
  61. var _resultR = ( _result & 0xFF) / 255;
  62. var _resultG = ((_result >> 8) & 0xFF) / 255;
  63. var _resultB = ((_result >> 16) & 0xFF) / 255;
  64. var _resultA = ((_result >> 24) & 0xFF) / 255;
  65. }
  66. else
  67. {
  68. //Unpack array of floating point values
  69. var _resultR = _result[0];
  70. var _resultG = _result[1];
  71. var _resultB = _result[2];
  72. var _resultA = _result[3];
  73. }
  74. _resultR *= exposure;
  75. _resultG *= exposure;
  76. _resultB *= exposure;
  77. _resultA = 255*clamp(_resultA, 0, 1); //Clamp the alpha channel
  78. static _funcLuminance = function(_red, _green, _blue)
  79. {
  80. return 0.2126*_red + 0.7152*_green + 0.0722*_blue;
  81. }
  82. var _tonemap = GetTonemap();
  83. if (_tonemap == BULB_TONEMAP_BAD_GAMMA)
  84. {
  85. _resultR = 255*clamp(_resultR, 0, 1);
  86. _resultG = 255*clamp(_resultG, 0, 1);
  87. _resultB = 255*clamp(_resultB, 0, 1);
  88. }
  89. else if (_tonemap == BULB_TONEMAP_HBD)
  90. {
  91. _resultR = max(0, _resultR - 0.004);
  92. _resultG = max(0, _resultG - 0.004);
  93. _resultB = max(0, _resultB - 0.004);
  94. _resultR = (_resultR * (6.2*_resultR + 0.5)) / (_resultR * (6.2*_resultR + 1.7) + 0.06);
  95. _resultG = (_resultG * (6.2*_resultG + 0.5)) / (_resultG * (6.2*_resultG + 1.7) + 0.06);
  96. _resultB = (_resultB * (6.2*_resultB + 0.5)) / (_resultB * (6.2*_resultB + 1.7) + 0.06);
  97. //Already includes gamma correction in calculation, no power() call needed
  98. _resultR = 255*clamp(_resultR, 0, 1);
  99. _resultG = 255*clamp(_resultG, 0, 1);
  100. _resultB = 255*clamp(_resultB, 0, 1);
  101. }
  102. else if (_tonemap == BULB_TONEMAP_UNREAL3)
  103. {
  104. _resultR = _resultR / (_resultR + 0.155) * 1.019;
  105. _resultG = _resultG / (_resultG + 0.155) * 1.019;
  106. _resultB = _resultB / (_resultB + 0.155) * 1.019;
  107. //Already includes gamma correction in calculation, no power() call needed
  108. _resultR = 255*clamp(_resultR, 0, 1);
  109. _resultG = 255*clamp(_resultG, 0, 1);
  110. _resultB = 255*clamp(_resultB, 0, 1);
  111. }
  112. else
  113. {
  114. if ((_tonemap == BULB_TONEMAP_NONE) || (_tonemap == BULB_TONEMAP_CLAMP))
  115. {
  116. //Nothing else needed
  117. }
  118. else if (_tonemap == BULB_TONEMAP_REINHARD)
  119. {
  120. var _luminance = _funcLuminance(_resultR, _resultG, _resultB);
  121. var _luminanceNew = _luminance / (1 + _luminance);
  122. _resultR *= _luminanceNew / _luminance;
  123. _resultG *= _luminanceNew / _luminance;
  124. _resultB *= _luminanceNew / _luminance;
  125. }
  126. else if (_tonemap == BULB_TONEMAP_REINHARD_EXTENDED)
  127. {
  128. var _luminance = _funcLuminance(_resultR, _resultG, _resultB);
  129. var _luminanceNew = _luminance * (1.0 + (_luminance / (4*4))) / (1 + _luminance);
  130. _resultR *= _luminanceNew / _luminance;
  131. _resultG *= _luminanceNew / _luminance;
  132. _resultB *= _luminanceNew / _luminance;
  133. }
  134. else if (_tonemap == BULB_TONEMAP_UNCHARTED2)
  135. {
  136. _resultR *= 4;
  137. _resultG *= 4;
  138. _resultB *= 4;
  139. static _uc2_A = 0.15;
  140. static _uc2_B = 0.50;
  141. static _uc2_C = 0.10;
  142. static _uc2_D = 0.20;
  143. static _uc2_E = 0.02;
  144. static _uc2_F = 0.30;
  145. _resultR = ((_resultR*(_uc2_A*_resultR + _uc2_C*_uc2_B) + _uc2_D*_uc2_E) / (_resultR*(_uc2_A*_resultR + _uc2_B) + _uc2_D*_uc2_F)) - _uc2_E/_uc2_F;
  146. _resultG = ((_resultG*(_uc2_A*_resultG + _uc2_C*_uc2_B) + _uc2_D*_uc2_E) / (_resultG*(_uc2_A*_resultG + _uc2_B) + _uc2_D*_uc2_F)) - _uc2_E/_uc2_F;
  147. _resultB = ((_resultB*(_uc2_A*_resultB + _uc2_C*_uc2_B) + _uc2_D*_uc2_E) / (_resultB*(_uc2_A*_resultB + _uc2_B) + _uc2_D*_uc2_F)) - _uc2_E/_uc2_F;
  148. }
  149. else if (_tonemap == BULB_TONEMAP_UNREAL3)
  150. {
  151. _resultR = max(0, _resultR - 0.004);
  152. _resultG = max(0, _resultG - 0.004);
  153. _resultB = max(0, _resultB - 0.004);
  154. _resultR = (_resultR * (6.2*_resultR + 0.5)) / (_resultR * (6.2*_resultR + 1.7) + 0.06);
  155. _resultG = (_resultG * (6.2*_resultG + 0.5)) / (_resultG * (6.2*_resultG + 1.7) + 0.06);
  156. _resultB = (_resultB * (6.2*_resultB + 0.5)) / (_resultB * (6.2*_resultB + 1.7) + 0.06);
  157. }
  158. else if (_tonemap == BULB_TONEMAP_ACES)
  159. {
  160. _resultR = (_resultR*(2.51*_resultR + 0.03)) / (_resultR*(2.43*_resultR + 0.59) + 0.14);
  161. _resultG = (_resultG*(2.51*_resultG + 0.03)) / (_resultG*(2.43*_resultG + 0.59) + 0.14);
  162. _resultB = (_resultB*(2.51*_resultB + 0.03)) / (_resultB*(2.43*_resultB + 0.59) + 0.14);
  163. }
  164. //Final gamma correction stage
  165. _resultR = 255*clamp(power(_resultR, 1/BULB_GAMMA), 0, 1);
  166. _resultG = 255*clamp(power(_resultG, 1/BULB_GAMMA), 0, 1);
  167. _resultB = 255*clamp(power(_resultB, 1/BULB_GAMMA), 0, 1);
  168. }
  169. return ((_resultA << 24) | (_resultB << 16) | (_resultG << 8) | _resultR);
  170. }
  171. }