You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

125 lines
4.6 KiB

#pragma kernel EvaluateCloudMap
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
// #pragma enable_d3d11_debug_symbols
CBUFFER_START(UnityCloudMapGenerator)
int _CloudMapResolution;
float _CumulusMapMultiplier;
float _CumulonimbusMapMultiplier;
float _AltostratusMapMultiplier;
CBUFFER_END
SamplerState linear_repeat_sampler;
Texture2D<float> _CumulusMap;
Texture2D<float> _CumulonimbusMap;
Texture2D<float> _AltostratusMap;
Texture2D<float> _RainMap;
RWTexture2D<float4> _CloudMapTextureRW;
#define ALTOSTRATUS_ONLY_RANGE_MIN (0.0f/256.0f)
#define ALTOSTRATUS_ONLY_RANGE_MAX (32.0f/256.0f)
#define ALTOSTRATUS_ONLY_MAX_HEIGHT 1.0f
#define CUMULUS_ALTOSTRATUS_RANGE_MIN (32.0f/256.0f)
#define CUMULUS_ALTOSTRATUS_RANGE_MAX (64.0f/256.0f)
#define CUMULUS_ALTOSTRATUS_MAX_HEIGHT 1.0f
#define CUMULUS_ONLY_RANGE_MIN (64.0f/256.0f)
#define CUMULUS_ONLY_RANGE_MAX (128.0f/256.0f)
#define CUMULUS_ONLY_MAX_HEIGHT 0.5f
#define CUMULONIMBUS_RANGE_FIRST_MIN (128.0f/256.0f)
#define CUMULONIMBUS_RANGE_SECOND_MIN (130.0f/256.0f)
#define CUMULONIMBUS_RANGE_THIRD_MIN (136.0f/256.0f)
#define CUMULONIMBUS_RANGE_MAX 1.0f
#define CUMULONIMBUS_MAX_HEIGHT 1.0f
float2 NormalizedCoordinates(uint2 coord)
{
return (coord + 0.5f) / _CloudMapResolution;
}
[numthreads(8, 8, 1)]
void EvaluateCloudMap(uint2 currentCoord : SV_DispatchThreadID)
{
// If this pixel is not in the range, we are done
if (any(currentCoord.xy >= (uint2) _CloudMapResolution))
return;
// Compute the normalized coordinate of the current pixel
float2 normalizedCoord = NormalizedCoordinates(currentCoord.xy);
// Read all the cloud data
float2 tapUV = float2(normalizedCoord.x, 1.0 - normalizedCoord.y);
float cumulusCoverage = _CumulusMap.SampleLevel(linear_repeat_sampler, tapUV, 0) * _CumulusMapMultiplier;
cumulusCoverage = cumulusCoverage < 0.01 ? 0.0 : cumulusCoverage;
float cumulonimbusCoverage = _CumulonimbusMap.SampleLevel(linear_repeat_sampler, tapUV, 0);
cumulonimbusCoverage = cumulonimbusCoverage < 0.01 ? 0.0 : cumulonimbusCoverage;
float altoStratusCoverage = _AltostratusMap.SampleLevel(linear_repeat_sampler, tapUV, 0) * _AltostratusMapMultiplier;
altoStratusCoverage = altoStratusCoverage < 0.01 ? 0.0 : altoStratusCoverage;
float cloudRain = _RainMap.SampleLevel(linear_repeat_sampler, tapUV, 0);
float cloudCoverage = 0.0;
float cloudType = 0.0;
float cloudMaxHeight = 0.0;
// Cumulonimbus clouds have precedence over all the other clouds
if (cumulonimbusCoverage * _CumulonimbusMapMultiplier > 0.0)
{
cloudType = cumulonimbusCoverage * (CUMULONIMBUS_RANGE_MAX - CUMULONIMBUS_RANGE_FIRST_MIN) + CUMULONIMBUS_RANGE_FIRST_MIN;
if (cloudType < CUMULONIMBUS_RANGE_SECOND_MIN)
{
cloudCoverage = 0.0f;
cloudMaxHeight = 0.0;
}
else if (cloudType < CUMULONIMBUS_RANGE_THIRD_MIN)
{
cloudCoverage = lerp(0.0, _CumulonimbusMapMultiplier, (cloudType - CUMULONIMBUS_RANGE_SECOND_MIN) / (CUMULONIMBUS_RANGE_THIRD_MIN - CUMULONIMBUS_RANGE_SECOND_MIN));
cloudMaxHeight = lerp(0.0, 1.0, (cloudType - CUMULONIMBUS_RANGE_SECOND_MIN) / (CUMULONIMBUS_RANGE_THIRD_MIN - CUMULONIMBUS_RANGE_SECOND_MIN));
}
else
{
cloudCoverage = lerp(0.0, 0.75, _CumulonimbusMapMultiplier);
cloudMaxHeight = 1.0f;
}
}
// Cumulus have precedence over stratus
else if (cumulusCoverage > 0.0)
{
if (altoStratusCoverage > 0.0)
{
cloudType = 0.5 * (CUMULUS_ALTOSTRATUS_RANGE_MAX - CUMULUS_ALTOSTRATUS_RANGE_MIN) + CUMULUS_ALTOSTRATUS_RANGE_MIN;
cloudCoverage = max(cumulusCoverage, altoStratusCoverage);
cloudMaxHeight = CUMULUS_ALTOSTRATUS_MAX_HEIGHT;
}
else
{
cloudType = 0.5 * (CUMULUS_ONLY_RANGE_MAX - CUMULUS_ONLY_RANGE_MIN) + CUMULUS_ONLY_RANGE_MIN;
cloudCoverage = cumulusCoverage;
cloudMaxHeight = CUMULUS_ONLY_MAX_HEIGHT;
}
}
else
{
if (altoStratusCoverage > 0.0)
{
cloudType = 0.5 * (ALTOSTRATUS_ONLY_RANGE_MAX - ALTOSTRATUS_ONLY_RANGE_MIN) + ALTOSTRATUS_ONLY_RANGE_MIN;
cloudCoverage = altoStratusCoverage;
cloudMaxHeight = ALTOSTRATUS_ONLY_MAX_HEIGHT;
}
else
{
// No clouds were found
cloudCoverage = 0.0f;
cloudType = 0.0f;
cloudMaxHeight = 0.0f;
}
}
_CloudMapTextureRW[currentCoord] = float4(cloudCoverage, cloudRain, cloudType, cloudMaxHeight);
}