[Add] Synaptic AI Pro
https://assetstore.unity.com/packages/tools/generative-ai/synaptic-ai-pro-natural-language-control-for-unity-336030
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
// Synaptic AI Pro - Cloud Noise Generator
|
||||
// Generates 3D Worley and Perlin noise for volumetric clouds
|
||||
|
||||
#pragma kernel GenerateWorley3D
|
||||
#pragma kernel GeneratePerlin3D
|
||||
#pragma kernel CombineNoise
|
||||
|
||||
RWTexture3D<float4> _Result;
|
||||
RWTexture3D<float> _WorkBuffer;
|
||||
|
||||
uint _Resolution;
|
||||
uint _Seed;
|
||||
float _Frequency;
|
||||
int _Octaves;
|
||||
float _Persistence;
|
||||
float _Lacunarity;
|
||||
|
||||
// ============ Random Functions ============
|
||||
|
||||
float3 Hash3(float3 p)
|
||||
{
|
||||
p = float3(
|
||||
dot(p, float3(127.1, 311.7, 74.7)),
|
||||
dot(p, float3(269.5, 183.3, 246.1)),
|
||||
dot(p, float3(113.5, 271.9, 124.6))
|
||||
);
|
||||
return frac(sin(p) * 43758.5453);
|
||||
}
|
||||
|
||||
float Hash1(float3 p)
|
||||
{
|
||||
return frac(sin(dot(p, float3(127.1, 311.7, 74.7))) * 43758.5453);
|
||||
}
|
||||
|
||||
// ============ Worley Noise ============
|
||||
|
||||
float Worley(float3 p)
|
||||
{
|
||||
float3 id = floor(p);
|
||||
float3 fp = frac(p);
|
||||
|
||||
float minDist = 1.0;
|
||||
|
||||
for (int z = -1; z <= 1; z++)
|
||||
{
|
||||
for (int y = -1; y <= 1; y++)
|
||||
{
|
||||
for (int x = -1; x <= 1; x++)
|
||||
{
|
||||
float3 offset = float3(x, y, z);
|
||||
float3 cellId = id + offset;
|
||||
float3 cellPoint = Hash3(cellId);
|
||||
float3 diff = offset + cellPoint - fp;
|
||||
float dist = length(diff);
|
||||
minDist = min(minDist, dist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return minDist;
|
||||
}
|
||||
|
||||
float WorleyFBM(float3 p, int octaves, float persistence, float lacunarity)
|
||||
{
|
||||
float value = 0.0;
|
||||
float amplitude = 0.5;
|
||||
float frequency = 1.0;
|
||||
float maxValue = 0.0;
|
||||
|
||||
for (int i = 0; i < octaves; i++)
|
||||
{
|
||||
value += Worley(p * frequency) * amplitude;
|
||||
maxValue += amplitude;
|
||||
amplitude *= persistence;
|
||||
frequency *= lacunarity;
|
||||
}
|
||||
|
||||
return value / maxValue;
|
||||
}
|
||||
|
||||
// ============ Perlin Noise ============
|
||||
|
||||
float3 Fade(float3 t)
|
||||
{
|
||||
return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
|
||||
}
|
||||
|
||||
float Grad(float hash, float3 p)
|
||||
{
|
||||
int h = int(hash * 16.0) & 15;
|
||||
float u = h < 8 ? p.x : p.y;
|
||||
float v = h < 4 ? p.y : (h == 12 || h == 14 ? p.x : p.z);
|
||||
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
|
||||
}
|
||||
|
||||
float Perlin(float3 p)
|
||||
{
|
||||
float3 Pi = floor(p);
|
||||
float3 Pf = frac(p);
|
||||
float3 fade = Fade(Pf);
|
||||
|
||||
float n000 = Grad(Hash1(Pi + float3(0, 0, 0)), Pf - float3(0, 0, 0));
|
||||
float n100 = Grad(Hash1(Pi + float3(1, 0, 0)), Pf - float3(1, 0, 0));
|
||||
float n010 = Grad(Hash1(Pi + float3(0, 1, 0)), Pf - float3(0, 1, 0));
|
||||
float n110 = Grad(Hash1(Pi + float3(1, 1, 0)), Pf - float3(1, 1, 0));
|
||||
float n001 = Grad(Hash1(Pi + float3(0, 0, 1)), Pf - float3(0, 0, 1));
|
||||
float n101 = Grad(Hash1(Pi + float3(1, 0, 1)), Pf - float3(1, 0, 1));
|
||||
float n011 = Grad(Hash1(Pi + float3(0, 1, 1)), Pf - float3(0, 1, 1));
|
||||
float n111 = Grad(Hash1(Pi + float3(1, 1, 1)), Pf - float3(1, 1, 1));
|
||||
|
||||
float n00 = lerp(n000, n100, fade.x);
|
||||
float n01 = lerp(n001, n101, fade.x);
|
||||
float n10 = lerp(n010, n110, fade.x);
|
||||
float n11 = lerp(n011, n111, fade.x);
|
||||
|
||||
float n0 = lerp(n00, n10, fade.y);
|
||||
float n1 = lerp(n01, n11, fade.y);
|
||||
|
||||
return lerp(n0, n1, fade.z) * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
float PerlinFBM(float3 p, int octaves, float persistence, float lacunarity)
|
||||
{
|
||||
float value = 0.0;
|
||||
float amplitude = 0.5;
|
||||
float frequency = 1.0;
|
||||
float maxValue = 0.0;
|
||||
|
||||
for (int i = 0; i < octaves; i++)
|
||||
{
|
||||
value += Perlin(p * frequency) * amplitude;
|
||||
maxValue += amplitude;
|
||||
amplitude *= persistence;
|
||||
frequency *= lacunarity;
|
||||
}
|
||||
|
||||
return value / maxValue;
|
||||
}
|
||||
|
||||
// ============ Kernels ============
|
||||
|
||||
[numthreads(8, 8, 8)]
|
||||
void GenerateWorley3D(uint3 id : SV_DispatchThreadID)
|
||||
{
|
||||
if (any(id >= _Resolution))
|
||||
return;
|
||||
|
||||
float3 uvw = float3(id) / float(_Resolution);
|
||||
float3 p = uvw * _Frequency;
|
||||
|
||||
// Generate tileable Worley noise
|
||||
float worley1 = WorleyFBM(p, _Octaves, _Persistence, _Lacunarity);
|
||||
float worley2 = WorleyFBM(p * 2.0, _Octaves, _Persistence, _Lacunarity);
|
||||
float worley3 = WorleyFBM(p * 4.0, _Octaves, _Persistence, _Lacunarity);
|
||||
|
||||
// Invert Worley for cloud-like shapes
|
||||
worley1 = 1.0 - worley1;
|
||||
worley2 = 1.0 - worley2;
|
||||
worley3 = 1.0 - worley3;
|
||||
|
||||
// Pack into RGBA
|
||||
_Result[id] = float4(worley1, worley2, worley3, 1.0);
|
||||
}
|
||||
|
||||
[numthreads(8, 8, 8)]
|
||||
void GeneratePerlin3D(uint3 id : SV_DispatchThreadID)
|
||||
{
|
||||
if (any(id >= _Resolution))
|
||||
return;
|
||||
|
||||
float3 uvw = float3(id) / float(_Resolution);
|
||||
float3 p = uvw * _Frequency;
|
||||
|
||||
float perlin = PerlinFBM(p, _Octaves, _Persistence, _Lacunarity);
|
||||
|
||||
_WorkBuffer[id] = perlin;
|
||||
}
|
||||
|
||||
[numthreads(8, 8, 8)]
|
||||
void CombineNoise(uint3 id : SV_DispatchThreadID)
|
||||
{
|
||||
if (any(id >= _Resolution))
|
||||
return;
|
||||
|
||||
float3 uvw = float3(id) / float(_Resolution);
|
||||
float3 p = uvw * _Frequency;
|
||||
|
||||
// Worley for cloud shapes (multiple octaves)
|
||||
float worley1 = 1.0 - WorleyFBM(p, 3, 0.5, 2.0);
|
||||
float worley2 = 1.0 - WorleyFBM(p * 2.0, 3, 0.5, 2.0);
|
||||
float worley3 = 1.0 - WorleyFBM(p * 4.0, 3, 0.5, 2.0);
|
||||
|
||||
// Perlin for low frequency base shape
|
||||
float perlin = PerlinFBM(p, 4, 0.5, 2.0);
|
||||
|
||||
// Combine: Perlin-Worley for base shape
|
||||
float baseShape = saturate(perlin * 0.6 + worley1 * 0.4);
|
||||
|
||||
// Detail layers
|
||||
float detail1 = worley2;
|
||||
float detail2 = worley3;
|
||||
|
||||
// Erosion (subtract detail from base)
|
||||
float erosion = saturate(baseShape - detail1 * 0.3 - detail2 * 0.1);
|
||||
|
||||
// R: Base shape with erosion
|
||||
// G: Low frequency detail
|
||||
// B: High frequency detail
|
||||
// A: Perlin base (for animation blending)
|
||||
_Result[id] = float4(erosion, detail1, detail2, perlin);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 81d34d35ae5b84546a0a971124c61744
|
||||
ComputeShaderImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 336030
|
||||
packageName: Synaptic AI Pro - Natural Language Control for Unity
|
||||
packageVersion: 1.2.23
|
||||
assetPath: Assets/Synaptic AI Pro/Shaders/Sky/CloudNoise.compute
|
||||
uploadId: 920982
|
||||
@@ -0,0 +1,570 @@
|
||||
Shader "Synaptic/SkyPro"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
[Header(Atmosphere)]
|
||||
_AtmosphereColor ("Atmosphere Color", Color) = (0.4, 0.7, 1.0, 1)
|
||||
_HorizonColor ("Horizon Color", Color) = (0.8, 0.85, 0.9, 1)
|
||||
_GroundColor ("Ground Color", Color) = (0.3, 0.3, 0.35, 1)
|
||||
_AtmosphereThickness ("Atmosphere Thickness", Range(0, 5)) = 1
|
||||
_MieScattering ("Mie Scattering", Range(0, 1)) = 0.1
|
||||
_RayleighScattering ("Rayleigh Scattering", Range(0, 2)) = 1
|
||||
|
||||
[Header(Sun)]
|
||||
_SunColor ("Sun Color", Color) = (1, 0.95, 0.8, 1)
|
||||
_SunSize ("Sun Size", Range(0.001, 0.1)) = 0.02
|
||||
_SunIntensity ("Sun Intensity", Range(0, 10)) = 5
|
||||
_SunGlowSize ("Sun Glow Size", Range(0, 1)) = 0.3
|
||||
_SunGlowIntensity ("Sun Glow Intensity", Range(0, 5)) = 1
|
||||
|
||||
[Header(Clouds Volumetric)]
|
||||
[Toggle(_CLOUDS_ON)] _CloudsEnabled ("Enable Clouds", Float) = 1
|
||||
_CloudColor ("Cloud Color", Color) = (1, 1, 1, 1)
|
||||
_CloudShadowColor ("Cloud Shadow Color", Color) = (0.6, 0.65, 0.7, 1)
|
||||
_CloudDensity ("Cloud Density", Range(0, 2)) = 1
|
||||
_CloudCoverage ("Cloud Coverage", Range(0, 1)) = 0.5
|
||||
_CloudHeight ("Cloud Height", Float) = 2000
|
||||
_CloudThickness ("Cloud Thickness", Float) = 500
|
||||
_CloudSpeed ("Cloud Speed", Float) = 0.01
|
||||
_CloudDirection ("Cloud Direction", Vector) = (1, 0, 0, 0)
|
||||
|
||||
[Header(Cloud Detail)]
|
||||
_CloudScale ("Cloud Scale", Float) = 0.0001
|
||||
_CloudDetailScale ("Detail Scale", Float) = 0.0005
|
||||
_CloudDetailStrength ("Detail Strength", Range(0, 1)) = 0.5
|
||||
_CloudEdgeSoftness ("Edge Softness", Range(0, 1)) = 0.3
|
||||
|
||||
[Header(Cloud Lighting)]
|
||||
_CloudAmbient ("Cloud Ambient", Range(0, 1)) = 0.3
|
||||
_CloudSunPenetration ("Sun Penetration", Range(0, 1)) = 0.3
|
||||
_CloudSilverLining ("Silver Lining", Range(0, 1)) = 0.5
|
||||
_CloudSilverLiningSpread ("Silver Spread", Range(0.5, 5)) = 2
|
||||
|
||||
[Header(Stars)]
|
||||
[Toggle(_STARS_ON)] _StarsEnabled ("Enable Stars", Float) = 1
|
||||
_StarsDensity ("Stars Density", Range(0, 1)) = 0.5
|
||||
_StarsIntensity ("Stars Intensity", Range(0, 3)) = 1
|
||||
_StarsTwinkleSpeed ("Twinkle Speed", Float) = 2
|
||||
|
||||
[Header(Night Sky)]
|
||||
_NightColor ("Night Sky Color", Color) = (0.02, 0.02, 0.05, 1)
|
||||
_NightTransition ("Night Transition", Range(0, 1)) = 0.3
|
||||
|
||||
[Header(Performance)]
|
||||
_CloudSteps ("Cloud Ray Steps", Range(4, 64)) = 16
|
||||
_CloudLightSteps ("Light Ray Steps", Range(2, 16)) = 4
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
PackageRequirements { "com.unity.render-pipelines.universal" }
|
||||
Tags
|
||||
{
|
||||
"RenderType" = "Background"
|
||||
"Queue" = "Background"
|
||||
"PreviewType" = "Skybox"
|
||||
"RenderPipeline" = "UniversalPipeline"
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "SkyPro"
|
||||
|
||||
Cull Off
|
||||
ZWrite Off
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 4.5
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#pragma shader_feature_local _CLOUDS_ON
|
||||
#pragma shader_feature_local _STARS_ON
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
// Atmosphere
|
||||
float4 _AtmosphereColor;
|
||||
float4 _HorizonColor;
|
||||
float4 _GroundColor;
|
||||
float _AtmosphereThickness;
|
||||
float _MieScattering;
|
||||
float _RayleighScattering;
|
||||
|
||||
// Sun
|
||||
float4 _SunColor;
|
||||
float _SunSize;
|
||||
float _SunIntensity;
|
||||
float _SunGlowSize;
|
||||
float _SunGlowIntensity;
|
||||
|
||||
// Clouds
|
||||
float4 _CloudColor;
|
||||
float4 _CloudShadowColor;
|
||||
float _CloudDensity;
|
||||
float _CloudCoverage;
|
||||
float _CloudHeight;
|
||||
float _CloudThickness;
|
||||
float _CloudSpeed;
|
||||
float4 _CloudDirection;
|
||||
float _CloudScale;
|
||||
float _CloudDetailScale;
|
||||
float _CloudDetailStrength;
|
||||
float _CloudEdgeSoftness;
|
||||
float _CloudAmbient;
|
||||
float _CloudSunPenetration;
|
||||
float _CloudSilverLining;
|
||||
float _CloudSilverLiningSpread;
|
||||
|
||||
// Stars
|
||||
float _StarsDensity;
|
||||
float _StarsIntensity;
|
||||
float _StarsTwinkleSpeed;
|
||||
|
||||
// Night
|
||||
float4 _NightColor;
|
||||
float _NightTransition;
|
||||
|
||||
// Performance
|
||||
float _CloudSteps;
|
||||
float _CloudLightSteps;
|
||||
CBUFFER_END
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float3 viewDir : TEXCOORD0;
|
||||
float3 worldPos : TEXCOORD1;
|
||||
};
|
||||
|
||||
// Noise functions
|
||||
float Hash(float3 p)
|
||||
{
|
||||
p = frac(p * 0.3183099 + 0.1);
|
||||
p *= 17.0;
|
||||
return frac(p.x * p.y * p.z * (p.x + p.y + p.z));
|
||||
}
|
||||
|
||||
float Noise3D(float3 p)
|
||||
{
|
||||
float3 i = floor(p);
|
||||
float3 f = frac(p);
|
||||
f = f * f * (3.0 - 2.0 * f);
|
||||
|
||||
return lerp(
|
||||
lerp(lerp(Hash(i + float3(0, 0, 0)), Hash(i + float3(1, 0, 0)), f.x),
|
||||
lerp(Hash(i + float3(0, 1, 0)), Hash(i + float3(1, 1, 0)), f.x), f.y),
|
||||
lerp(lerp(Hash(i + float3(0, 0, 1)), Hash(i + float3(1, 0, 1)), f.x),
|
||||
lerp(Hash(i + float3(0, 1, 1)), Hash(i + float3(1, 1, 1)), f.x), f.y), f.z
|
||||
);
|
||||
}
|
||||
|
||||
float FBM(float3 p, int octaves)
|
||||
{
|
||||
float value = 0;
|
||||
float amplitude = 0.5;
|
||||
float frequency = 1;
|
||||
|
||||
for (int i = 0; i < octaves; i++)
|
||||
{
|
||||
value += amplitude * Noise3D(p * frequency);
|
||||
frequency *= 2;
|
||||
amplitude *= 0.5;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// Cloud density at a point
|
||||
float CloudDensity(float3 p)
|
||||
{
|
||||
float time = _Time.y * _CloudSpeed;
|
||||
float3 windOffset = _CloudDirection.xyz * time;
|
||||
|
||||
// Main cloud shape
|
||||
float mainNoise = FBM((p + windOffset) * _CloudScale, 4);
|
||||
|
||||
// Detail noise
|
||||
float detailNoise = FBM((p + windOffset * 2) * _CloudDetailScale, 3);
|
||||
mainNoise = lerp(mainNoise, mainNoise * detailNoise, _CloudDetailStrength);
|
||||
|
||||
// Coverage threshold
|
||||
float density = mainNoise - (1 - _CloudCoverage);
|
||||
density = saturate(density / _CloudEdgeSoftness);
|
||||
|
||||
return density * _CloudDensity;
|
||||
}
|
||||
|
||||
// Ray-sphere intersection
|
||||
float2 RaySphereIntersect(float3 rayOrigin, float3 rayDir, float3 sphereCenter, float sphereRadius)
|
||||
{
|
||||
float3 oc = rayOrigin - sphereCenter;
|
||||
float b = dot(oc, rayDir);
|
||||
float c = dot(oc, oc) - sphereRadius * sphereRadius;
|
||||
float h = b * b - c;
|
||||
|
||||
if (h < 0) return float2(-1, -1);
|
||||
|
||||
h = sqrt(h);
|
||||
return float2(-b - h, -b + h);
|
||||
}
|
||||
|
||||
// Rayleigh phase function
|
||||
float RayleighPhase(float cosTheta)
|
||||
{
|
||||
return 0.75 * (1.0 + cosTheta * cosTheta);
|
||||
}
|
||||
|
||||
// Mie phase function (Henyey-Greenstein)
|
||||
float MiePhase(float cosTheta, float g)
|
||||
{
|
||||
float g2 = g * g;
|
||||
return (1 - g2) / (4 * PI * pow(1 + g2 - 2 * g * cosTheta, 1.5));
|
||||
}
|
||||
|
||||
Varyings vert(Attributes IN)
|
||||
{
|
||||
Varyings OUT;
|
||||
OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz);
|
||||
OUT.viewDir = normalize(TransformObjectToWorld(IN.positionOS.xyz));
|
||||
OUT.worldPos = TransformObjectToWorld(IN.positionOS.xyz);
|
||||
return OUT;
|
||||
}
|
||||
|
||||
float4 frag(Varyings IN) : SV_Target
|
||||
{
|
||||
float3 viewDir = normalize(IN.viewDir);
|
||||
|
||||
// Get sun direction
|
||||
Light mainLight = GetMainLight();
|
||||
float3 sunDir = mainLight.direction;
|
||||
float sunDot = dot(viewDir, sunDir);
|
||||
|
||||
// Day/night factor based on sun height
|
||||
float sunHeight = sunDir.y;
|
||||
float dayFactor = saturate((sunHeight + _NightTransition) / (2 * _NightTransition));
|
||||
|
||||
// ==================== ATMOSPHERE ====================
|
||||
|
||||
// Vertical gradient
|
||||
float upDot = viewDir.y;
|
||||
float horizonFactor = 1 - abs(upDot);
|
||||
horizonFactor = pow(horizonFactor, 3);
|
||||
|
||||
// Rayleigh scattering (blue sky)
|
||||
float rayleigh = RayleighPhase(sunDot) * _RayleighScattering;
|
||||
|
||||
// Mie scattering (sun glow)
|
||||
float mie = MiePhase(sunDot, 0.76) * _MieScattering;
|
||||
|
||||
// Sky color
|
||||
float3 skyColor = _AtmosphereColor.rgb * _AtmosphereThickness;
|
||||
skyColor = lerp(skyColor, _HorizonColor.rgb, horizonFactor);
|
||||
|
||||
// Apply scattering
|
||||
float3 scatterColor = skyColor * rayleigh + _SunColor.rgb * mie;
|
||||
|
||||
// Ground color (below horizon)
|
||||
float groundMask = saturate(-upDot * 10);
|
||||
scatterColor = lerp(scatterColor, _GroundColor.rgb, groundMask);
|
||||
|
||||
// ==================== SUN ====================
|
||||
|
||||
float sunMask = saturate((sunDot - (1 - _SunSize)) / _SunSize);
|
||||
sunMask = pow(sunMask, 0.5);
|
||||
|
||||
// Sun glow
|
||||
float sunGlow = pow(saturate(sunDot), 8 / _SunGlowSize) * _SunGlowIntensity;
|
||||
|
||||
float3 sunColor = _SunColor.rgb * _SunIntensity * (sunMask + sunGlow);
|
||||
|
||||
// ==================== STARS ====================
|
||||
|
||||
float3 starsColor = float3(0, 0, 0);
|
||||
#if defined(_STARS_ON)
|
||||
if (dayFactor < 0.8)
|
||||
{
|
||||
// Star field
|
||||
float3 starDir = viewDir * 1000;
|
||||
float starNoise = Hash(floor(starDir));
|
||||
|
||||
if (starNoise > 1 - _StarsDensity * 0.01)
|
||||
{
|
||||
float twinkle = sin(_Time.y * _StarsTwinkleSpeed + starNoise * 100) * 0.3 + 0.7;
|
||||
float starBrightness = pow(starNoise, 20) * _StarsIntensity * twinkle;
|
||||
starsColor = float3(1, 1, 1) * starBrightness * (1 - dayFactor);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// ==================== CLOUDS ====================
|
||||
|
||||
float3 cloudColor = float3(0, 0, 0);
|
||||
float cloudAlpha = 0;
|
||||
|
||||
#if defined(_CLOUDS_ON)
|
||||
// Ray march through cloud layer
|
||||
float3 rayOrigin = float3(0, 0, 0);
|
||||
float3 rayDir = viewDir;
|
||||
|
||||
// Cloud layer bounds
|
||||
float cloudBottom = _CloudHeight;
|
||||
float cloudTop = _CloudHeight + _CloudThickness;
|
||||
|
||||
// Calculate entry/exit points
|
||||
float2 tBottom = RaySphereIntersect(rayOrigin, rayDir, float3(0, -6371000, 0), 6371000 + cloudBottom);
|
||||
float2 tTop = RaySphereIntersect(rayOrigin, rayDir, float3(0, -6371000, 0), 6371000 + cloudTop);
|
||||
|
||||
float tStart = max(tBottom.x, 0);
|
||||
float tEnd = tTop.x > 0 ? tTop.x : tTop.y;
|
||||
|
||||
if (tEnd > tStart && viewDir.y > -0.1)
|
||||
{
|
||||
float stepSize = (tEnd - tStart) / _CloudSteps;
|
||||
float transmittance = 1;
|
||||
float3 lightEnergy = float3(0, 0, 0);
|
||||
|
||||
for (int i = 0; i < (int)_CloudSteps; i++)
|
||||
{
|
||||
float t = tStart + (i + 0.5) * stepSize;
|
||||
float3 samplePos = rayOrigin + rayDir * t;
|
||||
|
||||
float density = CloudDensity(samplePos);
|
||||
|
||||
if (density > 0.001)
|
||||
{
|
||||
// Light march toward sun
|
||||
float lightTransmittance = 1;
|
||||
float lightStepSize = _CloudThickness / _CloudLightSteps;
|
||||
|
||||
for (int j = 0; j < (int)_CloudLightSteps; j++)
|
||||
{
|
||||
float3 lightSamplePos = samplePos + sunDir * (j + 0.5) * lightStepSize;
|
||||
float lightDensity = CloudDensity(lightSamplePos);
|
||||
lightTransmittance *= exp(-lightDensity * lightStepSize * 0.01);
|
||||
}
|
||||
|
||||
// Beer's law
|
||||
float extinctionCoeff = density * stepSize * 0.01;
|
||||
float sampleTransmittance = exp(-extinctionCoeff);
|
||||
|
||||
// Lighting
|
||||
float3 ambient = _CloudColor.rgb * _CloudAmbient;
|
||||
float3 directLight = _SunColor.rgb * lightTransmittance * _CloudSunPenetration;
|
||||
|
||||
// Silver lining (forward scattering)
|
||||
float silverLining = pow(saturate(sunDot), _CloudSilverLiningSpread) * _CloudSilverLining;
|
||||
directLight += _SunColor.rgb * silverLining * lightTransmittance;
|
||||
|
||||
// Shadow color blend
|
||||
float3 cloudSample = lerp(_CloudShadowColor.rgb, _CloudColor.rgb, lightTransmittance);
|
||||
cloudSample *= (ambient + directLight);
|
||||
|
||||
lightEnergy += cloudSample * transmittance * (1 - sampleTransmittance);
|
||||
transmittance *= sampleTransmittance;
|
||||
|
||||
if (transmittance < 0.01) break;
|
||||
}
|
||||
}
|
||||
|
||||
cloudColor = lightEnergy;
|
||||
cloudAlpha = 1 - transmittance;
|
||||
}
|
||||
#endif
|
||||
|
||||
// ==================== COMBINE ====================
|
||||
|
||||
// Night sky
|
||||
float3 nightSky = lerp(_NightColor.rgb, scatterColor, dayFactor);
|
||||
nightSky += starsColor;
|
||||
|
||||
// Add sun
|
||||
float3 finalColor = nightSky + sunColor * dayFactor;
|
||||
|
||||
// Blend clouds
|
||||
finalColor = lerp(finalColor, cloudColor, cloudAlpha);
|
||||
|
||||
// Tone mapping (simple Reinhard)
|
||||
finalColor = finalColor / (finalColor + 1);
|
||||
|
||||
return float4(finalColor, 1);
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== Built-in Pipeline SubShader ====================
|
||||
SubShader
|
||||
{
|
||||
Tags
|
||||
{
|
||||
"RenderType" = "Background"
|
||||
"Queue" = "Background"
|
||||
"PreviewType" = "Skybox"
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "SkyProBuiltIn"
|
||||
Cull Off
|
||||
ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma target 3.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#pragma shader_feature_local _CLOUDS_ON
|
||||
#pragma shader_feature_local _STARS_ON
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
#include "Lighting.cginc"
|
||||
|
||||
float4 _AtmosphereColor;
|
||||
float4 _HorizonColor;
|
||||
float4 _GroundColor;
|
||||
float _AtmosphereThickness;
|
||||
float4 _SunColor;
|
||||
float _SunSize;
|
||||
float _SunIntensity;
|
||||
float _SunGlowSize;
|
||||
float _SunGlowIntensity;
|
||||
float4 _NightColor;
|
||||
float _NightTransition;
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float3 viewDir : TEXCOORD0;
|
||||
};
|
||||
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.viewDir = normalize(mul((float3x3)unity_ObjectToWorld, v.vertex.xyz));
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 frag(v2f i) : SV_Target
|
||||
{
|
||||
float3 viewDir = normalize(i.viewDir);
|
||||
float3 sunDir = normalize(_WorldSpaceLightPos0.xyz);
|
||||
float sunDot = dot(viewDir, sunDir);
|
||||
float sunHeight = sunDir.y;
|
||||
float dayFactor = saturate((sunHeight + _NightTransition) / (2 * _NightTransition));
|
||||
|
||||
float upDot = viewDir.y;
|
||||
float horizonFactor = 1 - abs(upDot);
|
||||
horizonFactor = pow(horizonFactor, 3);
|
||||
|
||||
float3 skyColor = _AtmosphereColor.rgb * _AtmosphereThickness;
|
||||
skyColor = lerp(skyColor, _HorizonColor.rgb, horizonFactor);
|
||||
|
||||
float groundMask = saturate(-upDot * 10);
|
||||
skyColor = lerp(skyColor, _GroundColor.rgb, groundMask);
|
||||
|
||||
float sunMask = saturate((sunDot - (1 - _SunSize)) / _SunSize);
|
||||
sunMask = pow(sunMask, 0.5);
|
||||
float sunGlow = pow(saturate(sunDot), 8 / _SunGlowSize) * _SunGlowIntensity;
|
||||
float3 sunColor = _SunColor.rgb * _SunIntensity * (sunMask + sunGlow);
|
||||
|
||||
float3 nightSky = lerp(_NightColor.rgb, skyColor, dayFactor);
|
||||
float3 finalColor = nightSky + sunColor * dayFactor;
|
||||
finalColor = finalColor / (finalColor + 1);
|
||||
|
||||
return float4(finalColor, 1);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== HDRP SubShader ====================
|
||||
SubShader
|
||||
{
|
||||
PackageRequirements { "com.unity.render-pipelines.high-definition" }
|
||||
Tags
|
||||
{
|
||||
"RenderType" = "Background"
|
||||
"Queue" = "Background"
|
||||
"PreviewType" = "Skybox"
|
||||
"RenderPipeline" = "HDRenderPipeline"
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "SkyProHDRP"
|
||||
Cull Off
|
||||
ZWrite Off
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 4.5
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _AtmosphereColor;
|
||||
float4 _HorizonColor;
|
||||
float4 _GroundColor;
|
||||
float _AtmosphereThickness;
|
||||
float4 _SunColor;
|
||||
float _SunSize;
|
||||
float _SunIntensity;
|
||||
float _SunGlowSize;
|
||||
float _SunGlowIntensity;
|
||||
float4 _NightColor;
|
||||
float _NightTransition;
|
||||
CBUFFER_END
|
||||
|
||||
struct Attributes { float4 positionOS : POSITION; };
|
||||
struct Varyings { float4 positionCS : SV_POSITION; float3 viewDir : TEXCOORD0; };
|
||||
|
||||
Varyings vert(Attributes IN)
|
||||
{
|
||||
Varyings OUT;
|
||||
OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz);
|
||||
OUT.viewDir = normalize(TransformObjectToWorld(IN.positionOS.xyz));
|
||||
return OUT;
|
||||
}
|
||||
|
||||
float4 frag(Varyings IN) : SV_Target
|
||||
{
|
||||
float3 viewDir = normalize(IN.viewDir);
|
||||
float3 sunDir = float3(0.3, 0.8, 0.5);
|
||||
float sunDot = dot(viewDir, sunDir);
|
||||
float dayFactor = saturate((sunDir.y + _NightTransition) / (2 * _NightTransition));
|
||||
|
||||
float upDot = viewDir.y;
|
||||
float horizonFactor = pow(1 - abs(upDot), 3);
|
||||
|
||||
float3 skyColor = lerp(_AtmosphereColor.rgb * _AtmosphereThickness, _HorizonColor.rgb, horizonFactor);
|
||||
skyColor = lerp(skyColor, _GroundColor.rgb, saturate(-upDot * 10));
|
||||
|
||||
float sunMask = pow(saturate((sunDot - (1 - _SunSize)) / _SunSize), 0.5);
|
||||
float sunGlow = pow(saturate(sunDot), 8 / _SunGlowSize) * _SunGlowIntensity;
|
||||
float3 sunColor = _SunColor.rgb * _SunIntensity * (sunMask + sunGlow);
|
||||
|
||||
float3 finalColor = lerp(_NightColor.rgb, skyColor, dayFactor) + sunColor * dayFactor;
|
||||
return float4(finalColor / (finalColor + 1), 1);
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
FallBack Off
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a97609946080146e6878c24356ab4b20
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 336030
|
||||
packageName: Synaptic AI Pro - Natural Language Control for Unity
|
||||
packageVersion: 1.2.23
|
||||
assetPath: Assets/Synaptic AI Pro/Shaders/Sky/SynapticSkyPro.shader
|
||||
uploadId: 920982
|
||||
Reference in New Issue
Block a user