diff --git a/Shaders/std/sky.glsl b/Shaders/std/sky.glsl index 310ed2ad..921eb7e8 100644 --- a/Shaders/std/sky.glsl +++ b/Shaders/std/sky.glsl @@ -1,9 +1,12 @@ /* Various sky functions + * ===================== * - * Nishita model is based on https://github.com/wwwtyro/glsl-atmosphere (Unlicense License) - * Changes to the original implementation: - * - r and pSun parameters of nishita_atmosphere() are already normalized - * - Some original parameters of nishita_atmosphere() are replaced with pre-defined values + * Nishita model is based on https://github.com/wwwtyro/glsl-atmosphere(Unlicense License) + * + * Changes to the original implementation: + * - r and pSun parameters of nishita_atmosphere() are already normalized + * - Some original parameters of nishita_atmosphere() are replaced with pre-defined values + * - Implemented air and dust density node parameters (see Blender source) */ #ifndef _SKY_GLSL_ @@ -47,8 +50,9 @@ vec2 nishita_rsi(const vec3 r0, const vec3 rd, const float sr) { * r0: ray origin * pSun: normalized sun direction * rPlanet: planet radius + * density: (air density, dust density) */ -vec3 nishita_atmosphere(const vec3 r, const vec3 r0, const vec3 pSun, const float rPlanet) { +vec3 nishita_atmosphere(const vec3 r, const vec3 r0, const vec3 pSun, const float rPlanet, const vec2 density) { // Calculate the step size of the primary ray. vec2 p = nishita_rsi(r0, r, nishita_atmo_radius); if (p.x > p.y) return vec3(0,0,0); @@ -82,8 +86,8 @@ vec3 nishita_atmosphere(const vec3 r, const vec3 r0, const vec3 pSun, const floa float iHeight = length(iPos) - rPlanet; // Calculate the optical depth of the Rayleigh and Mie scattering for this step. - float odStepRlh = exp(-iHeight / nishita_rayleigh_scale) * iStepSize; - float odStepMie = exp(-iHeight / nishita_mie_scale) * iStepSize; + float odStepRlh = exp(-iHeight / nishita_rayleigh_scale) * density.x * iStepSize; + float odStepMie = exp(-iHeight / nishita_mie_scale) * density.y * iStepSize; // Accumulate optical depth. iOdRlh += odStepRlh; @@ -109,8 +113,8 @@ vec3 nishita_atmosphere(const vec3 r, const vec3 r0, const vec3 pSun, const floa float jHeight = length(jPos) - rPlanet; // Accumulate the optical depth. - jOdRlh += exp(-jHeight / nishita_rayleigh_scale) * jStepSize; - jOdMie += exp(-jHeight / nishita_mie_scale) * jStepSize; + jOdRlh += exp(-jHeight / nishita_rayleigh_scale) * density.x * jStepSize; + jOdMie += exp(-jHeight / nishita_mie_scale) * density.y * jStepSize; // Increment the secondary ray time. jTime += jStepSize; diff --git a/blender/arm/material/cycles.py b/blender/arm/material/cycles.py index 71cf6f84..b587226c 100644 --- a/blender/arm/material/cycles.py +++ b/blender/arm/material/cycles.py @@ -640,8 +640,12 @@ def to_vec1(v): return str(v) +def to_vec2(v): + return f'vec2({v[0]}, {v[1]})' + + def to_vec3(v): - return 'vec3({0}, {1}, {2})'.format(v[0], v[1], v[2]) + return f'vec3({v[0]}, {v[1]}, {v[2]})' def rgb_to_bw(res_var: vec3str) -> floatstr: diff --git a/blender/arm/material/cycles_nodes/nodes_texture.py b/blender/arm/material/cycles_nodes/nodes_texture.py index 1cb4eb98..4aef494c 100644 --- a/blender/arm/material/cycles_nodes/nodes_texture.py +++ b/blender/arm/material/cycles_nodes/nodes_texture.py @@ -376,7 +376,13 @@ def parse_sky_nishita(node: bpy.types.ShaderNodeTexSky, state: ParserState) -> v planet_radius = 6360e3 # Earth radius used in Blender ray_origin_z = planet_radius + node.altitude * 1000 - return f'nishita_atmosphere(n, vec3(0, 0, {ray_origin_z}), sunDir, {planet_radius})' + d_air = node.air_density + d_dust = node.dust_density + # Todo: Implement ozone density (ignored for now) + # d_ozone = node.ozone_density + density = c.to_vec2((d_air, d_dust)) + + return f'nishita_atmosphere(n, vec3(0, 0, {ray_origin_z}), sunDir, {planet_radius}, {density})' def parse_tex_environment(node: bpy.types.ShaderNodeTexEnvironment, out_socket: bpy.types.NodeSocket, state: ParserState) -> vec3str: