Research:Weather

From OpenMW Wiki
Revision as of 12:08, 24 May 2019 by Hrnchamd (talk | contribs) (Added weather wind speed.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

{{#switch:|subgroup|child=|none=|#default=

}}


Sun glare[edit]

Actions affected During day hours
Description Rendering the sun glare overlay
Implementation status Implemented
Analysis status Needs verification

TitleCaps variables indicate values taken from the morrowind.ini section related to that object.


Glare magnitude calculation <syntaxhighlight lang="python"> theta = angleBetween(camera view vector, camera to sun vector) # in degrees peakHour = Weather.SunriseHour + (Weather.SunsetHour - Weather.SunriseHour) / 2


  1. Angular proximity

if theta <= Weather.SunGlareFaderAngleMax:

   a = 1 - theta / Weather.SunGlareFaderAngleMax

else:

   a = 0
  1. Time of day, prevents glare interfering at sunrise/sunset

if gameHour < Weather.SunriseHour or gameHour > Weather.SunsetHour:

   b = 0

elif gameHour < peakHour:

   b = 1 - (peakHour - gameHour) / (peakHour - Weather.SunriseHour)

else:

   b = 1 - (gameHour - peakHour) / (Weather.SunsetHour - peakHour)

b *= Weather.SunGlareFaderMax

  1. Specific weather variables
  1. transition is 0 at the start of a weather change and 1.0 at the end
  2. note that CloudsMaximumPercent is not actually a percentage

if weather is changing and transition < nextWeather.CloudsMaximumPercent:

   t = transition / nextWeather.CloudsMaximumPercent
   c = (1-t) * currentWeather.GlareView + t * nextWeather.GlareView

else:

   c = currentWeather.GlareView
  1. Occlusion

d = time-averaged visibility of sun via raycast [range: 0-1] </syntaxhighlight>

Rendering <syntaxhighlight lang="python"> Blend mode: src=SRC_ALPHA, dest=ONE

Material colour = saturate(2 * Weather.SunGlareFaderColor) # design flaw Material alpha = a * b * c * d </syntaxhighlight>


Comments[edit]

There is an issue with the colour specification. The default SunGlareFaderColor is sRGB [222,095,039], which is very red compared to the actual rendering. This is due to the game setting the ambient, diffuse and emissive materials to the SunGlareFaderColor, in combination with pure white ambient lighting for this effect (but no diffuse due to lack of normals). This essentially multiplies the colour by 2, which is then clamped by the fixed function pipeline, causing a final colour of light orange.


Wind speed[edit]

Actions affected In all cells
Description Wind speed velocity vector
Implementation status Unknown condition
Analysis status Needs verification


The game runs a simulation tick for weathers each frame. While transitioning between weathers, it simulates both the current and next weather. It stores wind velocity for both current and next weather, and interpolates between them after simulating the weathers. For interiors, wind speed is zero.


Common pre-calculation for all weathers

<syntaxhighlight lang="python"> weatherState = weather persistent state weatherType = simulated weather type iniSpeed = morrowind.ini, Weather section, Wind Speed for this weather targetSpeed = min(8.0 * iniSpeed, 70);

if currentWeather.type is weatherType:

   currentSpeed = length(weatherState.windVelocityCurrentWeather)

elif nextWeather:

   currentSpeed = length(weatherState.windVelocityNextWeather)

else

   currentSpeed = targetSpeed

if (currentSpeed == 0)

   currentSpeed = targetSpeed

</syntaxhighlight>


Clear, Cloudy, Fog, Overcast, Snow, Blizzard

<syntaxhighlight lang="python"> updatedSpeed = (randFloat() - 0.5) * targetSpeed + currentSpeed;

if updatedSpeed > 0.5 * targetSpeed and updatedSpeed < 2 * targetSpeed:

   currentSpeed = updatedSpeed

if currentWeather.type is weatherType:

   weatherState.windVelocityCurrentWeather = (0, currentSpeed, 0)

else:

   weatherState.windVelocityNextWeather = (0, currentSpeed, 0)

</syntaxhighlight>


Rain, Storm

<syntaxhighlight lang="python"> updatedSpeed = (randFloat() - 0.5) * 0.5 * targetSpeed + currentSpeed;

if updatedSpeed > 0.5 * targetSpeed and updatedSpeed < 2 * targetSpeed:

   currentSpeed = updatedSpeed

if currentWeather.type is weatherType:

   weatherState.windVelocityCurrentWeather = (0, currentSpeed, 0)

else:

   weatherState.windVelocityNextWeather = (0, currentSpeed, 0)

</syntaxhighlight>


Ashstorm, Blight

<syntaxhighlight lang="python"> stormCentre = (25000, 70000) updatedSpeed = (randFloat() - 0.5) * targetSpeed + currentSpeed;

if updatedSpeed > 0.5 * targetSpeed and updatedSpeed < 2 * targetSpeed:

   currentSpeed = updatedSpeed

if currentWeather.type is weatherType:

   direction = normalize(camera.position.xy - stormCentre.xy)
   weatherState.windVelocityCurrentWeather = (currentSpeed * direction.x, currentSpeed * direction.y, 0)

else:

   weatherState.windVelocityNextWeather = (currentSpeed * direction.x, currentSpeed * direction.y, 0)

</syntaxhighlight>


Comments[edit]

Final wind velocity is interpolated between weatherState.windVelocityCurrentWeather and weatherState.windVelocityNextWeather, or is zero for interiors.


{{#switch:|subgroup|child=|none=|#default=

}}