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
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);
|
|
}
|