| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- // Feather disable all
- function __BulbRendererDefineLight()
- {
- //Screen-space surface for final accumulation of lights
- //In HDR mode, this is a per-channel 64-bit RGBA surface
- __lightSurface = undefined;
-
- __lightsArray = [];
- __sunlightArray = [];
-
- GetLightSurface = function()
- {
- if ((__surfaceWidth <= 0) || (__surfaceHeight <= 0)) return undefined;
-
- var _surfaceWidth = floor(__surfaceWidth);
- var _surfaceHeight = floor(__surfaceHeight);
-
- if ((__lightSurface != undefined) && ((surface_get_width(__lightSurface) != _surfaceWidth) || (surface_get_height(__lightSurface) != _surfaceHeight)))
- {
- surface_free(__lightSurface);
- __lightSurface = undefined;
- }
-
- if ((__lightSurface == undefined) || !surface_exists(__lightSurface))
- {
- //Only try to create an HDR surface if floating point surfaces are available
- if (_system.__hdrAvailable)
- {
- //Work around compile error in LTS
- var _surface_create = surface_create;
- __lightSurface = _surface_create(_surfaceWidth, _surfaceHeight, hdr? surface_rgba16float : surface_rgba8unorm);
- }
- else
- {
- __lightSurface = surface_create(_surfaceWidth, _surfaceHeight);
- }
-
- surface_set_target(__lightSurface);
- draw_clear_alpha(c_black, 1.0);
- surface_reset_target();
- }
-
- return __lightSurface;
- }
-
- __FreeLightSurface = function()
- {
- if ((__lightSurface != undefined) && surface_exists(__lightSurface))
- {
- surface_free(__lightSurface);
- __lightSurface = undefined;
- }
- }
-
- GetLightValue = function(_worldX, _worldY)
- {
- var _surface = GetLightSurface();
-
- //Deploy PROPER MATHS in case the dev is using matrices
- var _viewMatrix = camera_get_view_mat(__camera);
- var _projMatrix = camera_get_proj_mat(__camera);
- var _cameraW = round(abs(2/_projMatrix[0]));
- var _cameraH = round(abs(2/_projMatrix[5]));
-
- var _vector = matrix_transform_vertex(matrix_multiply(_viewMatrix, _projMatrix), _worldX, _worldY, 0);
- var _x = _cameraW * (0.5 + 0.5*_vector[0]);
- var _y = _cameraH * (0.5 - 0.5*_vector[1]); //Silly GM matrix quirk
-
- var _result = surface_getpixel_ext(_surface, _x, _y);
- if (not is_array(_result))
- {
- //Unpack 32-bit colour
- var _resultR = ( _result & 0xFF) / 255;
- var _resultG = ((_result >> 8) & 0xFF) / 255;
- var _resultB = ((_result >> 16) & 0xFF) / 255;
- var _resultA = ((_result >> 24) & 0xFF) / 255;
- }
- else
- {
- //Unpack array of floating point values
- var _resultR = _result[0];
- var _resultG = _result[1];
- var _resultB = _result[2];
- var _resultA = _result[3];
- }
-
- _resultR *= exposure;
- _resultG *= exposure;
- _resultB *= exposure;
- _resultA = 255*clamp(_resultA, 0, 1); //Clamp the alpha channel
-
- static _funcLuminance = function(_red, _green, _blue)
- {
- return 0.2126*_red + 0.7152*_green + 0.0722*_blue;
- }
-
- var _tonemap = GetTonemap();
-
- if (_tonemap == BULB_TONEMAP_BAD_GAMMA)
- {
- _resultR = 255*clamp(_resultR, 0, 1);
- _resultG = 255*clamp(_resultG, 0, 1);
- _resultB = 255*clamp(_resultB, 0, 1);
- }
- else if (_tonemap == BULB_TONEMAP_HBD)
- {
- _resultR = max(0, _resultR - 0.004);
- _resultG = max(0, _resultG - 0.004);
- _resultB = max(0, _resultB - 0.004);
-
- _resultR = (_resultR * (6.2*_resultR + 0.5)) / (_resultR * (6.2*_resultR + 1.7) + 0.06);
- _resultG = (_resultG * (6.2*_resultG + 0.5)) / (_resultG * (6.2*_resultG + 1.7) + 0.06);
- _resultB = (_resultB * (6.2*_resultB + 0.5)) / (_resultB * (6.2*_resultB + 1.7) + 0.06);
-
- //Already includes gamma correction in calculation, no power() call needed
- _resultR = 255*clamp(_resultR, 0, 1);
- _resultG = 255*clamp(_resultG, 0, 1);
- _resultB = 255*clamp(_resultB, 0, 1);
- }
- else if (_tonemap == BULB_TONEMAP_UNREAL3)
- {
- _resultR = _resultR / (_resultR + 0.155) * 1.019;
- _resultG = _resultG / (_resultG + 0.155) * 1.019;
- _resultB = _resultB / (_resultB + 0.155) * 1.019;
-
- //Already includes gamma correction in calculation, no power() call needed
- _resultR = 255*clamp(_resultR, 0, 1);
- _resultG = 255*clamp(_resultG, 0, 1);
- _resultB = 255*clamp(_resultB, 0, 1);
- }
- else
- {
- if ((_tonemap == BULB_TONEMAP_NONE) || (_tonemap == BULB_TONEMAP_CLAMP))
- {
- //Nothing else needed
- }
- else if (_tonemap == BULB_TONEMAP_REINHARD)
- {
- var _luminance = _funcLuminance(_resultR, _resultG, _resultB);
- var _luminanceNew = _luminance / (1 + _luminance);
-
- _resultR *= _luminanceNew / _luminance;
- _resultG *= _luminanceNew / _luminance;
- _resultB *= _luminanceNew / _luminance;
- }
- else if (_tonemap == BULB_TONEMAP_REINHARD_EXTENDED)
- {
- var _luminance = _funcLuminance(_resultR, _resultG, _resultB);
- var _luminanceNew = _luminance * (1.0 + (_luminance / (4*4))) / (1 + _luminance);
-
- _resultR *= _luminanceNew / _luminance;
- _resultG *= _luminanceNew / _luminance;
- _resultB *= _luminanceNew / _luminance;
- }
- else if (_tonemap == BULB_TONEMAP_UNCHARTED2)
- {
- _resultR *= 4;
- _resultG *= 4;
- _resultB *= 4;
-
- static _uc2_A = 0.15;
- static _uc2_B = 0.50;
- static _uc2_C = 0.10;
- static _uc2_D = 0.20;
- static _uc2_E = 0.02;
- static _uc2_F = 0.30;
-
- _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;
- _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;
- _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;
- }
- else if (_tonemap == BULB_TONEMAP_UNREAL3)
- {
- _resultR = max(0, _resultR - 0.004);
- _resultG = max(0, _resultG - 0.004);
- _resultB = max(0, _resultB - 0.004);
-
- _resultR = (_resultR * (6.2*_resultR + 0.5)) / (_resultR * (6.2*_resultR + 1.7) + 0.06);
- _resultG = (_resultG * (6.2*_resultG + 0.5)) / (_resultG * (6.2*_resultG + 1.7) + 0.06);
- _resultB = (_resultB * (6.2*_resultB + 0.5)) / (_resultB * (6.2*_resultB + 1.7) + 0.06);
- }
- else if (_tonemap == BULB_TONEMAP_ACES)
- {
- _resultR = (_resultR*(2.51*_resultR + 0.03)) / (_resultR*(2.43*_resultR + 0.59) + 0.14);
- _resultG = (_resultG*(2.51*_resultG + 0.03)) / (_resultG*(2.43*_resultG + 0.59) + 0.14);
- _resultB = (_resultB*(2.51*_resultB + 0.03)) / (_resultB*(2.43*_resultB + 0.59) + 0.14);
- }
-
- //Final gamma correction stage
- _resultR = 255*clamp(power(_resultR, 1/BULB_GAMMA), 0, 1);
- _resultG = 255*clamp(power(_resultG, 1/BULB_GAMMA), 0, 1);
- _resultB = 255*clamp(power(_resultB, 1/BULB_GAMMA), 0, 1);
- }
-
- return ((_resultA << 24) | (_resultB << 16) | (_resultG << 8) | _resultR);
- }
- }
|