|  | @@ -0,0 +1,537 @@
 | 
	
		
			
				|  |  | +#include "la_5.h"
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const int TRANSMITTANCE_TEXTURE_WIDTH = 256;
 | 
	
		
			
				|  |  | +const int TRANSMITTANCE_TEXTURE_HEIGHT = 64;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const int SCATTERING_TEXTURE_R_SIZE = 32;
 | 
	
		
			
				|  |  | +const int SCATTERING_TEXTURE_MU_SIZE = 128;
 | 
	
		
			
				|  |  | +const int SCATTERING_TEXTURE_MU_S_SIZE = 32;
 | 
	
		
			
				|  |  | +const int SCATTERING_TEXTURE_NU_SIZE = 8;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const int SCATTERING_TEXTURE_WIDTH =
 | 
	
		
			
				|  |  | +    SCATTERING_TEXTURE_NU_SIZE * SCATTERING_TEXTURE_MU_S_SIZE;
 | 
	
		
			
				|  |  | +const int SCATTERING_TEXTURE_HEIGHT = SCATTERING_TEXTURE_MU_SIZE;
 | 
	
		
			
				|  |  | +const int SCATTERING_TEXTURE_DEPTH = SCATTERING_TEXTURE_R_SIZE;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const int IRRADIANCE_TEXTURE_WIDTH = 64;
 | 
	
		
			
				|  |  | +const int IRRADIANCE_TEXTURE_HEIGHT = 16;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// The conversion factor between watts and lumens.
 | 
	
		
			
				|  |  | +const double MAX_LUMINOUS_EFFICACY = 683.0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// Values from "CIE (1931) 2-deg color matching functions", see
 | 
	
		
			
				|  |  | +// "http://web.archive.org/web/20081228084047/
 | 
	
		
			
				|  |  | +//    http://www.cvrl.org/database/data/cmfs/ciexyz31.txt".
 | 
	
		
			
				|  |  | +const double CIE_2_DEG_COLOR_MATCHING_FUNCTIONS[380] = {
 | 
	
		
			
				|  |  | +  360, 0.000129900000, 0.000003917000, 0.000606100000,
 | 
	
		
			
				|  |  | +  365, 0.000232100000, 0.000006965000, 0.001086000000,
 | 
	
		
			
				|  |  | +  370, 0.000414900000, 0.000012390000, 0.001946000000,
 | 
	
		
			
				|  |  | +  375, 0.000741600000, 0.000022020000, 0.003486000000,
 | 
	
		
			
				|  |  | +  380, 0.001368000000, 0.000039000000, 0.006450001000,
 | 
	
		
			
				|  |  | +  385, 0.002236000000, 0.000064000000, 0.010549990000,
 | 
	
		
			
				|  |  | +  390, 0.004243000000, 0.000120000000, 0.020050010000,
 | 
	
		
			
				|  |  | +  395, 0.007650000000, 0.000217000000, 0.036210000000,
 | 
	
		
			
				|  |  | +  400, 0.014310000000, 0.000396000000, 0.067850010000,
 | 
	
		
			
				|  |  | +  405, 0.023190000000, 0.000640000000, 0.110200000000,
 | 
	
		
			
				|  |  | +  410, 0.043510000000, 0.001210000000, 0.207400000000,
 | 
	
		
			
				|  |  | +  415, 0.077630000000, 0.002180000000, 0.371300000000,
 | 
	
		
			
				|  |  | +  420, 0.134380000000, 0.004000000000, 0.645600000000,
 | 
	
		
			
				|  |  | +  425, 0.214770000000, 0.007300000000, 1.039050100000,
 | 
	
		
			
				|  |  | +  430, 0.283900000000, 0.011600000000, 1.385600000000,
 | 
	
		
			
				|  |  | +  435, 0.328500000000, 0.016840000000, 1.622960000000,
 | 
	
		
			
				|  |  | +  440, 0.348280000000, 0.023000000000, 1.747060000000,
 | 
	
		
			
				|  |  | +  445, 0.348060000000, 0.029800000000, 1.782600000000,
 | 
	
		
			
				|  |  | +  450, 0.336200000000, 0.038000000000, 1.772110000000,
 | 
	
		
			
				|  |  | +  455, 0.318700000000, 0.048000000000, 1.744100000000,
 | 
	
		
			
				|  |  | +  460, 0.290800000000, 0.060000000000, 1.669200000000,
 | 
	
		
			
				|  |  | +  465, 0.251100000000, 0.073900000000, 1.528100000000,
 | 
	
		
			
				|  |  | +  470, 0.195360000000, 0.090980000000, 1.287640000000,
 | 
	
		
			
				|  |  | +  475, 0.142100000000, 0.112600000000, 1.041900000000,
 | 
	
		
			
				|  |  | +  480, 0.095640000000, 0.139020000000, 0.812950100000,
 | 
	
		
			
				|  |  | +  485, 0.057950010000, 0.169300000000, 0.616200000000,
 | 
	
		
			
				|  |  | +  490, 0.032010000000, 0.208020000000, 0.465180000000,
 | 
	
		
			
				|  |  | +  495, 0.014700000000, 0.258600000000, 0.353300000000,
 | 
	
		
			
				|  |  | +  500, 0.004900000000, 0.323000000000, 0.272000000000,
 | 
	
		
			
				|  |  | +  505, 0.002400000000, 0.407300000000, 0.212300000000,
 | 
	
		
			
				|  |  | +  510, 0.009300000000, 0.503000000000, 0.158200000000,
 | 
	
		
			
				|  |  | +  515, 0.029100000000, 0.608200000000, 0.111700000000,
 | 
	
		
			
				|  |  | +  520, 0.063270000000, 0.710000000000, 0.078249990000,
 | 
	
		
			
				|  |  | +  525, 0.109600000000, 0.793200000000, 0.057250010000,
 | 
	
		
			
				|  |  | +  530, 0.165500000000, 0.862000000000, 0.042160000000,
 | 
	
		
			
				|  |  | +  535, 0.225749900000, 0.914850100000, 0.029840000000,
 | 
	
		
			
				|  |  | +  540, 0.290400000000, 0.954000000000, 0.020300000000,
 | 
	
		
			
				|  |  | +  545, 0.359700000000, 0.980300000000, 0.013400000000,
 | 
	
		
			
				|  |  | +  550, 0.433449900000, 0.994950100000, 0.008749999000,
 | 
	
		
			
				|  |  | +  555, 0.512050100000, 1.000000000000, 0.005749999000,
 | 
	
		
			
				|  |  | +  560, 0.594500000000, 0.995000000000, 0.003900000000,
 | 
	
		
			
				|  |  | +  565, 0.678400000000, 0.978600000000, 0.002749999000,
 | 
	
		
			
				|  |  | +  570, 0.762100000000, 0.952000000000, 0.002100000000,
 | 
	
		
			
				|  |  | +  575, 0.842500000000, 0.915400000000, 0.001800000000,
 | 
	
		
			
				|  |  | +  580, 0.916300000000, 0.870000000000, 0.001650001000,
 | 
	
		
			
				|  |  | +  585, 0.978600000000, 0.816300000000, 0.001400000000,
 | 
	
		
			
				|  |  | +  590, 1.026300000000, 0.757000000000, 0.001100000000,
 | 
	
		
			
				|  |  | +  595, 1.056700000000, 0.694900000000, 0.001000000000,
 | 
	
		
			
				|  |  | +  600, 1.062200000000, 0.631000000000, 0.000800000000,
 | 
	
		
			
				|  |  | +  605, 1.045600000000, 0.566800000000, 0.000600000000,
 | 
	
		
			
				|  |  | +  610, 1.002600000000, 0.503000000000, 0.000340000000,
 | 
	
		
			
				|  |  | +  615, 0.938400000000, 0.441200000000, 0.000240000000,
 | 
	
		
			
				|  |  | +  620, 0.854449900000, 0.381000000000, 0.000190000000,
 | 
	
		
			
				|  |  | +  625, 0.751400000000, 0.321000000000, 0.000100000000,
 | 
	
		
			
				|  |  | +  630, 0.642400000000, 0.265000000000, 0.000049999990,
 | 
	
		
			
				|  |  | +  635, 0.541900000000, 0.217000000000, 0.000030000000,
 | 
	
		
			
				|  |  | +  640, 0.447900000000, 0.175000000000, 0.000020000000,
 | 
	
		
			
				|  |  | +  645, 0.360800000000, 0.138200000000, 0.000010000000,
 | 
	
		
			
				|  |  | +  650, 0.283500000000, 0.107000000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  655, 0.218700000000, 0.081600000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  660, 0.164900000000, 0.061000000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  665, 0.121200000000, 0.044580000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  670, 0.087400000000, 0.032000000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  675, 0.063600000000, 0.023200000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  680, 0.046770000000, 0.017000000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  685, 0.032900000000, 0.011920000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  690, 0.022700000000, 0.008210000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  695, 0.015840000000, 0.005723000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  700, 0.011359160000, 0.004102000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  705, 0.008110916000, 0.002929000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  710, 0.005790346000, 0.002091000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  715, 0.004109457000, 0.001484000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  720, 0.002899327000, 0.001047000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  725, 0.002049190000, 0.000740000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  730, 0.001439971000, 0.000520000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  735, 0.000999949300, 0.000361100000, 0.000000000000,
 | 
	
		
			
				|  |  | +  740, 0.000690078600, 0.000249200000, 0.000000000000,
 | 
	
		
			
				|  |  | +  745, 0.000476021300, 0.000171900000, 0.000000000000,
 | 
	
		
			
				|  |  | +  750, 0.000332301100, 0.000120000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  755, 0.000234826100, 0.000084800000, 0.000000000000,
 | 
	
		
			
				|  |  | +  760, 0.000166150500, 0.000060000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  765, 0.000117413000, 0.000042400000, 0.000000000000,
 | 
	
		
			
				|  |  | +  770, 0.000083075270, 0.000030000000, 0.000000000000,
 | 
	
		
			
				|  |  | +  775, 0.000058706520, 0.000021200000, 0.000000000000,
 | 
	
		
			
				|  |  | +  780, 0.000041509940, 0.000014990000, 0.000000000000,
 | 
	
		
			
				|  |  | +  785, 0.000029353260, 0.000010600000, 0.000000000000,
 | 
	
		
			
				|  |  | +  790, 0.000020673830, 0.000007465700, 0.000000000000,
 | 
	
		
			
				|  |  | +  795, 0.000014559770, 0.000005257800, 0.000000000000,
 | 
	
		
			
				|  |  | +  800, 0.000010253980, 0.000003702900, 0.000000000000,
 | 
	
		
			
				|  |  | +  805, 0.000007221456, 0.000002607800, 0.000000000000,
 | 
	
		
			
				|  |  | +  810, 0.000005085868, 0.000001836600, 0.000000000000,
 | 
	
		
			
				|  |  | +  815, 0.000003581652, 0.000001293400, 0.000000000000,
 | 
	
		
			
				|  |  | +  820, 0.000002522525, 0.000000910930, 0.000000000000,
 | 
	
		
			
				|  |  | +  825, 0.000001776509, 0.000000641530, 0.000000000000,
 | 
	
		
			
				|  |  | +  830, 0.000001251141, 0.000000451810, 0.000000000000,
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// The conversion matrix from XYZ to linear sRGB color spaces.
 | 
	
		
			
				|  |  | +// Values from https://en.wikipedia.org/wiki/SRGB.
 | 
	
		
			
				|  |  | +const double XYZ_TO_SRGB[9] = {
 | 
	
		
			
				|  |  | +  +3.2406, -1.5372, -0.4986,
 | 
	
		
			
				|  |  | +  -0.9689, +1.8758, +0.0415,
 | 
	
		
			
				|  |  | +  +0.0557, -0.2040, +1.0570
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const char kVertexShader[] = "\n\
 | 
	
		
			
				|  |  | +#version 330\n\
 | 
	
		
			
				|  |  | +layout(location = 0) in vec2 vertex;\n\
 | 
	
		
			
				|  |  | +void main() {\n\
 | 
	
		
			
				|  |  | +    gl_Position = vec4(vertex, 0.0, 1.0);\n\
 | 
	
		
			
				|  |  | +}";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const char kGeometryShader[] = "\n\
 | 
	
		
			
				|  |  | +#version 330\n\
 | 
	
		
			
				|  |  | +layout(triangles) in;\n\
 | 
	
		
			
				|  |  | +layout(triangle_strip, max_vertices = 3) out;\n\
 | 
	
		
			
				|  |  | +uniform int layer;\n\
 | 
	
		
			
				|  |  | +void main() {\n\
 | 
	
		
			
				|  |  | +    gl_Position = gl_in[0].gl_Position;\n\
 | 
	
		
			
				|  |  | +    gl_Layer = layer;\n\
 | 
	
		
			
				|  |  | +    EmitVertex();\n\
 | 
	
		
			
				|  |  | +    gl_Position = gl_in[1].gl_Position;\n\
 | 
	
		
			
				|  |  | +    gl_Layer = layer;\n\
 | 
	
		
			
				|  |  | +    EmitVertex();\n\
 | 
	
		
			
				|  |  | +    gl_Position = gl_in[2].gl_Position;\n\
 | 
	
		
			
				|  |  | +    gl_Layer = layer;\n\
 | 
	
		
			
				|  |  | +    EmitVertex();\n\
 | 
	
		
			
				|  |  | +    EndPrimitive();\n\
 | 
	
		
			
				|  |  | +}";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const char kComputeTransmittanceShader[] = "\n\
 | 
	
		
			
				|  |  | +    layout(location = 0) out vec3 transmittance;\n\
 | 
	
		
			
				|  |  | +    void main() {\n\
 | 
	
		
			
				|  |  | +      transmittance = ComputeTransmittanceToTopAtmosphereBoundaryTexture(\n\
 | 
	
		
			
				|  |  | +          ATMOSPHERE, gl_FragCoord.xy);\n\
 | 
	
		
			
				|  |  | +    }";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const char kComputeDirectIrradianceShader[] = "\n\
 | 
	
		
			
				|  |  | +    layout(location = 0) out vec3 delta_irradiance;\n\
 | 
	
		
			
				|  |  | +    layout(location = 1) out vec3 irradiance;\n\
 | 
	
		
			
				|  |  | +    uniform sampler2D transmittance_texture;\n\
 | 
	
		
			
				|  |  | +    void main() {\n\
 | 
	
		
			
				|  |  | +      delta_irradiance = ComputeDirectIrradianceTexture(\n\
 | 
	
		
			
				|  |  | +          ATMOSPHERE, transmittance_texture, gl_FragCoord.xy);\n\
 | 
	
		
			
				|  |  | +      irradiance = vec3(0.0);\n\
 | 
	
		
			
				|  |  | +    }";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const char kComputeSingleScatteringShader[] = "\n\
 | 
	
		
			
				|  |  | +    layout(location = 0) out vec3 delta_rayleigh;\n\
 | 
	
		
			
				|  |  | +    layout(location = 1) out vec3 delta_mie;\n\
 | 
	
		
			
				|  |  | +    layout(location = 2) out vec4 scattering;\n\
 | 
	
		
			
				|  |  | +    layout(location = 3) out vec3 single_mie_scattering;\n\
 | 
	
		
			
				|  |  | +    uniform mat3 luminance_from_radiance;\n\
 | 
	
		
			
				|  |  | +    uniform sampler2D transmittance_texture;\n\
 | 
	
		
			
				|  |  | +    uniform int layer;\n\
 | 
	
		
			
				|  |  | +    void main() {\n\
 | 
	
		
			
				|  |  | +      ComputeSingleScatteringTexture(\n\
 | 
	
		
			
				|  |  | +          ATMOSPHERE, transmittance_texture, vec3(gl_FragCoord.xy, layer + 0.5),\n\
 | 
	
		
			
				|  |  | +          delta_rayleigh, delta_mie);\n\
 | 
	
		
			
				|  |  | +      scattering = vec4(luminance_from_radiance * delta_rayleigh.rgb,\n\
 | 
	
		
			
				|  |  | +          (luminance_from_radiance * delta_mie).r);\n\
 | 
	
		
			
				|  |  | +      single_mie_scattering = luminance_from_radiance * delta_mie;\n\
 | 
	
		
			
				|  |  | +    }";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const char kComputeScatteringDensityShader[] = "\n\
 | 
	
		
			
				|  |  | +    layout(location = 0) out vec3 scattering_density;\n\
 | 
	
		
			
				|  |  | +    uniform sampler2D transmittance_texture;\n\
 | 
	
		
			
				|  |  | +    uniform sampler3D single_rayleigh_scattering_texture;\n\
 | 
	
		
			
				|  |  | +    uniform sampler3D single_mie_scattering_texture;\n\
 | 
	
		
			
				|  |  | +    uniform sampler3D multiple_scattering_texture;\n\
 | 
	
		
			
				|  |  | +    uniform sampler2D irradiance_texture;\n\
 | 
	
		
			
				|  |  | +    uniform int scattering_order;\n\
 | 
	
		
			
				|  |  | +    uniform int layer;\n\
 | 
	
		
			
				|  |  | +    void main() {\n\
 | 
	
		
			
				|  |  | +      scattering_density = ComputeScatteringDensityTexture(\n\
 | 
	
		
			
				|  |  | +          ATMOSPHERE, transmittance_texture, single_rayleigh_scattering_texture,\n\
 | 
	
		
			
				|  |  | +          single_mie_scattering_texture, multiple_scattering_texture,\n\
 | 
	
		
			
				|  |  | +          irradiance_texture, vec3(gl_FragCoord.xy, layer + 0.5),\n\
 | 
	
		
			
				|  |  | +          scattering_order);\n\
 | 
	
		
			
				|  |  | +    }";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const char kComputeIndirectIrradianceShader[] = "\n\
 | 
	
		
			
				|  |  | +    layout(location = 0) out vec3 delta_irradiance;\n\
 | 
	
		
			
				|  |  | +    layout(location = 1) out vec3 irradiance;\n\
 | 
	
		
			
				|  |  | +    uniform mat3 luminance_from_radiance;\n\
 | 
	
		
			
				|  |  | +    uniform sampler3D single_rayleigh_scattering_texture;\n\
 | 
	
		
			
				|  |  | +    uniform sampler3D single_mie_scattering_texture;\n\
 | 
	
		
			
				|  |  | +    uniform sampler3D multiple_scattering_texture;\n\
 | 
	
		
			
				|  |  | +    uniform int scattering_order;\n\
 | 
	
		
			
				|  |  | +    void main() {\n\
 | 
	
		
			
				|  |  | +      delta_irradiance = ComputeIndirectIrradianceTexture(\n\
 | 
	
		
			
				|  |  | +          ATMOSPHERE, single_rayleigh_scattering_texture,\n\
 | 
	
		
			
				|  |  | +          single_mie_scattering_texture, multiple_scattering_texture,\n\
 | 
	
		
			
				|  |  | +          gl_FragCoord.xy, scattering_order);\n\
 | 
	
		
			
				|  |  | +      irradiance = luminance_from_radiance * delta_irradiance;\n\
 | 
	
		
			
				|  |  | +    }";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const char kComputeMultipleScatteringShader[] = "\n\
 | 
	
		
			
				|  |  | +    layout(location = 0) out vec3 delta_multiple_scattering;\n\
 | 
	
		
			
				|  |  | +    layout(location = 1) out vec4 scattering;\n\
 | 
	
		
			
				|  |  | +    uniform mat3 luminance_from_radiance;\n\
 | 
	
		
			
				|  |  | +    uniform sampler2D transmittance_texture;\n\
 | 
	
		
			
				|  |  | +    uniform sampler3D scattering_density_texture;\n\
 | 
	
		
			
				|  |  | +    uniform int layer;\n\
 | 
	
		
			
				|  |  | +    void main() {\n\
 | 
	
		
			
				|  |  | +      float nu;\n\
 | 
	
		
			
				|  |  | +      delta_multiple_scattering = ComputeMultipleScatteringTexture(\n\
 | 
	
		
			
				|  |  | +          ATMOSPHERE, transmittance_texture, scattering_density_texture,\n\
 | 
	
		
			
				|  |  | +          vec3(gl_FragCoord.xy, layer + 0.5), nu);\n\
 | 
	
		
			
				|  |  | +      scattering = vec4(\n\
 | 
	
		
			
				|  |  | +          luminance_from_radiance *\n\
 | 
	
		
			
				|  |  | +              delta_multiple_scattering.rgb / RayleighPhaseFunction(nu),\n\
 | 
	
		
			
				|  |  | +          0.0);\n\
 | 
	
		
			
				|  |  | +    }";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const char kAtmosphereShader[] = "\n\
 | 
	
		
			
				|  |  | +    uniform sampler2D transmittance_texture;\n\
 | 
	
		
			
				|  |  | +    uniform sampler3D scattering_texture;\n\
 | 
	
		
			
				|  |  | +    uniform sampler3D single_mie_scattering_texture;\n\
 | 
	
		
			
				|  |  | +    uniform sampler2D irradiance_texture;\n\
 | 
	
		
			
				|  |  | +    #ifdef RADIANCE_API_ENABLED\n\
 | 
	
		
			
				|  |  | +    RadianceSpectrum GetSolarRadiance() {\n\
 | 
	
		
			
				|  |  | +      return ATMOSPHERE.solar_irradiance /\n\
 | 
	
		
			
				|  |  | +          (PI * ATMOSPHERE.sun_angular_radius * ATMOSPHERE.sun_angular_radius);\n\
 | 
	
		
			
				|  |  | +    }\n\
 | 
	
		
			
				|  |  | +    RadianceSpectrum GetSkyRadiance(\n\
 | 
	
		
			
				|  |  | +        Position camera, Direction view_ray, Length shadow_length,\n\
 | 
	
		
			
				|  |  | +        Direction sun_direction, out DimensionlessSpectrum transmittance) {\n\
 | 
	
		
			
				|  |  | +      return GetSkyRadiance(ATMOSPHERE, transmittance_texture,\n\
 | 
	
		
			
				|  |  | +          scattering_texture, single_mie_scattering_texture,\n\
 | 
	
		
			
				|  |  | +          camera, view_ray, shadow_length, sun_direction, transmittance);\n\
 | 
	
		
			
				|  |  | +    }\n\
 | 
	
		
			
				|  |  | +    RadianceSpectrum GetSkyRadianceToPoint(\n\
 | 
	
		
			
				|  |  | +        Position camera, Position point, Length shadow_length,\n\
 | 
	
		
			
				|  |  | +        Direction sun_direction, out DimensionlessSpectrum transmittance) {\n\
 | 
	
		
			
				|  |  | +      return GetSkyRadianceToPoint(ATMOSPHERE, transmittance_texture,\n\
 | 
	
		
			
				|  |  | +          scattering_texture, single_mie_scattering_texture,\n\
 | 
	
		
			
				|  |  | +          camera, point, shadow_length, sun_direction, transmittance);\n\
 | 
	
		
			
				|  |  | +    }\n\
 | 
	
		
			
				|  |  | +    IrradianceSpectrum GetSunAndSkyIrradiance(\n\
 | 
	
		
			
				|  |  | +       Position p, Direction normal, Direction sun_direction,\n\
 | 
	
		
			
				|  |  | +       out IrradianceSpectrum sky_irradiance) {\n\
 | 
	
		
			
				|  |  | +      return GetSunAndSkyIrradiance(ATMOSPHERE, transmittance_texture,\n\
 | 
	
		
			
				|  |  | +          irradiance_texture, p, normal, sun_direction, sky_irradiance);\n\
 | 
	
		
			
				|  |  | +    }\n\
 | 
	
		
			
				|  |  | +    #endif\n\
 | 
	
		
			
				|  |  | +    Luminance3 GetSolarLuminance() {\n\
 | 
	
		
			
				|  |  | +      return ATMOSPHERE.solar_irradiance /\n\
 | 
	
		
			
				|  |  | +          (PI * ATMOSPHERE.sun_angular_radius * ATMOSPHERE.sun_angular_radius) *\n\
 | 
	
		
			
				|  |  | +          SUN_SPECTRAL_RADIANCE_TO_LUMINANCE;\n\
 | 
	
		
			
				|  |  | +    }\n\
 | 
	
		
			
				|  |  | +    Luminance3 GetSkyLuminance(\n\
 | 
	
		
			
				|  |  | +        Position camera, Direction view_ray, Length shadow_length,\n\
 | 
	
		
			
				|  |  | +        Direction sun_direction, out DimensionlessSpectrum transmittance) {\n\
 | 
	
		
			
				|  |  | +      return GetSkyRadiance(ATMOSPHERE, transmittance_texture,\n\
 | 
	
		
			
				|  |  | +          scattering_texture, single_mie_scattering_texture,\n\
 | 
	
		
			
				|  |  | +          camera, view_ray, shadow_length, sun_direction, transmittance) *\n\
 | 
	
		
			
				|  |  | +          SKY_SPECTRAL_RADIANCE_TO_LUMINANCE;\n\
 | 
	
		
			
				|  |  | +    }\n\
 | 
	
		
			
				|  |  | +    Luminance3 GetSkyLuminanceToPoint(\n\
 | 
	
		
			
				|  |  | +        Position camera, Position point, Length shadow_length,\n\
 | 
	
		
			
				|  |  | +        Direction sun_direction, out DimensionlessSpectrum transmittance) {\n\
 | 
	
		
			
				|  |  | +      return GetSkyRadianceToPoint(ATMOSPHERE, transmittance_texture,\n\
 | 
	
		
			
				|  |  | +          scattering_texture, single_mie_scattering_texture,\n\
 | 
	
		
			
				|  |  | +          camera, point, shadow_length, sun_direction, transmittance) *\n\
 | 
	
		
			
				|  |  | +          SKY_SPECTRAL_RADIANCE_TO_LUMINANCE;\n\
 | 
	
		
			
				|  |  | +    }\n\
 | 
	
		
			
				|  |  | +    Illuminance3 GetSunAndSkyIlluminance(\n\
 | 
	
		
			
				|  |  | +       Position p, Direction normal, Direction sun_direction,\n\
 | 
	
		
			
				|  |  | +       out IrradianceSpectrum sky_irradiance) {\n\
 | 
	
		
			
				|  |  | +      IrradianceSpectrum sun_irradiance = GetSunAndSkyIrradiance(\n\
 | 
	
		
			
				|  |  | +          ATMOSPHERE, transmittance_texture, irradiance_texture, p, normal,\n\
 | 
	
		
			
				|  |  | +          sun_direction, sky_irradiance);\n\
 | 
	
		
			
				|  |  | +      sky_irradiance *= SKY_SPECTRAL_RADIANCE_TO_LUMINANCE;\n\
 | 
	
		
			
				|  |  | +      return sun_irradiance * SUN_SPECTRAL_RADIANCE_TO_LUMINANCE;\n\
 | 
	
		
			
				|  |  | +    }";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const char header[]="#version 330\n\
 | 
	
		
			
				|  |  | +#define IN(x) const in x\n\
 | 
	
		
			
				|  |  | +#define OUT(x) out x\n\
 | 
	
		
			
				|  |  | +#define TEMPLATE(x)\n\
 | 
	
		
			
				|  |  | +#define TEMPLATE_ARGUMENT(x)\n\
 | 
	
		
			
				|  |  | +#define assert(x)\n\
 | 
	
		
			
				|  |  | +const int TRANSMITTANCE_TEXTURE_WIDTH = 256;\n\
 | 
	
		
			
				|  |  | +const int TRANSMITTANCE_TEXTURE_HEIGHT = 64;\n\
 | 
	
		
			
				|  |  | +const int SCATTERING_TEXTURE_R_SIZE = 32;\n\
 | 
	
		
			
				|  |  | +const int SCATTERING_TEXTURE_MU_SIZE = 128;\n\
 | 
	
		
			
				|  |  | +const int SCATTERING_TEXTURE_MU_S_SIZE = 32;\n\
 | 
	
		
			
				|  |  | +const int SCATTERING_TEXTURE_NU_SIZE = 8;\n\
 | 
	
		
			
				|  |  | +const int IRRADIANCE_TEXTURE_WIDTH = 64;\n\
 | 
	
		
			
				|  |  | +const int IRRADIANCE_TEXTURE_HEIGHT = 16;\n\
 | 
	
		
			
				|  |  | +#define COMBINED_SCATTERING_TEXTURES\n\
 | 
	
		
			
				|  |  | +\n\
 | 
	
		
			
				|  |  | +#define Length float\n\
 | 
	
		
			
				|  |  | +#define Wavelength float\n\
 | 
	
		
			
				|  |  | +#define Angle float\n\
 | 
	
		
			
				|  |  | +#define SolidAngle float\n\
 | 
	
		
			
				|  |  | +#define Power float\n\
 | 
	
		
			
				|  |  | +#define LuminousPower float\n\
 | 
	
		
			
				|  |  | +#define Number float\n\
 | 
	
		
			
				|  |  | +#define InverseLength float\n\
 | 
	
		
			
				|  |  | +#define Area float\n\
 | 
	
		
			
				|  |  | +#define Volume float\n\
 | 
	
		
			
				|  |  | +#define NumberDensity float\n\
 | 
	
		
			
				|  |  | +#define Irradiance float\n\
 | 
	
		
			
				|  |  | +#define Radiance float\n\
 | 
	
		
			
				|  |  | +#define SpectralPower float\n\
 | 
	
		
			
				|  |  | +#define SpectralIrradiance float\n\
 | 
	
		
			
				|  |  | +#define SpectralRadiance float\n\
 | 
	
		
			
				|  |  | +#define SpectralRadianceDensity float\n\
 | 
	
		
			
				|  |  | +#define ScatteringCoefficient float\n\
 | 
	
		
			
				|  |  | +#define InverseSolidAngle float\n\
 | 
	
		
			
				|  |  | +#define LuminousIntensity float\n\
 | 
	
		
			
				|  |  | +#define Luminance float\n\
 | 
	
		
			
				|  |  | +#define Illuminance float\n\
 | 
	
		
			
				|  |  | +#define AbstractSpectrum vec3\n\
 | 
	
		
			
				|  |  | +#define DimensionlessSpectrum vec3\n\
 | 
	
		
			
				|  |  | +#define PowerSpectrum vec3\n\
 | 
	
		
			
				|  |  | +#define IrradianceSpectrum vec3\n\
 | 
	
		
			
				|  |  | +#define RadianceSpectrum vec3\n\
 | 
	
		
			
				|  |  | +#define RadianceDensitySpectrum vec3\n\
 | 
	
		
			
				|  |  | +#define ScatteringSpectrum vec3\n\
 | 
	
		
			
				|  |  | +#define Position vec3\n\
 | 
	
		
			
				|  |  | +#define Direction vec3\n\
 | 
	
		
			
				|  |  | +#define Luminance3 vec3\n\
 | 
	
		
			
				|  |  | +#define Illuminance3 vec3\n\
 | 
	
		
			
				|  |  | +#define TransmittanceTexture sampler2D\n\
 | 
	
		
			
				|  |  | +#define AbstractScatteringTexture sampler3D\n\
 | 
	
		
			
				|  |  | +#define ReducedScatteringTexture sampler3D\n\
 | 
	
		
			
				|  |  | +#define ScatteringTexture sampler3D\n\
 | 
	
		
			
				|  |  | +#define ScatteringDensityTexture sampler3D\n\
 | 
	
		
			
				|  |  | +#define IrradianceTexture sampler2D\n\
 | 
	
		
			
				|  |  | +const Length m = 1.0;\n\
 | 
	
		
			
				|  |  | +const Wavelength nm = 1.0;\n\
 | 
	
		
			
				|  |  | +const Angle rad = 1.0;\n\
 | 
	
		
			
				|  |  | +const SolidAngle sr = 1.0;\n\
 | 
	
		
			
				|  |  | +const Power watt = 1.0;\n\
 | 
	
		
			
				|  |  | +const LuminousPower lm = 1.0;\n\
 | 
	
		
			
				|  |  | +const float PI = 3.14159265358979323846;\n\
 | 
	
		
			
				|  |  | +const Length km = 1000.0 * m;\n\
 | 
	
		
			
				|  |  | +const Area m2 = m * m;\n\
 | 
	
		
			
				|  |  | +const Volume m3 = m * m * m;\n\
 | 
	
		
			
				|  |  | +const Angle pi = PI * rad;\n\
 | 
	
		
			
				|  |  | +const Angle deg = pi / 180.0;\n\
 | 
	
		
			
				|  |  | +const Irradiance watt_per_square_meter = watt / m2;\n\
 | 
	
		
			
				|  |  | +const Radiance watt_per_square_meter_per_sr = watt / (m2 * sr);\n\
 | 
	
		
			
				|  |  | +const SpectralIrradiance watt_per_square_meter_per_nm = watt / (m2 * nm);\n\
 | 
	
		
			
				|  |  | +const SpectralRadiance watt_per_square_meter_per_sr_per_nm =\n\
 | 
	
		
			
				|  |  | +    watt / (m2 * sr * nm);\n\
 | 
	
		
			
				|  |  | +const SpectralRadianceDensity watt_per_cubic_meter_per_sr_per_nm =\n\
 | 
	
		
			
				|  |  | +    watt / (m3 * sr * nm);\n\
 | 
	
		
			
				|  |  | +const LuminousIntensity cd = lm / sr;\n\
 | 
	
		
			
				|  |  | +const LuminousIntensity kcd = 1000.0 * cd;\n\
 | 
	
		
			
				|  |  | +const Luminance cd_per_square_meter = cd / m2;\n\
 | 
	
		
			
				|  |  | +const Luminance kcd_per_square_meter = kcd / m2;\n\
 | 
	
		
			
				|  |  | +struct DensityProfileLayer {\n\
 | 
	
		
			
				|  |  | +  Length width;\n\
 | 
	
		
			
				|  |  | +  Number exp_term;\n\
 | 
	
		
			
				|  |  | +  InverseLength exp_scale;\n\
 | 
	
		
			
				|  |  | +  InverseLength linear_term;\n\
 | 
	
		
			
				|  |  | +  Number constant_term;\n\
 | 
	
		
			
				|  |  | +};\n\
 | 
	
		
			
				|  |  | +struct DensityProfile {\n\
 | 
	
		
			
				|  |  | +  DensityProfileLayer layers[2];\n\
 | 
	
		
			
				|  |  | +};\n\
 | 
	
		
			
				|  |  | +struct AtmosphereParameters {\n\
 | 
	
		
			
				|  |  | +  IrradianceSpectrum solar_irradiance;\n\
 | 
	
		
			
				|  |  | +  Angle sun_angular_radius;\n\
 | 
	
		
			
				|  |  | +  Length bottom_radius;\n\
 | 
	
		
			
				|  |  | +  Length top_radius;\n\
 | 
	
		
			
				|  |  | +  DensityProfile rayleigh_density;\n\
 | 
	
		
			
				|  |  | +  ScatteringSpectrum rayleigh_scattering;\n\
 | 
	
		
			
				|  |  | +  DensityProfile mie_density;\n\
 | 
	
		
			
				|  |  | +  ScatteringSpectrum mie_scattering;\n\
 | 
	
		
			
				|  |  | +  ScatteringSpectrum mie_extinction;\n\
 | 
	
		
			
				|  |  | +  Number mie_phase_function_g;\n\
 | 
	
		
			
				|  |  | +  DensityProfile absorption_density;\n\
 | 
	
		
			
				|  |  | +  ScatteringSpectrum absorption_extinction;\n\
 | 
	
		
			
				|  |  | +  DimensionlessSpectrum ground_albedo;\n\
 | 
	
		
			
				|  |  | +  Number mu_s_min;\n\
 | 
	
		
			
				|  |  | +};\n\
 | 
	
		
			
				|  |  | +const AtmosphereParameters ATMOSPHERE = AtmosphereParameters(\n\
 | 
	
		
			
				|  |  | +vec3(1.474000,1.850400,1.911980),\n\
 | 
	
		
			
				|  |  | +0.004675,\n\
 | 
	
		
			
				|  |  | +6360.000000,\n\
 | 
	
		
			
				|  |  | +6420.000000,\n\
 | 
	
		
			
				|  |  | +DensityProfile(DensityProfileLayer[2](DensityProfileLayer(0.000000,0.000000,0.000000,0.000000,0.000000),DensityProfileLayer(0.000000,1.000000,-0.125000,0.000000,0.000000))),\n\
 | 
	
		
			
				|  |  | +vec3(0.005802,0.013558,0.033100),\n\
 | 
	
		
			
				|  |  | +DensityProfile(DensityProfileLayer[2](DensityProfileLayer(0.000000,0.000000,0.000000,0.000000,0.000000),DensityProfileLayer(0.000000,1.000000,-0.833333,0.000000,0.000000))),\n\
 | 
	
		
			
				|  |  | +vec3(0.003996,0.003996,0.003996),\n\
 | 
	
		
			
				|  |  | +vec3(0.004440,0.004440,0.004440),\n\
 | 
	
		
			
				|  |  | +0.800000,\n\
 | 
	
		
			
				|  |  | +DensityProfile(DensityProfileLayer[2](DensityProfileLayer(25.000000,0.000000,0.000000,0.066667,-0.666667),DensityProfileLayer(0.000000,0.000000,0.000000,-0.066667,2.666667))),\n\
 | 
	
		
			
				|  |  | +vec3(0.000650,0.001881,0.000085),\n\
 | 
	
		
			
				|  |  | +vec3(0.100000,0.100000,0.100000),\n\
 | 
	
		
			
				|  |  | +-0.207912);\n\
 | 
	
		
			
				|  |  | +const vec3 SKY_SPECTRAL_RADIANCE_TO_LUMINANCE = vec3(683.000000,683.000000,683.000000);\n\
 | 
	
		
			
				|  |  | +const vec3 SUN_SPECTRAL_RADIANCE_TO_LUMINANCE = vec3(98242.786222,69954.398112,66475.012354);\n\
 | 
	
		
			
				|  |  | +";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void tns_InitAtmosphere(){
 | 
	
		
			
				|  |  | +    laSafeString* ss=0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    tnsTexture* transmittance_texture_ = tnsCreate2DTexture(GL_RGBA32F, TRANSMITTANCE_TEXTURE_WIDTH, TRANSMITTANCE_TEXTURE_HEIGHT, 0);
 | 
	
		
			
				|  |  | +    tnsTexture* scattering_texture_ = tnsCreate3DTexture(GL_RGBA16F, SCATTERING_TEXTURE_WIDTH, SCATTERING_TEXTURE_HEIGHT,SCATTERING_TEXTURE_DEPTH);
 | 
	
		
			
				|  |  | +    tnsTexture* irradiance_texture_ = tnsCreate2DTexture(GL_RGBA32F, IRRADIANCE_TEXTURE_WIDTH, IRRADIANCE_TEXTURE_HEIGHT, 0);
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    tnsTexture* delta_irradiance_texture = tnsCreate2DTexture(GL_RGBA32F, IRRADIANCE_TEXTURE_WIDTH, IRRADIANCE_TEXTURE_HEIGHT, 0);
 | 
	
		
			
				|  |  | +    tnsTexture* delta_rayleigh_scattering_texture = tnsCreate3DTexture(GL_RGBA16F, SCATTERING_TEXTURE_WIDTH, SCATTERING_TEXTURE_HEIGHT,SCATTERING_TEXTURE_DEPTH);
 | 
	
		
			
				|  |  | +    tnsTexture* delta_mie_scattering_texture = tnsCreate3DTexture(GL_RGBA16F, SCATTERING_TEXTURE_WIDTH, SCATTERING_TEXTURE_HEIGHT,SCATTERING_TEXTURE_DEPTH);
 | 
	
		
			
				|  |  | +    tnsTexture* delta_scattering_density_texture =tnsCreate3DTexture(GL_RGBA16F, SCATTERING_TEXTURE_WIDTH, SCATTERING_TEXTURE_HEIGHT,SCATTERING_TEXTURE_DEPTH);
 | 
	
		
			
				|  |  | +    tnsTexture* delta_multiple_scattering_texture = delta_rayleigh_scattering_texture;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    GLuint fbo;
 | 
	
		
			
				|  |  | +    glGenFramebuffers(1, &fbo);
 | 
	
		
			
				|  |  | +    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // The actual precomputations depend on whether we want to store precomputed
 | 
	
		
			
				|  |  | +    // irradiance or illuminance values.
 | 
	
		
			
				|  |  | +    //if (num_precomputed_wavelengths_ <= 3) {
 | 
	
		
			
				|  |  | +    //    vec3 lambdas{kLambdaR, kLambdaG, kLambdaB};
 | 
	
		
			
				|  |  | +    //    mat3 luminance_from_radiance{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
 | 
	
		
			
				|  |  | +    //    Precompute(fbo, delta_irradiance_texture, delta_rayleigh_scattering_texture,
 | 
	
		
			
				|  |  | +    //        delta_mie_scattering_texture, delta_scattering_density_texture,
 | 
	
		
			
				|  |  | +    //        delta_multiple_scattering_texture, lambdas, luminance_from_radiance,
 | 
	
		
			
				|  |  | +    //        false /* blend */, num_scattering_orders);
 | 
	
		
			
				|  |  | +    //} else {
 | 
	
		
			
				|  |  | +    //    constexpr double kLambdaMin = 360.0;
 | 
	
		
			
				|  |  | +    //    constexpr double kLambdaMax = 830.0;
 | 
	
		
			
				|  |  | +    //    int num_iterations = (num_precomputed_wavelengths_ + 2) / 3;
 | 
	
		
			
				|  |  | +    //    double dlambda = (kLambdaMax - kLambdaMin) / (3 * num_iterations);
 | 
	
		
			
				|  |  | +    //    for (int i = 0; i < num_iterations; ++i) {
 | 
	
		
			
				|  |  | +    //    vec3 lambdas{
 | 
	
		
			
				|  |  | +    //        kLambdaMin + (3 * i + 0.5) * dlambda,
 | 
	
		
			
				|  |  | +    //        kLambdaMin + (3 * i + 1.5) * dlambda,
 | 
	
		
			
				|  |  | +    //        kLambdaMin + (3 * i + 2.5) * dlambda
 | 
	
		
			
				|  |  | +    //    };
 | 
	
		
			
				|  |  | +    //    auto coeff = [dlambda](double lambda, int component) {
 | 
	
		
			
				|  |  | +    //        // Note that we don't include MAX_LUMINOUS_EFFICACY here, to avoid
 | 
	
		
			
				|  |  | +    //        // artefacts due to too large values when using half precision on GPU.
 | 
	
		
			
				|  |  | +    //        // We add this term back in kAtmosphereShader, via
 | 
	
		
			
				|  |  | +    //        // SKY_SPECTRAL_RADIANCE_TO_LUMINANCE (see also the comments in the
 | 
	
		
			
				|  |  | +    //        // Model constructor).
 | 
	
		
			
				|  |  | +    //        double x = CieColorMatchingFunctionTableValue(lambda, 1);
 | 
	
		
			
				|  |  | +    //        double y = CieColorMatchingFunctionTableValue(lambda, 2);
 | 
	
		
			
				|  |  | +    //        double z = CieColorMatchingFunctionTableValue(lambda, 3);
 | 
	
		
			
				|  |  | +    //        return static_cast<float>((
 | 
	
		
			
				|  |  | +    //            XYZ_TO_SRGB[component * 3] * x +
 | 
	
		
			
				|  |  | +    //            XYZ_TO_SRGB[component * 3 + 1] * y +
 | 
	
		
			
				|  |  | +    //            XYZ_TO_SRGB[component * 3 + 2] * z) * dlambda);
 | 
	
		
			
				|  |  | +    //    };
 | 
	
		
			
				|  |  | +    //    mat3 luminance_from_radiance{
 | 
	
		
			
				|  |  | +    //        coeff(lambdas[0], 0), coeff(lambdas[1], 0), coeff(lambdas[2], 0),
 | 
	
		
			
				|  |  | +    //        coeff(lambdas[0], 1), coeff(lambdas[1], 1), coeff(lambdas[2], 1),
 | 
	
		
			
				|  |  | +    //        coeff(lambdas[0], 2), coeff(lambdas[1], 2), coeff(lambdas[2], 2)
 | 
	
		
			
				|  |  | +    //    };
 | 
	
		
			
				|  |  | +    //    Precompute(fbo, delta_irradiance_texture,
 | 
	
		
			
				|  |  | +    //        delta_rayleigh_scattering_texture, delta_mie_scattering_texture,
 | 
	
		
			
				|  |  | +    //        delta_scattering_density_texture, delta_multiple_scattering_texture,
 | 
	
		
			
				|  |  | +    //        lambdas, luminance_from_radiance, i > 0 /* blend */,
 | 
	
		
			
				|  |  | +    //        num_scattering_orders);
 | 
	
		
			
				|  |  | +    //    }
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +    //    // After the above iterations, the transmittance texture contains the
 | 
	
		
			
				|  |  | +    //    // transmittance for the 3 wavelengths used at the last iteration. But we
 | 
	
		
			
				|  |  | +    //    // want the transmittance at kLambdaR, kLambdaG, kLambdaB instead, so we
 | 
	
		
			
				|  |  | +    //    // must recompute it here for these 3 wavelengths:
 | 
	
		
			
				|  |  | +    //    std::string header = glsl_header_factory_({kLambdaR, kLambdaG, kLambdaB});
 | 
	
		
			
				|  |  | +    //    Program compute_transmittance(
 | 
	
		
			
				|  |  | +    //        kVertexShader, header + kComputeTransmittanceShader);
 | 
	
		
			
				|  |  | +    //    glFramebufferTexture(
 | 
	
		
			
				|  |  | +    //        GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, transmittance_texture_, 0);
 | 
	
		
			
				|  |  | +    //    glDrawBuffer(GL_COLOR_ATTACHMENT0);
 | 
	
		
			
				|  |  | +    //    glViewport(0, 0, TRANSMITTANCE_TEXTURE_WIDTH, TRANSMITTANCE_TEXTURE_HEIGHT);
 | 
	
		
			
				|  |  | +    //    compute_transmittance.Use();
 | 
	
		
			
				|  |  | +    //    DrawQuad({}, full_screen_quad_vao_);
 | 
	
		
			
				|  |  | +    //}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Delete the temporary resources allocated at the begining of this method.
 | 
	
		
			
				|  |  | +    glUseProgram(0);
 | 
	
		
			
				|  |  | +    glBindFramebuffer(GL_FRAMEBUFFER, 0);
 | 
	
		
			
				|  |  | +    glDeleteFramebuffers(1, &fbo);
 | 
	
		
			
				|  |  | +    glDeleteTextures(1, &delta_scattering_density_texture);
 | 
	
		
			
				|  |  | +    glDeleteTextures(1, &delta_mie_scattering_texture);
 | 
	
		
			
				|  |  | +    glDeleteTextures(1, &delta_rayleigh_scattering_texture);
 | 
	
		
			
				|  |  | +    glDeleteTextures(1, &delta_irradiance_texture);
 | 
	
		
			
				|  |  | +    assert(glGetError() == 0);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    strSafeDestroy(&ss);  strSafePrint(&ss,"%s%s",header,kComputeTransmittanceShader);
 | 
	
		
			
				|  |  | +    tnsShader* compute_transmittance=tnsNewShaderProgram(tnsNewVertexShader(kVertexShader),tnsNewFragmentShader(ss->Ptr),-1);
 | 
	
		
			
				|  |  | +    strSafeDestroy(&ss); strSafePrint(&ss,"%s%s",header,kComputeDirectIrradianceShader);
 | 
	
		
			
				|  |  | +    tnsShader* compute_direct_irradiance=tnsNewShaderProgram(tnsNewVertexShader(kVertexShader),tnsNewFragmentShader(ss->Ptr),-1);
 | 
	
		
			
				|  |  | +    strSafeDestroy(&ss); strSafePrint(&ss,"%s%s",header,kComputeSingleScatteringShader);
 | 
	
		
			
				|  |  | +    tnsShader* compute_single_scattering=tnsNewShaderProgram(tnsNewVertexShader(kVertexShader),tnsNewFragmentShader(ss->Ptr),tnsNewGeometryShader(kGeometryShader));
 | 
	
		
			
				|  |  | +    strSafeDestroy(&ss); strSafePrint(&ss,"%s%s",header,kComputeScatteringDensityShader);
 | 
	
		
			
				|  |  | +    tnsShader* compute_scattering_density=tnsNewShaderProgram(tnsNewVertexShader(kVertexShader),tnsNewFragmentShader(ss->Ptr),tnsNewGeometryShader(kGeometryShader));
 | 
	
		
			
				|  |  | +    strSafeDestroy(&ss); strSafePrint(&ss,"%s%s",header,kComputeIndirectIrradianceShader);
 | 
	
		
			
				|  |  | +    tnsShader* compute_indirect_irradiance=tnsNewShaderProgram(tnsNewVertexShader(kVertexShader),tnsNewFragmentShader(ss->Ptr),-1);
 | 
	
		
			
				|  |  | +    strSafeDestroy(&ss); strSafePrint(&ss,"%s%s",header,kComputeMultipleScatteringShader);
 | 
	
		
			
				|  |  | +    tnsShader* compute_multiple_scattering=tnsNewShaderProgram(tnsNewVertexShader(kVertexShader),tnsNewFragmentShader(ss->Ptr),tnsNewGeometryShader(kGeometryShader));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const GLuint kDrawBuffers[4] = {
 | 
	
		
			
				|  |  | +        GL_COLOR_ATTACHMENT0,
 | 
	
		
			
				|  |  | +        GL_COLOR_ATTACHMENT1,
 | 
	
		
			
				|  |  | +        GL_COLOR_ATTACHMENT2,
 | 
	
		
			
				|  |  | +        GL_COLOR_ATTACHMENT3
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
 | 
	
		
			
				|  |  | +    glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ONE);;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 |