shaders/atmos/atmos.tstypescript
import { ShaderProgram } from "../../webgl/ShaderProgram";
import transmittance_vert from "./transmittance.vert.glsl";
import transmittance_frag from "./transmittance.frag.glsl";
import scattering_vert from "./scattering.vert.glsl";
import scattering_frag from "./scattering.frag.glsl";
import { stringTemplate2 } from "../../utils/shared";
export interface AtmosphereParameters {
ATMOS_HEIGHT: number;
RAYLEIGH_SCALE: number;
MIE_SCALE: number;
GROUND_ALBEDO: number;
BOTTOM_RADIUS: number;
EQUATORIAL_RADIUS: number;
rayleighScatteringCoefficient_0: number;
rayleighScatteringCoefficient_1: number;
rayleighScatteringCoefficient_2: number;
mieScatteringCoefficient: number;
mieExtinctionCoefficient: number;
ozoneAbsorptionCoefficient_0: number;
ozoneAbsorptionCoefficient_1: number;
ozoneAbsorptionCoefficient_2: number;
SUN_ANGULAR_RADIUS: number;
SUN_INTENSITY: number;
ozoneDensityHeight: number;
ozoneDensityWide: number;
disableSunDisk?: boolean;
}
/*
* Previous DEFAULT_PARAMS values:
* ATMOS_HEIGHT: 100000.0
* RAYLEIGH_SCALE: 0.08
* MIE_SCALE: 0.012
* GROUND_ALBEDO: 0.05
* BOTTOM_RADIUS: 6356752.3142451793
* EQUATORIAL_RADIUS: 6378137.0
* rayleighScatteringCoefficient_0: 5.802
* rayleighScatteringCoefficient_1: 13.558
* rayleighScatteringCoefficient_2: 33.1
* mieScatteringCoefficient: 3.996
* mieExtinctionCoefficient: 4.44
* ozoneAbsorptionCoefficient_0: 0.65
* ozoneAbsorptionCoefficient_1: 1.881
* ozoneAbsorptionCoefficient_2: 0.085
* SUN_ANGULAR_RADIUS: 0.004685
* SUN_INTENSITY: 1.0
* ozoneDensityHeight: 25e3
* ozoneDensityWide: 15e3
* disableSunDisk: false
*/
export const DEFAULT_PARAMS: AtmosphereParameters = {
ATMOS_HEIGHT: 100000.0,
RAYLEIGH_SCALE: 0.056, //0.086
MIE_SCALE: 0.0045,
GROUND_ALBEDO: 0.022,
BOTTOM_RADIUS: 6356752.3142451793,
EQUATORIAL_RADIUS: 6378137.0,
rayleighScatteringCoefficient_0: 3.9,
rayleighScatteringCoefficient_1: 10.8,
rayleighScatteringCoefficient_2: 20.0, //42.0
mieScatteringCoefficient: 1.6,
mieExtinctionCoefficient: 1.85,
ozoneAbsorptionCoefficient_0: 1.25,
ozoneAbsorptionCoefficient_1: 2.1,
ozoneAbsorptionCoefficient_2: 0.09,
SUN_ANGULAR_RADIUS: 0.004685,
SUN_INTENSITY: 0.78, //1.0
ozoneDensityHeight: 25e3,
ozoneDensityWide: 15e3,
disableSunDisk: false
};
export const MARS_PARAMS: AtmosphereParameters = {
ATMOS_HEIGHT: 60000.0,
RAYLEIGH_SCALE: 0.18,
MIE_SCALE: 0.08,
GROUND_ALBEDO: 0.15,
BOTTOM_RADIUS: 3389508.0,
EQUATORIAL_RADIUS: 3396200.0,
rayleighScatteringCoefficient_0: 1.0,
rayleighScatteringCoefficient_1: 1.2,
rayleighScatteringCoefficient_2: 1.4,
mieScatteringCoefficient: 10.0,
mieExtinctionCoefficient: 20.0,
ozoneAbsorptionCoefficient_0: 0.1,
ozoneAbsorptionCoefficient_1: 0.15,
ozoneAbsorptionCoefficient_2: 0.8,
SUN_ANGULAR_RADIUS: 0.004685,
SUN_INTENSITY: 1.0,
ozoneDensityHeight: 10e3,
ozoneDensityWide: 30e3,
disableSunDisk: false
};
export function transmittance(atmosParams?: AtmosphereParameters): ShaderProgram {
return new ShaderProgram("transmittance", {
uniforms: {
iResolution: "vec2"
},
attributes: {
a_position: "vec2"
},
vertexShader: transmittance_vert,
fragmentShader: stringTemplate2(transmittance_frag, atmosParams || DEFAULT_PARAMS)
});
}
export function scattering(atmosParams?: AtmosphereParameters): ShaderProgram {
return new ShaderProgram("scattering", {
uniforms: {
iResolution: "vec2",
transmittanceTexture: "sampler2d"
},
attributes: {
a_position: "vec2"
},
vertexShader: scattering_vert,
fragmentShader: stringTemplate2(scattering_frag, atmosParams || DEFAULT_PARAMS)
});
}
// const vec3 solar_irradiance = vec3(1.474000,1.850400,1.911980);
// float GetTextureCoordFromUnitRange(float x, int texture_size) {
// return 0.5 / float(texture_size) + x * (1.0 - 1.0 / float(texture_size));
// }
//
// float ClampDistance(float d) {
// return max(d, 0.0 * m);
// }
//
// float SafeSqrt(float a) {
// return sqrt(max(a, 0.0 * m2));
// }
// float DistanceToTopAtmosphereBoundary(float r, float mu) {
//
// //assert(r <= atmosphere.top_radius);
// //assert(mu >= -1.0 && mu <= 1.0);
//
// float discriminant = r * r * (mu * mu - 1.0) + TOP_RADIUS * TOP_RADIUS;
// return ClampDistance(-r * mu + SafeSqrt(discriminant));
// }
// vec2 GetTransmittanceTextureUvFromRMu(
// float r,
// float mu)
// {
// //assert(r >= atmosphere.BOTTOM_RADIUS && r <= TOP_RADIUS);
// //assert(mu >= -1.0 && mu <= 1.0);
//
// float H = sqrt(TOP_RADIUS * TOP_RADIUS - BOTTOM_RADIUS * BOTTOM_RADIUS);
// float rho = SafeSqrt(r * r - BOTTOM_RADIUS * BOTTOM_RADIUS);
// float d = DistanceToTopAtmosphereBoundary(r, mu);
// float d_min = TOP_RADIUS - r;
// float d_max = rho + H;
// float x_mu = (d - d_min) / (d_max - d_min);
// float x_r = rho / H;
//
// return vec2(
// GetTextureCoordFromUnitRange(x_mu, TRANSMITTANCE_TEXTURE_WIDTH),
// GetTextureCoordFromUnitRange(x_r, TRANSMITTANCE_TEXTURE_HEIGHT)
// );
// }
// vec3 GetTransmittanceToTopAtmosphereBoundary(in sampler2D transmittance_texture, float r, float mu)
// {
// //assert(r >= BOTTOM_RADIUS && r <= TOP_RADIUS);
//
// vec2 uv = GetTransmittanceTextureUvFromRMu(r, mu);
// return texture(transmittance_texture, uv).xyz;
// }
// vec3 GetTransmittanceToSun(
// in sampler2D transmittance_texture,
// float r,
// float mu_s)
// {
// float sin_theta_h = BOTTOM_RADIUS / r;
// float cos_theta_h = -sqrt(max(1.0 - sin_theta_h * sin_theta_h, 0.0));
//
// return GetTransmittanceToTopAtmosphereBoundary(transmittance_texture, r, mu_s) * smoothstep(
// -sin_theta_h * SUN_ANGULAR_RADIUS / rad, sin_theta_h * SUN_ANGULAR_RADIUS / rad,
// mu_s - cos_theta_h
// );
// }
// vec3 GetSunAndSkyIrradiance(
// in sampler2D transmittance_texture,
// in vec3 point,
// in vec3 normal,
// in vec3 sun_direction,
// out vec3 sky_irradiance)
// {
// float r = length(point);
// float mu_s = dot(point, sun_direction) / r;
//
// sky_irradiance = vec3(0.0); // GetIrradiance(atmosphere, irradiance_texture, r, mu_s) * (1.0 + dot(normal, point) / r) * 0.5;
//
// return solar_irradiance * GetTransmittanceToSun(transmittance_texture, r, mu_s) * max(dot(normal, sun_direction), 0.0);
// }