clouds: advect cloud field with Open-Meteo wind
This commit is contained in:
1 parent
0d8a5f93d3
commit
45e35982da
3 files changed
+73
-16
No files matched your search
+29
-4
@@ -2133,8 +2133,8 @@ window.weatherThemes = {
|
|||||||
function fetchWeather() {
|
function fetchWeather() {
|
||||||
var url = 'https://api.open-meteo.com/v1/forecast?latitude=' + WEATHER_LAT +
|
var url = 'https://api.open-meteo.com/v1/forecast?latitude=' + WEATHER_LAT +
|
||||||
'&longitude=' + WEATHER_LON +
|
'&longitude=' + WEATHER_LON +
|
||||||
'¤t=temperature_2m,relative_humidity_2m,weather_code,wind_speed_10m' +
|
'¤t=temperature_2m,relative_humidity_2m,weather_code,wind_speed_10m,wind_direction_10m' +
|
||||||
'&hourly=temperature_2m,weather_code' +
|
'&hourly=temperature_2m,weather_code,wind_speed_10m,wind_direction_10m' +
|
||||||
'&daily=weather_code,temperature_2m_max,temperature_2m_min' +
|
'&daily=weather_code,temperature_2m_max,temperature_2m_min' +
|
||||||
'&timezone=Europe/Berlin&forecast_days=5';
|
'&timezone=Europe/Berlin&forecast_days=5';
|
||||||
|
|
||||||
@@ -2147,6 +2147,10 @@ window.weatherThemes = {
|
|||||||
window.BackgroundCache.put('meta/weather', { json: data });
|
window.BackgroundCache.put('meta/weather', { json: data });
|
||||||
}
|
}
|
||||||
currentWeatherCode = data.current.weather_code;
|
currentWeatherCode = data.current.weather_code;
|
||||||
|
window.__currentWind = {
|
||||||
|
speedKmh: Number(data.current.wind_speed_10m || 0),
|
||||||
|
dirDeg: Number(data.current.wind_direction_10m || 0)
|
||||||
|
};
|
||||||
// while the weather sim runs it owns the theme - a live
|
// while the weather sim runs it owns the theme - a live
|
||||||
// poll must not override the configured test weather
|
// poll must not override the configured test weather
|
||||||
if (!__weatherSimActive)
|
if (!__weatherSimActive)
|
||||||
@@ -2163,6 +2167,10 @@ window.weatherThemes = {
|
|||||||
weatherData = rec.json;
|
weatherData = rec.json;
|
||||||
window.__weatherStale = true;
|
window.__weatherStale = true;
|
||||||
currentWeatherCode = rec.json.current.weather_code;
|
currentWeatherCode = rec.json.current.weather_code;
|
||||||
|
window.__currentWind = {
|
||||||
|
speedKmh: Number(rec.json.current.wind_speed_10m || 0),
|
||||||
|
dirDeg: Number(rec.json.current.wind_direction_10m || 0)
|
||||||
|
};
|
||||||
if (!__weatherSimActive)
|
if (!__weatherSimActive)
|
||||||
setWeatherTheme(getWeatherThemeName(currentWeatherCode));
|
setWeatherTheme(getWeatherThemeName(currentWeatherCode));
|
||||||
updateWeatherDisplay();
|
updateWeatherDisplay();
|
||||||
@@ -2220,6 +2228,12 @@ window.weatherThemes = {
|
|||||||
var curIdx = findHourlyIndex(eff, hourly.time);
|
var curIdx = findHourlyIndex(eff, hourly.time);
|
||||||
curTemp = hourly.temperature_2m[curIdx];
|
curTemp = hourly.temperature_2m[curIdx];
|
||||||
curCode = hourly.weather_code[curIdx];
|
curCode = hourly.weather_code[curIdx];
|
||||||
|
if (hourly.wind_speed_10m && hourly.wind_direction_10m) {
|
||||||
|
window.__currentWind = {
|
||||||
|
speedKmh: Number(hourly.wind_speed_10m[curIdx] || 0),
|
||||||
|
dirDeg: Number(hourly.wind_direction_10m[curIdx] || 0)
|
||||||
|
};
|
||||||
|
}
|
||||||
if (!__weatherSimActive && curCode !== currentWeatherCode) {
|
if (!__weatherSimActive && curCode !== currentWeatherCode) {
|
||||||
currentWeatherCode = curCode;
|
currentWeatherCode = curCode;
|
||||||
setWeatherTheme(getWeatherThemeName(curCode));
|
setWeatherTheme(getWeatherThemeName(curCode));
|
||||||
@@ -2231,9 +2245,20 @@ window.weatherThemes = {
|
|||||||
var tempDisplay = currentUnits === 'imperial'
|
var tempDisplay = currentUnits === 'imperial'
|
||||||
? Math.round(curTemp * 9 / 5 + 32) + '\u00b0F'
|
? Math.round(curTemp * 9 / 5 + 32) + '\u00b0F'
|
||||||
: Math.round(curTemp) + '\u00b0C';
|
: Math.round(curTemp) + '\u00b0C';
|
||||||
|
var curWindSpeed = current.wind_speed_10m;
|
||||||
|
var curWindDir = current.wind_direction_10m;
|
||||||
|
if (SIM_ACTIVE && hourly.wind_speed_10m && hourly.wind_direction_10m) {
|
||||||
|
var curIdx = findHourlyIndex(eff, hourly.time);
|
||||||
|
curWindSpeed = hourly.wind_speed_10m[curIdx];
|
||||||
|
curWindDir = hourly.wind_direction_10m[curIdx];
|
||||||
|
}
|
||||||
|
window.__currentWind = {
|
||||||
|
speedKmh: Number(curWindSpeed || 0),
|
||||||
|
dirDeg: Number(curWindDir || 0)
|
||||||
|
};
|
||||||
var windDisplay = currentUnits === 'imperial'
|
var windDisplay = currentUnits === 'imperial'
|
||||||
? Math.round(current.wind_speed_10m * 0.621371) + ' mph'
|
? Math.round(curWindSpeed * 0.621371) + ' mph'
|
||||||
: Math.round(current.wind_speed_10m) + ' km/h';
|
: Math.round(curWindSpeed) + ' km/h';
|
||||||
var currentHtml = '<div class="weather-current-icon">' + weatherSVG(curCode) + '</div>' +
|
var currentHtml = '<div class="weather-current-icon">' + weatherSVG(curCode) + '</div>' +
|
||||||
'<div><div class="weather-current-temp"><span>' + tempDisplay + '</span><span class="weather-location" id="weather-location">' +
|
'<div><div class="weather-current-temp"><span>' + tempDisplay + '</span><span class="weather-location" id="weather-location">' +
|
||||||
((window.CONFIG && window.CONFIG.location && (window.CONFIG.location.label || (window.CONFIG.location.lat.toFixed(2) + ',' + window.CONFIG.location.lon.toFixed(2)))) || '') + '</span></div>' +
|
((window.CONFIG && window.CONFIG.location && (window.CONFIG.location.label || (window.CONFIG.location.lat.toFixed(2) + ',' + window.CONFIG.location.lon.toFixed(2)))) || '') + '</span></div>' +
|
||||||
|
|||||||
@@ -152,7 +152,16 @@ window.CONFIG = {
|
|||||||
// only ever reports sunny/cloudy/stormy, so the deck keeps that
|
// only ever reports sunny/cloudy/stormy, so the deck keeps that
|
||||||
// coverage through the night as well - 'night' is used by the weather
|
// coverage through the night as well - 'night' is used by the weather
|
||||||
// simulation (weatherSim: true) alone.
|
// simulation (weatherSim: true) alone.
|
||||||
density: { sunny: 0.30, cloudy: 0.70, stormy: 1.00, night: 0.45 }
|
density: { sunny: 0.30, cloudy: 0.70, stormy: 1.00, night: 0.45 },
|
||||||
|
// Cloud motion from Open-Meteo wind. Open-Meteo reports wind FROM
|
||||||
|
// the reported compass direction; clouds advect toward the opposite
|
||||||
|
// bearing. speedScale exaggerates real advection so the motion is
|
||||||
|
// visible at the world scale (1 unit ~ 12.9 km).
|
||||||
|
wind: {
|
||||||
|
speedScale: 80,
|
||||||
|
minSpeed: 0.004,
|
||||||
|
maxSpeed: 0.08
|
||||||
|
}
|
||||||
// density: { sunny: 0.05, cloudy: 0.9, stormy: 1.0, night: 0.2 }
|
// density: { sunny: 0.05, cloudy: 0.9, stormy: 1.0, night: 0.2 }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Vendored
+34
-11
@@ -60,6 +60,7 @@ var FRAG_SRC = [
|
|||||||
'precision highp float;',
|
'precision highp float;',
|
||||||
'uniform vec2 uResolution;',
|
'uniform vec2 uResolution;',
|
||||||
'uniform float uTime;',
|
'uniform float uTime;',
|
||||||
|
'uniform vec3 uWind;',
|
||||||
'uniform sampler2D uGround;',
|
'uniform sampler2D uGround;',
|
||||||
'uniform vec2 uGroundCenter;', // current mosaic centre (world units)
|
'uniform vec2 uGroundCenter;', // current mosaic centre (world units)
|
||||||
'uniform vec2 uGroundSize;', // mosaic side extents (canvas tiles: W x H)
|
'uniform vec2 uGroundSize;', // mosaic side extents (canvas tiles: W x H)
|
||||||
@@ -203,13 +204,13 @@ var FRAG_SRC = [
|
|||||||
'}',
|
'}',
|
||||||
'float cloudDensity(vec3 p, float baseThresh, float soft) {',
|
'float cloudDensity(vec3 p, float baseThresh, float soft) {',
|
||||||
'float py = p.y + earthDrop(p.xz);',
|
'float py = p.y + earthDrop(p.xz);',
|
||||||
'vec3 cp = vec3(p.x, py, p.z);',
|
'vec3 cp = vec3(p.x, py, p.z) + uWind * uTime;',
|
||||||
'float n = fbm3(cp * 0.22 + vec3(0.0, 0.0, uTime * 0.05));',
|
'float n = fbm3(cp * 0.22 + vec3(0.0, 0.0, uTime * 0.02));',
|
||||||
// The detail octave weighs at most 0.20 and fades to zero with
|
// The detail octave weighs at most 0.20 and fades to zero with
|
||||||
// distance; past soft = 0.95 it contributes under 1 %, so the whole
|
// distance; past soft = 0.95 it contributes under 1 %, so the whole
|
||||||
// 4-octave lookup is skipped for the (numerous) far samples.
|
// 4-octave lookup is skipped for the (numerous) far samples.
|
||||||
'if (soft < 0.75) {',
|
'if (soft < 0.75) {',
|
||||||
'float d = fbm3(cp * 1.80 + vec3(uTime * 0.045, 7.3, uTime * 0.035));',
|
'float d = fbm3(cp * 1.80 + vec3(uTime * 0.015, 7.3, uTime * 0.012));',
|
||||||
'n = n + d * mix(0.22, 0.0, soft / 0.75);',
|
'n = n + d * mix(0.22, 0.0, soft / 0.75);',
|
||||||
'}',
|
'}',
|
||||||
// Cloud layer between uCloudBot and uCloudTop, densest in the
|
// Cloud layer between uCloudBot and uCloudTop, densest in the
|
||||||
@@ -397,10 +398,10 @@ var FRAG_SRC = [
|
|||||||
'return vec2((-b - sq) / (2.0 * a), (-b + sq) / (2.0 * a));',
|
'return vec2((-b - sq) / (2.0 * a), (-b + sq) / (2.0 * a));',
|
||||||
'}',
|
'}',
|
||||||
'float cloudDensitySpherical(vec3 p, float alt, float baseThresh, float soft) {',
|
'float cloudDensitySpherical(vec3 p, float alt, float baseThresh, float soft) {',
|
||||||
'vec3 q = vec3(p.x, alt, p.z);',
|
'vec3 q = vec3(p.x, alt, p.z) + uWind * uTime;',
|
||||||
'float n = fbm3(q * 0.22 + vec3(0.0, 0.0, uTime * 0.05));',
|
'float n = fbm3(q * 0.22 + vec3(0.0, 0.0, uTime * 0.02));',
|
||||||
'if (soft < 0.75) {',
|
'if (soft < 0.75) {',
|
||||||
'float d = fbm3(q * 1.80 + vec3(uTime * 0.045, 7.3, uTime * 0.035));',
|
'float d = fbm3(q * 1.80 + vec3(uTime * 0.015, 7.3, uTime * 0.012));',
|
||||||
'n = n + d * mix(0.22, 0.0, soft / 0.75);',
|
'n = n + d * mix(0.22, 0.0, soft / 0.75);',
|
||||||
'}',
|
'}',
|
||||||
'float h = clamp((alt - uCloudBot) / max(0.01, uCloudTop - uCloudBot), 0.0, 1.0);',
|
'float h = clamp((alt - uCloudBot) / max(0.01, uCloudTop - uCloudBot), 0.0, 1.0);',
|
||||||
@@ -852,13 +853,13 @@ var CLOUD_SAMPLER_GLSL = [
|
|||||||
'}',
|
'}',
|
||||||
'float cloudDensity(vec3 p, float baseThresh, float soft) {',
|
'float cloudDensity(vec3 p, float baseThresh, float soft) {',
|
||||||
'float py = p.y + earthDrop(p.xz);',
|
'float py = p.y + earthDrop(p.xz);',
|
||||||
'vec3 cp = vec3(p.x, py, p.z);',
|
'vec3 cp = vec3(p.x, py, p.z) + uWind * uTime;',
|
||||||
'float n = fbm3(cp * 0.22 + vec3(0.0, 0.0, uTime * 0.05));',
|
'float n = fbm3(cp * 0.22 + vec3(0.0, 0.0, uTime * 0.02));',
|
||||||
// The detail octave weighs at most 0.20 and fades to zero with
|
// The detail octave weighs at most 0.20 and fades to zero with
|
||||||
// distance; past soft = 0.95 it contributes under 1 %, so the whole
|
// distance; past soft = 0.95 it contributes under 1 %, so the whole
|
||||||
// 4-octave lookup is skipped for the (numerous) far samples.
|
// 4-octave lookup is skipped for the (numerous) far samples.
|
||||||
'if (soft < 0.75) {',
|
'if (soft < 0.75) {',
|
||||||
'float d = fbm3(cp * 1.80 + vec3(uTime * 0.045, 7.3, uTime * 0.035));',
|
'float d = fbm3(cp * 1.80 + vec3(uTime * 0.015, 7.3, uTime * 0.012));',
|
||||||
'n = n + d * mix(0.22, 0.0, soft / 0.75);',
|
'n = n + d * mix(0.22, 0.0, soft / 0.75);',
|
||||||
'}',
|
'}',
|
||||||
'float h = clamp((py - uCloudBot) / (uCloudTop - uCloudBot), 0.0, 1.0);',
|
'float h = clamp((py - uCloudBot) / (uCloudTop - uCloudBot), 0.0, 1.0);',
|
||||||
@@ -885,6 +886,7 @@ var TERRAIN_FRAG_SRC = [
|
|||||||
'uniform vec3 uHorizonColor;', // fog colour taken from the same light model
|
'uniform vec3 uHorizonColor;', // fog colour taken from the same light model
|
||||||
'uniform float uStarAmb;', // diffuse starlight + airglow (night only)
|
'uniform float uStarAmb;', // diffuse starlight + airglow (night only)
|
||||||
'uniform float uTime;', // must match the sky pass: same cloud field
|
'uniform float uTime;', // must match the sky pass: same cloud field
|
||||||
|
'uniform vec3 uWind;', // cloud advection vector, world units / s
|
||||||
'uniform float uCloudBot;',
|
'uniform float uCloudBot;',
|
||||||
'uniform float uCloudTop;',
|
'uniform float uCloudTop;',
|
||||||
'uniform float uDensity;', // cloud coverage, same as the sky pass
|
'uniform float uDensity;', // cloud coverage, same as the sky pass
|
||||||
@@ -1087,6 +1089,7 @@ function init(canvas) {
|
|||||||
var aPos = gl.getAttribLocation(prog, 'aPos');
|
var aPos = gl.getAttribLocation(prog, 'aPos');
|
||||||
var uRes = gl.getUniformLocation(prog, 'uResolution');
|
var uRes = gl.getUniformLocation(prog, 'uResolution');
|
||||||
var uTime = gl.getUniformLocation(prog, 'uTime');
|
var uTime = gl.getUniformLocation(prog, 'uTime');
|
||||||
|
var uWind = gl.getUniformLocation(prog, 'uWind');
|
||||||
var uGround = gl.getUniformLocation(prog, 'uGround');
|
var uGround = gl.getUniformLocation(prog, 'uGround');
|
||||||
var uGroundCenter = gl.getUniformLocation(prog, 'uGroundCenter');
|
var uGroundCenter = gl.getUniformLocation(prog, 'uGroundCenter');
|
||||||
var uGroundSize = gl.getUniformLocation(prog, 'uGroundSize');
|
var uGroundSize = gl.getUniformLocation(prog, 'uGroundSize');
|
||||||
@@ -1223,6 +1226,7 @@ function init(canvas) {
|
|||||||
var terrainUFarPlane = terrainProg ? gl.getUniformLocation(terrainProg, 'uFarPlane') : null;
|
var terrainUFarPlane = terrainProg ? gl.getUniformLocation(terrainProg, 'uFarPlane') : null;
|
||||||
var terrainUstarAmb = terrainProg ? gl.getUniformLocation(terrainProg, 'uStarAmb') : null;
|
var terrainUstarAmb = terrainProg ? gl.getUniformLocation(terrainProg, 'uStarAmb') : null;
|
||||||
var terrainUtime = terrainProg ? gl.getUniformLocation(terrainProg, 'uTime') : null;
|
var terrainUtime = terrainProg ? gl.getUniformLocation(terrainProg, 'uTime') : null;
|
||||||
|
var terrainUwind = terrainProg ? gl.getUniformLocation(terrainProg, 'uWind') : null;
|
||||||
var terrainUcloudbot = terrainProg ? gl.getUniformLocation(terrainProg, 'uCloudBot') : null;
|
var terrainUcloudbot = terrainProg ? gl.getUniformLocation(terrainProg, 'uCloudBot') : null;
|
||||||
var terrainUcloudtop = terrainProg ? gl.getUniformLocation(terrainProg, 'uCloudTop') : null;
|
var terrainUcloudtop = terrainProg ? gl.getUniformLocation(terrainProg, 'uCloudTop') : null;
|
||||||
var terrainUdensity = terrainProg ? gl.getUniformLocation(terrainProg, 'uDensity') : null;
|
var terrainUdensity = terrainProg ? gl.getUniformLocation(terrainProg, 'uDensity') : null;
|
||||||
@@ -1250,7 +1254,7 @@ function init(canvas) {
|
|||||||
return {
|
return {
|
||||||
gl: gl, prog: prog, buf: buf, aPos: aPos,
|
gl: gl, prog: prog, buf: buf, aPos: aPos,
|
||||||
blackTex: blackTex,
|
blackTex: blackTex,
|
||||||
uRes: uRes, uTime: uTime, uGround: uGround,
|
uRes: uRes, uTime: uTime, uWind: uWind, uGround: uGround,
|
||||||
uGroundCenter: uGroundCenter, uGroundSize: uGroundSize,
|
uGroundCenter: uGroundCenter, uGroundSize: uGroundSize,
|
||||||
uCorridorRot: uCorridorRot,
|
uCorridorRot: uCorridorRot,
|
||||||
uViewProjInv: uViewProjInv,
|
uViewProjInv: uViewProjInv,
|
||||||
@@ -1314,7 +1318,7 @@ function init(canvas) {
|
|||||||
uHazeMaxAlpha: terrainUHazeMaxAlpha, uHazeColor: terrainUHazeColor,
|
uHazeMaxAlpha: terrainUHazeMaxAlpha, uHazeColor: terrainUHazeColor,
|
||||||
uDistancePassOn: terrainUDistancePass, uFarPlane: terrainUFarPlane,
|
uDistancePassOn: terrainUDistancePass, uFarPlane: terrainUFarPlane,
|
||||||
uStarAmb: terrainUstarAmb,
|
uStarAmb: terrainUstarAmb,
|
||||||
uTime: terrainUtime, uCloudBot: terrainUcloudbot,
|
uTime: terrainUtime, uWind: terrainUwind, uCloudBot: terrainUcloudbot,
|
||||||
uCloudTop: terrainUcloudtop, uDensity: terrainUdensity,
|
uCloudTop: terrainUcloudtop, uDensity: terrainUdensity,
|
||||||
uCloudShadowOn: terrainUcloudshadow,
|
uCloudShadowOn: terrainUcloudshadow,
|
||||||
uCloudShadowDensity: terrainUcsDens,
|
uCloudShadowDensity: terrainUcsDens,
|
||||||
@@ -1435,6 +1439,22 @@ if (window.CONFIG && window.CONFIG.clouds) {
|
|||||||
CLOUD_TOP = Math.max(0.2, Math.min(CLOUD_TOP, 2.0));
|
CLOUD_TOP = Math.max(0.2, Math.min(CLOUD_TOP, 2.0));
|
||||||
CLOUD_BOT = Math.min(CLOUD_BOT, CLOUD_TOP - 0.4);
|
CLOUD_BOT = Math.min(CLOUD_BOT, CLOUD_TOP - 0.4);
|
||||||
var CLOUDS_ON = !(window.CONFIG && window.CONFIG.clouds && window.CONFIG.clouds.enabled === false);
|
var CLOUDS_ON = !(window.CONFIG && window.CONFIG.clouds && window.CONFIG.clouds.enabled === false);
|
||||||
|
var CLOUD_WIND_CFG = (window.CONFIG && window.CONFIG.clouds && window.CONFIG.clouds.wind) || {};
|
||||||
|
var CLOUD_WIND_SCALE = (typeof CLOUD_WIND_CFG.speedScale === 'number') ? Math.max(0, CLOUD_WIND_CFG.speedScale) : 80;
|
||||||
|
var CLOUD_WIND_MIN = (typeof CLOUD_WIND_CFG.minSpeed === 'number') ? Math.max(0, CLOUD_WIND_CFG.minSpeed) : 0.004;
|
||||||
|
var CLOUD_WIND_MAX = (typeof CLOUD_WIND_CFG.maxSpeed === 'number') ? Math.max(0, CLOUD_WIND_CFG.maxSpeed) : 0.08;
|
||||||
|
function cloudWindVector() {
|
||||||
|
var w = window.__currentWind || {};
|
||||||
|
var speedKmh = Number(w.speedKmh || 0);
|
||||||
|
var dirDeg = Number(w.dirDeg || 0);
|
||||||
|
var speed = speedKmh * CLOUD_WIND_SCALE / (KM_PER_TILE * 3600);
|
||||||
|
speed = Math.max(CLOUD_WIND_MIN, Math.min(CLOUD_WIND_MAX, speed));
|
||||||
|
// Open-Meteo wind_direction_10m is the compass bearing the wind blows
|
||||||
|
// FROM. Clouds advect toward the opposite bearing. World +X = east,
|
||||||
|
// +Z = north, bearing 0 = north and clockwise.
|
||||||
|
var rad = (dirDeg + 180) * Math.PI / 180;
|
||||||
|
return [Math.sin(rad) * speed, 0.0, Math.cos(rad) * speed];
|
||||||
|
}
|
||||||
|
|
||||||
// Terrain elevation grid (CONFIG.terrain). Heights come from Mapzen/
|
// Terrain elevation grid (CONFIG.terrain). Heights come from Mapzen/
|
||||||
// TILEZEN "terrarium" tiles (Copernicus DEM) at ELEV_Z, fetched once
|
// TILEZEN "terrarium" tiles (Copernicus DEM) at ELEV_Z, fetched once
|
||||||
@@ -6130,6 +6150,8 @@ window.clouds3dRender = function(target) {
|
|||||||
gl.uniform2f(s.uRes, canvas.width, canvas.height);
|
gl.uniform2f(s.uRes, canvas.width, canvas.height);
|
||||||
var now = performance.now() / 1000;
|
var now = performance.now() / 1000;
|
||||||
gl.uniform1f(s.uTime, now);
|
gl.uniform1f(s.uTime, now);
|
||||||
|
var _cloudWind = cloudWindVector();
|
||||||
|
gl.uniform3f(s.uWind, _cloudWind[0], _cloudWind[1], _cloudWind[2]);
|
||||||
|
|
||||||
var pal = window.__currentPalette;
|
var pal = window.__currentPalette;
|
||||||
if (!pal) {
|
if (!pal) {
|
||||||
@@ -6485,6 +6507,7 @@ window.clouds3dRender = function(target) {
|
|||||||
// sky pass (same noise, same uTime, same coverage) and marches from
|
// sky pass (same noise, same uTime, same coverage) and marches from
|
||||||
// the surface towards the sun through the deck.
|
// the surface towards the sun through the deck.
|
||||||
gl.uniform1f(terr.uTime, now);
|
gl.uniform1f(terr.uTime, now);
|
||||||
|
gl.uniform3f(terr.uWind, _cloudWind[0], _cloudWind[1], _cloudWind[2]);
|
||||||
gl.uniform1f(terr.uCloudBot, CLOUD_BOT);
|
gl.uniform1f(terr.uCloudBot, CLOUD_BOT);
|
||||||
gl.uniform1f(terr.uCloudTop, CLOUD_TOP);
|
gl.uniform1f(terr.uCloudTop, CLOUD_TOP);
|
||||||
gl.uniform1f(terr.uDensity, density);
|
gl.uniform1f(terr.uDensity, density);
|
||||||
|
|||||||
Reference in new issue
Block a user