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.
154 lines
4.5 KiB
154 lines
4.5 KiB
#ifndef __CLOUDLAYER_COMMON_H__
|
|
#define __CLOUDLAYER_COMMON_H__
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/SphericalHarmonics.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyUtils.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudUtils.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSkyCommon.hlsl"
|
|
|
|
|
|
TEXTURE2D_ARRAY(_CloudTexture);
|
|
SAMPLER(sampler_CloudTexture);
|
|
|
|
TEXTURE2D(_FlowmapA);
|
|
SAMPLER(sampler_FlowmapA);
|
|
|
|
TEXTURE2D(_FlowmapB);
|
|
SAMPLER(sampler_FlowmapB);
|
|
|
|
float4 _FlowmapParam[2];
|
|
float4 _Params1[2];
|
|
float4 _Params2; // zw ununsed
|
|
float3 _SunDirection;
|
|
|
|
StructuredBuffer<float4> _AmbientProbeBuffer;
|
|
|
|
#define _ScrollDirection(l) _FlowmapParam[l].xy
|
|
#define _ScrollFactor(l) _FlowmapParam[l].z
|
|
#define _UpperHemisphere (_FlowmapParam[0].w != 0.0)
|
|
#define _Opacity _FlowmapParam[1].w
|
|
|
|
#define _SunLightColor(l) _Params1[l].xyz
|
|
#define _Altitude(l) _Params1[l].w
|
|
#define _AmbientDimmer(l) _Params2[l]
|
|
|
|
#define _LowestAltitude(l) (_Altitude(l) + _PlanetaryRadius)
|
|
|
|
struct CloudLayerData
|
|
{
|
|
int index;
|
|
bool distort, use_flowmap;
|
|
|
|
TEXTURE2D(flowmap);
|
|
SAMPLER(flowmapSampler);
|
|
};
|
|
|
|
float2 SampleCloudMap(float3 dir, int layer)
|
|
{
|
|
float2 coords = GetLatLongCoords(dir, _UpperHemisphere);
|
|
return SAMPLE_TEXTURE2D_ARRAY_LOD(_CloudTexture, sampler_CloudTexture, coords, layer, 0).rg;
|
|
}
|
|
|
|
CloudLayerData GetCloudLayer(int index)
|
|
{
|
|
CloudLayerData layer;
|
|
layer.index = index;
|
|
layer.distort = false;
|
|
layer.use_flowmap = false;
|
|
|
|
if (index == 0)
|
|
{
|
|
#ifndef LAYER1_STATIC
|
|
layer.distort = true;
|
|
#ifdef LAYER1_FLOWMAP
|
|
layer.use_flowmap = true;
|
|
layer.flowmap = _FlowmapA;
|
|
layer.flowmapSampler = sampler_FlowmapA;
|
|
#endif
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
#ifndef LAYER2_STATIC
|
|
layer.distort = true;
|
|
#ifdef LAYER2_FLOWMAP
|
|
layer.use_flowmap = true;
|
|
layer.flowmap = _FlowmapB;
|
|
layer.flowmapSampler = sampler_FlowmapB;
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
return layer;
|
|
}
|
|
|
|
float4 GetCloudLayerColor(float3 dir, int index)
|
|
{
|
|
float2 cloud;
|
|
float3 position = dir * IntersectSphere(_LowestAltitude(index), dir.y, _PlanetaryRadius).y;
|
|
|
|
CloudLayerData layer = GetCloudLayer(index);
|
|
if (layer.distort)
|
|
{
|
|
float scrollDist = 2 * _Altitude(index); // max horizontal distance clouds can travel, arbitrary but looks good
|
|
|
|
float2 alpha = frac(_ScrollFactor(index) / scrollDist + float2(0.0, 0.5)) - 0.5;
|
|
float3 delta;
|
|
|
|
if (layer.use_flowmap)
|
|
{
|
|
float3 tangent = normalize(cross(dir, float3(0.0, 1.0, 0.0)));
|
|
float3 bitangent = cross(tangent, dir);
|
|
|
|
float3 windDir = RotationUp(dir, _ScrollDirection(index));
|
|
float2 flow = SAMPLE_TEXTURE2D_LOD(layer.flowmap, layer.flowmapSampler, GetLatLongCoords(windDir, _UpperHemisphere), 0).rg * 2.0 - 1.0;
|
|
delta = flow.x * tangent + flow.y * bitangent;
|
|
}
|
|
else
|
|
delta = float3(_ScrollDirection(index).x, 0.0f, _ScrollDirection(index).y);
|
|
|
|
float coverage1 = abs(2.0 * alpha.x), coverage2 = 1 - coverage1;
|
|
float2 cloud1 = SampleCloudMap(normalize(position + alpha.x * delta * scrollDist), index);
|
|
float2 cloud2 = SampleCloudMap(normalize(position + alpha.y * delta * scrollDist), index);
|
|
cloud = lerp(cloud1, cloud2, abs(2.0 * alpha.x));
|
|
}
|
|
else
|
|
cloud = SampleCloudMap(dir, index);
|
|
|
|
float3 lightColor = _SunLightColor(index);
|
|
float3 ambient = max(SampleSH9(_AmbientProbeBuffer, float3(0, -1, 0)), 0) * _AmbientDimmer(index);
|
|
|
|
#ifdef PHYSICALLY_BASED_SUN
|
|
float3 positionPS = position + float3(0,_PlanetaryRadius,0);
|
|
lightColor *= EvaluateSunColorAttenuation(positionPS, _SunDirection, true);
|
|
#endif
|
|
|
|
return float4(cloud.x * lightColor + ambient * cloud.y, cloud.y) * _Opacity;
|
|
}
|
|
|
|
float4 RenderClouds(float3 dir)
|
|
{
|
|
float4 clouds = 0;
|
|
|
|
if (dir.y >= 0 || !_UpperHemisphere)
|
|
{
|
|
#ifndef LAYER1_OFF
|
|
clouds = GetCloudLayerColor(dir, 0);
|
|
#endif
|
|
|
|
#ifndef LAYER2_OFF
|
|
float4 cloudsB = GetCloudLayerColor(dir, 1);
|
|
clouds += cloudsB * (1-clouds.a);
|
|
#endif
|
|
}
|
|
return clouds;
|
|
}
|
|
|
|
// For shadows
|
|
float4 RenderClouds(float2 positionCS)
|
|
{
|
|
return RenderClouds(-GetSkyViewDirWS(positionCS));
|
|
}
|
|
|
|
#endif // __CLOUDLAYER_COMMON_H__
|