Add API to set Nishita density parameters
This commit is contained in:
parent
845d2aff93
commit
420033c86d
|
@ -21,6 +21,7 @@
|
|||
#define _SKY_GLSL_
|
||||
|
||||
uniform sampler2D nishitaLUT;
|
||||
uniform vec2 nishitaDensity;
|
||||
|
||||
#ifndef PI
|
||||
#define PI 3.141592
|
||||
|
@ -91,9 +92,8 @@ 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, ozone density)
|
||||
*/
|
||||
vec3 nishita_atmosphere(const vec3 r, const vec3 r0, const vec3 pSun, const float rPlanet, const vec3 density) {
|
||||
vec3 nishita_atmosphere(const vec3 r, const vec3 r0, const vec3 pSun, const float rPlanet) {
|
||||
// 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);
|
||||
|
@ -127,8 +127,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) * density.x * iStepSize;
|
||||
float odStepMie = exp(-iHeight / nishita_mie_scale) * density.y * iStepSize;
|
||||
float odStepRlh = exp(-iHeight / nishita_rayleigh_scale) * nishitaDensity.x * iStepSize;
|
||||
float odStepMie = exp(-iHeight / nishita_mie_scale) * nishitaDensity.y * iStepSize;
|
||||
|
||||
// Accumulate optical depth.
|
||||
iOdRlh += odStepRlh;
|
||||
|
|
|
@ -11,14 +11,14 @@ class Uniforms {
|
|||
|
||||
public static function register() {
|
||||
iron.object.Uniforms.externalTextureLinks = [textureLink];
|
||||
iron.object.Uniforms.externalVec2Links = [];
|
||||
iron.object.Uniforms.externalVec2Links = [vec2Link];
|
||||
iron.object.Uniforms.externalVec3Links = [vec3Link];
|
||||
iron.object.Uniforms.externalVec4Links = [];
|
||||
iron.object.Uniforms.externalFloatLinks = [floatLink];
|
||||
iron.object.Uniforms.externalIntLinks = [];
|
||||
}
|
||||
|
||||
public static function textureLink(object: Object, mat: MaterialData, link: String): kha.Image {
|
||||
public static function textureLink(object: Object, mat: MaterialData, link: String): Null<kha.Image> {
|
||||
switch (link) {
|
||||
case "_nishitaLUT": {
|
||||
if (armory.renderpath.Nishita.data == null) armory.renderpath.Nishita.recompute(Scene.active.world);
|
||||
|
@ -40,7 +40,7 @@ class Uniforms {
|
|||
return target != null ? target.image : null;
|
||||
}
|
||||
|
||||
public static function vec3Link(object: Object, mat: MaterialData, link: String): iron.math.Vec4 {
|
||||
public static function vec3Link(object: Object, mat: MaterialData, link: String): Null<iron.math.Vec4> {
|
||||
var v: Vec4 = null;
|
||||
switch (link) {
|
||||
#if arm_hosek
|
||||
|
@ -173,6 +173,23 @@ class Uniforms {
|
|||
return v;
|
||||
}
|
||||
|
||||
public static function vec2Link(object: Object, mat: MaterialData, link: String): Null<iron.math.Vec4> {
|
||||
var v: Vec4 = null;
|
||||
switch (link) {
|
||||
case "_nishitaDensity": {
|
||||
v = iron.object.Uniforms.helpVec;
|
||||
var w = Scene.active.world;
|
||||
if (w != null) {
|
||||
// We only need Rayleigh and Mie density in the sky shader -> Vec2
|
||||
v.x = w.raw.nishita_density[0];
|
||||
v.y = w.raw.nishita_density[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
public static function floatLink(object: Object, mat: MaterialData, link: String): Null<kha.FastFloat> {
|
||||
switch (link) {
|
||||
#if rp_dynres
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package armory.renderpath;
|
||||
|
||||
import kha.FastFloat;
|
||||
import kha.arrays.Float32Array;
|
||||
import kha.graphics4.TextureFormat;
|
||||
import kha.graphics4.Usage;
|
||||
|
||||
|
@ -18,15 +19,28 @@ class Nishita {
|
|||
public static var data: NishitaData = null;
|
||||
|
||||
/**
|
||||
Recompute the nishita lookup table. Call this function after updating
|
||||
the sky density settings.
|
||||
Recomputes the nishita lookup table after the density settings changed.
|
||||
Do not call this method on every frame (it's slow)!
|
||||
**/
|
||||
public static function recompute(world: WorldData) {
|
||||
if (world == null || world.raw.sun_direction == null) return;
|
||||
if (world == null || world.raw.nishita_density == null) return;
|
||||
if (data == null) data = new NishitaData();
|
||||
|
||||
// TODO
|
||||
data.computeLUT(new Vec3(1.0, 1.0, 1.0));
|
||||
var density = world.raw.nishita_density;
|
||||
data.computeLUT(new Vec3(density[0], density[1], density[2]));
|
||||
}
|
||||
|
||||
/** Sets the sky's density parameters and calls `recompute()` afterwards. **/
|
||||
public static function setDensity(world: WorldData, densityAir: FastFloat, densityDust: FastFloat, densityOzone: FastFloat) {
|
||||
if (world == null) return;
|
||||
|
||||
if (world.raw.nishita_density == null) world.raw.nishita_density = new Float32Array(3);
|
||||
var density = world.raw.nishita_density;
|
||||
density[0] = Helper.clamp(densityAir, 0, 10);
|
||||
density[1] = Helper.clamp(densityDust, 0, 10);
|
||||
density[2] = Helper.clamp(densityOzone, 0, 10);
|
||||
|
||||
recompute(world);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2843,6 +2843,7 @@ class ArmoryExporter:
|
|||
out_world['sun_direction'] = list(world.arm_envtex_sun_direction)
|
||||
out_world['turbidity'] = world.arm_envtex_turbidity
|
||||
out_world['ground_albedo'] = world.arm_envtex_ground_albedo
|
||||
out_world['nishita_density'] = list(world.arm_nishita_density)
|
||||
|
||||
disable_hdr = world.arm_envtex_name.endswith('.jpg')
|
||||
|
||||
|
|
|
@ -375,11 +375,12 @@ def parse_sky_nishita(node: bpy.types.ShaderNodeTexSky, state: ParserState) -> v
|
|||
curshader.add_uniform('vec3 sunDir', link='_sunDirection')
|
||||
curshader.add_uniform('sampler2D nishitaLUT', link='_nishitaLUT', included=True,
|
||||
tex_addr_u='clamp', tex_addr_v='clamp')
|
||||
curshader.add_uniform('vec2 nishitaDensity', link='_nishitaDensity', included=True)
|
||||
|
||||
planet_radius = 6360e3 # Earth radius used in Blender
|
||||
ray_origin_z = planet_radius + node.altitude
|
||||
|
||||
density = c.to_vec3((node.air_density, node.dust_density, node.ozone_density))
|
||||
state.world.arm_nishita_density = [node.air_density, node.dust_density, node.ozone_density]
|
||||
|
||||
sun = ''
|
||||
if node.sun_disc:
|
||||
|
@ -399,7 +400,7 @@ def parse_sky_nishita(node: bpy.types.ShaderNodeTexSky, state: ParserState) -> v
|
|||
size = math.cos(theta)
|
||||
sun = f'* sun_disk(n, sunDir, {size}, {node.sun_intensity})'
|
||||
|
||||
return f'nishita_atmosphere(n, vec3(0, 0, {ray_origin_z}), sunDir, {planet_radius}, {density}){sun}'
|
||||
return f'nishita_atmosphere(n, vec3(0, 0, {ray_origin_z}), sunDir, {planet_radius}){sun}'
|
||||
|
||||
|
||||
def parse_tex_environment(node: bpy.types.ShaderNodeTexEnvironment, out_socket: bpy.types.NodeSocket, state: ParserState) -> vec3str:
|
||||
|
|
|
@ -326,6 +326,7 @@ def init_properties():
|
|||
bpy.types.World.arm_envtex_sun_direction = FloatVectorProperty(name="Sun Direction", size=3, default=[0,0,0])
|
||||
bpy.types.World.arm_envtex_turbidity = FloatProperty(name="Turbidity", default=1.0)
|
||||
bpy.types.World.arm_envtex_ground_albedo = FloatProperty(name="Ground Albedo", default=0.0)
|
||||
bpy.types.World.arm_nishita_density = FloatVectorProperty(name="Nishita Density", size=3, default=[1, 1, 1])
|
||||
bpy.types.Material.arm_cast_shadow = BoolProperty(name="Cast Shadow", default=True)
|
||||
bpy.types.Material.arm_receive_shadow = BoolProperty(name="Receive Shadow", description="Requires forward render path", default=True)
|
||||
bpy.types.Material.arm_overlay = BoolProperty(name="Overlay", default=False)
|
||||
|
|
Loading…
Reference in a new issue