[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,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bff611ec25fcf40999dfd4044f540557
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,216 @@
|
||||
Shader "Synaptic/Caustics"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
[Header(Caustics Settings)]
|
||||
_CausticsTex ("Caustics Texture", 2D) = "white" {}
|
||||
_CausticsColor ("Caustics Color", Color) = (1, 1, 1, 1)
|
||||
_CausticsIntensity ("Intensity", Range(0, 3)) = 1.0
|
||||
|
||||
[Header(Animation)]
|
||||
_Speed1 ("Layer 1 Speed", Vector) = (0.1, 0.1, 0, 0)
|
||||
_Speed2 ("Layer 2 Speed", Vector) = (-0.07, 0.05, 0, 0)
|
||||
_Scale1 ("Layer 1 Scale", Float) = 1.0
|
||||
_Scale2 ("Layer 2 Scale", Float) = 1.2
|
||||
|
||||
[Header(Depth Fade)]
|
||||
_DepthFadeStart ("Depth Fade Start", Float) = 0.0
|
||||
_DepthFadeEnd ("Depth Fade End", Float) = 10.0
|
||||
|
||||
[Header(Projection)]
|
||||
_ProjectionHeight ("Projection Height", Float) = 5.0
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
PackageRequirements { "com.unity.render-pipelines.universal" }
|
||||
Tags
|
||||
{
|
||||
"RenderType" = "Transparent"
|
||||
"Queue" = "Transparent+100"
|
||||
"RenderPipeline" = "UniversalPipeline"
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "CausticsURP"
|
||||
|
||||
Blend One One
|
||||
ZWrite Off
|
||||
Cull Back
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile_fog
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 worldPos : TEXCOORD1;
|
||||
float4 screenPos : TEXCOORD2;
|
||||
float fogFactor : TEXCOORD3;
|
||||
};
|
||||
|
||||
TEXTURE2D(_CausticsTex);
|
||||
SAMPLER(sampler_CausticsTex);
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _CausticsTex_ST;
|
||||
float4 _CausticsColor;
|
||||
float _CausticsIntensity;
|
||||
float4 _Speed1;
|
||||
float4 _Speed2;
|
||||
float _Scale1;
|
||||
float _Scale2;
|
||||
float _DepthFadeStart;
|
||||
float _DepthFadeEnd;
|
||||
float _ProjectionHeight;
|
||||
CBUFFER_END
|
||||
|
||||
Varyings vert(Attributes IN)
|
||||
{
|
||||
Varyings OUT;
|
||||
OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz);
|
||||
OUT.worldPos = TransformObjectToWorld(IN.positionOS.xyz);
|
||||
OUT.uv = IN.uv;
|
||||
OUT.screenPos = ComputeScreenPos(OUT.positionCS);
|
||||
OUT.fogFactor = ComputeFogFactor(OUT.positionCS.z);
|
||||
return OUT;
|
||||
}
|
||||
|
||||
float4 frag(Varyings IN) : SV_Target
|
||||
{
|
||||
// World position based UV for seamless projection
|
||||
float2 worldUV = IN.worldPos.xz;
|
||||
|
||||
// Animated dual-layer caustics
|
||||
float time = _Time.y;
|
||||
float2 uv1 = worldUV * _Scale1 + time * _Speed1.xy;
|
||||
float2 uv2 = worldUV * _Scale2 + time * _Speed2.xy;
|
||||
|
||||
// Sample both layers
|
||||
float caustics1 = SAMPLE_TEXTURE2D(_CausticsTex, sampler_CausticsTex, uv1).r;
|
||||
float caustics2 = SAMPLE_TEXTURE2D(_CausticsTex, sampler_CausticsTex, uv2).r;
|
||||
|
||||
// Combine with min for more realistic caustics pattern
|
||||
float caustics = min(caustics1, caustics2);
|
||||
caustics = pow(caustics, 1.5) * 2.0; // Contrast boost
|
||||
|
||||
// Depth-based fade (if depth texture available)
|
||||
float2 screenUV = IN.screenPos.xy / IN.screenPos.w;
|
||||
float depth = SampleSceneDepth(screenUV);
|
||||
float linearDepth = LinearEyeDepth(depth, _ZBufferParams);
|
||||
float depthFade = saturate((linearDepth - _DepthFadeStart) / (_DepthFadeEnd - _DepthFadeStart));
|
||||
depthFade = 1.0 - depthFade;
|
||||
|
||||
// Final color
|
||||
float3 color = _CausticsColor.rgb * caustics * _CausticsIntensity * depthFade;
|
||||
|
||||
// Apply fog
|
||||
color = MixFog(color, IN.fogFactor);
|
||||
|
||||
return float4(color, caustics * _CausticsColor.a * depthFade);
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
// Built-in Render Pipeline fallback
|
||||
SubShader
|
||||
{
|
||||
Tags
|
||||
{
|
||||
"RenderType" = "Transparent"
|
||||
"Queue" = "Transparent+100"
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "CausticsBuiltIn"
|
||||
|
||||
Blend One One
|
||||
ZWrite Off
|
||||
Cull Back
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile_fog
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 worldPos : TEXCOORD1;
|
||||
UNITY_FOG_COORDS(2)
|
||||
};
|
||||
|
||||
sampler2D _CausticsTex;
|
||||
float4 _CausticsTex_ST;
|
||||
float4 _CausticsColor;
|
||||
float _CausticsIntensity;
|
||||
float4 _Speed1;
|
||||
float4 _Speed2;
|
||||
float _Scale1;
|
||||
float _Scale2;
|
||||
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
|
||||
o.uv = v.uv;
|
||||
UNITY_TRANSFER_FOG(o, o.pos);
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag(v2f i) : SV_Target
|
||||
{
|
||||
// World position based UV
|
||||
float2 worldUV = i.worldPos.xz;
|
||||
|
||||
// Animated dual-layer
|
||||
float time = _Time.y;
|
||||
float2 uv1 = worldUV * _Scale1 + time * _Speed1.xy;
|
||||
float2 uv2 = worldUV * _Scale2 + time * _Speed2.xy;
|
||||
|
||||
// Sample both layers
|
||||
float caustics1 = tex2D(_CausticsTex, uv1).r;
|
||||
float caustics2 = tex2D(_CausticsTex, uv2).r;
|
||||
|
||||
// Combine
|
||||
float caustics = min(caustics1, caustics2);
|
||||
caustics = pow(caustics, 1.5) * 2.0;
|
||||
|
||||
// Final color
|
||||
fixed3 color = _CausticsColor.rgb * caustics * _CausticsIntensity;
|
||||
|
||||
UNITY_APPLY_FOG(i.fogCoord, color);
|
||||
|
||||
return fixed4(color, caustics * _CausticsColor.a);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
FallBack "Transparent/Diffuse"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 29cc4c20a7f2644ae8f99c7d830a5579
|
||||
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/Caustics/SynapticCaustics.shader
|
||||
uploadId: 920982
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2013feabd49be423f954a46de25772f0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,848 @@
|
||||
Shader "Synaptic/EyePro"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
[Header(Iris)]
|
||||
_IrisColor ("Iris Color", Color) = (0.3, 0.5, 0.8, 1)
|
||||
_IrisTex ("Iris Texture", 2D) = "white" {}
|
||||
_IrisSize ("Iris Size", Range(0.1, 1)) = 0.5
|
||||
_IrisDepth ("Iris Depth (Parallax)", Range(0, 0.5)) = 0.15
|
||||
|
||||
[Header(Pupil)]
|
||||
_PupilColor ("Pupil Color", Color) = (0.05, 0.05, 0.1, 1)
|
||||
_PupilSize ("Pupil Size", Range(0.05, 0.5)) = 0.2
|
||||
_PupilDilation ("Pupil Dilation", Range(0.5, 2)) = 1.0
|
||||
_PupilSharpness ("Pupil Sharpness", Range(1, 20)) = 10
|
||||
|
||||
[Header(Sclera)]
|
||||
_ScleraColor ("Sclera Color", Color) = (1, 0.98, 0.95, 1)
|
||||
_ScleraTex ("Sclera Texture", 2D) = "white" {}
|
||||
|
||||
[Header(Cornea Reflection)]
|
||||
_ReflectionStrength ("Reflection Strength", Range(0, 2)) = 1.0
|
||||
_ReflectionSmoothness ("Reflection Smoothness", Range(0, 1)) = 0.95
|
||||
_Cubemap ("Environment Map", CUBE) = "" {}
|
||||
|
||||
[Header(Highlight)]
|
||||
_Highlight1Pos ("Highlight 1 Position", Vector) = (0.2, 0.3, 0, 0)
|
||||
_Highlight1Size ("Highlight 1 Size", Range(0, 0.3)) = 0.08
|
||||
_Highlight1Strength ("Highlight 1 Strength", Range(0, 2)) = 1.5
|
||||
|
||||
_Highlight2Pos ("Highlight 2 Position", Vector) = (-0.15, -0.2, 0, 0)
|
||||
_Highlight2Size ("Highlight 2 Size", Range(0, 0.2)) = 0.04
|
||||
_Highlight2Strength ("Highlight 2 Strength", Range(0, 2)) = 0.8
|
||||
|
||||
[Header(Limbal Ring)]
|
||||
_LimbalColor ("Limbal Ring Color", Color) = (0.1, 0.15, 0.2, 1)
|
||||
_LimbalWidth ("Limbal Ring Width", Range(0, 0.3)) = 0.1
|
||||
_LimbalStrength ("Limbal Ring Strength", Range(0, 2)) = 1.0
|
||||
|
||||
[Header(Caustics)]
|
||||
_CausticsStrength ("Caustics Strength", Range(0, 1)) = 0.3
|
||||
_CausticsScale ("Caustics Scale", Range(1, 20)) = 8
|
||||
_CausticsSpeed ("Caustics Speed", Range(0, 2)) = 0.5
|
||||
|
||||
[Header(Subsurface)]
|
||||
_SSSColor ("SSS Color", Color) = (1, 0.3, 0.2, 1)
|
||||
_SSSStrength ("SSS Strength", Range(0, 1)) = 0.2
|
||||
|
||||
[Header(Rim Light)]
|
||||
_RimColor ("Rim Color", Color) = (0.8, 0.9, 1, 1)
|
||||
_RimPower ("Rim Power", Range(0.5, 10)) = 4
|
||||
_RimStrength ("Rim Strength", Range(0, 2)) = 0.5
|
||||
|
||||
[Header(Shadow)]
|
||||
_ShadowColor ("Shadow Color", Color) = (0.3, 0.3, 0.4, 1)
|
||||
_ShadowThreshold ("Shadow Threshold", Range(0, 1)) = 0.5
|
||||
}
|
||||
|
||||
HLSLINCLUDE
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _IrisColor;
|
||||
float4 _IrisTex_ST;
|
||||
float _IrisSize;
|
||||
float _IrisDepth;
|
||||
|
||||
float4 _PupilColor;
|
||||
float _PupilSize;
|
||||
float _PupilDilation;
|
||||
float _PupilSharpness;
|
||||
|
||||
float4 _ScleraColor;
|
||||
|
||||
float _ReflectionStrength;
|
||||
float _ReflectionSmoothness;
|
||||
|
||||
float4 _Highlight1Pos;
|
||||
float _Highlight1Size;
|
||||
float _Highlight1Strength;
|
||||
|
||||
float4 _Highlight2Pos;
|
||||
float _Highlight2Size;
|
||||
float _Highlight2Strength;
|
||||
|
||||
float4 _LimbalColor;
|
||||
float _LimbalWidth;
|
||||
float _LimbalStrength;
|
||||
|
||||
float _CausticsStrength;
|
||||
float _CausticsScale;
|
||||
float _CausticsSpeed;
|
||||
|
||||
float4 _SSSColor;
|
||||
float _SSSStrength;
|
||||
|
||||
float4 _RimColor;
|
||||
float _RimPower;
|
||||
float _RimStrength;
|
||||
|
||||
float4 _ShadowColor;
|
||||
float _ShadowThreshold;
|
||||
CBUFFER_END
|
||||
|
||||
TEXTURE2D(_IrisTex);
|
||||
SAMPLER(sampler_IrisTex);
|
||||
TEXTURE2D(_ScleraTex);
|
||||
SAMPLER(sampler_ScleraTex);
|
||||
TEXTURECUBE(_Cubemap);
|
||||
SAMPLER(sampler_Cubemap);
|
||||
|
||||
// Simple noise for caustics
|
||||
float noise2D(float2 p)
|
||||
{
|
||||
return frac(sin(dot(p, float2(127.1, 311.7))) * 43758.5453);
|
||||
}
|
||||
|
||||
float smoothNoise(float2 p)
|
||||
{
|
||||
float2 i = floor(p);
|
||||
float2 f = frac(p);
|
||||
f = f * f * (3.0 - 2.0 * f);
|
||||
|
||||
float a = noise2D(i);
|
||||
float b = noise2D(i + float2(1, 0));
|
||||
float c = noise2D(i + float2(0, 1));
|
||||
float d = noise2D(i + float2(1, 1));
|
||||
|
||||
return lerp(lerp(a, b, f.x), lerp(c, d, f.x), f.y);
|
||||
}
|
||||
|
||||
float caustics(float2 uv, float time)
|
||||
{
|
||||
float c1 = smoothNoise(uv * _CausticsScale + time * 0.5);
|
||||
float c2 = smoothNoise(uv * _CausticsScale * 1.3 - time * 0.3);
|
||||
return pow(c1 * c2, 2) * 4.0;
|
||||
}
|
||||
|
||||
ENDHLSL
|
||||
|
||||
// ==================== URP SubShader ====================
|
||||
SubShader
|
||||
{
|
||||
PackageRequirements { "com.unity.render-pipelines.universal" }
|
||||
Tags
|
||||
{
|
||||
"RenderType" = "Opaque"
|
||||
"RenderPipeline" = "UniversalPipeline"
|
||||
"Queue" = "Geometry"
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "ForwardLit"
|
||||
Tags { "LightMode" = "UniversalForward" }
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE
|
||||
#pragma multi_compile_fog
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float3 normalOS : NORMAL;
|
||||
float4 tangentOS : TANGENT;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 positionWS : TEXCOORD1;
|
||||
float3 normalWS : TEXCOORD2;
|
||||
float3 tangentWS : TEXCOORD3;
|
||||
float3 bitangentWS : TEXCOORD4;
|
||||
float3 viewDirTS : TEXCOORD5;
|
||||
float fogFactor : TEXCOORD6;
|
||||
};
|
||||
|
||||
Varyings vert(Attributes input)
|
||||
{
|
||||
Varyings output;
|
||||
|
||||
VertexPositionInputs posInputs = GetVertexPositionInputs(input.positionOS.xyz);
|
||||
VertexNormalInputs normalInputs = GetVertexNormalInputs(input.normalOS, input.tangentOS);
|
||||
|
||||
output.positionCS = posInputs.positionCS;
|
||||
output.positionWS = posInputs.positionWS;
|
||||
output.normalWS = normalInputs.normalWS;
|
||||
output.tangentWS = normalInputs.tangentWS;
|
||||
output.bitangentWS = normalInputs.bitangentWS;
|
||||
output.uv = input.uv;
|
||||
|
||||
// Tangent space view direction for parallax
|
||||
float3 viewDirWS = GetWorldSpaceViewDir(posInputs.positionWS);
|
||||
float3x3 TBN = float3x3(normalInputs.tangentWS, normalInputs.bitangentWS, normalInputs.normalWS);
|
||||
output.viewDirTS = mul(TBN, viewDirWS);
|
||||
|
||||
output.fogFactor = ComputeFogFactor(posInputs.positionCS.z);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
half4 frag(Varyings input) : SV_Target
|
||||
{
|
||||
// Centered UV
|
||||
float2 centeredUV = input.uv - 0.5;
|
||||
float dist = length(centeredUV);
|
||||
|
||||
// Parallax offset for iris depth
|
||||
float3 viewDirTS = normalize(input.viewDirTS);
|
||||
float2 parallaxOffset = viewDirTS.xy / viewDirTS.z * _IrisDepth;
|
||||
float2 irisUV = centeredUV + parallaxOffset;
|
||||
float irisDist = length(irisUV);
|
||||
|
||||
// Pupil (with dilation)
|
||||
float pupilRadius = _PupilSize * _PupilDilation;
|
||||
float pupilMask = 1.0 - saturate(pow(irisDist / pupilRadius, _PupilSharpness));
|
||||
|
||||
// Iris mask
|
||||
float irisMask = saturate(1.0 - smoothstep(_IrisSize - 0.05, _IrisSize + 0.05, irisDist));
|
||||
irisMask *= (1.0 - pupilMask);
|
||||
|
||||
// Limbal ring
|
||||
float limbalDist = abs(irisDist - _IrisSize);
|
||||
float limbalMask = (1.0 - smoothstep(0, _LimbalWidth, limbalDist)) * irisMask;
|
||||
|
||||
// Sample iris texture
|
||||
float2 irisTexUV = (irisUV / _IrisSize) * 0.5 + 0.5;
|
||||
half4 irisTex = SAMPLE_TEXTURE2D(_IrisTex, sampler_IrisTex, irisTexUV);
|
||||
|
||||
// Sample sclera
|
||||
half4 scleraTex = SAMPLE_TEXTURE2D(_ScleraTex, sampler_ScleraTex, input.uv);
|
||||
|
||||
// Build eye color
|
||||
float3 eyeColor = _ScleraColor.rgb * scleraTex.rgb;
|
||||
eyeColor = lerp(eyeColor, _IrisColor.rgb * irisTex.rgb, irisMask);
|
||||
eyeColor = lerp(eyeColor, _LimbalColor.rgb, limbalMask * _LimbalStrength);
|
||||
eyeColor = lerp(eyeColor, _PupilColor.rgb, pupilMask);
|
||||
|
||||
// Caustics inside iris
|
||||
float time = _Time.y * _CausticsSpeed;
|
||||
float causticsValue = caustics(irisUV * 2.0, time);
|
||||
eyeColor += causticsValue * _CausticsStrength * irisMask * (1.0 - pupilMask);
|
||||
|
||||
// Normalize vectors
|
||||
float3 N = normalize(input.normalWS);
|
||||
float3 V = normalize(GetWorldSpaceViewDir(input.positionWS));
|
||||
|
||||
// Get main light
|
||||
Light mainLight = GetMainLight(TransformWorldToShadowCoord(input.positionWS));
|
||||
float3 L = mainLight.direction;
|
||||
|
||||
// Toon shading
|
||||
float NdotL = dot(N, L);
|
||||
float halfLambert = NdotL * 0.5 + 0.5;
|
||||
float shadow = step(_ShadowThreshold, halfLambert) * mainLight.shadowAttenuation;
|
||||
float3 diffuse = lerp(_ShadowColor.rgb, float3(1,1,1), shadow);
|
||||
|
||||
// Environment reflection (cornea)
|
||||
float3 reflectDir = reflect(-V, N);
|
||||
float3 envReflection = SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, reflectDir, (1.0 - _ReflectionSmoothness) * 6.0).rgb;
|
||||
float fresnel = pow(1.0 - saturate(dot(N, V)), 3.0);
|
||||
float3 reflection = envReflection * _ReflectionStrength * fresnel;
|
||||
|
||||
// Highlights (anime style)
|
||||
float2 hl1UV = centeredUV - _Highlight1Pos.xy;
|
||||
float hl1 = 1.0 - saturate(length(hl1UV) / _Highlight1Size);
|
||||
hl1 = pow(hl1, 2.0) * _Highlight1Strength;
|
||||
|
||||
float2 hl2UV = centeredUV - _Highlight2Pos.xy;
|
||||
float hl2 = 1.0 - saturate(length(hl2UV) / _Highlight2Size);
|
||||
hl2 = pow(hl2, 2.0) * _Highlight2Strength;
|
||||
|
||||
float3 highlights = float3(1,1,1) * (hl1 + hl2);
|
||||
|
||||
// Subsurface scattering
|
||||
float sss = pow(saturate(dot(-V, L)), 3.0) * _SSSStrength;
|
||||
float3 sssColor = _SSSColor.rgb * sss;
|
||||
|
||||
// Rim light
|
||||
float NdotV = saturate(dot(N, V));
|
||||
float rim = pow(1.0 - NdotV, _RimPower) * _RimStrength;
|
||||
float3 rimColor = _RimColor.rgb * rim;
|
||||
|
||||
// Combine
|
||||
float3 finalColor = eyeColor * diffuse * mainLight.color;
|
||||
finalColor += reflection;
|
||||
finalColor += highlights;
|
||||
finalColor += sssColor;
|
||||
finalColor += rimColor;
|
||||
|
||||
finalColor = MixFog(finalColor, input.fogFactor);
|
||||
|
||||
return half4(finalColor, 1);
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// Shadow Caster
|
||||
Pass
|
||||
{
|
||||
Name "ShadowCaster"
|
||||
Tags { "LightMode" = "ShadowCaster" }
|
||||
|
||||
ZWrite On
|
||||
ZTest LEqual
|
||||
ColorMask 0
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vertShadow
|
||||
#pragma fragment fragShadow
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
|
||||
float3 _LightDirection;
|
||||
|
||||
float3 ApplyShadowBiasCustom(float3 positionWS, float3 normalWS, float3 lightDirection)
|
||||
{
|
||||
float invNdotL = 1.0 - saturate(dot(lightDirection, normalWS));
|
||||
float scale = invNdotL * 0.001;
|
||||
positionWS = lightDirection * 0.001 + positionWS;
|
||||
positionWS = normalWS * scale.xxx + positionWS;
|
||||
return positionWS;
|
||||
}
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float3 normalOS : NORMAL;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
};
|
||||
|
||||
Varyings vertShadow(Attributes input)
|
||||
{
|
||||
Varyings output;
|
||||
float3 posWS = TransformObjectToWorld(input.positionOS.xyz);
|
||||
float3 normalWS = TransformObjectToWorldNormal(input.normalOS);
|
||||
posWS = ApplyShadowBiasCustom(posWS, normalWS, _LightDirection);
|
||||
output.positionCS = TransformWorldToHClip(posWS);
|
||||
#if UNITY_REVERSED_Z
|
||||
output.positionCS.z = min(output.positionCS.z, UNITY_NEAR_CLIP_VALUE);
|
||||
#else
|
||||
output.positionCS.z = max(output.positionCS.z, UNITY_NEAR_CLIP_VALUE);
|
||||
#endif
|
||||
return output;
|
||||
}
|
||||
|
||||
half4 fragShadow(Varyings input) : SV_Target
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// Depth Only
|
||||
Pass
|
||||
{
|
||||
Name "DepthOnly"
|
||||
Tags { "LightMode" = "DepthOnly" }
|
||||
|
||||
ZWrite On
|
||||
ColorMask 0
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vertDepth
|
||||
#pragma fragment fragDepth
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
};
|
||||
|
||||
Varyings vertDepth(Attributes input)
|
||||
{
|
||||
Varyings output;
|
||||
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
|
||||
return output;
|
||||
}
|
||||
|
||||
half4 fragDepth(Varyings input) : SV_Target
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== Built-in SubShader ====================
|
||||
SubShader
|
||||
{
|
||||
Tags
|
||||
{
|
||||
"RenderType" = "Opaque"
|
||||
"Queue" = "Geometry"
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "ForwardBase"
|
||||
Tags { "LightMode" = "ForwardBase" }
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile_fwdbase
|
||||
#pragma multi_compile_fog
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
#include "Lighting.cginc"
|
||||
#include "AutoLight.cginc"
|
||||
|
||||
sampler2D _IrisTex;
|
||||
float4 _IrisTex_ST;
|
||||
sampler2D _ScleraTex;
|
||||
samplerCUBE _Cubemap;
|
||||
|
||||
fixed4 _IrisColor;
|
||||
float _IrisSize;
|
||||
float _IrisDepth;
|
||||
|
||||
fixed4 _PupilColor;
|
||||
float _PupilSize;
|
||||
float _PupilDilation;
|
||||
float _PupilSharpness;
|
||||
|
||||
fixed4 _ScleraColor;
|
||||
|
||||
float _ReflectionStrength;
|
||||
float _ReflectionSmoothness;
|
||||
|
||||
float4 _Highlight1Pos;
|
||||
float _Highlight1Size;
|
||||
float _Highlight1Strength;
|
||||
|
||||
float4 _Highlight2Pos;
|
||||
float _Highlight2Size;
|
||||
float _Highlight2Strength;
|
||||
|
||||
fixed4 _LimbalColor;
|
||||
float _LimbalWidth;
|
||||
float _LimbalStrength;
|
||||
|
||||
float _CausticsStrength;
|
||||
float _CausticsScale;
|
||||
float _CausticsSpeed;
|
||||
|
||||
fixed4 _SSSColor;
|
||||
float _SSSStrength;
|
||||
|
||||
fixed4 _RimColor;
|
||||
float _RimPower;
|
||||
float _RimStrength;
|
||||
|
||||
fixed4 _ShadowColor;
|
||||
float _ShadowThreshold;
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float3 normal : NORMAL;
|
||||
float4 tangent : TANGENT;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 worldPos : TEXCOORD1;
|
||||
float3 worldNormal : TEXCOORD2;
|
||||
float3 viewDirTS : TEXCOORD3;
|
||||
UNITY_FOG_COORDS(4)
|
||||
SHADOW_COORDS(5)
|
||||
};
|
||||
|
||||
float noise2D(float2 p)
|
||||
{
|
||||
return frac(sin(dot(p, float2(127.1, 311.7))) * 43758.5453);
|
||||
}
|
||||
|
||||
float smoothNoise(float2 p)
|
||||
{
|
||||
float2 i = floor(p);
|
||||
float2 f = frac(p);
|
||||
f = f * f * (3.0 - 2.0 * f);
|
||||
float a = noise2D(i);
|
||||
float b = noise2D(i + float2(1, 0));
|
||||
float c = noise2D(i + float2(0, 1));
|
||||
float d = noise2D(i + float2(1, 1));
|
||||
return lerp(lerp(a, b, f.x), lerp(c, d, f.x), f.y);
|
||||
}
|
||||
|
||||
float caustics(float2 uv, float time)
|
||||
{
|
||||
float c1 = smoothNoise(uv * _CausticsScale + time * 0.5);
|
||||
float c2 = smoothNoise(uv * _CausticsScale * 1.3 - time * 0.3);
|
||||
return pow(c1 * c2, 2) * 4.0;
|
||||
}
|
||||
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.uv;
|
||||
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
|
||||
o.worldNormal = UnityObjectToWorldNormal(v.normal);
|
||||
|
||||
float3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
|
||||
float3 worldBitangent = cross(o.worldNormal, worldTangent) * v.tangent.w;
|
||||
float3 viewDirWS = normalize(_WorldSpaceCameraPos - o.worldPos);
|
||||
float3x3 TBN = float3x3(worldTangent, worldBitangent, o.worldNormal);
|
||||
o.viewDirTS = mul(TBN, viewDirWS);
|
||||
|
||||
UNITY_TRANSFER_FOG(o, o.pos);
|
||||
TRANSFER_SHADOW(o);
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag(v2f i) : SV_Target
|
||||
{
|
||||
float2 centeredUV = i.uv - 0.5;
|
||||
float dist = length(centeredUV);
|
||||
|
||||
float3 viewDirTS = normalize(i.viewDirTS);
|
||||
float2 parallaxOffset = viewDirTS.xy / viewDirTS.z * _IrisDepth;
|
||||
float2 irisUV = centeredUV + parallaxOffset;
|
||||
float irisDist = length(irisUV);
|
||||
|
||||
float pupilRadius = _PupilSize * _PupilDilation;
|
||||
float pupilMask = 1.0 - saturate(pow(irisDist / pupilRadius, _PupilSharpness));
|
||||
|
||||
float irisMask = saturate(1.0 - smoothstep(_IrisSize - 0.05, _IrisSize + 0.05, irisDist));
|
||||
irisMask *= (1.0 - pupilMask);
|
||||
|
||||
float limbalDist = abs(irisDist - _IrisSize);
|
||||
float limbalMask = (1.0 - smoothstep(0, _LimbalWidth, limbalDist)) * irisMask;
|
||||
|
||||
float2 irisTexUV = (irisUV / _IrisSize) * 0.5 + 0.5;
|
||||
fixed4 irisTex = tex2D(_IrisTex, irisTexUV);
|
||||
fixed4 scleraTex = tex2D(_ScleraTex, i.uv);
|
||||
|
||||
float3 eyeColor = _ScleraColor.rgb * scleraTex.rgb;
|
||||
eyeColor = lerp(eyeColor, _IrisColor.rgb * irisTex.rgb, irisMask);
|
||||
eyeColor = lerp(eyeColor, _LimbalColor.rgb, limbalMask * _LimbalStrength);
|
||||
eyeColor = lerp(eyeColor, _PupilColor.rgb, pupilMask);
|
||||
|
||||
float time = _Time.y * _CausticsSpeed;
|
||||
float causticsValue = caustics(irisUV * 2.0, time);
|
||||
eyeColor += causticsValue * _CausticsStrength * irisMask * (1.0 - pupilMask);
|
||||
|
||||
float3 N = normalize(i.worldNormal);
|
||||
float3 V = normalize(_WorldSpaceCameraPos - i.worldPos);
|
||||
float3 L = normalize(_WorldSpaceLightPos0.xyz);
|
||||
|
||||
float atten = SHADOW_ATTENUATION(i);
|
||||
float NdotL = dot(N, L);
|
||||
float halfLambert = NdotL * 0.5 + 0.5;
|
||||
float shadow = step(_ShadowThreshold, halfLambert) * atten;
|
||||
float3 diffuse = lerp(_ShadowColor.rgb, float3(1,1,1), shadow);
|
||||
|
||||
float3 reflectDir = reflect(-V, N);
|
||||
float3 envReflection = texCUBElod(_Cubemap, float4(reflectDir, (1.0 - _ReflectionSmoothness) * 6.0)).rgb;
|
||||
float fresnel = pow(1.0 - saturate(dot(N, V)), 3.0);
|
||||
float3 reflection = envReflection * _ReflectionStrength * fresnel;
|
||||
|
||||
float2 hl1UV = centeredUV - _Highlight1Pos.xy;
|
||||
float hl1 = 1.0 - saturate(length(hl1UV) / _Highlight1Size);
|
||||
hl1 = pow(hl1, 2.0) * _Highlight1Strength;
|
||||
|
||||
float2 hl2UV = centeredUV - _Highlight2Pos.xy;
|
||||
float hl2 = 1.0 - saturate(length(hl2UV) / _Highlight2Size);
|
||||
hl2 = pow(hl2, 2.0) * _Highlight2Strength;
|
||||
|
||||
float3 highlights = float3(1,1,1) * (hl1 + hl2);
|
||||
|
||||
float sss = pow(saturate(dot(-V, L)), 3.0) * _SSSStrength;
|
||||
float3 sssColor = _SSSColor.rgb * sss;
|
||||
|
||||
float NdotV = saturate(dot(N, V));
|
||||
float rim = pow(1.0 - NdotV, _RimPower) * _RimStrength;
|
||||
float3 rimColor = _RimColor.rgb * rim;
|
||||
|
||||
float3 finalColor = eyeColor * diffuse * _LightColor0.rgb;
|
||||
finalColor += reflection;
|
||||
finalColor += highlights;
|
||||
finalColor += sssColor;
|
||||
finalColor += rimColor;
|
||||
|
||||
UNITY_APPLY_FOG(i.fogCoord, finalColor);
|
||||
return fixed4(finalColor, 1);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// Shadow Caster
|
||||
Pass
|
||||
{
|
||||
Name "ShadowCaster"
|
||||
Tags { "LightMode" = "ShadowCaster" }
|
||||
|
||||
ZWrite On
|
||||
ZTest LEqual
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile_shadowcaster
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float3 normal : NORMAL;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
V2F_SHADOW_CASTER;
|
||||
};
|
||||
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o;
|
||||
TRANSFER_SHADOW_CASTER_NORMALOFFSET(o);
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag(v2f i) : SV_Target
|
||||
{
|
||||
SHADOW_CASTER_FRAGMENT(i);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== HDRP SubShader ====================
|
||||
SubShader
|
||||
{
|
||||
PackageRequirements { "com.unity.render-pipelines.high-definition" }
|
||||
Tags
|
||||
{
|
||||
"RenderType" = "Opaque"
|
||||
"RenderPipeline" = "HDRenderPipeline"
|
||||
"Queue" = "Geometry"
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "ForwardOnly"
|
||||
Tags { "LightMode" = "ForwardOnly" }
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma target 4.5
|
||||
|
||||
#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 _IrisColor;
|
||||
float4 _IrisTex_ST;
|
||||
float _IrisSize;
|
||||
float _IrisDepth;
|
||||
float4 _PupilColor;
|
||||
float _PupilSize;
|
||||
float _PupilDilation;
|
||||
float _PupilSharpness;
|
||||
float4 _ScleraColor;
|
||||
float _ReflectionStrength;
|
||||
float _ReflectionSmoothness;
|
||||
float4 _Highlight1Pos;
|
||||
float _Highlight1Size;
|
||||
float _Highlight1Strength;
|
||||
float4 _Highlight2Pos;
|
||||
float _Highlight2Size;
|
||||
float _Highlight2Strength;
|
||||
float4 _LimbalColor;
|
||||
float _LimbalWidth;
|
||||
float _LimbalStrength;
|
||||
float _CausticsStrength;
|
||||
float _CausticsScale;
|
||||
float _CausticsSpeed;
|
||||
float4 _SSSColor;
|
||||
float _SSSStrength;
|
||||
float4 _RimColor;
|
||||
float _RimPower;
|
||||
float _RimStrength;
|
||||
float4 _ShadowColor;
|
||||
float _ShadowThreshold;
|
||||
CBUFFER_END
|
||||
|
||||
TEXTURE2D(_IrisTex);
|
||||
SAMPLER(sampler_IrisTex);
|
||||
TEXTURE2D(_ScleraTex);
|
||||
SAMPLER(sampler_ScleraTex);
|
||||
TEXTURECUBE(_Cubemap);
|
||||
SAMPLER(sampler_Cubemap);
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float3 normalOS : NORMAL;
|
||||
float4 tangentOS : TANGENT;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 positionWS : TEXCOORD1;
|
||||
float3 normalWS : TEXCOORD2;
|
||||
float3 viewDirTS : TEXCOORD3;
|
||||
};
|
||||
|
||||
float noise2D(float2 p)
|
||||
{
|
||||
return frac(sin(dot(p, float2(127.1, 311.7))) * 43758.5453);
|
||||
}
|
||||
|
||||
float smoothNoise(float2 p)
|
||||
{
|
||||
float2 i = floor(p);
|
||||
float2 f = frac(p);
|
||||
f = f * f * (3.0 - 2.0 * f);
|
||||
float a = noise2D(i);
|
||||
float b = noise2D(i + float2(1, 0));
|
||||
float c = noise2D(i + float2(0, 1));
|
||||
float d = noise2D(i + float2(1, 1));
|
||||
return lerp(lerp(a, b, f.x), lerp(c, d, f.x), f.y);
|
||||
}
|
||||
|
||||
float causticsFunc(float2 uv, float time)
|
||||
{
|
||||
float c1 = smoothNoise(uv * _CausticsScale + time * 0.5);
|
||||
float c2 = smoothNoise(uv * _CausticsScale * 1.3 - time * 0.3);
|
||||
return pow(c1 * c2, 2) * 4.0;
|
||||
}
|
||||
|
||||
Varyings vert(Attributes input)
|
||||
{
|
||||
Varyings output;
|
||||
|
||||
output.positionWS = TransformObjectToWorld(input.positionOS.xyz);
|
||||
output.positionCS = TransformWorldToHClip(output.positionWS);
|
||||
output.normalWS = TransformObjectToWorldNormal(input.normalOS);
|
||||
output.uv = input.uv;
|
||||
|
||||
float3 tangentWS = TransformObjectToWorldDir(input.tangentOS.xyz);
|
||||
float3 bitangentWS = cross(output.normalWS, tangentWS) * input.tangentOS.w;
|
||||
float3 viewDirWS = GetWorldSpaceViewDir(output.positionWS);
|
||||
float3x3 TBN = float3x3(tangentWS, bitangentWS, output.normalWS);
|
||||
output.viewDirTS = mul(TBN, viewDirWS);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 frag(Varyings input) : SV_Target
|
||||
{
|
||||
float2 centeredUV = input.uv - 0.5;
|
||||
float dist = length(centeredUV);
|
||||
|
||||
float3 viewDirTS = normalize(input.viewDirTS);
|
||||
float2 parallaxOffset = viewDirTS.xy / viewDirTS.z * _IrisDepth;
|
||||
float2 irisUV = centeredUV + parallaxOffset;
|
||||
float irisDist = length(irisUV);
|
||||
|
||||
float pupilRadius = _PupilSize * _PupilDilation;
|
||||
float pupilMask = 1.0 - saturate(pow(irisDist / pupilRadius, _PupilSharpness));
|
||||
|
||||
float irisMask = saturate(1.0 - smoothstep(_IrisSize - 0.05, _IrisSize + 0.05, irisDist));
|
||||
irisMask *= (1.0 - pupilMask);
|
||||
|
||||
float limbalDist = abs(irisDist - _IrisSize);
|
||||
float limbalMask = (1.0 - smoothstep(0, _LimbalWidth, limbalDist)) * irisMask;
|
||||
|
||||
float2 irisTexUV = (irisUV / _IrisSize) * 0.5 + 0.5;
|
||||
float4 irisTex = SAMPLE_TEXTURE2D(_IrisTex, sampler_IrisTex, irisTexUV);
|
||||
float4 scleraTex = SAMPLE_TEXTURE2D(_ScleraTex, sampler_ScleraTex, input.uv);
|
||||
|
||||
float3 eyeColor = _ScleraColor.rgb * scleraTex.rgb;
|
||||
eyeColor = lerp(eyeColor, _IrisColor.rgb * irisTex.rgb, irisMask);
|
||||
eyeColor = lerp(eyeColor, _LimbalColor.rgb, limbalMask * _LimbalStrength);
|
||||
eyeColor = lerp(eyeColor, _PupilColor.rgb, pupilMask);
|
||||
|
||||
float time = _Time.y * _CausticsSpeed;
|
||||
float causticsValue = causticsFunc(irisUV * 2.0, time);
|
||||
eyeColor += causticsValue * _CausticsStrength * irisMask * (1.0 - pupilMask);
|
||||
|
||||
float3 N = normalize(input.normalWS);
|
||||
float3 V = normalize(GetWorldSpaceViewDir(input.positionWS));
|
||||
float3 L = normalize(float3(0.5, 1, 0.3));
|
||||
|
||||
float NdotL = dot(N, L);
|
||||
float halfLambert = NdotL * 0.5 + 0.5;
|
||||
float shadow = step(_ShadowThreshold, halfLambert);
|
||||
float3 diffuse = lerp(_ShadowColor.rgb, float3(1,1,1), shadow);
|
||||
|
||||
float3 reflectDir = reflect(-V, N);
|
||||
float3 envReflection = SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, reflectDir, (1.0 - _ReflectionSmoothness) * 6.0).rgb;
|
||||
float fresnel = pow(1.0 - saturate(dot(N, V)), 3.0);
|
||||
float3 reflection = envReflection * _ReflectionStrength * fresnel;
|
||||
|
||||
float2 hl1UV = centeredUV - _Highlight1Pos.xy;
|
||||
float hl1 = 1.0 - saturate(length(hl1UV) / _Highlight1Size);
|
||||
hl1 = pow(hl1, 2.0) * _Highlight1Strength;
|
||||
|
||||
float2 hl2UV = centeredUV - _Highlight2Pos.xy;
|
||||
float hl2 = 1.0 - saturate(length(hl2UV) / _Highlight2Size);
|
||||
hl2 = pow(hl2, 2.0) * _Highlight2Strength;
|
||||
|
||||
float3 highlights = float3(1,1,1) * (hl1 + hl2);
|
||||
|
||||
float sss = pow(saturate(dot(-V, L)), 3.0) * _SSSStrength;
|
||||
float3 sssColor = _SSSColor.rgb * sss;
|
||||
|
||||
float NdotV = saturate(dot(N, V));
|
||||
float rim = pow(1.0 - NdotV, _RimPower) * _RimStrength;
|
||||
float3 rimColor = _RimColor.rgb * rim;
|
||||
|
||||
float3 finalColor = eyeColor * diffuse + reflection + highlights + sssColor + rimColor;
|
||||
|
||||
return float4(finalColor, 1);
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
FallBack "Diffuse"
|
||||
CustomEditor "SynapticEyeProEditor"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 75bb34e0ac07042dfa4db9dde6a54ab5
|
||||
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/Character/SynapticEyePro.shader
|
||||
uploadId: 920982
|
||||
@@ -0,0 +1,941 @@
|
||||
Shader "Synaptic/HairPro"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
[Header(Base)]
|
||||
_MainTex ("Albedo", 2D) = "white" {}
|
||||
_Color ("Color", Color) = (0.3, 0.2, 0.15, 1)
|
||||
_Cutoff ("Alpha Cutoff", Range(0, 1)) = 0.5
|
||||
|
||||
[Header(Kajiya Kay Specular)]
|
||||
_SpecularShift ("Specular Shift", Range(-1, 1)) = 0.1
|
||||
_ShiftTex ("Shift Texture", 2D) = "gray" {}
|
||||
|
||||
[Header(Primary Specular)]
|
||||
_SpecularColor1 ("Primary Color", Color) = (1, 1, 1, 1)
|
||||
_SpecularWidth1 ("Primary Width", Range(0, 1)) = 0.5
|
||||
_SpecularStrength1 ("Primary Strength", Range(0, 2)) = 0.5
|
||||
_SpecularShift1 ("Primary Shift", Range(-1, 1)) = 0.1
|
||||
|
||||
[Header(Secondary Specular)]
|
||||
_SpecularColor2 ("Secondary Color", Color) = (0.8, 0.6, 0.4, 1)
|
||||
_SpecularWidth2 ("Secondary Width", Range(0, 1)) = 0.3
|
||||
_SpecularStrength2 ("Secondary Strength", Range(0, 2)) = 0.3
|
||||
_SpecularShift2 ("Secondary Shift", Range(-1, 1)) = -0.1
|
||||
|
||||
[Header(Anisotropic)]
|
||||
_Anisotropy ("Anisotropy", Range(0, 1)) = 0.8
|
||||
_TangentMap ("Tangent Map", 2D) = "bump" {}
|
||||
|
||||
[Header(Rim Light)]
|
||||
_RimColor ("Rim Color", Color) = (1, 0.9, 0.8, 1)
|
||||
_RimPower ("Rim Power", Range(0.1, 10)) = 3
|
||||
_RimStrength ("Rim Strength", Range(0, 2)) = 0.5
|
||||
|
||||
[Header(Shadow)]
|
||||
_ShadowColor ("Shadow Color", Color) = (0.4, 0.3, 0.3, 1)
|
||||
_ShadowThreshold ("Shadow Threshold", Range(0, 1)) = 0.5
|
||||
_ShadowSoftness ("Shadow Softness", Range(0, 1)) = 0.1
|
||||
|
||||
[Header(Subsurface Scattering)]
|
||||
_SSSColor ("SSS Color", Color) = (1, 0.5, 0.3, 1)
|
||||
_SSSStrength ("SSS Strength", Range(0, 2)) = 0.3
|
||||
_SSSDistortion ("SSS Distortion", Range(0, 1)) = 0.5
|
||||
|
||||
[Header(Outline)]
|
||||
_OutlineColor ("Outline Color", Color) = (0.1, 0.05, 0.05, 1)
|
||||
_OutlineWidth ("Outline Width", Range(0, 0.1)) = 0.002
|
||||
|
||||
[Header(Wind Animation)]
|
||||
_WindStrength ("Wind Strength", Range(0, 1)) = 0.1
|
||||
_WindSpeed ("Wind Speed", Range(0, 5)) = 1
|
||||
_WindDirection ("Wind Direction", Vector) = (1, 0, 0.5, 0)
|
||||
}
|
||||
|
||||
// ==================== URP SubShader ====================
|
||||
SubShader
|
||||
{
|
||||
PackageRequirements { "com.unity.render-pipelines.universal" }
|
||||
Tags
|
||||
{
|
||||
"RenderType" = "Opaque"
|
||||
"RenderPipeline" = "UniversalPipeline"
|
||||
"Queue" = "Geometry"
|
||||
}
|
||||
|
||||
// Main Pass
|
||||
Pass
|
||||
{
|
||||
Name "ForwardLit"
|
||||
Tags { "LightMode" = "UniversalForward" }
|
||||
|
||||
Cull Off
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE
|
||||
#pragma multi_compile _ _ADDITIONAL_LIGHTS
|
||||
#pragma multi_compile_fog
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _MainTex_ST;
|
||||
float4 _Color;
|
||||
float _Cutoff;
|
||||
float _SpecularShift;
|
||||
float4 _SpecularColor1;
|
||||
float _SpecularWidth1;
|
||||
float _SpecularStrength1;
|
||||
float _SpecularShift1;
|
||||
float4 _SpecularColor2;
|
||||
float _SpecularWidth2;
|
||||
float _SpecularStrength2;
|
||||
float _SpecularShift2;
|
||||
float _Anisotropy;
|
||||
float4 _RimColor;
|
||||
float _RimPower;
|
||||
float _RimStrength;
|
||||
float4 _ShadowColor;
|
||||
float _ShadowThreshold;
|
||||
float _ShadowSoftness;
|
||||
float4 _SSSColor;
|
||||
float _SSSStrength;
|
||||
float _SSSDistortion;
|
||||
float4 _OutlineColor;
|
||||
float _OutlineWidth;
|
||||
float _WindStrength;
|
||||
float _WindSpeed;
|
||||
float4 _WindDirection;
|
||||
CBUFFER_END
|
||||
|
||||
TEXTURE2D(_MainTex);
|
||||
SAMPLER(sampler_MainTex);
|
||||
TEXTURE2D(_ShiftTex);
|
||||
SAMPLER(sampler_ShiftTex);
|
||||
TEXTURE2D(_TangentMap);
|
||||
SAMPLER(sampler_TangentMap);
|
||||
|
||||
// Kajiya-Kay Specular Function
|
||||
float KajiyaKaySpecular(float3 T, float3 H, float width)
|
||||
{
|
||||
float TdotH = dot(T, H);
|
||||
float sinTH = sqrt(1.0 - TdotH * TdotH);
|
||||
float dirAtten = smoothstep(-1.0, 0.0, TdotH);
|
||||
return dirAtten * pow(sinTH, width * 100.0);
|
||||
}
|
||||
|
||||
// Shift tangent by normal and shift amount
|
||||
float3 SynapticShiftTangent(float3 T, float3 N, float shift)
|
||||
{
|
||||
return normalize(T + N * shift);
|
||||
}
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float3 normalOS : NORMAL;
|
||||
float4 tangentOS : TANGENT;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 positionWS : TEXCOORD1;
|
||||
float3 normalWS : TEXCOORD2;
|
||||
float3 tangentWS : TEXCOORD3;
|
||||
float3 bitangentWS : TEXCOORD4;
|
||||
float fogFactor : TEXCOORD5;
|
||||
};
|
||||
|
||||
Varyings vert(Attributes input)
|
||||
{
|
||||
Varyings output;
|
||||
|
||||
// Wind animation
|
||||
float3 posOS = input.positionOS.xyz;
|
||||
float windPhase = _Time.y * _WindSpeed + posOS.x * 2.0 + posOS.z * 2.0;
|
||||
float windOffset = sin(windPhase) * _WindStrength * input.uv.y;
|
||||
posOS += _WindDirection.xyz * windOffset;
|
||||
|
||||
VertexPositionInputs posInputs = GetVertexPositionInputs(posOS);
|
||||
VertexNormalInputs normalInputs = GetVertexNormalInputs(input.normalOS, input.tangentOS);
|
||||
|
||||
output.positionCS = posInputs.positionCS;
|
||||
output.positionWS = posInputs.positionWS;
|
||||
output.normalWS = normalInputs.normalWS;
|
||||
output.tangentWS = normalInputs.tangentWS;
|
||||
output.bitangentWS = normalInputs.bitangentWS;
|
||||
output.uv = TRANSFORM_TEX(input.uv, _MainTex);
|
||||
output.fogFactor = ComputeFogFactor(posInputs.positionCS.z);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
half4 frag(Varyings input) : SV_Target
|
||||
{
|
||||
// Sample textures
|
||||
half4 albedo = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv) * _Color;
|
||||
clip(albedo.a - _Cutoff);
|
||||
|
||||
float shiftTex = SAMPLE_TEXTURE2D(_ShiftTex, sampler_ShiftTex, input.uv).r - 0.5;
|
||||
|
||||
// Normalize vectors
|
||||
float3 N = normalize(input.normalWS);
|
||||
float3 T = normalize(input.tangentWS);
|
||||
float3 B = normalize(input.bitangentWS);
|
||||
float3 V = normalize(GetWorldSpaceViewDir(input.positionWS));
|
||||
|
||||
// Get main light
|
||||
Light mainLight = GetMainLight(TransformWorldToShadowCoord(input.positionWS));
|
||||
float3 L = mainLight.direction;
|
||||
float3 H = normalize(L + V);
|
||||
|
||||
// Shift tangent for hair strands
|
||||
float shift1 = _SpecularShift + _SpecularShift1 + shiftTex;
|
||||
float shift2 = _SpecularShift + _SpecularShift2 + shiftTex;
|
||||
float3 T1 = SynapticShiftTangent(B, N, shift1);
|
||||
float3 T2 = SynapticShiftTangent(B, N, shift2);
|
||||
|
||||
// Kajiya-Kay dual specular
|
||||
float spec1 = KajiyaKaySpecular(T1, H, _SpecularWidth1) * _SpecularStrength1;
|
||||
float spec2 = KajiyaKaySpecular(T2, H, _SpecularWidth2) * _SpecularStrength2;
|
||||
|
||||
float3 specular = _SpecularColor1.rgb * spec1 + _SpecularColor2.rgb * spec2;
|
||||
specular *= mainLight.color * mainLight.shadowAttenuation;
|
||||
|
||||
// Diffuse with toon shading
|
||||
float NdotL = dot(N, L);
|
||||
float halfLambert = NdotL * 0.5 + 0.5;
|
||||
float shadow = smoothstep(_ShadowThreshold - _ShadowSoftness, _ShadowThreshold + _ShadowSoftness, halfLambert);
|
||||
shadow *= mainLight.shadowAttenuation;
|
||||
|
||||
float3 diffuse = lerp(_ShadowColor.rgb, float3(1,1,1), shadow) * albedo.rgb;
|
||||
|
||||
// Subsurface Scattering
|
||||
float3 sssH = normalize(L + N * _SSSDistortion);
|
||||
float VdotH = pow(saturate(dot(V, -sssH)), 3.0);
|
||||
float3 sss = _SSSColor.rgb * VdotH * _SSSStrength * (1.0 - shadow);
|
||||
|
||||
// Rim light
|
||||
float NdotV = saturate(dot(N, V));
|
||||
float rim = pow(1.0 - NdotV, _RimPower) * _RimStrength;
|
||||
float3 rimColor = _RimColor.rgb * rim * mainLight.color;
|
||||
|
||||
// Additional lights
|
||||
float3 additionalLight = float3(0, 0, 0);
|
||||
#ifdef _ADDITIONAL_LIGHTS
|
||||
uint additionalLightsCount = GetAdditionalLightsCount();
|
||||
for (uint i = 0; i < additionalLightsCount; ++i)
|
||||
{
|
||||
Light light = GetAdditionalLight(i, input.positionWS);
|
||||
float addNdotL = saturate(dot(N, light.direction));
|
||||
additionalLight += light.color * light.distanceAttenuation * addNdotL * 0.5;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Combine
|
||||
float3 finalColor = diffuse * mainLight.color + specular + sss + rimColor + additionalLight * albedo.rgb;
|
||||
finalColor = MixFog(finalColor, input.fogFactor);
|
||||
|
||||
return half4(finalColor, albedo.a);
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// Outline Pass
|
||||
Pass
|
||||
{
|
||||
Name "Outline"
|
||||
Tags { "LightMode" = "SRPDefaultUnlit" }
|
||||
|
||||
Cull Front
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vertOutline
|
||||
#pragma fragment fragOutline
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _MainTex_ST;
|
||||
float4 _Color;
|
||||
float _Cutoff;
|
||||
float _SpecularShift;
|
||||
float4 _SpecularColor1;
|
||||
float _SpecularWidth1;
|
||||
float _SpecularStrength1;
|
||||
float _SpecularShift1;
|
||||
float4 _SpecularColor2;
|
||||
float _SpecularWidth2;
|
||||
float _SpecularStrength2;
|
||||
float _SpecularShift2;
|
||||
float _Anisotropy;
|
||||
float4 _RimColor;
|
||||
float _RimPower;
|
||||
float _RimStrength;
|
||||
float4 _ShadowColor;
|
||||
float _ShadowThreshold;
|
||||
float _ShadowSoftness;
|
||||
float4 _SSSColor;
|
||||
float _SSSStrength;
|
||||
float _SSSDistortion;
|
||||
float4 _OutlineColor;
|
||||
float _OutlineWidth;
|
||||
float _WindStrength;
|
||||
float _WindSpeed;
|
||||
float4 _WindDirection;
|
||||
CBUFFER_END
|
||||
|
||||
TEXTURE2D(_MainTex);
|
||||
SAMPLER(sampler_MainTex);
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float3 normalOS : NORMAL;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
Varyings vertOutline(Attributes input)
|
||||
{
|
||||
Varyings output;
|
||||
|
||||
float3 normalOS = normalize(input.normalOS);
|
||||
float3 posOS = input.positionOS.xyz + normalOS * _OutlineWidth;
|
||||
|
||||
output.positionCS = TransformObjectToHClip(posOS);
|
||||
output.uv = TRANSFORM_TEX(input.uv, _MainTex);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
half4 fragOutline(Varyings input) : SV_Target
|
||||
{
|
||||
half4 albedo = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv);
|
||||
clip(albedo.a - _Cutoff);
|
||||
return _OutlineColor;
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// Shadow Caster
|
||||
Pass
|
||||
{
|
||||
Name "ShadowCaster"
|
||||
Tags { "LightMode" = "ShadowCaster" }
|
||||
|
||||
ZWrite On
|
||||
ZTest LEqual
|
||||
ColorMask 0
|
||||
Cull Off
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vertShadow
|
||||
#pragma fragment fragShadow
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
|
||||
float3 _LightDirection;
|
||||
|
||||
float3 ApplyShadowBiasCustom(float3 positionWS, float3 normalWS, float3 lightDirection)
|
||||
{
|
||||
float invNdotL = 1.0 - saturate(dot(lightDirection, normalWS));
|
||||
float scale = invNdotL * 0.001;
|
||||
positionWS = lightDirection * 0.001 + positionWS;
|
||||
positionWS = normalWS * scale.xxx + positionWS;
|
||||
return positionWS;
|
||||
}
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _MainTex_ST;
|
||||
float4 _Color;
|
||||
float _Cutoff;
|
||||
float _SpecularShift;
|
||||
float4 _SpecularColor1;
|
||||
float _SpecularWidth1;
|
||||
float _SpecularStrength1;
|
||||
float _SpecularShift1;
|
||||
float4 _SpecularColor2;
|
||||
float _SpecularWidth2;
|
||||
float _SpecularStrength2;
|
||||
float _SpecularShift2;
|
||||
float _Anisotropy;
|
||||
float4 _RimColor;
|
||||
float _RimPower;
|
||||
float _RimStrength;
|
||||
float4 _ShadowColor;
|
||||
float _ShadowThreshold;
|
||||
float _ShadowSoftness;
|
||||
float4 _SSSColor;
|
||||
float _SSSStrength;
|
||||
float _SSSDistortion;
|
||||
float4 _OutlineColor;
|
||||
float _OutlineWidth;
|
||||
float _WindStrength;
|
||||
float _WindSpeed;
|
||||
float4 _WindDirection;
|
||||
CBUFFER_END
|
||||
|
||||
TEXTURE2D(_MainTex);
|
||||
SAMPLER(sampler_MainTex);
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float3 normalOS : NORMAL;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
Varyings vertShadow(Attributes input)
|
||||
{
|
||||
Varyings output;
|
||||
|
||||
float3 posWS = TransformObjectToWorld(input.positionOS.xyz);
|
||||
float3 normalWS = TransformObjectToWorldNormal(input.normalOS);
|
||||
|
||||
posWS = ApplyShadowBiasCustom(posWS, normalWS, _LightDirection);
|
||||
output.positionCS = TransformWorldToHClip(posWS);
|
||||
#if UNITY_REVERSED_Z
|
||||
output.positionCS.z = min(output.positionCS.z, UNITY_NEAR_CLIP_VALUE);
|
||||
#else
|
||||
output.positionCS.z = max(output.positionCS.z, UNITY_NEAR_CLIP_VALUE);
|
||||
#endif
|
||||
output.uv = TRANSFORM_TEX(input.uv, _MainTex);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
half4 fragShadow(Varyings input) : SV_Target
|
||||
{
|
||||
half4 albedo = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv);
|
||||
clip(albedo.a - _Cutoff);
|
||||
return 0;
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// Depth Only
|
||||
Pass
|
||||
{
|
||||
Name "DepthOnly"
|
||||
Tags { "LightMode" = "DepthOnly" }
|
||||
|
||||
ZWrite On
|
||||
ColorMask 0
|
||||
Cull Off
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vertDepth
|
||||
#pragma fragment fragDepth
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _MainTex_ST;
|
||||
float4 _Color;
|
||||
float _Cutoff;
|
||||
float _SpecularShift;
|
||||
float4 _SpecularColor1;
|
||||
float _SpecularWidth1;
|
||||
float _SpecularStrength1;
|
||||
float _SpecularShift1;
|
||||
float4 _SpecularColor2;
|
||||
float _SpecularWidth2;
|
||||
float _SpecularStrength2;
|
||||
float _SpecularShift2;
|
||||
float _Anisotropy;
|
||||
float4 _RimColor;
|
||||
float _RimPower;
|
||||
float _RimStrength;
|
||||
float4 _ShadowColor;
|
||||
float _ShadowThreshold;
|
||||
float _ShadowSoftness;
|
||||
float4 _SSSColor;
|
||||
float _SSSStrength;
|
||||
float _SSSDistortion;
|
||||
float4 _OutlineColor;
|
||||
float _OutlineWidth;
|
||||
float _WindStrength;
|
||||
float _WindSpeed;
|
||||
float4 _WindDirection;
|
||||
CBUFFER_END
|
||||
|
||||
TEXTURE2D(_MainTex);
|
||||
SAMPLER(sampler_MainTex);
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
Varyings vertDepth(Attributes input)
|
||||
{
|
||||
Varyings output;
|
||||
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
|
||||
output.uv = TRANSFORM_TEX(input.uv, _MainTex);
|
||||
return output;
|
||||
}
|
||||
|
||||
half4 fragDepth(Varyings input) : SV_Target
|
||||
{
|
||||
half4 albedo = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv);
|
||||
clip(albedo.a - _Cutoff);
|
||||
return 0;
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== Built-in SubShader ====================
|
||||
SubShader
|
||||
{
|
||||
Tags
|
||||
{
|
||||
"RenderType" = "Opaque"
|
||||
"Queue" = "Geometry"
|
||||
}
|
||||
|
||||
// Main Pass
|
||||
Pass
|
||||
{
|
||||
Name "ForwardBase"
|
||||
Tags { "LightMode" = "ForwardBase" }
|
||||
|
||||
Cull Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile_fwdbase
|
||||
#pragma multi_compile_fog
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
#include "Lighting.cginc"
|
||||
#include "AutoLight.cginc"
|
||||
|
||||
sampler2D _MainTex;
|
||||
float4 _MainTex_ST;
|
||||
sampler2D _ShiftTex;
|
||||
sampler2D _TangentMap;
|
||||
|
||||
fixed4 _Color;
|
||||
float _Cutoff;
|
||||
|
||||
float _SpecularShift;
|
||||
fixed4 _SpecularColor1;
|
||||
float _SpecularWidth1;
|
||||
float _SpecularStrength1;
|
||||
float _SpecularShift1;
|
||||
|
||||
fixed4 _SpecularColor2;
|
||||
float _SpecularWidth2;
|
||||
float _SpecularStrength2;
|
||||
float _SpecularShift2;
|
||||
|
||||
fixed4 _RimColor;
|
||||
float _RimPower;
|
||||
float _RimStrength;
|
||||
|
||||
fixed4 _ShadowColor;
|
||||
float _ShadowThreshold;
|
||||
float _ShadowSoftness;
|
||||
|
||||
fixed4 _SSSColor;
|
||||
float _SSSStrength;
|
||||
float _SSSDistortion;
|
||||
|
||||
float _WindStrength;
|
||||
float _WindSpeed;
|
||||
float4 _WindDirection;
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float3 normal : NORMAL;
|
||||
float4 tangent : TANGENT;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 worldPos : TEXCOORD1;
|
||||
float3 worldNormal : TEXCOORD2;
|
||||
float3 worldTangent : TEXCOORD3;
|
||||
float3 worldBitangent : TEXCOORD4;
|
||||
UNITY_FOG_COORDS(5)
|
||||
SHADOW_COORDS(6)
|
||||
};
|
||||
|
||||
float KajiyaKaySpec(float3 T, float3 H, float width)
|
||||
{
|
||||
float TdotH = dot(T, H);
|
||||
float sinTH = sqrt(1.0 - TdotH * TdotH);
|
||||
float dirAtten = smoothstep(-1.0, 0.0, TdotH);
|
||||
return dirAtten * pow(sinTH, width * 100.0);
|
||||
}
|
||||
|
||||
float3 ShiftT(float3 T, float3 N, float shift)
|
||||
{
|
||||
return normalize(T + N * shift);
|
||||
}
|
||||
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o;
|
||||
|
||||
// Wind animation
|
||||
float3 posOS = v.vertex.xyz;
|
||||
float windPhase = _Time.y * _WindSpeed + posOS.x * 2.0 + posOS.z * 2.0;
|
||||
float windOffset = sin(windPhase) * _WindStrength * v.uv.y;
|
||||
posOS += _WindDirection.xyz * windOffset;
|
||||
|
||||
o.pos = UnityObjectToClipPos(float4(posOS, 1));
|
||||
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
|
||||
o.worldPos = mul(unity_ObjectToWorld, float4(posOS, 1)).xyz;
|
||||
o.worldNormal = UnityObjectToWorldNormal(v.normal);
|
||||
o.worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
|
||||
o.worldBitangent = cross(o.worldNormal, o.worldTangent) * v.tangent.w;
|
||||
|
||||
UNITY_TRANSFER_FOG(o, o.pos);
|
||||
TRANSFER_SHADOW(o);
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag(v2f i) : SV_Target
|
||||
{
|
||||
fixed4 albedo = tex2D(_MainTex, i.uv) * _Color;
|
||||
clip(albedo.a - _Cutoff);
|
||||
|
||||
float shiftTex = tex2D(_ShiftTex, i.uv).r - 0.5;
|
||||
|
||||
float3 N = normalize(i.worldNormal);
|
||||
float3 T = normalize(i.worldTangent);
|
||||
float3 B = normalize(i.worldBitangent);
|
||||
float3 V = normalize(_WorldSpaceCameraPos - i.worldPos);
|
||||
float3 L = normalize(_WorldSpaceLightPos0.xyz);
|
||||
float3 H = normalize(L + V);
|
||||
|
||||
// Kajiya-Kay
|
||||
float shift1 = _SpecularShift + _SpecularShift1 + shiftTex;
|
||||
float shift2 = _SpecularShift + _SpecularShift2 + shiftTex;
|
||||
float3 T1 = ShiftT(B, N, shift1);
|
||||
float3 T2 = ShiftT(B, N, shift2);
|
||||
|
||||
float spec1 = KajiyaKaySpec(T1, H, _SpecularWidth1) * _SpecularStrength1;
|
||||
float spec2 = KajiyaKaySpec(T2, H, _SpecularWidth2) * _SpecularStrength2;
|
||||
float3 specular = _SpecularColor1.rgb * spec1 + _SpecularColor2.rgb * spec2;
|
||||
|
||||
// Shadow
|
||||
float atten = SHADOW_ATTENUATION(i);
|
||||
float NdotL = dot(N, L);
|
||||
float halfLambert = NdotL * 0.5 + 0.5;
|
||||
float shadow = smoothstep(_ShadowThreshold - _ShadowSoftness, _ShadowThreshold + _ShadowSoftness, halfLambert);
|
||||
shadow *= atten;
|
||||
|
||||
float3 diffuse = lerp(_ShadowColor.rgb, float3(1,1,1), shadow) * albedo.rgb;
|
||||
|
||||
// SSS
|
||||
float3 sssH = normalize(L + N * _SSSDistortion);
|
||||
float VdotH = pow(saturate(dot(V, -sssH)), 3.0);
|
||||
float3 sss = _SSSColor.rgb * VdotH * _SSSStrength * (1.0 - shadow);
|
||||
|
||||
// Rim
|
||||
float NdotV = saturate(dot(N, V));
|
||||
float rim = pow(1.0 - NdotV, _RimPower) * _RimStrength;
|
||||
float3 rimColor = _RimColor.rgb * rim;
|
||||
|
||||
float3 finalColor = diffuse * _LightColor0.rgb + specular * _LightColor0.rgb * atten + sss + rimColor;
|
||||
|
||||
UNITY_APPLY_FOG(i.fogCoord, finalColor);
|
||||
return fixed4(finalColor, albedo.a);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// Outline Pass
|
||||
Pass
|
||||
{
|
||||
Name "Outline"
|
||||
Tags { "LightMode" = "Always" }
|
||||
|
||||
Cull Front
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
sampler2D _MainTex;
|
||||
float4 _MainTex_ST;
|
||||
float _Cutoff;
|
||||
fixed4 _OutlineColor;
|
||||
float _OutlineWidth;
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float3 normal : NORMAL;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o;
|
||||
float3 normalOS = normalize(v.normal);
|
||||
float3 posOS = v.vertex.xyz + normalOS * _OutlineWidth;
|
||||
o.pos = UnityObjectToClipPos(float4(posOS, 1));
|
||||
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag(v2f i) : SV_Target
|
||||
{
|
||||
fixed4 albedo = tex2D(_MainTex, i.uv);
|
||||
clip(albedo.a - _Cutoff);
|
||||
return _OutlineColor;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// Shadow Caster
|
||||
Pass
|
||||
{
|
||||
Name "ShadowCaster"
|
||||
Tags { "LightMode" = "ShadowCaster" }
|
||||
|
||||
ZWrite On
|
||||
ZTest LEqual
|
||||
Cull Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile_shadowcaster
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
sampler2D _MainTex;
|
||||
float4 _MainTex_ST;
|
||||
float _Cutoff;
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float3 normal : NORMAL;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
V2F_SHADOW_CASTER;
|
||||
float2 uv : TEXCOORD1;
|
||||
};
|
||||
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o;
|
||||
TRANSFER_SHADOW_CASTER_NORMALOFFSET(o);
|
||||
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag(v2f i) : SV_Target
|
||||
{
|
||||
fixed4 albedo = tex2D(_MainTex, i.uv);
|
||||
clip(albedo.a - _Cutoff);
|
||||
SHADOW_CASTER_FRAGMENT(i);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== HDRP SubShader ====================
|
||||
SubShader
|
||||
{
|
||||
PackageRequirements { "com.unity.render-pipelines.high-definition" }
|
||||
Tags
|
||||
{
|
||||
"RenderType" = "Opaque"
|
||||
"RenderPipeline" = "HDRenderPipeline"
|
||||
"Queue" = "Geometry"
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "ForwardOnly"
|
||||
Tags { "LightMode" = "ForwardOnly" }
|
||||
|
||||
Cull Off
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma target 4.5
|
||||
|
||||
#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 _MainTex_ST;
|
||||
float4 _Color;
|
||||
float _Cutoff;
|
||||
float _SpecularShift;
|
||||
float4 _SpecularColor1;
|
||||
float _SpecularWidth1;
|
||||
float _SpecularStrength1;
|
||||
float _SpecularShift1;
|
||||
float4 _SpecularColor2;
|
||||
float _SpecularWidth2;
|
||||
float _SpecularStrength2;
|
||||
float _SpecularShift2;
|
||||
float4 _RimColor;
|
||||
float _RimPower;
|
||||
float _RimStrength;
|
||||
float4 _ShadowColor;
|
||||
float _ShadowThreshold;
|
||||
float _ShadowSoftness;
|
||||
float4 _SSSColor;
|
||||
float _SSSStrength;
|
||||
float _SSSDistortion;
|
||||
float _WindStrength;
|
||||
float _WindSpeed;
|
||||
float4 _WindDirection;
|
||||
CBUFFER_END
|
||||
|
||||
TEXTURE2D(_MainTex);
|
||||
SAMPLER(sampler_MainTex);
|
||||
TEXTURE2D(_ShiftTex);
|
||||
SAMPLER(sampler_ShiftTex);
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float3 normalOS : NORMAL;
|
||||
float4 tangentOS : TANGENT;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 positionWS : TEXCOORD1;
|
||||
float3 normalWS : TEXCOORD2;
|
||||
float3 tangentWS : TEXCOORD3;
|
||||
float3 bitangentWS : TEXCOORD4;
|
||||
};
|
||||
|
||||
float KKSpec(float3 T, float3 H, float width)
|
||||
{
|
||||
float TdotH = dot(T, H);
|
||||
float sinTH = sqrt(1.0 - TdotH * TdotH);
|
||||
float dirAtten = smoothstep(-1.0, 0.0, TdotH);
|
||||
return dirAtten * pow(sinTH, width * 100.0);
|
||||
}
|
||||
|
||||
float3 ShiftTan(float3 T, float3 N, float shift)
|
||||
{
|
||||
return normalize(T + N * shift);
|
||||
}
|
||||
|
||||
Varyings vert(Attributes input)
|
||||
{
|
||||
Varyings output;
|
||||
|
||||
float3 posOS = input.positionOS.xyz;
|
||||
float windPhase = _Time.y * _WindSpeed + posOS.x * 2.0 + posOS.z * 2.0;
|
||||
float windOffset = sin(windPhase) * _WindStrength * input.uv.y;
|
||||
posOS += _WindDirection.xyz * windOffset;
|
||||
|
||||
output.positionWS = TransformObjectToWorld(posOS);
|
||||
output.positionCS = TransformWorldToHClip(output.positionWS);
|
||||
output.normalWS = TransformObjectToWorldNormal(input.normalOS);
|
||||
output.tangentWS = TransformObjectToWorldDir(input.tangentOS.xyz);
|
||||
output.bitangentWS = cross(output.normalWS, output.tangentWS) * input.tangentOS.w;
|
||||
output.uv = input.uv * _MainTex_ST.xy + _MainTex_ST.zw;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 frag(Varyings input) : SV_Target
|
||||
{
|
||||
float4 albedo = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv) * _Color;
|
||||
clip(albedo.a - _Cutoff);
|
||||
|
||||
float shiftTex = SAMPLE_TEXTURE2D(_ShiftTex, sampler_ShiftTex, input.uv).r - 0.5;
|
||||
|
||||
float3 N = normalize(input.normalWS);
|
||||
float3 T = normalize(input.tangentWS);
|
||||
float3 B = normalize(input.bitangentWS);
|
||||
float3 V = normalize(GetWorldSpaceViewDir(input.positionWS));
|
||||
float3 L = normalize(float3(0.5, 1, 0.3));
|
||||
float3 H = normalize(L + V);
|
||||
|
||||
float shift1 = _SpecularShift + _SpecularShift1 + shiftTex;
|
||||
float shift2 = _SpecularShift + _SpecularShift2 + shiftTex;
|
||||
float3 T1 = ShiftTan(B, N, shift1);
|
||||
float3 T2 = ShiftTan(B, N, shift2);
|
||||
|
||||
float spec1 = KKSpec(T1, H, _SpecularWidth1) * _SpecularStrength1;
|
||||
float spec2 = KKSpec(T2, H, _SpecularWidth2) * _SpecularStrength2;
|
||||
float3 specular = _SpecularColor1.rgb * spec1 + _SpecularColor2.rgb * spec2;
|
||||
|
||||
float NdotL = dot(N, L);
|
||||
float halfLambert = NdotL * 0.5 + 0.5;
|
||||
float shadow = smoothstep(_ShadowThreshold - _ShadowSoftness, _ShadowThreshold + _ShadowSoftness, halfLambert);
|
||||
|
||||
float3 diffuse = lerp(_ShadowColor.rgb, float3(1,1,1), shadow) * albedo.rgb;
|
||||
|
||||
float3 sssH = normalize(L + N * _SSSDistortion);
|
||||
float VdotH = pow(saturate(dot(V, -sssH)), 3.0);
|
||||
float3 sss = _SSSColor.rgb * VdotH * _SSSStrength * (1.0 - shadow);
|
||||
|
||||
float NdotV = saturate(dot(N, V));
|
||||
float rim = pow(1.0 - NdotV, _RimPower) * _RimStrength;
|
||||
float3 rimColor = _RimColor.rgb * rim;
|
||||
|
||||
float3 finalColor = diffuse + specular + sss + rimColor;
|
||||
|
||||
return float4(finalColor, albedo.a);
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
FallBack "Diffuse"
|
||||
CustomEditor "SynapticHairProEditor"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 68c7c53a8b8c44bad8eaf97b96af2bb7
|
||||
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/Character/SynapticHairPro.shader
|
||||
uploadId: 920982
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5473f0df413f8489485cd60e967157a7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,520 @@
|
||||
Shader "Synaptic/DissolvePro"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
[Header(Base)]
|
||||
_MainTex ("Albedo", 2D) = "white" {}
|
||||
_BaseColor ("Base Color", Color) = (1, 1, 1, 1)
|
||||
_Metallic ("Metallic", Range(0, 1)) = 0
|
||||
_Smoothness ("Smoothness", Range(0, 1)) = 0.5
|
||||
_BumpMap ("Normal Map", 2D) = "bump" {}
|
||||
_BumpScale ("Normal Scale", Float) = 1
|
||||
|
||||
[Header(Dissolve)]
|
||||
_DissolveAmount ("Dissolve Amount", Range(0, 1)) = 0
|
||||
_DissolveNoise ("Dissolve Noise", 2D) = "white" {}
|
||||
_DissolveScale ("Noise Scale", Float) = 1
|
||||
_DissolveDirection ("Direction (XYZ)", Vector) = (0, 1, 0, 0)
|
||||
[Toggle(_DIRECTIONAL_DISSOLVE)] _DirectionalDissolve ("Directional", Float) = 0
|
||||
_DirectionalBias ("Directional Bias", Range(0, 1)) = 0.5
|
||||
|
||||
[Header(Edge Effect)]
|
||||
_EdgeColor1 ("Edge Color 1", Color) = (1, 0.5, 0, 1)
|
||||
_EdgeColor2 ("Edge Color 2", Color) = (1, 0, 0, 1)
|
||||
_EdgeWidth ("Edge Width", Range(0, 0.5)) = 0.1
|
||||
_EdgeIntensity ("Edge Intensity", Range(0, 10)) = 3
|
||||
[Toggle(_EDGE_GLOW)] _EdgeGlow ("Edge Glow", Float) = 1
|
||||
|
||||
[Header(Particles)]
|
||||
[Toggle(_PARTICLES_ON)] _ParticlesEnabled ("Enable Particles", Float) = 1
|
||||
_ParticleColor ("Particle Color", Color) = (1, 0.7, 0.3, 1)
|
||||
_ParticleSize ("Particle Size", Range(0, 0.1)) = 0.02
|
||||
_ParticleSpeed ("Particle Speed", Float) = 2
|
||||
_ParticleDensity ("Particle Density", Range(0, 1)) = 0.5
|
||||
|
||||
[Header(Vertex Displacement)]
|
||||
[Toggle(_VERTEX_DISPLACEMENT)] _VertexDisplacement ("Vertex Displacement", Float) = 0
|
||||
_DisplacementStrength ("Displacement Strength", Float) = 0.5
|
||||
_DisplacementDirection ("Displacement Dir", Vector) = (0, 1, 0, 0)
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
PackageRequirements { "com.unity.render-pipelines.universal" }
|
||||
Tags
|
||||
{
|
||||
"RenderType" = "Opaque"
|
||||
"Queue" = "Geometry"
|
||||
"RenderPipeline" = "UniversalPipeline"
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "DissolveForward"
|
||||
Tags { "LightMode" = "UniversalForward" }
|
||||
|
||||
Cull Back
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 4.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE
|
||||
#pragma multi_compile_fragment _ _SHADOWS_SOFT
|
||||
#pragma multi_compile_fog
|
||||
|
||||
#pragma shader_feature_local _DIRECTIONAL_DISSOLVE
|
||||
#pragma shader_feature_local _EDGE_GLOW
|
||||
#pragma shader_feature_local _PARTICLES_ON
|
||||
#pragma shader_feature_local _VERTEX_DISPLACEMENT
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
|
||||
TEXTURE2D(_MainTex);
|
||||
TEXTURE2D(_BumpMap);
|
||||
TEXTURE2D(_DissolveNoise);
|
||||
SAMPLER(sampler_MainTex);
|
||||
SAMPLER(sampler_BumpMap);
|
||||
SAMPLER(sampler_DissolveNoise);
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _MainTex_ST;
|
||||
float4 _BaseColor;
|
||||
float _Metallic;
|
||||
float _Smoothness;
|
||||
float4 _BumpMap_ST;
|
||||
float _BumpScale;
|
||||
|
||||
float _DissolveAmount;
|
||||
float4 _DissolveNoise_ST;
|
||||
float _DissolveScale;
|
||||
float4 _DissolveDirection;
|
||||
float _DirectionalBias;
|
||||
|
||||
float4 _EdgeColor1;
|
||||
float4 _EdgeColor2;
|
||||
float _EdgeWidth;
|
||||
float _EdgeIntensity;
|
||||
|
||||
float4 _ParticleColor;
|
||||
float _ParticleSize;
|
||||
float _ParticleSpeed;
|
||||
float _ParticleDensity;
|
||||
|
||||
float _DisplacementStrength;
|
||||
float4 _DisplacementDirection;
|
||||
CBUFFER_END
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float3 normalOS : NORMAL;
|
||||
float4 tangentOS : TANGENT;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 worldPos : TEXCOORD1;
|
||||
float3 worldNormal : TEXCOORD2;
|
||||
float3 worldTangent : TEXCOORD3;
|
||||
float3 worldBitangent : TEXCOORD4;
|
||||
float4 shadowCoord : TEXCOORD5;
|
||||
float fogFactor : TEXCOORD6;
|
||||
float3 objectPos : TEXCOORD7;
|
||||
};
|
||||
|
||||
// Hash for particles
|
||||
float Hash(float2 p)
|
||||
{
|
||||
return frac(sin(dot(p, float2(12.9898, 78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
Varyings vert(Attributes IN)
|
||||
{
|
||||
Varyings OUT;
|
||||
|
||||
float3 posOS = IN.positionOS.xyz;
|
||||
OUT.objectPos = posOS;
|
||||
|
||||
// Sample noise for vertex displacement
|
||||
#if defined(_VERTEX_DISPLACEMENT)
|
||||
float2 noiseUV = IN.uv * _DissolveScale;
|
||||
float noise = SAMPLE_TEXTURE2D_LOD(_DissolveNoise, sampler_DissolveNoise, noiseUV, 0).r;
|
||||
|
||||
float dissolveEdge = 1 - _DissolveAmount;
|
||||
float edgeFactor = saturate((noise - dissolveEdge) / _EdgeWidth);
|
||||
|
||||
if (edgeFactor > 0)
|
||||
{
|
||||
float3 dispDir = normalize(_DisplacementDirection.xyz);
|
||||
posOS += dispDir * edgeFactor * _DisplacementStrength;
|
||||
}
|
||||
#endif
|
||||
|
||||
OUT.worldPos = TransformObjectToWorld(posOS);
|
||||
OUT.positionCS = TransformWorldToHClip(OUT.worldPos);
|
||||
OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex);
|
||||
|
||||
OUT.worldNormal = TransformObjectToWorldNormal(IN.normalOS);
|
||||
OUT.worldTangent = TransformObjectToWorldDir(IN.tangentOS.xyz);
|
||||
OUT.worldBitangent = cross(OUT.worldNormal, OUT.worldTangent) * IN.tangentOS.w;
|
||||
|
||||
OUT.shadowCoord = TransformWorldToShadowCoord(OUT.worldPos);
|
||||
OUT.fogFactor = ComputeFogFactor(OUT.positionCS.z);
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
float4 frag(Varyings IN) : SV_Target
|
||||
{
|
||||
// Sample dissolve noise
|
||||
float2 noiseUV = IN.uv * _DissolveScale;
|
||||
float noise = SAMPLE_TEXTURE2D(_DissolveNoise, sampler_DissolveNoise, noiseUV).r;
|
||||
|
||||
// Directional dissolve
|
||||
#if defined(_DIRECTIONAL_DISSOLVE)
|
||||
float3 dir = normalize(_DissolveDirection.xyz);
|
||||
float dirFactor = dot(normalize(IN.objectPos), dir) * 0.5 + 0.5;
|
||||
noise = lerp(noise, dirFactor, _DirectionalBias);
|
||||
#endif
|
||||
|
||||
// Dissolve threshold
|
||||
float dissolveThreshold = 1 - _DissolveAmount;
|
||||
clip(noise - dissolveThreshold);
|
||||
|
||||
// Edge detection
|
||||
float edge = 1 - saturate((noise - dissolveThreshold) / _EdgeWidth);
|
||||
|
||||
// Sample textures
|
||||
float4 albedo = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv) * _BaseColor;
|
||||
float3 normalTS = UnpackNormalScale(SAMPLE_TEXTURE2D(_BumpMap, sampler_BumpMap, IN.uv), _BumpScale);
|
||||
|
||||
// Transform normal
|
||||
float3x3 TBN = float3x3(IN.worldTangent, IN.worldBitangent, IN.worldNormal);
|
||||
float3 worldNormal = normalize(mul(normalTS, TBN));
|
||||
|
||||
// Lighting
|
||||
Light mainLight = GetMainLight(IN.shadowCoord);
|
||||
float3 lightDir = mainLight.direction;
|
||||
float3 lightColor = mainLight.color * mainLight.shadowAttenuation;
|
||||
float3 viewDir = normalize(_WorldSpaceCameraPos - IN.worldPos);
|
||||
|
||||
float NdotL = saturate(dot(worldNormal, lightDir));
|
||||
float3 diffuse = albedo.rgb * lightColor * NdotL;
|
||||
|
||||
// Specular
|
||||
float3 halfDir = normalize(lightDir + viewDir);
|
||||
float NdotH = saturate(dot(worldNormal, halfDir));
|
||||
float spec = pow(NdotH, _Smoothness * 128);
|
||||
float3 specular = spec * lightColor * _Metallic;
|
||||
|
||||
// Ambient
|
||||
float3 ambient = albedo.rgb * 0.1;
|
||||
|
||||
float3 finalColor = diffuse + specular + ambient;
|
||||
|
||||
// Edge glow
|
||||
#if defined(_EDGE_GLOW)
|
||||
float3 edgeColor = lerp(_EdgeColor2.rgb, _EdgeColor1.rgb, edge);
|
||||
float edgeGlow = edge * _EdgeIntensity;
|
||||
finalColor += edgeColor * edgeGlow;
|
||||
#endif
|
||||
|
||||
// Particles
|
||||
#if defined(_PARTICLES_ON)
|
||||
float particleHash = Hash(IN.uv * 100 + _Time.y * _ParticleSpeed);
|
||||
if (particleHash > 1 - _ParticleDensity && edge > 0.5)
|
||||
{
|
||||
float particleBrightness = particleHash * edge * 2;
|
||||
finalColor += _ParticleColor.rgb * particleBrightness;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fog
|
||||
finalColor = MixFog(finalColor, IN.fogFactor);
|
||||
|
||||
return float4(finalColor, albedo.a);
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// Shadow caster
|
||||
Pass
|
||||
{
|
||||
Name "ShadowCaster"
|
||||
Tags { "LightMode" = "ShadowCaster" }
|
||||
|
||||
ZWrite On
|
||||
ZTest LEqual
|
||||
ColorMask 0
|
||||
Cull Back
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex ShadowVert
|
||||
#pragma fragment ShadowFrag
|
||||
|
||||
#pragma shader_feature_local _DIRECTIONAL_DISSOLVE
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
|
||||
float3 _LightDirection;
|
||||
|
||||
float3 ApplyShadowBiasCustom(float3 positionWS, float3 normalWS, float3 lightDirection)
|
||||
{
|
||||
float invNdotL = 1.0 - saturate(dot(lightDirection, normalWS));
|
||||
float scale = invNdotL * 0.001;
|
||||
positionWS = lightDirection * 0.001 + positionWS;
|
||||
positionWS = normalWS * scale.xxx + positionWS;
|
||||
return positionWS;
|
||||
}
|
||||
|
||||
TEXTURE2D(_DissolveNoise);
|
||||
SAMPLER(sampler_DissolveNoise);
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _MainTex_ST;
|
||||
float _DissolveAmount;
|
||||
float _DissolveScale;
|
||||
float4 _DissolveDirection;
|
||||
float _DirectionalBias;
|
||||
CBUFFER_END
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float3 normalOS : NORMAL;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 objectPos : TEXCOORD1;
|
||||
};
|
||||
|
||||
Varyings ShadowVert(Attributes IN)
|
||||
{
|
||||
Varyings OUT;
|
||||
|
||||
float3 worldPos = TransformObjectToWorld(IN.positionOS.xyz);
|
||||
float3 worldNormal = TransformObjectToWorldNormal(IN.normalOS);
|
||||
|
||||
worldPos = ApplyShadowBiasCustom(worldPos, worldNormal, _LightDirection);
|
||||
OUT.positionCS = TransformWorldToHClip(worldPos);
|
||||
#if UNITY_REVERSED_Z
|
||||
OUT.positionCS.z = min(OUT.positionCS.z, UNITY_NEAR_CLIP_VALUE);
|
||||
#else
|
||||
OUT.positionCS.z = max(OUT.positionCS.z, UNITY_NEAR_CLIP_VALUE);
|
||||
#endif
|
||||
OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex);
|
||||
OUT.objectPos = IN.positionOS.xyz;
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
float4 ShadowFrag(Varyings IN) : SV_Target
|
||||
{
|
||||
float noise = SAMPLE_TEXTURE2D(_DissolveNoise, sampler_DissolveNoise, IN.uv * _DissolveScale).r;
|
||||
|
||||
#if defined(_DIRECTIONAL_DISSOLVE)
|
||||
float3 dir = normalize(_DissolveDirection.xyz);
|
||||
float dirFactor = dot(normalize(IN.objectPos), dir) * 0.5 + 0.5;
|
||||
noise = lerp(noise, dirFactor, _DirectionalBias);
|
||||
#endif
|
||||
|
||||
clip(noise - (1 - _DissolveAmount));
|
||||
return 0;
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== Built-in Pipeline SubShader ====================
|
||||
SubShader
|
||||
{
|
||||
Tags { "RenderType" = "Opaque" "Queue" = "Geometry" }
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "DissolveBuiltIn"
|
||||
Tags { "LightMode" = "ForwardBase" }
|
||||
Cull Back
|
||||
|
||||
CGPROGRAM
|
||||
#pragma target 3.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile_fwdbase
|
||||
#pragma multi_compile_fog
|
||||
|
||||
#pragma shader_feature_local _DIRECTIONAL_DISSOLVE
|
||||
#pragma shader_feature_local _EDGE_GLOW
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
#include "Lighting.cginc"
|
||||
#include "AutoLight.cginc"
|
||||
|
||||
sampler2D _MainTex;
|
||||
sampler2D _DissolveNoise;
|
||||
float4 _MainTex_ST;
|
||||
float4 _BaseColor;
|
||||
float _DissolveAmount;
|
||||
float _DissolveScale;
|
||||
float4 _DissolveDirection;
|
||||
float _DirectionalBias;
|
||||
float4 _EdgeColor1;
|
||||
float4 _EdgeColor2;
|
||||
float _EdgeWidth;
|
||||
float _EdgeIntensity;
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float3 normal : NORMAL;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 worldPos : TEXCOORD1;
|
||||
float3 worldNormal : TEXCOORD2;
|
||||
float3 objectPos : TEXCOORD3;
|
||||
SHADOW_COORDS(4)
|
||||
UNITY_FOG_COORDS(5)
|
||||
};
|
||||
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
|
||||
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
|
||||
o.worldNormal = UnityObjectToWorldNormal(v.normal);
|
||||
o.objectPos = v.vertex.xyz;
|
||||
TRANSFER_SHADOW(o)
|
||||
UNITY_TRANSFER_FOG(o, o.pos);
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 frag(v2f i) : SV_Target
|
||||
{
|
||||
float2 noiseUV = i.uv * _DissolveScale;
|
||||
float noise = tex2D(_DissolveNoise, noiseUV).r;
|
||||
|
||||
#if defined(_DIRECTIONAL_DISSOLVE)
|
||||
float3 dir = normalize(_DissolveDirection.xyz);
|
||||
float dirFactor = dot(normalize(i.objectPos), dir) * 0.5 + 0.5;
|
||||
noise = lerp(noise, dirFactor, _DirectionalBias);
|
||||
#endif
|
||||
|
||||
float dissolveThreshold = 1 - _DissolveAmount;
|
||||
clip(noise - dissolveThreshold);
|
||||
|
||||
float edge = 1 - saturate((noise - dissolveThreshold) / _EdgeWidth);
|
||||
|
||||
float4 albedo = tex2D(_MainTex, i.uv) * _BaseColor;
|
||||
float3 normal = normalize(i.worldNormal);
|
||||
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
|
||||
float shadow = SHADOW_ATTENUATION(i);
|
||||
|
||||
float NdotL = saturate(dot(normal, lightDir));
|
||||
float3 diffuse = albedo.rgb * _LightColor0.rgb * NdotL * shadow;
|
||||
float3 ambient = albedo.rgb * 0.1;
|
||||
float3 finalColor = diffuse + ambient;
|
||||
|
||||
#if defined(_EDGE_GLOW)
|
||||
float3 edgeColor = lerp(_EdgeColor2.rgb, _EdgeColor1.rgb, edge);
|
||||
finalColor += edgeColor * edge * _EdgeIntensity;
|
||||
#endif
|
||||
|
||||
UNITY_APPLY_FOG(i.fogCoord, finalColor);
|
||||
return float4(finalColor, albedo.a);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== HDRP SubShader ====================
|
||||
SubShader
|
||||
{
|
||||
PackageRequirements { "com.unity.render-pipelines.high-definition" }
|
||||
Tags { "RenderType" = "Opaque" "Queue" = "Geometry" "RenderPipeline" = "HDRenderPipeline" }
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "DissolveHDRP"
|
||||
Tags { "LightMode" = "Forward" }
|
||||
Cull Back
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 4.5
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma shader_feature_local _DIRECTIONAL_DISSOLVE
|
||||
#pragma shader_feature_local _EDGE_GLOW
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
||||
|
||||
TEXTURE2D(_MainTex);
|
||||
TEXTURE2D(_DissolveNoise);
|
||||
SAMPLER(sampler_MainTex);
|
||||
SAMPLER(sampler_DissolveNoise);
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _MainTex_ST;
|
||||
float4 _BaseColor;
|
||||
float _DissolveAmount;
|
||||
float _DissolveScale;
|
||||
float4 _DissolveDirection;
|
||||
float _DirectionalBias;
|
||||
float4 _EdgeColor1;
|
||||
float4 _EdgeColor2;
|
||||
float _EdgeWidth;
|
||||
float _EdgeIntensity;
|
||||
CBUFFER_END
|
||||
|
||||
struct Attributes { float4 positionOS : POSITION; float3 normalOS : NORMAL; float2 uv : TEXCOORD0; };
|
||||
struct Varyings { float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; float3 worldNormal : TEXCOORD1; float3 objectPos : TEXCOORD2; };
|
||||
|
||||
Varyings vert(Attributes IN)
|
||||
{
|
||||
Varyings OUT;
|
||||
OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz);
|
||||
OUT.uv = IN.uv * _MainTex_ST.xy + _MainTex_ST.zw;
|
||||
OUT.worldNormal = TransformObjectToWorldNormal(IN.normalOS);
|
||||
OUT.objectPos = IN.positionOS.xyz;
|
||||
return OUT;
|
||||
}
|
||||
|
||||
float4 frag(Varyings IN) : SV_Target
|
||||
{
|
||||
float noise = SAMPLE_TEXTURE2D(_DissolveNoise, sampler_DissolveNoise, IN.uv * _DissolveScale).r;
|
||||
#if defined(_DIRECTIONAL_DISSOLVE)
|
||||
float dirFactor = dot(normalize(IN.objectPos), normalize(_DissolveDirection.xyz)) * 0.5 + 0.5;
|
||||
noise = lerp(noise, dirFactor, _DirectionalBias);
|
||||
#endif
|
||||
clip(noise - (1 - _DissolveAmount));
|
||||
|
||||
float edge = 1 - saturate((noise - (1 - _DissolveAmount)) / _EdgeWidth);
|
||||
float4 albedo = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv) * _BaseColor;
|
||||
float3 finalColor = albedo.rgb;
|
||||
#if defined(_EDGE_GLOW)
|
||||
finalColor += lerp(_EdgeColor2.rgb, _EdgeColor1.rgb, edge) * edge * _EdgeIntensity;
|
||||
#endif
|
||||
return float4(finalColor, albedo.a);
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
FallBack "Universal Render Pipeline/Lit"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fef1849f0393c49c0a988af724c12ffb
|
||||
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/Effects/SynapticDissolvePro.shader
|
||||
uploadId: 920982
|
||||
@@ -0,0 +1,458 @@
|
||||
Shader "Synaptic/ShieldPro"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
[Header(Shield Color)]
|
||||
_MainColor ("Main Color", Color) = (0.2, 0.5, 1.0, 0.3)
|
||||
_EdgeColor ("Edge Color", Color) = (0.5, 0.8, 1.0, 1.0)
|
||||
_HitColor ("Hit Color", Color) = (1.0, 0.5, 0.2, 1.0)
|
||||
_FresnelColor ("Fresnel Color", Color) = (0.3, 0.6, 1.0, 1.0)
|
||||
|
||||
[Header(Pattern)]
|
||||
_PatternTex ("Pattern Texture", 2D) = "white" {}
|
||||
_PatternScale ("Pattern Scale", Float) = 1
|
||||
_PatternIntensity ("Pattern Intensity", Range(0, 2)) = 0.5
|
||||
_PatternScrollSpeed ("Pattern Scroll Speed", Vector) = (0.1, 0.1, 0, 0)
|
||||
|
||||
[Header(Hex Pattern)]
|
||||
[Toggle(_HEX_PATTERN)] _HexPattern ("Hex Pattern", Float) = 1
|
||||
_HexScale ("Hex Scale", Float) = 10
|
||||
_HexEdgeWidth ("Hex Edge Width", Range(0.01, 0.5)) = 0.1
|
||||
_HexPulseSpeed ("Hex Pulse Speed", Float) = 2
|
||||
|
||||
[Header(Fresnel)]
|
||||
_FresnelPower ("Fresnel Power", Range(0.5, 10)) = 3
|
||||
_FresnelIntensity ("Fresnel Intensity", Range(0, 5)) = 2
|
||||
|
||||
[Header(Hit Effect)]
|
||||
[Toggle(_HIT_EFFECT)] _HitEffect ("Enable Hit Effect", Float) = 1
|
||||
_HitPosition ("Hit Position", Vector) = (0, 0, 0, 0)
|
||||
_HitRadius ("Hit Radius", Float) = 0.5
|
||||
_HitIntensity ("Hit Intensity", Range(0, 1)) = 0
|
||||
_HitRippleCount ("Ripple Count", Float) = 3
|
||||
_HitRippleSpeed ("Ripple Speed", Float) = 5
|
||||
|
||||
[Header(Distortion)]
|
||||
[Toggle(_DISTORTION)] _Distortion ("Enable Distortion", Float) = 1
|
||||
_DistortionStrength ("Distortion Strength", Range(0, 0.1)) = 0.02
|
||||
_DistortionSpeed ("Distortion Speed", Float) = 1
|
||||
|
||||
[Header(Animation)]
|
||||
_PulseSpeed ("Pulse Speed", Float) = 2
|
||||
_PulseIntensity ("Pulse Intensity", Range(0, 1)) = 0.2
|
||||
_WaveSpeed ("Wave Speed", Float) = 1
|
||||
_WaveFrequency ("Wave Frequency", Float) = 5
|
||||
_WaveAmplitude ("Wave Amplitude", Range(0, 0.1)) = 0.02
|
||||
|
||||
[Header(Intersection)]
|
||||
[Toggle(_INTERSECTION)] _Intersection ("Intersection Glow", Float) = 1
|
||||
_IntersectionColor ("Intersection Color", Color) = (1, 1, 1, 1)
|
||||
_IntersectionWidth ("Intersection Width", Float) = 0.5
|
||||
_IntersectionIntensity ("Intersection Intensity", Range(0, 5)) = 2
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
PackageRequirements { "com.unity.render-pipelines.universal" }
|
||||
Tags
|
||||
{
|
||||
"RenderType" = "Transparent"
|
||||
"Queue" = "Transparent"
|
||||
"RenderPipeline" = "UniversalPipeline"
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "ShieldForward"
|
||||
Tags { "LightMode" = "UniversalForward" }
|
||||
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
ZWrite Off
|
||||
Cull Back
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 4.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#pragma shader_feature_local _HEX_PATTERN
|
||||
#pragma shader_feature_local _HIT_EFFECT
|
||||
#pragma shader_feature_local _DISTORTION
|
||||
#pragma shader_feature_local _INTERSECTION
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareOpaqueTexture.hlsl"
|
||||
|
||||
TEXTURE2D(_PatternTex);
|
||||
SAMPLER(sampler_PatternTex);
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _MainColor;
|
||||
float4 _EdgeColor;
|
||||
float4 _HitColor;
|
||||
float4 _FresnelColor;
|
||||
|
||||
float4 _PatternTex_ST;
|
||||
float _PatternScale;
|
||||
float _PatternIntensity;
|
||||
float4 _PatternScrollSpeed;
|
||||
|
||||
float _HexScale;
|
||||
float _HexEdgeWidth;
|
||||
float _HexPulseSpeed;
|
||||
|
||||
float _FresnelPower;
|
||||
float _FresnelIntensity;
|
||||
|
||||
float4 _HitPosition;
|
||||
float _HitRadius;
|
||||
float _HitIntensity;
|
||||
float _HitRippleCount;
|
||||
float _HitRippleSpeed;
|
||||
|
||||
float _DistortionStrength;
|
||||
float _DistortionSpeed;
|
||||
|
||||
float _PulseSpeed;
|
||||
float _PulseIntensity;
|
||||
float _WaveSpeed;
|
||||
float _WaveFrequency;
|
||||
float _WaveAmplitude;
|
||||
|
||||
float4 _IntersectionColor;
|
||||
float _IntersectionWidth;
|
||||
float _IntersectionIntensity;
|
||||
CBUFFER_END
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float3 normalOS : NORMAL;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 worldPos : TEXCOORD1;
|
||||
float3 worldNormal : TEXCOORD2;
|
||||
float3 viewDir : TEXCOORD3;
|
||||
float4 screenPos : TEXCOORD4;
|
||||
float3 objectPos : TEXCOORD5;
|
||||
};
|
||||
|
||||
// Hexagonal pattern
|
||||
float HexPattern(float2 p)
|
||||
{
|
||||
const float2 s = float2(1, 1.7320508);
|
||||
p *= _HexScale;
|
||||
|
||||
float4 hC = floor(float4(p, p - float2(0.5, 1)) / s.xyxy) + 0.5;
|
||||
float4 h = float4(p - hC.xy * s, p - (hC.zw + 0.5) * s);
|
||||
|
||||
float2 nearest = dot(h.xy, h.xy) < dot(h.zw, h.zw) ? h.xy : h.zw;
|
||||
|
||||
float dist = length(nearest);
|
||||
float hexEdge = smoothstep(_HexEdgeWidth, _HexEdgeWidth + 0.02, abs(dist - 0.5));
|
||||
|
||||
return 1 - hexEdge;
|
||||
}
|
||||
|
||||
Varyings vert(Attributes IN)
|
||||
{
|
||||
Varyings OUT;
|
||||
|
||||
float3 posOS = IN.positionOS.xyz;
|
||||
OUT.objectPos = posOS;
|
||||
|
||||
// Vertex wave animation
|
||||
float wave = sin(_Time.y * _WaveSpeed + posOS.y * _WaveFrequency) * _WaveAmplitude;
|
||||
posOS += IN.normalOS * wave;
|
||||
|
||||
OUT.worldPos = TransformObjectToWorld(posOS);
|
||||
OUT.positionCS = TransformWorldToHClip(OUT.worldPos);
|
||||
OUT.uv = IN.uv;
|
||||
|
||||
OUT.worldNormal = TransformObjectToWorldNormal(IN.normalOS);
|
||||
OUT.viewDir = normalize(_WorldSpaceCameraPos - OUT.worldPos);
|
||||
OUT.screenPos = ComputeScreenPos(OUT.positionCS);
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
float4 frag(Varyings IN) : SV_Target
|
||||
{
|
||||
float3 normal = normalize(IN.worldNormal);
|
||||
float3 viewDir = normalize(IN.viewDir);
|
||||
float time = _Time.y;
|
||||
|
||||
// Screen UV
|
||||
float2 screenUV = IN.screenPos.xy / IN.screenPos.w;
|
||||
|
||||
// Fresnel
|
||||
float fresnel = pow(1 - saturate(dot(viewDir, normal)), _FresnelPower) * _FresnelIntensity;
|
||||
|
||||
// Base color with fresnel
|
||||
float4 color = lerp(_MainColor, _FresnelColor, fresnel);
|
||||
|
||||
// Hex pattern
|
||||
#if defined(_HEX_PATTERN)
|
||||
float hex = HexPattern(IN.uv);
|
||||
float hexPulse = sin(time * _HexPulseSpeed) * 0.5 + 0.5;
|
||||
color.rgb += _EdgeColor.rgb * hex * (0.5 + hexPulse * 0.5);
|
||||
color.a += hex * 0.3;
|
||||
#endif
|
||||
|
||||
// Pattern texture
|
||||
float2 patternUV = IN.uv * _PatternScale + time * _PatternScrollSpeed.xy;
|
||||
float pattern = SAMPLE_TEXTURE2D(_PatternTex, sampler_PatternTex, patternUV).r;
|
||||
color.rgb += pattern * _PatternIntensity * _EdgeColor.rgb;
|
||||
|
||||
// Hit effect
|
||||
#if defined(_HIT_EFFECT)
|
||||
if (_HitIntensity > 0.001)
|
||||
{
|
||||
float3 hitDir = IN.worldPos - _HitPosition.xyz;
|
||||
float hitDist = length(hitDir);
|
||||
|
||||
// Ripple waves
|
||||
float ripple = 0;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
float ripplePhase = time * _HitRippleSpeed - i * 0.3;
|
||||
float rippleRadius = frac(ripplePhase) * _HitRadius * 2;
|
||||
float rippleWidth = 0.1;
|
||||
ripple += (1 - abs(hitDist - rippleRadius) / rippleWidth) * saturate(1 - frac(ripplePhase));
|
||||
}
|
||||
ripple = saturate(ripple);
|
||||
|
||||
// Fade out over distance
|
||||
float hitFade = 1 - saturate(hitDist / _HitRadius);
|
||||
|
||||
color.rgb = lerp(color.rgb, _HitColor.rgb, ripple * hitFade * _HitIntensity);
|
||||
color.a += ripple * hitFade * _HitIntensity * 0.5;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Intersection glow
|
||||
#if defined(_INTERSECTION)
|
||||
float depth = SampleSceneDepth(screenUV);
|
||||
float linearDepth = LinearEyeDepth(depth, _ZBufferParams);
|
||||
float surfaceDepth = LinearEyeDepth(IN.positionCS.z, _ZBufferParams);
|
||||
float depthDiff = abs(linearDepth - surfaceDepth);
|
||||
|
||||
if (depthDiff < _IntersectionWidth)
|
||||
{
|
||||
float intersectionFactor = 1 - saturate(depthDiff / _IntersectionWidth);
|
||||
intersectionFactor = pow(intersectionFactor, 2);
|
||||
color.rgb += _IntersectionColor.rgb * intersectionFactor * _IntersectionIntensity;
|
||||
color.a += intersectionFactor * 0.5;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Distortion
|
||||
#if defined(_DISTORTION)
|
||||
float2 distortionOffset = normal.xy * _DistortionStrength;
|
||||
distortionOffset *= sin(time * _DistortionSpeed + IN.uv.y * 10) * 0.5 + 0.5;
|
||||
float3 distortedBG = SampleSceneColor(screenUV + distortionOffset);
|
||||
color.rgb = lerp(distortedBG, color.rgb, color.a);
|
||||
#endif
|
||||
|
||||
// Pulse animation
|
||||
float pulse = sin(time * _PulseSpeed) * _PulseIntensity;
|
||||
color.a += pulse;
|
||||
|
||||
// Edge highlight
|
||||
color.rgb += _EdgeColor.rgb * fresnel * 0.5;
|
||||
|
||||
// Clamp alpha
|
||||
color.a = saturate(color.a);
|
||||
|
||||
return color;
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== Built-in Pipeline SubShader ====================
|
||||
SubShader
|
||||
{
|
||||
Tags { "RenderType" = "Transparent" "Queue" = "Transparent" }
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "ShieldBuiltIn"
|
||||
Tags { "LightMode" = "ForwardBase" }
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
ZWrite Off
|
||||
Cull Back
|
||||
|
||||
CGPROGRAM
|
||||
#pragma target 3.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma shader_feature_local _HEX_PATTERN
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
float4 _MainColor;
|
||||
float4 _EdgeColor;
|
||||
float4 _FresnelColor;
|
||||
float _FresnelPower;
|
||||
float _FresnelIntensity;
|
||||
float _HexScale;
|
||||
float _HexEdgeWidth;
|
||||
float _HexPulseSpeed;
|
||||
float _PulseSpeed;
|
||||
float _PulseIntensity;
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float3 normal : NORMAL;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 worldNormal : TEXCOORD1;
|
||||
float3 viewDir : TEXCOORD2;
|
||||
};
|
||||
|
||||
float HexPattern(float2 p)
|
||||
{
|
||||
const float2 s = float2(1, 1.7320508);
|
||||
p *= _HexScale;
|
||||
float4 hC = floor(float4(p, p - float2(0.5, 1)) / s.xyxy) + 0.5;
|
||||
float4 h = float4(p - hC.xy * s, p - (hC.zw + 0.5) * s);
|
||||
float2 nearest = dot(h.xy, h.xy) < dot(h.zw, h.zw) ? h.xy : h.zw;
|
||||
float dist = length(nearest);
|
||||
return 1 - smoothstep(_HexEdgeWidth, _HexEdgeWidth + 0.02, abs(dist - 0.5));
|
||||
}
|
||||
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.uv;
|
||||
o.worldNormal = UnityObjectToWorldNormal(v.normal);
|
||||
o.viewDir = normalize(_WorldSpaceCameraPos - mul(unity_ObjectToWorld, v.vertex).xyz);
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 frag(v2f i) : SV_Target
|
||||
{
|
||||
float3 normal = normalize(i.worldNormal);
|
||||
float3 viewDir = normalize(i.viewDir);
|
||||
float time = _Time.y;
|
||||
|
||||
float fresnel = pow(1 - saturate(dot(viewDir, normal)), _FresnelPower) * _FresnelIntensity;
|
||||
float4 color = lerp(_MainColor, _FresnelColor, fresnel);
|
||||
|
||||
#if defined(_HEX_PATTERN)
|
||||
float hex = HexPattern(i.uv);
|
||||
float hexPulse = sin(time * _HexPulseSpeed) * 0.5 + 0.5;
|
||||
color.rgb += _EdgeColor.rgb * hex * (0.5 + hexPulse * 0.5);
|
||||
color.a += hex * 0.3;
|
||||
#endif
|
||||
|
||||
float pulse = sin(time * _PulseSpeed) * _PulseIntensity;
|
||||
color.a += pulse;
|
||||
color.rgb += _EdgeColor.rgb * fresnel * 0.5;
|
||||
color.a = saturate(color.a);
|
||||
|
||||
return color;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== HDRP SubShader ====================
|
||||
SubShader
|
||||
{
|
||||
PackageRequirements { "com.unity.render-pipelines.high-definition" }
|
||||
Tags { "RenderType" = "Transparent" "Queue" = "Transparent" "RenderPipeline" = "HDRenderPipeline" }
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "ShieldHDRP"
|
||||
Tags { "LightMode" = "Forward" }
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
ZWrite Off
|
||||
Cull Back
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 4.5
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma shader_feature_local _HEX_PATTERN
|
||||
|
||||
#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 _MainColor;
|
||||
float4 _EdgeColor;
|
||||
float4 _FresnelColor;
|
||||
float _FresnelPower;
|
||||
float _FresnelIntensity;
|
||||
float _HexScale;
|
||||
float _HexEdgeWidth;
|
||||
float _HexPulseSpeed;
|
||||
float _PulseSpeed;
|
||||
float _PulseIntensity;
|
||||
CBUFFER_END
|
||||
|
||||
struct Attributes { float4 positionOS : POSITION; float3 normalOS : NORMAL; float2 uv : TEXCOORD0; };
|
||||
struct Varyings { float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; float3 worldNormal : TEXCOORD1; float3 viewDir : TEXCOORD2; };
|
||||
|
||||
float HexPattern(float2 p, float scale, float edgeWidth)
|
||||
{
|
||||
const float2 s = float2(1, 1.7320508);
|
||||
p *= scale;
|
||||
float4 hC = floor(float4(p, p - float2(0.5, 1)) / s.xyxy) + 0.5;
|
||||
float4 h = float4(p - hC.xy * s, p - (hC.zw + 0.5) * s);
|
||||
float2 nearest = dot(h.xy, h.xy) < dot(h.zw, h.zw) ? h.xy : h.zw;
|
||||
return 1 - smoothstep(edgeWidth, edgeWidth + 0.02, abs(length(nearest) - 0.5));
|
||||
}
|
||||
|
||||
Varyings vert(Attributes IN)
|
||||
{
|
||||
Varyings OUT;
|
||||
float3 worldPos = TransformObjectToWorld(IN.positionOS.xyz);
|
||||
OUT.positionCS = TransformWorldToHClip(worldPos);
|
||||
OUT.uv = IN.uv;
|
||||
OUT.worldNormal = TransformObjectToWorldNormal(IN.normalOS);
|
||||
OUT.viewDir = GetWorldSpaceNormalizeViewDir(worldPos);
|
||||
return OUT;
|
||||
}
|
||||
|
||||
float4 frag(Varyings IN) : SV_Target
|
||||
{
|
||||
float3 normal = normalize(IN.worldNormal);
|
||||
float3 viewDir = normalize(IN.viewDir);
|
||||
float fresnel = pow(1 - saturate(dot(viewDir, normal)), _FresnelPower) * _FresnelIntensity;
|
||||
float4 color = lerp(_MainColor, _FresnelColor, fresnel);
|
||||
|
||||
#if defined(_HEX_PATTERN)
|
||||
float hex = HexPattern(IN.uv, _HexScale, _HexEdgeWidth);
|
||||
float hexPulse = sin(_Time.y * _HexPulseSpeed) * 0.5 + 0.5;
|
||||
color.rgb += _EdgeColor.rgb * hex * (0.5 + hexPulse * 0.5);
|
||||
color.a += hex * 0.3;
|
||||
#endif
|
||||
|
||||
color.a += sin(_Time.y * _PulseSpeed) * _PulseIntensity;
|
||||
color.rgb += _EdgeColor.rgb * fresnel * 0.5;
|
||||
color.a = saturate(color.a);
|
||||
return color;
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
FallBack "Universal Render Pipeline/Unlit"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd72a59a6dbde45f8bf617b27ba32f94
|
||||
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/Effects/SynapticShieldPro.shader
|
||||
uploadId: 920982
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20c818fdd20f14e1d9b93c2b928652cc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,176 @@
|
||||
// Synaptic AI Pro - GPU Grass Instancing Compute Shader
|
||||
// Handles culling, LOD, and instance buffer generation for massive grass rendering
|
||||
|
||||
#pragma kernel CSMain
|
||||
#pragma kernel CSClear
|
||||
|
||||
// Grass instance data
|
||||
struct GrassInstance
|
||||
{
|
||||
float3 position;
|
||||
float3 normal;
|
||||
float2 uv;
|
||||
float height;
|
||||
float width;
|
||||
float rotation;
|
||||
float stiffness;
|
||||
float windPhase;
|
||||
};
|
||||
|
||||
// Indirect draw arguments
|
||||
struct IndirectArgs
|
||||
{
|
||||
uint vertexCountPerInstance;
|
||||
uint instanceCount;
|
||||
uint startVertexLocation;
|
||||
uint startInstanceLocation;
|
||||
};
|
||||
|
||||
// Input buffers
|
||||
StructuredBuffer<GrassInstance> _SourceInstances;
|
||||
RWStructuredBuffer<GrassInstance> _CulledInstances;
|
||||
RWStructuredBuffer<IndirectArgs> _IndirectArgs;
|
||||
|
||||
// Counters
|
||||
RWStructuredBuffer<uint> _InstanceCounter;
|
||||
|
||||
// Parameters
|
||||
float4x4 _ViewProjectionMatrix;
|
||||
float4x4 _ViewMatrix;
|
||||
float3 _CameraPosition;
|
||||
float3 _CameraForward;
|
||||
float _FrustumCullMargin;
|
||||
float _MaxRenderDistance;
|
||||
float _LOD0Distance;
|
||||
float _LOD1Distance;
|
||||
float _LOD2Distance;
|
||||
float _DensityFalloff;
|
||||
float _Time;
|
||||
|
||||
// Wind parameters
|
||||
float3 _WindDirection;
|
||||
float _WindStrength;
|
||||
float _WindSpeed;
|
||||
float _WindFrequency;
|
||||
|
||||
// Frustum planes
|
||||
float4 _FrustumPlanes[6];
|
||||
|
||||
// Instance counts
|
||||
uint _TotalInstances;
|
||||
uint _MaxVisibleInstances;
|
||||
|
||||
// LOD group (0, 1, 2)
|
||||
uint _LODGroup;
|
||||
|
||||
// Check if point is inside frustum
|
||||
bool IsInsideFrustum(float3 position, float margin)
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
float dist = dot(_FrustumPlanes[i].xyz, position) + _FrustumPlanes[i].w;
|
||||
if (dist < -margin)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Calculate LOD level based on distance
|
||||
uint GetLODLevel(float distance)
|
||||
{
|
||||
if (distance < _LOD0Distance)
|
||||
return 0;
|
||||
else if (distance < _LOD1Distance)
|
||||
return 1;
|
||||
else if (distance < _LOD2Distance)
|
||||
return 2;
|
||||
else
|
||||
return 3; // Culled
|
||||
}
|
||||
|
||||
// Hash function for consistent randomization
|
||||
float Hash(float2 p)
|
||||
{
|
||||
return frac(sin(dot(p, float2(127.1, 311.7))) * 43758.5453);
|
||||
}
|
||||
|
||||
// Wind offset calculation (matches shader)
|
||||
float3 CalculateWindOffset(float3 position, float height, float windPhase)
|
||||
{
|
||||
float3 windDir = normalize(_WindDirection);
|
||||
|
||||
// Main wind wave
|
||||
float phase = dot(position.xz, windDir.xz) * _WindFrequency + _Time * _WindSpeed + windPhase;
|
||||
float wave = sin(phase) * 0.5 + 0.5;
|
||||
|
||||
// Gust
|
||||
float gustPhase = _Time * 0.5 + windPhase;
|
||||
float gust = sin(gustPhase) * sin(gustPhase * 2.3) * 0.3;
|
||||
|
||||
float windFactor = (wave + gust) * _WindStrength * height * height;
|
||||
|
||||
return windDir * windFactor;
|
||||
}
|
||||
|
||||
[numthreads(256, 1, 1)]
|
||||
void CSMain(uint3 id : SV_DispatchThreadID)
|
||||
{
|
||||
if (id.x >= _TotalInstances)
|
||||
return;
|
||||
|
||||
GrassInstance instance = _SourceInstances[id.x];
|
||||
|
||||
// Calculate distance to camera
|
||||
float3 toCamera = _CameraPosition - instance.position;
|
||||
float distance = length(toCamera);
|
||||
|
||||
// Distance culling
|
||||
if (distance > _MaxRenderDistance)
|
||||
return;
|
||||
|
||||
// LOD selection
|
||||
uint lodLevel = GetLODLevel(distance);
|
||||
if (lodLevel != _LODGroup)
|
||||
return;
|
||||
|
||||
// Density falloff (render fewer instances at distance)
|
||||
if (lodLevel > 0)
|
||||
{
|
||||
float densityThreshold = 1.0 - (distance - _LOD0Distance) / (_MaxRenderDistance - _LOD0Distance) * _DensityFalloff;
|
||||
float randomValue = Hash(instance.position.xz);
|
||||
if (randomValue > densityThreshold)
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate wind-affected position for frustum culling
|
||||
float3 windOffset = CalculateWindOffset(instance.position, instance.height, instance.windPhase);
|
||||
float3 tipPosition = instance.position + float3(0, instance.height, 0) + windOffset;
|
||||
|
||||
// Frustum culling (check both root and tip)
|
||||
float cullMargin = _FrustumCullMargin + instance.height;
|
||||
if (!IsInsideFrustum(instance.position, cullMargin) && !IsInsideFrustum(tipPosition, cullMargin))
|
||||
return;
|
||||
|
||||
// Backface culling optimization (skip grass facing away)
|
||||
float3 grassForward = instance.normal;
|
||||
float facingRatio = dot(normalize(toCamera), grassForward);
|
||||
// Allow grass to be seen from both sides, but skip if completely edge-on
|
||||
if (abs(facingRatio) < 0.1)
|
||||
return;
|
||||
|
||||
// Add to visible buffer
|
||||
uint index;
|
||||
InterlockedAdd(_InstanceCounter[0], 1, index);
|
||||
|
||||
if (index < _MaxVisibleInstances)
|
||||
{
|
||||
_CulledInstances[index] = instance;
|
||||
}
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void CSClear(uint3 id : SV_DispatchThreadID)
|
||||
{
|
||||
_InstanceCounter[0] = 0;
|
||||
_IndirectArgs[0].instanceCount = 0;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6031fc9431d7a496bbcd62708bdb5f7a
|
||||
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/Grass/GrassInstancer.compute
|
||||
uploadId: 920982
|
||||
@@ -0,0 +1,874 @@
|
||||
Shader "Synaptic/GrassPro"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
[Header(Base)]
|
||||
_MainTex ("Albedo", 2D) = "white" {}
|
||||
_BaseColor ("Base Color", Color) = (0.2, 0.6, 0.2, 1)
|
||||
_TipColor ("Tip Color", Color) = (0.5, 0.9, 0.3, 1)
|
||||
_GradientPower ("Gradient Power", Range(0.1, 3)) = 1
|
||||
|
||||
[Header(Wind Animation)]
|
||||
[Toggle(_WIND_ON)] _WindEnabled ("Enable Wind", Float) = 1
|
||||
_WindStrength ("Wind Strength", Range(0, 2)) = 0.5
|
||||
_WindSpeed ("Wind Speed", Float) = 1
|
||||
_WindFrequency ("Wind Frequency", Float) = 1
|
||||
_WindDirection ("Wind Direction", Vector) = (1, 0, 0.5, 0)
|
||||
_WindNoiseTex ("Wind Noise", 2D) = "grey" {}
|
||||
_WindNoiseScale ("Wind Noise Scale", Float) = 0.1
|
||||
_WindGustStrength ("Gust Strength", Range(0, 2)) = 0.3
|
||||
_WindGustFrequency ("Gust Frequency", Float) = 0.5
|
||||
|
||||
[Header(Player Interaction)]
|
||||
[Toggle(_INTERACTION_ON)] _InteractionEnabled ("Enable Interaction", Float) = 1
|
||||
_InteractionRadius ("Interaction Radius", Float) = 2
|
||||
_InteractionStrength ("Interaction Strength", Range(0, 2)) = 1
|
||||
_InteractionFalloff ("Interaction Falloff", Range(0.1, 5)) = 2
|
||||
|
||||
[Header(Subsurface Scattering)]
|
||||
[Toggle(_SSS_ON)] _SSSEnabled ("Enable SSS", Float) = 1
|
||||
_SSSColor ("SSS Color", Color) = (0.8, 1.0, 0.5, 1)
|
||||
_SSSStrength ("SSS Strength", Range(0, 2)) = 1
|
||||
_SSSDistortion ("SSS Distortion", Range(0, 1)) = 0.5
|
||||
_SSSPower ("SSS Power", Range(1, 16)) = 4
|
||||
|
||||
[Header(Detail)]
|
||||
_AO ("Ambient Occlusion", Range(0, 1)) = 0.5
|
||||
_AOPower ("AO Power", Range(0.1, 3)) = 1
|
||||
_Roughness ("Roughness", Range(0, 1)) = 0.8
|
||||
|
||||
[Header(Specular)]
|
||||
[Toggle(_SPECULAR_ON)] _SpecularEnabled ("Enable Specular", Float) = 1
|
||||
_SpecularColor ("Specular Color", Color) = (1, 1, 0.8, 1)
|
||||
_SpecularIntensity ("Specular Intensity", Range(0, 3)) = 0.5
|
||||
_SpecularPower ("Specular Power", Range(1, 128)) = 32
|
||||
|
||||
[Header(Distance Fade)]
|
||||
[Toggle(_DISTANCE_FADE_ON)] _DistanceFadeEnabled ("Enable Distance Fade", Float) = 1
|
||||
_FadeStart ("Fade Start", Float) = 30
|
||||
_FadeEnd ("Fade End", Float) = 50
|
||||
_FadeMinScale ("Fade Min Scale", Range(0, 1)) = 0.3
|
||||
|
||||
[Header(Cutout)]
|
||||
_Cutoff ("Alpha Cutoff", Range(0, 1)) = 0.5
|
||||
|
||||
[Header(Rendering)]
|
||||
[Enum(UnityEngine.Rendering.CullMode)] _Cull ("Cull Mode", Float) = 0
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
PackageRequirements { "com.unity.render-pipelines.universal" }
|
||||
Tags
|
||||
{
|
||||
"RenderType" = "TransparentCutout"
|
||||
"Queue" = "AlphaTest"
|
||||
"RenderPipeline" = "UniversalPipeline"
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "GrassForward"
|
||||
Tags { "LightMode" = "UniversalForward" }
|
||||
|
||||
Cull [_Cull]
|
||||
AlphaToMask On
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 4.5
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE
|
||||
#pragma multi_compile_fragment _ _SHADOWS_SOFT
|
||||
#pragma multi_compile _ _ADDITIONAL_LIGHTS
|
||||
#pragma multi_compile_fog
|
||||
#pragma multi_compile_instancing
|
||||
|
||||
#pragma shader_feature_local _WIND_ON
|
||||
#pragma shader_feature_local _INTERACTION_ON
|
||||
#pragma shader_feature_local _SSS_ON
|
||||
#pragma shader_feature_local _SPECULAR_ON
|
||||
#pragma shader_feature_local _DISTANCE_FADE_ON
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
|
||||
TEXTURE2D(_MainTex);
|
||||
TEXTURE2D(_WindNoiseTex);
|
||||
SAMPLER(sampler_MainTex);
|
||||
SAMPLER(sampler_WindNoiseTex);
|
||||
|
||||
// Interaction positions (set from script)
|
||||
float4 _InteractionPositions[16];
|
||||
int _InteractionCount;
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _MainTex_ST;
|
||||
float4 _BaseColor;
|
||||
float4 _TipColor;
|
||||
float _GradientPower;
|
||||
|
||||
float _WindStrength;
|
||||
float _WindSpeed;
|
||||
float _WindFrequency;
|
||||
float4 _WindDirection;
|
||||
float4 _WindNoiseTex_ST;
|
||||
float _WindNoiseScale;
|
||||
float _WindGustStrength;
|
||||
float _WindGustFrequency;
|
||||
|
||||
float _InteractionRadius;
|
||||
float _InteractionStrength;
|
||||
float _InteractionFalloff;
|
||||
|
||||
float4 _SSSColor;
|
||||
float _SSSStrength;
|
||||
float _SSSDistortion;
|
||||
float _SSSPower;
|
||||
|
||||
float _AO;
|
||||
float _AOPower;
|
||||
float _Roughness;
|
||||
|
||||
float4 _SpecularColor;
|
||||
float _SpecularIntensity;
|
||||
float _SpecularPower;
|
||||
|
||||
float _FadeStart;
|
||||
float _FadeEnd;
|
||||
float _FadeMinScale;
|
||||
|
||||
float _Cutoff;
|
||||
CBUFFER_END
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float3 normalOS : NORMAL;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 color : COLOR; // R = height, G = AO, B = unused, A = stiffness
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 worldPos : TEXCOORD1;
|
||||
float3 worldNormal : TEXCOORD2;
|
||||
float4 vertexColor : TEXCOORD3;
|
||||
float4 shadowCoord : TEXCOORD4;
|
||||
float fogFactor : TEXCOORD5;
|
||||
float heightGradient : TEXCOORD6;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
// Wind functions
|
||||
float3 WindAnimation(float3 worldPos, float height, float stiffness, float time)
|
||||
{
|
||||
#if defined(_WIND_ON)
|
||||
float3 windDir = normalize(_WindDirection.xyz);
|
||||
|
||||
// Sample wind noise
|
||||
float2 noiseUV = worldPos.xz * _WindNoiseScale + time * _WindSpeed * 0.1;
|
||||
float noise = SAMPLE_TEXTURE2D_LOD(_WindNoiseTex, sampler_WindNoiseTex, noiseUV, 0).r;
|
||||
|
||||
// Main wind wave
|
||||
float windPhase = dot(worldPos.xz, windDir.xz) * _WindFrequency + time * _WindSpeed;
|
||||
float wave = sin(windPhase) * 0.5 + 0.5;
|
||||
|
||||
// Gust
|
||||
float gustPhase = time * _WindGustFrequency;
|
||||
float gust = sin(gustPhase) * sin(gustPhase * 2.3) * _WindGustStrength;
|
||||
|
||||
// Combined wind
|
||||
float windFactor = (wave + gust + noise - 0.5) * _WindStrength;
|
||||
windFactor *= height * height; // Quadratic falloff from root
|
||||
windFactor *= (1 - stiffness); // Stiffness reduces wind effect
|
||||
|
||||
return windDir * windFactor;
|
||||
#else
|
||||
return float3(0, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Player interaction
|
||||
float3 InteractionDisplacement(float3 worldPos, float height)
|
||||
{
|
||||
#if defined(_INTERACTION_ON)
|
||||
float3 totalDisplacement = float3(0, 0, 0);
|
||||
|
||||
for (int i = 0; i < _InteractionCount && i < 16; i++)
|
||||
{
|
||||
float3 interactorPos = _InteractionPositions[i].xyz;
|
||||
float3 toGrass = worldPos - interactorPos;
|
||||
toGrass.y = 0;
|
||||
|
||||
float dist = length(toGrass);
|
||||
float influence = 1 - saturate(pow(dist / _InteractionRadius, _InteractionFalloff));
|
||||
|
||||
if (influence > 0.001)
|
||||
{
|
||||
float3 pushDir = normalize(toGrass + float3(0.001, 0, 0.001));
|
||||
totalDisplacement += pushDir * influence * _InteractionStrength * height;
|
||||
}
|
||||
}
|
||||
|
||||
return totalDisplacement;
|
||||
#else
|
||||
return float3(0, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
Varyings vert(Attributes IN)
|
||||
{
|
||||
Varyings OUT;
|
||||
UNITY_SETUP_INSTANCE_ID(IN);
|
||||
UNITY_TRANSFER_INSTANCE_ID(IN, OUT);
|
||||
|
||||
float height = IN.color.r; // Height along blade (0 = root, 1 = tip)
|
||||
float stiffness = IN.color.a;
|
||||
float time = _Time.y;
|
||||
|
||||
float3 posOS = IN.positionOS.xyz;
|
||||
float3 worldPosBase = TransformObjectToWorld(float3(0, 0, 0));
|
||||
|
||||
// Distance fade
|
||||
#if defined(_DISTANCE_FADE_ON)
|
||||
float distToCam = distance(worldPosBase, _WorldSpaceCameraPos);
|
||||
float fadeFactor = saturate((distToCam - _FadeStart) / (_FadeEnd - _FadeStart));
|
||||
float scale = lerp(1, _FadeMinScale, fadeFactor);
|
||||
posOS *= scale;
|
||||
#endif
|
||||
|
||||
float3 worldPos = TransformObjectToWorld(posOS);
|
||||
|
||||
// Apply wind
|
||||
float3 windOffset = WindAnimation(worldPos, height, stiffness, time);
|
||||
worldPos += windOffset;
|
||||
|
||||
// Apply interaction
|
||||
float3 interactOffset = InteractionDisplacement(worldPos, height);
|
||||
worldPos += interactOffset;
|
||||
|
||||
OUT.worldPos = worldPos;
|
||||
OUT.positionCS = TransformWorldToHClip(worldPos);
|
||||
OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex);
|
||||
OUT.worldNormal = TransformObjectToWorldNormal(IN.normalOS);
|
||||
OUT.vertexColor = IN.color;
|
||||
OUT.shadowCoord = TransformWorldToShadowCoord(worldPos);
|
||||
OUT.fogFactor = ComputeFogFactor(OUT.positionCS.z);
|
||||
OUT.heightGradient = height;
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
// SSS function
|
||||
float3 SubsurfaceScattering(float3 viewDir, float3 lightDir, float3 normal, float3 lightColor)
|
||||
{
|
||||
#if defined(_SSS_ON)
|
||||
float3 H = normalize(lightDir + normal * _SSSDistortion);
|
||||
float VdotH = pow(saturate(dot(viewDir, -H)), _SSSPower);
|
||||
return _SSSColor.rgb * VdotH * _SSSStrength * lightColor;
|
||||
#else
|
||||
return float3(0, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
float4 frag(Varyings IN) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_INSTANCE_ID(IN);
|
||||
|
||||
// Sample texture
|
||||
float4 texColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv);
|
||||
clip(texColor.a - _Cutoff);
|
||||
|
||||
float3 viewDir = normalize(_WorldSpaceCameraPos - IN.worldPos);
|
||||
float3 normal = normalize(IN.worldNormal);
|
||||
|
||||
// Height-based color gradient
|
||||
float gradientFactor = pow(IN.heightGradient, _GradientPower);
|
||||
float3 albedo = lerp(_BaseColor.rgb, _TipColor.rgb, gradientFactor) * texColor.rgb;
|
||||
|
||||
// Ambient occlusion from vertex color
|
||||
float ao = lerp(1, IN.vertexColor.g, _AO);
|
||||
ao = pow(ao, _AOPower);
|
||||
|
||||
// Lighting
|
||||
Light mainLight = GetMainLight(IN.shadowCoord);
|
||||
float3 lightDir = mainLight.direction;
|
||||
float3 lightColor = mainLight.color;
|
||||
float shadow = mainLight.shadowAttenuation;
|
||||
|
||||
// Wrapped diffuse for softer look
|
||||
float NdotL = dot(normal, lightDir);
|
||||
float wrappedNdotL = NdotL * 0.5 + 0.5;
|
||||
float3 diffuse = albedo * lightColor * wrappedNdotL * shadow;
|
||||
|
||||
// SSS
|
||||
float3 sss = SubsurfaceScattering(viewDir, lightDir, normal, lightColor);
|
||||
sss *= (1 - IN.heightGradient) * shadow; // More SSS at base
|
||||
|
||||
// Specular
|
||||
float3 specular = float3(0, 0, 0);
|
||||
#if defined(_SPECULAR_ON)
|
||||
float3 halfDir = normalize(lightDir + viewDir);
|
||||
float NdotH = saturate(dot(normal, halfDir));
|
||||
float spec = pow(NdotH, _SpecularPower) * _SpecularIntensity;
|
||||
specular = _SpecularColor.rgb * spec * shadow * IN.heightGradient; // More specular at tip
|
||||
#endif
|
||||
|
||||
// Additional lights
|
||||
float3 additionalLights = float3(0, 0, 0);
|
||||
#if defined(_ADDITIONAL_LIGHTS)
|
||||
uint pixelLightCount = GetAdditionalLightsCount();
|
||||
for (uint i = 0; i < pixelLightCount; i++)
|
||||
{
|
||||
Light light = GetAdditionalLight(i, IN.worldPos);
|
||||
float addNdotL = saturate(dot(normal, light.direction));
|
||||
additionalLights += albedo * light.color * light.distanceAttenuation * addNdotL * 0.5;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Ambient
|
||||
float3 ambient = albedo * 0.1;
|
||||
|
||||
// Combine
|
||||
float3 finalColor = (diffuse + sss + specular + additionalLights + ambient) * ao;
|
||||
|
||||
// Fog
|
||||
finalColor = MixFog(finalColor, IN.fogFactor);
|
||||
|
||||
return float4(finalColor, texColor.a);
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// Shadow caster pass
|
||||
Pass
|
||||
{
|
||||
Name "ShadowCaster"
|
||||
Tags { "LightMode" = "ShadowCaster" }
|
||||
|
||||
ZWrite On
|
||||
ZTest LEqual
|
||||
ColorMask 0
|
||||
Cull Off
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 4.5
|
||||
#pragma vertex ShadowVert
|
||||
#pragma fragment ShadowFrag
|
||||
|
||||
#pragma multi_compile_instancing
|
||||
#pragma shader_feature_local _WIND_ON
|
||||
#pragma shader_feature_local _DISTANCE_FADE_ON
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
|
||||
float3 _LightDirection;
|
||||
|
||||
float3 ApplyShadowBiasCustom(float3 positionWS, float3 normalWS, float3 lightDirection)
|
||||
{
|
||||
float invNdotL = 1.0 - saturate(dot(lightDirection, normalWS));
|
||||
float scale = invNdotL * 0.001;
|
||||
positionWS = lightDirection * 0.001 + positionWS;
|
||||
positionWS = normalWS * scale.xxx + positionWS;
|
||||
return positionWS;
|
||||
}
|
||||
|
||||
TEXTURE2D(_MainTex);
|
||||
TEXTURE2D(_WindNoiseTex);
|
||||
SAMPLER(sampler_MainTex);
|
||||
SAMPLER(sampler_WindNoiseTex);
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _MainTex_ST;
|
||||
float _WindStrength;
|
||||
float _WindSpeed;
|
||||
float _WindFrequency;
|
||||
float4 _WindDirection;
|
||||
float _WindNoiseScale;
|
||||
float _WindGustStrength;
|
||||
float _WindGustFrequency;
|
||||
float _FadeStart;
|
||||
float _FadeEnd;
|
||||
float _FadeMinScale;
|
||||
float _Cutoff;
|
||||
CBUFFER_END
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float3 normalOS : NORMAL;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 color : COLOR;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
float3 WindAnimation(float3 worldPos, float height, float stiffness, float time)
|
||||
{
|
||||
#if defined(_WIND_ON)
|
||||
float3 windDir = normalize(_WindDirection.xyz);
|
||||
float windPhase = dot(worldPos.xz, windDir.xz) * _WindFrequency + time * _WindSpeed;
|
||||
float wave = sin(windPhase) * 0.5 + 0.5;
|
||||
float gustPhase = time * _WindGustFrequency;
|
||||
float gust = sin(gustPhase) * sin(gustPhase * 2.3) * _WindGustStrength;
|
||||
float windFactor = (wave + gust - 0.25) * _WindStrength;
|
||||
windFactor *= height * height;
|
||||
windFactor *= (1 - stiffness);
|
||||
return windDir * windFactor;
|
||||
#else
|
||||
return float3(0, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
Varyings ShadowVert(Attributes IN)
|
||||
{
|
||||
Varyings OUT;
|
||||
UNITY_SETUP_INSTANCE_ID(IN);
|
||||
UNITY_TRANSFER_INSTANCE_ID(IN, OUT);
|
||||
|
||||
float height = IN.color.r;
|
||||
float stiffness = IN.color.a;
|
||||
|
||||
float3 posOS = IN.positionOS.xyz;
|
||||
|
||||
#if defined(_DISTANCE_FADE_ON)
|
||||
float3 worldPosBase = TransformObjectToWorld(float3(0, 0, 0));
|
||||
float distToCam = distance(worldPosBase, _WorldSpaceCameraPos);
|
||||
float fadeFactor = saturate((distToCam - _FadeStart) / (_FadeEnd - _FadeStart));
|
||||
float scale = lerp(1, _FadeMinScale, fadeFactor);
|
||||
posOS *= scale;
|
||||
#endif
|
||||
|
||||
float3 worldPos = TransformObjectToWorld(posOS);
|
||||
worldPos += WindAnimation(worldPos, height, stiffness, _Time.y);
|
||||
|
||||
float3 worldNormal = TransformObjectToWorldNormal(IN.normalOS);
|
||||
worldPos = ApplyShadowBiasCustom(worldPos, worldNormal, _LightDirection);
|
||||
float4 posCS = TransformWorldToHClip(worldPos);
|
||||
|
||||
#if UNITY_REVERSED_Z
|
||||
posCS.z = min(posCS.z, UNITY_NEAR_CLIP_VALUE);
|
||||
#else
|
||||
posCS.z = max(posCS.z, UNITY_NEAR_CLIP_VALUE);
|
||||
#endif
|
||||
|
||||
OUT.positionCS = posCS;
|
||||
OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex);
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
float4 ShadowFrag(Varyings IN) : SV_Target
|
||||
{
|
||||
float alpha = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv).a;
|
||||
clip(alpha - _Cutoff);
|
||||
return 0;
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// Depth pass
|
||||
Pass
|
||||
{
|
||||
Name "DepthOnly"
|
||||
Tags { "LightMode" = "DepthOnly" }
|
||||
|
||||
ZWrite On
|
||||
ColorMask 0
|
||||
Cull Off
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 4.5
|
||||
#pragma vertex DepthVert
|
||||
#pragma fragment DepthFrag
|
||||
|
||||
#pragma multi_compile_instancing
|
||||
#pragma shader_feature_local _WIND_ON
|
||||
#pragma shader_feature_local _DISTANCE_FADE_ON
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
|
||||
TEXTURE2D(_MainTex);
|
||||
SAMPLER(sampler_MainTex);
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _MainTex_ST;
|
||||
float _WindStrength;
|
||||
float _WindSpeed;
|
||||
float _WindFrequency;
|
||||
float4 _WindDirection;
|
||||
float _WindGustStrength;
|
||||
float _WindGustFrequency;
|
||||
float _FadeStart;
|
||||
float _FadeEnd;
|
||||
float _FadeMinScale;
|
||||
float _Cutoff;
|
||||
CBUFFER_END
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 color : COLOR;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
float3 WindAnimation(float3 worldPos, float height, float stiffness, float time)
|
||||
{
|
||||
#if defined(_WIND_ON)
|
||||
float3 windDir = normalize(_WindDirection.xyz);
|
||||
float windPhase = dot(worldPos.xz, windDir.xz) * _WindFrequency + time * _WindSpeed;
|
||||
float wave = sin(windPhase) * 0.5 + 0.5;
|
||||
float gustPhase = time * _WindGustFrequency;
|
||||
float gust = sin(gustPhase) * sin(gustPhase * 2.3) * _WindGustStrength;
|
||||
float windFactor = (wave + gust - 0.25) * _WindStrength;
|
||||
windFactor *= height * height;
|
||||
windFactor *= (1 - stiffness);
|
||||
return windDir * windFactor;
|
||||
#else
|
||||
return float3(0, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
Varyings DepthVert(Attributes IN)
|
||||
{
|
||||
Varyings OUT;
|
||||
UNITY_SETUP_INSTANCE_ID(IN);
|
||||
|
||||
float height = IN.color.r;
|
||||
float stiffness = IN.color.a;
|
||||
float3 posOS = IN.positionOS.xyz;
|
||||
|
||||
#if defined(_DISTANCE_FADE_ON)
|
||||
float3 worldPosBase = TransformObjectToWorld(float3(0, 0, 0));
|
||||
float distToCam = distance(worldPosBase, _WorldSpaceCameraPos);
|
||||
float fadeFactor = saturate((distToCam - _FadeStart) / (_FadeEnd - _FadeStart));
|
||||
posOS *= lerp(1, _FadeMinScale, fadeFactor);
|
||||
#endif
|
||||
|
||||
float3 worldPos = TransformObjectToWorld(posOS);
|
||||
worldPos += WindAnimation(worldPos, height, stiffness, _Time.y);
|
||||
|
||||
OUT.positionCS = TransformWorldToHClip(worldPos);
|
||||
OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex);
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
float4 DepthFrag(Varyings IN) : SV_Target
|
||||
{
|
||||
float alpha = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv).a;
|
||||
clip(alpha - _Cutoff);
|
||||
return 0;
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== Built-in Pipeline SubShader ====================
|
||||
SubShader
|
||||
{
|
||||
Tags { "RenderType" = "TransparentCutout" "Queue" = "AlphaTest" }
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "GrassBuiltIn"
|
||||
Tags { "LightMode" = "ForwardBase" }
|
||||
Cull Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma target 3.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile_fwdbase
|
||||
#pragma multi_compile_fog
|
||||
#pragma multi_compile_instancing
|
||||
|
||||
#pragma shader_feature_local _WIND_ON
|
||||
#pragma shader_feature_local _SSS_ON
|
||||
#pragma shader_feature_local _SPECULAR_ON
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
#include "Lighting.cginc"
|
||||
#include "AutoLight.cginc"
|
||||
|
||||
sampler2D _MainTex;
|
||||
float4 _MainTex_ST;
|
||||
float4 _BaseColor;
|
||||
float4 _TipColor;
|
||||
float _GradientPower;
|
||||
float _WindStrength;
|
||||
float _WindSpeed;
|
||||
float _WindFrequency;
|
||||
float4 _WindDirection;
|
||||
float _WindGustStrength;
|
||||
float _WindGustFrequency;
|
||||
float4 _SSSColor;
|
||||
float _SSSStrength;
|
||||
float _SSSDistortion;
|
||||
float _SSSPower;
|
||||
float4 _SpecularColor;
|
||||
float _SpecularIntensity;
|
||||
float _SpecularPower;
|
||||
float _AO;
|
||||
float _AOPower;
|
||||
float _Cutoff;
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float3 normal : NORMAL;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 color : COLOR;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 worldPos : TEXCOORD1;
|
||||
float3 worldNormal : TEXCOORD2;
|
||||
float4 vertexColor : TEXCOORD3;
|
||||
float heightGradient : TEXCOORD4;
|
||||
SHADOW_COORDS(5)
|
||||
UNITY_FOG_COORDS(6)
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
float3 WindAnimation(float3 worldPos, float height, float stiffness, float time)
|
||||
{
|
||||
#if defined(_WIND_ON)
|
||||
float3 windDir = normalize(_WindDirection.xyz);
|
||||
float windPhase = dot(worldPos.xz, windDir.xz) * _WindFrequency + time * _WindSpeed;
|
||||
float wave = sin(windPhase) * 0.5 + 0.5;
|
||||
float gustPhase = time * _WindGustFrequency;
|
||||
float gust = sin(gustPhase) * sin(gustPhase * 2.3) * _WindGustStrength;
|
||||
float windFactor = (wave + gust - 0.25) * _WindStrength;
|
||||
windFactor *= height * height * (1 - stiffness);
|
||||
return windDir * windFactor;
|
||||
#else
|
||||
return float3(0, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_TRANSFER_INSTANCE_ID(v, o);
|
||||
|
||||
float height = v.color.r;
|
||||
float stiffness = v.color.a;
|
||||
float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
|
||||
worldPos += WindAnimation(worldPos, height, stiffness, _Time.y);
|
||||
|
||||
o.pos = mul(UNITY_MATRIX_VP, float4(worldPos, 1));
|
||||
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
|
||||
o.worldPos = worldPos;
|
||||
o.worldNormal = UnityObjectToWorldNormal(v.normal);
|
||||
o.vertexColor = v.color;
|
||||
o.heightGradient = height;
|
||||
TRANSFER_SHADOW(o)
|
||||
UNITY_TRANSFER_FOG(o, o.pos);
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 frag(v2f i) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_INSTANCE_ID(i);
|
||||
|
||||
float4 texColor = tex2D(_MainTex, i.uv);
|
||||
clip(texColor.a - _Cutoff);
|
||||
|
||||
float3 viewDir = normalize(_WorldSpaceCameraPos - i.worldPos);
|
||||
float3 normal = normalize(i.worldNormal);
|
||||
|
||||
float gradientFactor = pow(i.heightGradient, _GradientPower);
|
||||
float3 albedo = lerp(_BaseColor.rgb, _TipColor.rgb, gradientFactor) * texColor.rgb;
|
||||
|
||||
float ao = pow(lerp(1, i.vertexColor.g, _AO), _AOPower);
|
||||
|
||||
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
|
||||
float3 lightColor = _LightColor0.rgb;
|
||||
float shadow = SHADOW_ATTENUATION(i);
|
||||
|
||||
float NdotL = saturate(dot(normal, lightDir));
|
||||
float3 diffuse = albedo * lightColor * NdotL * shadow;
|
||||
|
||||
float3 sss = float3(0, 0, 0);
|
||||
#if defined(_SSS_ON)
|
||||
float3 H = normalize(lightDir + normal * _SSSDistortion);
|
||||
float VdotH = pow(saturate(dot(viewDir, -H)), _SSSPower);
|
||||
sss = _SSSColor.rgb * VdotH * _SSSStrength * lightColor * shadow;
|
||||
#endif
|
||||
|
||||
float3 specular = float3(0, 0, 0);
|
||||
#if defined(_SPECULAR_ON)
|
||||
float3 halfDir = normalize(lightDir + viewDir);
|
||||
float NdotH = saturate(dot(normal, halfDir));
|
||||
float spec = pow(NdotH, _SpecularPower);
|
||||
specular = _SpecularColor.rgb * spec * _SpecularIntensity * lightColor * shadow;
|
||||
#endif
|
||||
|
||||
float3 ambient = albedo * 0.1;
|
||||
float3 finalColor = (diffuse + sss + specular + ambient) * ao;
|
||||
UNITY_APPLY_FOG(i.fogCoord, finalColor);
|
||||
|
||||
return float4(finalColor, texColor.a);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== HDRP SubShader ====================
|
||||
SubShader
|
||||
{
|
||||
PackageRequirements { "com.unity.render-pipelines.high-definition" }
|
||||
Tags { "RenderType" = "TransparentCutout" "Queue" = "AlphaTest" "RenderPipeline" = "HDRenderPipeline" }
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "GrassHDRP"
|
||||
Tags { "LightMode" = "Forward" }
|
||||
Cull Off
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 4.5
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile_instancing
|
||||
#pragma shader_feature_local _WIND_ON
|
||||
#pragma shader_feature_local _SSS_ON
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
||||
|
||||
TEXTURE2D(_MainTex);
|
||||
SAMPLER(sampler_MainTex);
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _MainTex_ST;
|
||||
float4 _BaseColor;
|
||||
float4 _TipColor;
|
||||
float _GradientPower;
|
||||
float _WindStrength;
|
||||
float _WindSpeed;
|
||||
float _WindFrequency;
|
||||
float4 _WindDirection;
|
||||
float _WindGustStrength;
|
||||
float _WindGustFrequency;
|
||||
float4 _SSSColor;
|
||||
float _SSSStrength;
|
||||
float _SSSDistortion;
|
||||
float _SSSPower;
|
||||
float _AO;
|
||||
float _AOPower;
|
||||
float _Cutoff;
|
||||
CBUFFER_END
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float3 normalOS : NORMAL;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 color : COLOR;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 worldPos : TEXCOORD1;
|
||||
float3 worldNormal : TEXCOORD2;
|
||||
float4 vertexColor : TEXCOORD3;
|
||||
float heightGradient : TEXCOORD4;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
float3 WindAnimation(float3 worldPos, float height, float stiffness, float time)
|
||||
{
|
||||
#if defined(_WIND_ON)
|
||||
float3 windDir = normalize(_WindDirection.xyz);
|
||||
float windPhase = dot(worldPos.xz, windDir.xz) * _WindFrequency + time * _WindSpeed;
|
||||
float wave = sin(windPhase) * 0.5 + 0.5;
|
||||
float gust = sin(time * _WindGustFrequency) * sin(time * _WindGustFrequency * 2.3) * _WindGustStrength;
|
||||
float windFactor = (wave + gust - 0.25) * _WindStrength * height * height * (1 - stiffness);
|
||||
return windDir * windFactor;
|
||||
#else
|
||||
return float3(0, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
Varyings vert(Attributes IN)
|
||||
{
|
||||
Varyings OUT;
|
||||
UNITY_SETUP_INSTANCE_ID(IN);
|
||||
UNITY_TRANSFER_INSTANCE_ID(IN, OUT);
|
||||
|
||||
float height = IN.color.r;
|
||||
float stiffness = IN.color.a;
|
||||
float3 worldPos = TransformObjectToWorld(IN.positionOS.xyz);
|
||||
worldPos += WindAnimation(worldPos, height, stiffness, _Time.y);
|
||||
|
||||
OUT.positionCS = TransformWorldToHClip(worldPos);
|
||||
OUT.uv = IN.uv * _MainTex_ST.xy + _MainTex_ST.zw;
|
||||
OUT.worldPos = worldPos;
|
||||
OUT.worldNormal = TransformObjectToWorldNormal(IN.normalOS);
|
||||
OUT.vertexColor = IN.color;
|
||||
OUT.heightGradient = height;
|
||||
return OUT;
|
||||
}
|
||||
|
||||
float4 frag(Varyings IN) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_INSTANCE_ID(IN);
|
||||
|
||||
float4 texColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv);
|
||||
clip(texColor.a - _Cutoff);
|
||||
|
||||
float3 viewDir = GetWorldSpaceNormalizeViewDir(IN.worldPos);
|
||||
float3 normal = normalize(IN.worldNormal);
|
||||
|
||||
float gradientFactor = pow(IN.heightGradient, _GradientPower);
|
||||
float3 albedo = lerp(_BaseColor.rgb, _TipColor.rgb, gradientFactor) * texColor.rgb;
|
||||
float ao = pow(lerp(1, IN.vertexColor.g, _AO), _AOPower);
|
||||
|
||||
float3 lightDir = float3(0.5, 0.8, 0.2);
|
||||
float NdotL = saturate(dot(normal, lightDir));
|
||||
float3 diffuse = albedo * NdotL;
|
||||
|
||||
float3 sss = float3(0, 0, 0);
|
||||
#if defined(_SSS_ON)
|
||||
float3 H = normalize(lightDir + normal * _SSSDistortion);
|
||||
float VdotH = pow(saturate(dot(viewDir, -H)), _SSSPower);
|
||||
sss = _SSSColor.rgb * VdotH * _SSSStrength;
|
||||
#endif
|
||||
|
||||
float3 finalColor = (diffuse + sss + albedo * 0.1) * ao;
|
||||
return float4(finalColor, texColor.a);
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
FallBack "Universal Render Pipeline/Unlit"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 018e57d0f0e184f44b8e10e7c593c179
|
||||
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/Grass/SynapticGrassPro.shader
|
||||
uploadId: 920982
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4c5963f651ca4850bf6ab0bb31ef14c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14309571ccd3d4d109734f3a3950c40c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,168 @@
|
||||
Shader "Synaptic/SkySphere"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_MainTex ("Texture", 2D) = "white" {}
|
||||
_Tint ("Tint Color", Color) = (1,1,1,1)
|
||||
}
|
||||
|
||||
// URP SubShader
|
||||
SubShader
|
||||
{
|
||||
PackageRequirements { "com.unity.render-pipelines.universal" }
|
||||
Tags { "RenderType"="Background" "Queue"="Background" "RenderPipeline"="UniversalPipeline" }
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "SkySphereURP"
|
||||
Cull Front
|
||||
ZWrite Off
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
TEXTURE2D(_MainTex);
|
||||
SAMPLER(sampler_MainTex);
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _MainTex_ST;
|
||||
float4 _Tint;
|
||||
CBUFFER_END
|
||||
|
||||
Varyings vert(Attributes IN)
|
||||
{
|
||||
Varyings OUT;
|
||||
OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz);
|
||||
OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex);
|
||||
return OUT;
|
||||
}
|
||||
|
||||
half4 frag(Varyings IN) : SV_Target
|
||||
{
|
||||
half4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv) * _Tint;
|
||||
return col;
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
// HDRP SubShader
|
||||
SubShader
|
||||
{
|
||||
PackageRequirements { "com.unity.render-pipelines.high-definition" }
|
||||
Tags { "RenderType"="Background" "Queue"="Background" "RenderPipeline"="HDRenderPipeline" }
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "SkySphereHDRP"
|
||||
Cull Front
|
||||
ZWrite Off
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
TEXTURE2D(_MainTex);
|
||||
SAMPLER(sampler_MainTex);
|
||||
float4 _MainTex_ST;
|
||||
float4 _Tint;
|
||||
|
||||
Varyings vert(Attributes IN)
|
||||
{
|
||||
Varyings OUT;
|
||||
OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz);
|
||||
OUT.uv = IN.uv * _MainTex_ST.xy + _MainTex_ST.zw;
|
||||
return OUT;
|
||||
}
|
||||
|
||||
half4 frag(Varyings IN) : SV_Target
|
||||
{
|
||||
half4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv) * _Tint;
|
||||
return col;
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
// Built-in Render Pipeline fallback
|
||||
SubShader
|
||||
{
|
||||
Tags { "RenderType"="Background" "Queue"="Background" }
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "SkySphereBuiltIn"
|
||||
Cull Front
|
||||
ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 vertex : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
float4 _MainTex_ST;
|
||||
float4 _Tint;
|
||||
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o;
|
||||
o.vertex = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag(v2f i) : SV_Target
|
||||
{
|
||||
fixed4 col = tex2D(_MainTex, i.uv) * _Tint;
|
||||
return col;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
FallBack Off
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 875adde82c7e04d70bfc7791c10b998a
|
||||
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/SkySphere/SynapticSkySphere.shader
|
||||
uploadId: 920982
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2f5e9bae0ef2c48339b22b04ca813916
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1441c9d700fc54fb3b52f7e879cdb592
|
||||
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/Toon/SynapticToonPro.shader
|
||||
uploadId: 920982
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d21c3819758314baba63de21ec9279ba
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,406 @@
|
||||
Shader "Synaptic/Water"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
[Header(Water Color)]
|
||||
_ShallowColor ("Shallow Color", Color) = (0.3, 0.8, 0.9, 0.6)
|
||||
_DeepColor ("Deep Color", Color) = (0.1, 0.3, 0.5, 0.9)
|
||||
_DepthMaxDistance ("Depth Max Distance", Float) = 5.0
|
||||
|
||||
[Header(Waves)]
|
||||
_WaveSpeed ("Wave Speed", Float) = 1.0
|
||||
_WaveStrength ("Wave Strength", Float) = 0.1
|
||||
_WaveFrequency ("Wave Frequency", Float) = 1.0
|
||||
_WaveDirectionA ("Wave Direction A", Vector) = (1, 0, 0, 0)
|
||||
_WaveDirectionB ("Wave Direction B", Vector) = (0, 0, 1, 0)
|
||||
|
||||
[Header(Normal Map)]
|
||||
_NormalMap ("Normal Map", 2D) = "bump" {}
|
||||
_NormalStrength ("Normal Strength", Range(0, 2)) = 1.0
|
||||
_NormalSpeed ("Normal Speed", Float) = 0.5
|
||||
_NormalScale ("Normal Scale", Float) = 1.0
|
||||
|
||||
[Header(Reflection and Refraction)]
|
||||
_ReflectionStrength ("Reflection Strength", Range(0, 1)) = 0.5
|
||||
_RefractionStrength ("Refraction Strength", Range(0, 0.5)) = 0.1
|
||||
_FresnelPower ("Fresnel Power", Range(0.5, 10)) = 5.0
|
||||
|
||||
[Header(Foam)]
|
||||
_FoamColor ("Foam Color", Color) = (1, 1, 1, 1)
|
||||
_FoamDistance ("Foam Distance", Float) = 0.5
|
||||
_FoamCutoff ("Foam Cutoff", Range(0, 1)) = 0.5
|
||||
_FoamSpeed ("Foam Speed", Float) = 1.0
|
||||
_FoamScale ("Foam Scale", Float) = 10.0
|
||||
|
||||
[Header(Specular)]
|
||||
_SpecularColor ("Specular Color", Color) = (1, 1, 1, 1)
|
||||
_Smoothness ("Smoothness", Range(0, 1)) = 0.9
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
PackageRequirements { "com.unity.render-pipelines.universal" }
|
||||
Tags
|
||||
{
|
||||
"RenderType" = "Transparent"
|
||||
"Queue" = "Transparent"
|
||||
"RenderPipeline" = "UniversalPipeline"
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "WaterURP"
|
||||
Tags { "LightMode" = "UniversalForward" }
|
||||
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
ZWrite Off
|
||||
Cull Back
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile_fog
|
||||
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE
|
||||
#pragma multi_compile_fragment _ _SHADOWS_SOFT
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareOpaqueTexture.hlsl"
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float4 positionOS : POSITION;
|
||||
float3 normalOS : NORMAL;
|
||||
float4 tangentOS : TANGENT;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 worldPos : TEXCOORD1;
|
||||
float3 worldNormal : TEXCOORD2;
|
||||
float3 worldTangent : TEXCOORD3;
|
||||
float3 worldBitangent : TEXCOORD4;
|
||||
float4 screenPos : TEXCOORD5;
|
||||
float3 viewDir : TEXCOORD6;
|
||||
float fogFactor : TEXCOORD7;
|
||||
};
|
||||
|
||||
TEXTURE2D(_NormalMap);
|
||||
SAMPLER(sampler_NormalMap);
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float4 _ShallowColor;
|
||||
float4 _DeepColor;
|
||||
float _DepthMaxDistance;
|
||||
|
||||
float _WaveSpeed;
|
||||
float _WaveStrength;
|
||||
float _WaveFrequency;
|
||||
float4 _WaveDirectionA;
|
||||
float4 _WaveDirectionB;
|
||||
|
||||
float4 _NormalMap_ST;
|
||||
float _NormalStrength;
|
||||
float _NormalSpeed;
|
||||
float _NormalScale;
|
||||
|
||||
float _ReflectionStrength;
|
||||
float _RefractionStrength;
|
||||
float _FresnelPower;
|
||||
|
||||
float4 _FoamColor;
|
||||
float _FoamDistance;
|
||||
float _FoamCutoff;
|
||||
float _FoamSpeed;
|
||||
float _FoamScale;
|
||||
|
||||
float4 _SpecularColor;
|
||||
float _Smoothness;
|
||||
CBUFFER_END
|
||||
|
||||
// Gerstner wave function
|
||||
float3 GerstnerWave(float3 position, float2 direction, float steepness, float wavelength, float time)
|
||||
{
|
||||
float k = 2.0 * PI / wavelength;
|
||||
float c = sqrt(9.8 / k);
|
||||
float2 d = normalize(direction);
|
||||
float f = k * (dot(d, position.xz) - c * time);
|
||||
float a = steepness / k;
|
||||
|
||||
return float3(
|
||||
d.x * a * cos(f),
|
||||
a * sin(f),
|
||||
d.y * a * cos(f)
|
||||
);
|
||||
}
|
||||
|
||||
Varyings vert(Attributes IN)
|
||||
{
|
||||
Varyings OUT;
|
||||
|
||||
float3 posOS = IN.positionOS.xyz;
|
||||
float time = _Time.y * _WaveSpeed;
|
||||
|
||||
// Apply Gerstner waves
|
||||
float3 wave1 = GerstnerWave(posOS, _WaveDirectionA.xy, _WaveStrength, _WaveFrequency * 10.0, time);
|
||||
float3 wave2 = GerstnerWave(posOS, _WaveDirectionB.xy, _WaveStrength * 0.5, _WaveFrequency * 7.0, time * 1.3);
|
||||
float3 wave3 = GerstnerWave(posOS, float2(0.7, 0.7), _WaveStrength * 0.3, _WaveFrequency * 5.0, time * 0.8);
|
||||
|
||||
posOS += wave1 + wave2 + wave3;
|
||||
|
||||
OUT.worldPos = TransformObjectToWorld(posOS);
|
||||
OUT.positionCS = TransformWorldToHClip(OUT.worldPos);
|
||||
OUT.uv = IN.uv;
|
||||
OUT.screenPos = ComputeScreenPos(OUT.positionCS);
|
||||
|
||||
// Calculate wave normal
|
||||
float3 tangent = float3(1, 0, 0);
|
||||
float3 bitangent = float3(0, 0, 1);
|
||||
|
||||
// Approximate normal from wave derivatives
|
||||
float delta = 0.1;
|
||||
float3 p1 = posOS + GerstnerWave(posOS + float3(delta, 0, 0), _WaveDirectionA.xy, _WaveStrength, _WaveFrequency * 10.0, time);
|
||||
float3 p2 = posOS + GerstnerWave(posOS + float3(0, 0, delta), _WaveDirectionA.xy, _WaveStrength, _WaveFrequency * 10.0, time);
|
||||
|
||||
tangent = normalize(p1 - posOS);
|
||||
bitangent = normalize(p2 - posOS);
|
||||
float3 waveNormal = normalize(cross(bitangent, tangent));
|
||||
|
||||
OUT.worldNormal = TransformObjectToWorldNormal(waveNormal);
|
||||
OUT.worldTangent = TransformObjectToWorldDir(IN.tangentOS.xyz);
|
||||
OUT.worldBitangent = cross(OUT.worldNormal, OUT.worldTangent) * IN.tangentOS.w;
|
||||
|
||||
OUT.viewDir = GetWorldSpaceViewDir(OUT.worldPos);
|
||||
OUT.fogFactor = ComputeFogFactor(OUT.positionCS.z);
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
// Simple noise for foam
|
||||
float SimpleNoise(float2 uv)
|
||||
{
|
||||
return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
float4 frag(Varyings IN) : SV_Target
|
||||
{
|
||||
float time = _Time.y;
|
||||
|
||||
// Sample normal map (dual layer for movement)
|
||||
float2 normalUV1 = IN.worldPos.xz * _NormalScale + time * _NormalSpeed * float2(0.5, 0.3);
|
||||
float2 normalUV2 = IN.worldPos.xz * _NormalScale * 0.8 - time * _NormalSpeed * float2(0.3, 0.5);
|
||||
|
||||
float3 normalTex1 = UnpackNormalScale(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, normalUV1), _NormalStrength);
|
||||
float3 normalTex2 = UnpackNormalScale(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, normalUV2), _NormalStrength);
|
||||
float3 normalTS = normalize(normalTex1 + normalTex2);
|
||||
|
||||
// Transform normal to world space
|
||||
float3x3 TBN = float3x3(IN.worldTangent, IN.worldBitangent, IN.worldNormal);
|
||||
float3 worldNormal = normalize(mul(normalTS, TBN));
|
||||
|
||||
// Screen UV
|
||||
float2 screenUV = IN.screenPos.xy / IN.screenPos.w;
|
||||
|
||||
// Depth-based color
|
||||
float depth = SampleSceneDepth(screenUV);
|
||||
float linearDepth = LinearEyeDepth(depth, _ZBufferParams);
|
||||
float surfaceDepth = LinearEyeDepth(IN.positionCS.z, _ZBufferParams);
|
||||
float depthDifference = linearDepth - surfaceDepth;
|
||||
float depthFactor = saturate(depthDifference / _DepthMaxDistance);
|
||||
|
||||
float4 waterColor = lerp(_ShallowColor, _DeepColor, depthFactor);
|
||||
|
||||
// Refraction
|
||||
float2 refractionOffset = worldNormal.xz * _RefractionStrength;
|
||||
float2 refractionUV = screenUV + refractionOffset;
|
||||
float3 refractionColor = SampleSceneColor(refractionUV);
|
||||
|
||||
// Fresnel
|
||||
float3 viewDir = normalize(IN.viewDir);
|
||||
float fresnel = pow(1.0 - saturate(dot(viewDir, worldNormal)), _FresnelPower);
|
||||
|
||||
// Reflection (simple sky reflection approximation)
|
||||
float3 reflectDir = reflect(-viewDir, worldNormal);
|
||||
float3 reflectionColor = lerp(float3(0.5, 0.7, 0.9), float3(0.8, 0.9, 1.0), reflectDir.y * 0.5 + 0.5);
|
||||
|
||||
// Lighting
|
||||
Light mainLight = GetMainLight();
|
||||
float3 lightDir = mainLight.direction;
|
||||
|
||||
// Specular (GGX approximation)
|
||||
float3 halfDir = normalize(lightDir + viewDir);
|
||||
float NdotH = saturate(dot(worldNormal, halfDir));
|
||||
float specular = pow(NdotH, _Smoothness * 256.0) * _Smoothness;
|
||||
float3 specularColor = _SpecularColor.rgb * specular * mainLight.color;
|
||||
|
||||
// Foam
|
||||
float foam = 0.0;
|
||||
if (depthDifference < _FoamDistance)
|
||||
{
|
||||
float foamNoise = SimpleNoise(IN.worldPos.xz * _FoamScale + time * _FoamSpeed);
|
||||
float foamFactor = 1.0 - saturate(depthDifference / _FoamDistance);
|
||||
foam = step(_FoamCutoff, foamNoise * foamFactor);
|
||||
}
|
||||
|
||||
// Combine
|
||||
float3 finalColor = lerp(refractionColor, waterColor.rgb, waterColor.a);
|
||||
finalColor = lerp(finalColor, reflectionColor, fresnel * _ReflectionStrength);
|
||||
finalColor += specularColor;
|
||||
finalColor = lerp(finalColor, _FoamColor.rgb, foam);
|
||||
|
||||
// Apply fog
|
||||
finalColor = MixFog(finalColor, IN.fogFactor);
|
||||
|
||||
float alpha = saturate(waterColor.a + fresnel * 0.3 + foam);
|
||||
|
||||
return float4(finalColor, alpha);
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
// Built-in Render Pipeline fallback
|
||||
SubShader
|
||||
{
|
||||
Tags
|
||||
{
|
||||
"RenderType" = "Transparent"
|
||||
"Queue" = "Transparent"
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "WaterBuiltIn"
|
||||
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
ZWrite Off
|
||||
Cull Back
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile_fog
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
#include "Lighting.cginc"
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float3 normal : NORMAL;
|
||||
float4 tangent : TANGENT;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 worldPos : TEXCOORD1;
|
||||
float3 worldNormal : TEXCOORD2;
|
||||
float3 viewDir : TEXCOORD3;
|
||||
UNITY_FOG_COORDS(4)
|
||||
};
|
||||
|
||||
sampler2D _NormalMap;
|
||||
float4 _NormalMap_ST;
|
||||
|
||||
float4 _ShallowColor;
|
||||
float4 _DeepColor;
|
||||
float _WaveSpeed;
|
||||
float _WaveStrength;
|
||||
float _WaveFrequency;
|
||||
float4 _WaveDirectionA;
|
||||
float4 _WaveDirectionB;
|
||||
float _NormalStrength;
|
||||
float _NormalSpeed;
|
||||
float _NormalScale;
|
||||
float _FresnelPower;
|
||||
float4 _SpecularColor;
|
||||
float _Smoothness;
|
||||
float4 _FoamColor;
|
||||
|
||||
// Gerstner wave
|
||||
float3 GerstnerWave(float3 position, float2 direction, float steepness, float wavelength, float time)
|
||||
{
|
||||
float k = 2.0 * UNITY_PI / wavelength;
|
||||
float c = sqrt(9.8 / k);
|
||||
float2 d = normalize(direction);
|
||||
float f = k * (dot(d, position.xz) - c * time);
|
||||
float a = steepness / k;
|
||||
|
||||
return float3(
|
||||
d.x * a * cos(f),
|
||||
a * sin(f),
|
||||
d.y * a * cos(f)
|
||||
);
|
||||
}
|
||||
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o;
|
||||
|
||||
float3 posOS = v.vertex.xyz;
|
||||
float time = _Time.y * _WaveSpeed;
|
||||
|
||||
// Apply waves
|
||||
float3 wave1 = GerstnerWave(posOS, _WaveDirectionA.xy, _WaveStrength, _WaveFrequency * 10.0, time);
|
||||
float3 wave2 = GerstnerWave(posOS, _WaveDirectionB.xy, _WaveStrength * 0.5, _WaveFrequency * 7.0, time * 1.3);
|
||||
posOS += wave1 + wave2;
|
||||
|
||||
o.worldPos = mul(unity_ObjectToWorld, float4(posOS, 1.0)).xyz;
|
||||
o.pos = UnityObjectToClipPos(float4(posOS, 1.0));
|
||||
o.uv = v.uv;
|
||||
o.worldNormal = UnityObjectToWorldNormal(v.normal);
|
||||
o.viewDir = normalize(_WorldSpaceCameraPos - o.worldPos);
|
||||
|
||||
UNITY_TRANSFER_FOG(o, o.pos);
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag(v2f i) : SV_Target
|
||||
{
|
||||
float time = _Time.y;
|
||||
|
||||
// Normal map
|
||||
float2 normalUV1 = i.worldPos.xz * _NormalScale + time * _NormalSpeed * float2(0.5, 0.3);
|
||||
float2 normalUV2 = i.worldPos.xz * _NormalScale * 0.8 - time * _NormalSpeed * float2(0.3, 0.5);
|
||||
|
||||
float3 normal1 = UnpackNormal(tex2D(_NormalMap, normalUV1));
|
||||
float3 normal2 = UnpackNormal(tex2D(_NormalMap, normalUV2));
|
||||
float3 worldNormal = normalize(i.worldNormal + (normal1 + normal2) * _NormalStrength);
|
||||
|
||||
// Fresnel
|
||||
float fresnel = pow(1.0 - saturate(dot(i.viewDir, worldNormal)), _FresnelPower);
|
||||
|
||||
// Base color
|
||||
float4 waterColor = lerp(_ShallowColor, _DeepColor, fresnel);
|
||||
|
||||
// Specular
|
||||
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
|
||||
float3 halfDir = normalize(lightDir + i.viewDir);
|
||||
float spec = pow(saturate(dot(worldNormal, halfDir)), _Smoothness * 256.0);
|
||||
float3 specular = _SpecularColor.rgb * spec * _LightColor0.rgb;
|
||||
|
||||
// Reflection approximation
|
||||
float3 reflectColor = lerp(float3(0.5, 0.7, 0.9), float3(0.8, 0.9, 1.0), worldNormal.y * 0.5 + 0.5);
|
||||
|
||||
// Combine
|
||||
float3 finalColor = waterColor.rgb;
|
||||
finalColor = lerp(finalColor, reflectColor, fresnel * 0.5);
|
||||
finalColor += specular;
|
||||
|
||||
UNITY_APPLY_FOG(i.fogCoord, finalColor);
|
||||
|
||||
return float4(finalColor, waterColor.a);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
FallBack "Transparent/Diffuse"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cb968a929f0b345cbb686b20d5f91a05
|
||||
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/Water/SynapticWater.shader
|
||||
uploadId: 920982
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1310fcc8eeee9473aab068335ceacef6
|
||||
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/Water/SynapticWaterPro.shader
|
||||
uploadId: 920982
|
||||
Reference in New Issue
Block a user