[HLSL Code] Smooth Weather Transition

share shaders here
Post Reply
  • Author
  • Message
Offline
User avatar
*blah-blah-blah maniac*
Posts: 1938
Joined: 05 Mar 2012, 02:08

[HLSL Code] Smooth Weather Transition

So i've been working on having a smooth/linear weather transition from a unspecified weather index into a specified weather index.
A lot of back and forth work to determine the best approach based on how I wanted it to behave. I ended up using the base code
from kingeric1992 enblens.fx WeatherFX shader, but with a smooth transition between weathers instead of a "on & off at middle/0.5 value" transition.

Purpose for this code
Enable effects only during specified weathers.
You can have 1 effect value separated between the specified weather/weathers and the unspecified weather/weathers.
And it can also serve as a "WeatherFactor", splitting 1 initial control into 99 controls, as an example.

This can be very useful to apply to weathers that does not have a day time cycle.
For Skyrim:
Sovngarde: 10d9ec, 10fef8, 923fd
BluePalace: 105945, 105942, 105943, 105944
DA02Weather: 105f40
MQ206Weather: 10199f
Soulcairn: 1407, 14551, 18dbb, 18dbc, 18dbd, 959f
Apocrypha: 1dff5, 34cfb


The code

Code: Select all

Copy&paste this above the Vertex Shader
// Helper functions and constants
/// Weather Index constants
#define WTHRINDEX_START    1   // Where in the index list to start including weathers
#define WTHRINDEX_ENDS     99  // Where in the index list to stop including weathers

/// Transition between selected and unselected weather index
/// Serves as a activator/de-activator of effects during specified weathers
float WthrTransition()
{
    float2 wthrlvl;
    if(WeatherAndTime.x > (WTHRINDEX_START - 0.2) && WeatherAndTime.x < (WTHRINDEX_ENDS + 0.2))
        wthrlvl.x = WeatherAndTime.z;       // Affects transition In
    else
        wthrlvl.x = 1 - WeatherAndTime.z;   // Affects transition Out

    if(WeatherAndTime.y > (WTHRINDEX_START - 0.2) && WeatherAndTime.y < (WTHRINDEX_ENDS + 0.2))
        wthrlvl.y = 1 - WeatherAndTime.z;   // Affects transition Out, 1 = effect applies during specified weather index
    else
        wthrlvl.y = 0 + WeatherAndTime.z;   // Affects transition In, 0 = effect applies during unspecified weather index

  return lerp(wthrlvl.x, wthrlvl.y, step(WeatherAndTime.z, 0.5));
}
OR

Code: Select all

Copy&paste this above the Vertex Shader
// Helper functions and constants
/// Transition between selected and unselected weather index
/// Serves as a per weather activator, or "WeatherFactor"
float WthrTransition(float WTHRINDEX_START, float WTHRINDEX_ENDS)
{
    float2 wthrlvl;
    if(WeatherAndTime.x > (WTHRINDEX_START - 0.2) && WeatherAndTime.x < (WTHRINDEX_ENDS + 0.2))
        wthrlvl.x = WeatherAndTime.z;       // Affects transition In
    else
        wthrlvl.x = 1 - WeatherAndTime.z;   // Affects transition Out

    if(WeatherAndTime.y > (WTHRINDEX_START - 0.2) && WeatherAndTime.y < (WTHRINDEX_ENDS + 0.2))
        wthrlvl.y = 1 - WeatherAndTime.z;   // Affects transition Out, 1 = effect applies during specified weather index
    else
        wthrlvl.y = 0 + WeatherAndTime.z;   // Affects transition In, 0 = effect applies during unspecified weather index

  return lerp(wthrlvl.x, wthrlvl.y, step(WeatherAndTime.z, 0.5));
}
Test code

Code: Select all

Copy&paste this into the Pixel shader
    color.rgb = lerp(color.rgb, float3(1, 0, 0), WthrTransition());
OR
    color.rgb = lerp(color.rgb, float3(1, 0, 0), WthrTransition(1, 99));
TimeFactor test code

Code: Select all

  float fBrightness = lerp(lerp(fBrightness_Night, fBrightness_Day, ENightDayFactor), lerp(fBrightness_Day, fBrightness_Day, ENightDayFactor), WthrTransition());

    color.rgb *= fBrightness;
OR

Code: Select all

  float fBrightness = lerp(fBrightness_Night, fBrightness_Day, ENightDayFactor);

    color.rgb *= lerp(fBrightness, 1.0, WthrTransition());


There is probably a much neater way of doing this, but this is what I ended up with and so far it works as I wanted it to work.
Improvements are needed, but not required. Won't break your visuals in anyway.
Post Reply