修复技能输入并更新战斗资源

This commit is contained in:
ud18010
2026-07-30 20:10:38 +08:00
parent d3c4bba5b2
commit 576aa6c14e
9077 changed files with 1322721 additions and 2648 deletions
@@ -0,0 +1,408 @@
#ifndef CHARACTER_CORE_INCLUDED
#define CHARACTER_CORE_INCLUDED
#include "CharacterPBR_Inputs.hlsl"
////INPUTS////////////////////////////////////////////////////////////
///////////////////////////////////
#if defined(_EMISSION_ON) || defined(_ANISO_GGX_ON) || defined(ANISO_KAJIYA_KAY)
TEXTURE2D(_MaskMap2); SAMPLER(sampler_MaskMap2);
#endif
CBUFFER_START(UnityPerMaterial)
half4 _MainTex_ST; half4 _NormalMap_ST;
half _CutoffThres;
half _HighLightLerp; half4 _HighLightLerpColor; half _OriColorAdd; half4 _Color;
half _NormalMapScale;half _ColorLerpMask; half4 _LerpMaskColor; half4 _AmbientColor;
half4 _MaskMap_ST; half4 _MaskMap2_ST;
half4 _EmissionColor; half _EmissionStrength;
half _SmoothnessScale; half _MetallicScale; half _Occlusion; half _DiffuseWrap;
half _CameraLightIntensityMin; half _CameraLightIntensityMax;
half _SkinNormalBias; half _SkinBlurStrength; half _SkinCurvature; half _SkinAmbientIntensity;
half4 _SSSLut_ST; half _ReflectionCubeLod; half _ReflectionYOffset;
#if defined(TRANSLUCENCY_ON)
half3 _SkinTranslucencyColor;
#endif
#if defined(_ANISO_GGX_ON)
half _AnisoSmoothnessScale;
half _AnisoMetallicScale;
half _AnisoSpecAlbedoScale;
half _AmbientReflectionStrength;
#endif
CBUFFER_END
/////////////////////////////////////////////////////////////////////////////////////////////////////////
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
TEXTURE2D(_MaskMap); SAMPLER(sampler_MaskMap);
TEXTURE2D(_SSSLut); SAMPLER(sampler_SSSLut);
TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap);
TEXTURECUBE(_ReflectionCube); SAMPLER(sampler_ReflectionCube);
struct SurfaceOutputStandardCustom
{
half3 Albedo; half3 Normal; half3 Emission;
half Metallic; half Smoothness; half Occlusion; half Alpha;
half IsSkin; half3 SkinNormal; half SkinCurvature;
half3 TranslucencyColor; half Anisotropy; half3 WorldTangent; half3 WorldBitangent;
half3 HighlightColor; half3 AnisoSpecColor;
half MainShift; half MainExponent; half SubShift; half SubExponent;
};
struct VertexInput
{
half4 vertex : POSITION;
half4 normal : NORMAL;
half4 tangent: TANGENT;
half2 texcoord : TEXCOORD0;
half2 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct VertexOutput
{
half4 pos : SV_POSITION;
half2 texcoord : TEXCOORD0;
half4 tSpace0 : TEXCOORD1;
half4 tSpace1 : TEXCOORD2;
half4 tSpace2 : TEXCOORD3;
half3 normal : TEXCOORD4;
float4 shadowCoord : TEXCOORD5;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
#define WorldNormalVector(i, normal) normalize(half3(dot(i.tSpace0.xyz,normal), dot(i.tSpace1.xyz,normal), dot(i.tSpace2.xyz,normal)))
////BRDF/////////////////////////////////////////////////////////////////////////////////////////////////
half3 Unity_GlossyEnvironment (half4 hdr, Unity_GlossyEnvironmentData glossIn)
{
half perceptualRoughness = glossIn.roughness /* perceptualRoughness */ ;
#if 0
float m = PerceptualRoughnessToRoughness(perceptualRoughness);
const float fEps = 1.192092896e-07F;
float n = (2.0/max(fEps, m*m))-2.0;
n /= 4;
perceptualRoughness = pow( 2/(n+2), 0.25);
#else
perceptualRoughness = perceptualRoughness*(1.7 - 0.7*perceptualRoughness);
#endif
half3 R = glossIn.reflUVW;
half4 rgbm = SAMPLE_TEXTURECUBE_LOD(_ReflectionCube, sampler_ReflectionCube, R, 3);
return DecodeHDR(rgbm, hdr);
}
inline half GGXSpecularTerm(half roughness, half nh, half lh)
{
half a = roughness;
float a2 = a * a;
float d = nh * nh * (a2 - 1.f) + 1.00001f;
float specularTerm = a2 / (max(0.1f, lh * lh) * (roughness + 0.5f) * (d * d) * 4);
#if defined (SHADER_API_MOBILE)
specularTerm = clamp(specularTerm - 1e-4f, 0.0, 100.0); // Prevent FP16 overflow on mobiles
#endif
return specularTerm;
}
#if defined(_SKIN_ON)
inline half3 SkinDiffuseTerm(half3 normal, half3 lightDir, half skinCurvature)
{
half NoL = dot(normal, lightDir);
NoL = NoL * 0.5 + 0.5;
half3 diffuseTerm = SAMPLE_TEXTURE2D(_SSSLut, sampler_SSSLut, half2(NoL, skinCurvature));
return diffuseTerm;
}
#endif
#if defined(_ANISO_GGX_ON)
inline half D_GGXAniso_SGame(half TdotH, half BdotH, half mt, half mb, half nh)
{
half d = TdotH * TdotH / (mt * mt) + BdotH * BdotH / (mb * mb) + nh * nh;
return (1.0 / (3.14 * mt * mb * d * d));
}
inline half V_SmithJointGGXAniso_SGame(half TdotV, half BdotV, half NdotV, half TdotL, half BdotL, half NdotL, half roughnessT, half roughnessB)
{
half lambdaV = NdotL * sqrt(roughnessT * TdotV * TdotV + roughnessB * BdotV * BdotV + NdotV * NdotV);
half lambdaL = NdotV * sqrt(roughnessT * TdotL * TdotL + roughnessB * BdotL * BdotL + NdotL * NdotL);
return 0.5 / max(1e-5f, (lambdaV + lambdaL));
}
inline half GGXSpecularTermAniso_SGame(half3 worldTangent, half3 worldBiTangent, half roughnessT, half roughnessB, half3 halfDir, half3 lightDir, half3 viewDir
, half nl, half nh, half nv)
{
half mt = roughnessT;
half mb = roughnessB;
half TdotH = dot(worldTangent, halfDir);
half BdotH = dot(worldBiTangent, halfDir);
half TdotV = dot(worldTangent, viewDir);
half BdotV = dot(worldBiTangent, viewDir);
half TdotL = dot(worldTangent, lightDir);
half BdotL = dot(worldBiTangent, lightDir);
half D = D_GGXAniso_SGame(TdotH, BdotH, mt, mb, nh);
half V = V_SmithJointGGXAniso_SGame(TdotV, BdotV, nv, TdotL, BdotL, nl, mt, mb);
half specularTerm = (V * D) * 3.14;
return clamp(specularTerm, 0, 5);
}
#endif
half3 DirectDiffuse(SurfaceOutputStandardCustom s, half nl, half3 lightDir, half3 viewDir)
{
half3 diffColor = s.Albedo;
half3 diffuseTerm = half3(nl, nl, nl);
#if defined(_SKIN_ON)
half3 skinDiffuseTerm = SkinDiffuseTerm(s.SkinNormal, lightDir, s.SkinCurvature);
diffuseTerm = lerp(diffuseTerm, skinDiffuseTerm, s.IsSkin);
#endif
return diffColor * diffuseTerm;
}
half3 DirectSpecular(SurfaceOutputStandardCustom s, half nl, half3 lightDir, half smoothness, half roughness, half3 specColor, half3 viewDir)
{
half3 normal = s.Normal;
#if defined(_ANISO_GGX_ON)
half3 worldTangent = s.WorldTangent;
half3 worldBitangent = s.WorldBitangent;
#endif
half3 halfDir = normalize(lightDir + viewDir);
half nh = saturate(dot(normal, halfDir));
half nv = abs(dot(normal, viewDir));
half lh = saturate(dot(lightDir, halfDir));
half specularTerm = GGXSpecularTerm(roughness, nh, lh);
#if defined(_ANISO_GGX_ON)
half roughnessT = roughness;
half roughnessB = 1.0;
half anisoSpecularTerm = GGXSpecularTermAniso_SGame(worldTangent, worldBitangent, roughnessT, roughnessB, halfDir, lightDir, viewDir, nl, nh, nv);
specularTerm = lerp(specularTerm, anisoSpecularTerm, s.Anisotropy);
#endif
specularTerm = max(0, specularTerm * nl);
return specularTerm * specColor;
}
half3 DirectSpecular(SurfaceOutputStandardCustom s, half nl, half3 lightDir, half3 specColor, half3 viewDir) {
half smoothness = s.Smoothness;
half perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(smoothness);
half roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
return DirectSpecular(s, nl, lightDir, smoothness, roughness, specColor, viewDir);
}
inline half4 Character_BRDF2_PBS(SurfaceOutputStandardCustom s, half3 specColor, half oneMinusReflectivity, half3 viewDir, UnityLight light) {
half3 normal = s.Normal;
half nl = saturate((dot(normal, light.dir) + _DiffuseWrap) / ((1 + _DiffuseWrap) * (1 + _DiffuseWrap)));
half3 directDiffuse = DirectDiffuse(s, nl, light.dir, viewDir);
half3 directSpecular = DirectSpecular(s, nl, light.dir, specColor, viewDir);
half3 color = directDiffuse * light.color + directSpecular * light.color;
return half4(color, 1);
}
half3 IndirectSpecular(half roughness, half3 specColor)
{
half surfaceReduction;
surfaceReduction = 1.0 / (roughness * roughness + 1.0);
return surfaceReduction * specColor;
}
inline half4 Character_BRDF2_PBS(SurfaceOutputStandardCustom s, half3 specColor, half oneMinusReflectivity,
half3 viewDir, UnityLight light, UnityIndirect gi) {
half3 diffColor = s.Albedo;
half3 normal = s.Normal;
half smoothness = s.Smoothness;
half perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(smoothness);
half roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
half nl = saturate((dot(normal, light.dir) + _DiffuseWrap) / ((1 + _DiffuseWrap) * (1 + _DiffuseWrap)));
half3 directDiffuse = DirectDiffuse(s, nl, light.dir, viewDir);
half3 directSpecular = DirectSpecular(s, nl, light.dir, smoothness, roughness, specColor, viewDir);
half3 directColor = directDiffuse * light.color + directSpecular * light.color;
half3 indirectSpecular = IndirectSpecular(roughness, specColor) * gi.specular;
half3 indirectColor = diffColor * gi.diffuse + indirectSpecular;
half3 finalColor = directColor + indirectColor;
return half4(finalColor, 1);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////LIGHTING////////////////////////////////////////////////////////////////////////////////////////////
inline half4 LightingCharacter(SurfaceOutputStandardCustom s, half3 viewDir, UnityGI gi)
{
half3 mainLightDir = gi.light.dir;
half3 normalizeLightDir = normalize(half3(mainLightDir.x, 0.0, mainLightDir.z));
half3 normalizeViewDir = normalize(half3(viewDir.x, 0.0, viewDir.z));
half3 dirFactor = dot(normalizeLightDir, normalizeViewDir) * 0.5 + 0.5;
half cameraLightAtten = lerp(_CameraLightIntensityMax, _CameraLightIntensityMin, dirFactor);
#if defined(TRANSLUCENCY_ON)
half translucencyAtten = lerp(_CameraLightIntensityMin, _CameraLightIntensityMax, dirFactor);
s.Albedo += s.TranslucencyColor * (saturate(dot(s.Normal, -mainLightDir)) + saturate(dot(s.Normal, viewDir)) * translucencyAtten);
#endif
half oneMinusReflectivity;
half3 specColor;
half outputAlpha;
half3 albedo = DiffuseAndSpecularFromMetallic(s.Albedo, s.Metallic, /*out*/ specColor, /*out*/ oneMinusReflectivity);
#if defined(_ANISO_GGX_ON)
specColor = lerp(specColor, lerp(half4(0.04, 0.04, 0.04, 0.06), s.Albedo, _AnisoSpecAlbedoScale), s.Anisotropy);
#endif
half nv = dot(s.Normal, viewDir);
// s.Albedo = PreMultiplyAlpha(albedo, s.Alpha, oneMinusReflectivity, /*out*/ outputAlpha);
half4 c = Character_BRDF2_PBS(s, specColor, oneMinusReflectivity, viewDir, gi.light, gi.indirect);
UnityGI gi2 = gi;
// HSV Color Alter
half3 hsvLightCol = RgbToHsv_SGame(GetMainLight().color.rgb);
hsvLightCol.b = 1;
hsvLightCol = HsvToRgb_SGame(hsvLightCol);
gi2.light.color = hsvLightCol * cameraLightAtten;
gi2.light.dir = viewDir;
c.rgb += Character_BRDF2_PBS(s, specColor, oneMinusReflectivity, viewDir, gi2.light);
c.a = outputAlpha;
return c;
}
inline half3 CharacterGI_IndirectSpecular(UnityGIInput data, half occlusion, Unity_GlossyEnvironmentData glossIn)
{
half4 hdr = data.probeHDR[0];
hdr.x = 1;
glossIn.reflUVW = RotationY(glossIn.reflUVW, _ReflectionYOffset);
half3 env0 = Unity_GlossyEnvironment(hdr, glossIn);
return env0 * occlusion;
}
inline UnityGI CharacterGI_Base(UnityGIInput data, half occlusion, half3 normalWorld)
{
UnityGI o_gi;
ResetUnityGI(o_gi);
o_gi.light = data.light;
half3 hsvLightCol = RgbToHsv_SGame(GetMainLight().color.rgb);
hsvLightCol.b = 1;
hsvLightCol = HsvToRgb_SGame(hsvLightCol);
o_gi.light.color = hsvLightCol * data.atten;
o_gi.indirect.diffuse = data.ambient;
o_gi.indirect.diffuse *= occlusion;
return o_gi;
}
inline UnityGI CharacterGlobalIllumination(UnityGIInput data, half occlusion, half3 normalWorld, Unity_GlossyEnvironmentData glossIn)
{
UnityGI o_gi = CharacterGI_Base(data, occlusion, normalWorld);
o_gi.indirect.specular = CharacterGI_IndirectSpecular(data, occlusion, glossIn);
return o_gi;
}
inline void LightingCharacter_GI(SurfaceOutputStandardCustom s, UnityGIInput data, inout UnityGI gi)
{
// Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(_ReflectionCubeLod, data.worldViewDir, s.Normal, half3(0, 0, 0));
Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(s.Smoothness, data.worldViewDir, s.Normal, half3(0, 0, 0));
gi = CharacterGlobalIllumination(data, s.Occlusion, s.Normal, g);
#if defined(_SKIN_ON)
gi.indirect.diffuse *= lerp(1, _SkinAmbientIntensity, s.IsSkin);
#endif
#if defined(_ANISO_GGX_ON)
gi.indirect.specular *= lerp(1, _AmbientReflectionStrength, s.Anisotropy);
#endif
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
VertexOutput VertBaseCore(VertexInput v)
{
VertexOutput o;
VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(v.normal, v.tangent);
o.pos = vertexInput.positionCS;
half3 worldPos = vertexInput.positionWS;
float3 worldNormal = normalInput.normalWS;
half3 worldViewDir = GetCameraPositionWS() - worldPos;
o.tSpace0 = half4(normalInput.tangentWS.x, normalInput.bitangentWS.x, normalInput.normalWS.x, worldPos.x);
o.tSpace1 = half4(normalInput.tangentWS.y, normalInput.bitangentWS.y, normalInput.normalWS.y, worldPos.y);
o.tSpace2 = half4(normalInput.tangentWS.z, normalInput.bitangentWS.z, normalInput.normalWS.z, worldPos.z);
o.texcoord = v.texcoord.xy;
o.normal = worldNormal;
o.shadowCoord = GetShadowCoord(vertexInput);
return o;
}
half4 FragBaseCore(VertexOutput i, half3 worldPos, half3 worldViewDir, half3 worldTangent = half3(0, 0, 0))
{
half2 uv_MainTex = TRANSFORM_TEX(i.texcoord, _MainTex);
half2 uv_NrmTex = TRANSFORM_TEX(i.texcoord, _NormalMap);
half2 uv_mskTex = TRANSFORM_TEX(i.texcoord, _MaskMap);
half4 albedoColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv_MainTex);
half4 normalColor = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, uv_NrmTex);
half4 mask = SAMPLE_TEXTURE2D(_MaskMap, sampler_MaskMap, uv_mskTex);
#if defined(_CUTOFF_ON)
clip(albedoColor.a - _CutoffThres / 255);
#endif
SurfaceOutputStandardCustom o = (SurfaceOutputStandardCustom)0;
o.Occlusion = 1.0;
half3 colorAddLerp = lerp(_Color.rgb * _OriColorAdd, _LerpMaskColor.rgb * 0.8, _ColorLerpMask * albedoColor.a);
#if defined(_ANISO_GGX_ON)
half4 mask2 = SAMPLE_TEXTURE2D(_MaskMap2, sampler_MaskMap2, TRANSFORM_TEX(i.texcoord, _MaskMap2));
o.Albedo = albedoColor.rgb * colorAddLerp * step(0.5, mask2.g) + albedoColor.rgb * step(mask2.g, 0.5);
#else
o.Albedo = albedoColor.rgb * colorAddLerp;
#endif
o.Alpha = albedoColor.a * _Color.a;
half4 c = 0;
#if defined(_USENORMALMAP_OFF)
o.Normal = i.normal;
#else
o.Normal = lerp(half3(0, 0, 1), normalColor.rgb * 2 - 1, _NormalMapScale);
#endif
o.Normal = WorldNormalVector(i, o.Normal);
o.Metallic = mask.r * (_MetallicScale + 1);
o.Emission = normalColor.a * _EmissionColor.rgb * _EmissionStrength;
o.Occlusion = lerp(mask.b, 1, _Occlusion);
o.Smoothness = (1 - mask.a) * (_SmoothnessScale + 1);
#if defined(_ANISO_GGX_ON)
o.Anisotropy = mask2.g;
half anisoMetallic = _AnisoMetallicScale;
half anisoSmoothness = _AnisoSmoothnessScale;
o.Metallic = lerp(o.Metallic, anisoMetallic, o.Anisotropy);
o.Smoothness = lerp(o.Smoothness, anisoSmoothness, o.Anisotropy);
o.WorldTangent = worldTangent;
o.WorldBitangent = cross(o.Normal, o.WorldTangent);
o.WorldTangent = cross(o.WorldBitangent, o.Normal);
#endif
o.IsSkin = 0;
#if defined(_SKIN_ON)
o.IsSkin = mask.g;
half3 skinNormal = UnpackNormal(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, uv_NrmTex));
o.SkinNormal = normalize(lerp(o.Normal, skinNormal, _SkinBlurStrength));
o.SkinCurvature = _SkinCurvature;
o.SkinNormal = WorldNormalVector(i, o.SkinNormal);
#endif
half atten = 1;
UnityGI gi = (UnityGI)0;
gi.indirect.diffuse = 0;
gi.indirect.specular = 0;
gi.light.color = GetMainLight().color.rgb;
gi.light.dir = GetMainLight().direction;
UnityGIInput giInput = (UnityGIInput)0;
giInput.light = gi.light;
giInput.worldPos = worldPos;
giInput.worldViewDir = worldViewDir;
giInput.atten = atten;
giInput.ambient.rgb = _AmbientColor;
giInput.probeHDR[0] = unity_SpecCube0_HDR;
LightingCharacter_GI(o, giInput, gi);
c += LightingCharacter(o, worldViewDir, gi);
c.rgb += o.Emission;
c.rgb = clamp(c.rgb, 0, 3);
c.rgb = lerp(c.rgb, c.rgb + pow(1 - saturate(dot(o.Normal, worldViewDir)), 2.5) * _HighLightLerpColor * 4, _HighLightLerp);
c.a = albedoColor.a;
return c;
}
half4 FragBaseCore(VertexOutput i)
{
half3 worldPos = half3(i.tSpace0.w, i.tSpace1.w, i.tSpace2.w);
half3 worldViewDir = normalize(GetCameraPositionWS() - worldPos);
#if defined(_ANISO_GGX_ON)
half3 worldTangent = normalize(half3(i.tSpace0.x, i.tSpace1.x, i.tSpace2.x));
#else
half3 worldTangent = half3(0, 0, 0);
#endif
return FragBaseCore(i, worldPos, worldViewDir, worldTangent);
}
VertexOutput VertBase(VertexInput v)
{
return VertBaseCore(v);
}
half4 FragBase(VertexOutput i) : SV_Target
{
half4 finalColor = FragBaseCore(i);
return finalColor;
}
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: aacde924bce097c43bd6d82ff2ad9eab
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,354 @@
#ifndef CHARACTERCOMMONUTIL_BASE
#define CHARACTERCOMMONUTIL_BASE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
inline half3 BlendMode_Screen( half3 s, half3 d)
{
return s + d - s*d;
}
inline half3 RotationY(half3 pointP, half angle)
{
half radY = radians(angle);
half sinY = sin(radY);
half cosY = cos(radY);
return half3(pointP.x * cosY - pointP.z * sinY,
pointP.y, pointP.x * sinY + pointP.z * cosY);
}
inline half3 RgbToHsv_SGame(half3 c)
{
half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));
half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));
half d = q.x - min(q.w, q.y);
half e = 1.0e-4;
return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
inline half3 HsvToRgb_SGame(half3 c)
{
half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);
}
struct UnityLight
{
half3 color;
half3 dir;
half ndotl; // Deprecated: Ndotl is now calculated on the fly and is no longer stored. Do not used it.
};
struct UnityIndirect
{
half3 diffuse;
half3 specular;
};
struct UnityGI
{
UnityLight light;
UnityIndirect indirect;
};
struct UnityGIInput
{
UnityLight light; // pixel light, sent from the engine
float3 worldPos;
half3 worldViewDir;
half atten;
half3 ambient;
float4 lightmapUV; // .xy = static lightmap UV, .zw = dynamic lightmap UV
#if defined(UNITY_SPECCUBE_BLENDING) || defined(UNITY_SPECCUBE_BOX_PROJECTION) || defined(UNITY_ENABLE_REFLECTION_BUFFERS)
float4 boxMin[2];
#endif
#ifdef UNITY_SPECCUBE_BOX_PROJECTION
float4 boxMax[2];
float4 probePosition[2];
#endif
// HDR cubemap properties, use to decompress HDR texture
float4 probeHDR[2];
};
struct Unity_GlossyEnvironmentData
{
half roughness; // CAUTION: This is perceptualRoughness but because of compatibility this name can't be change :(
half3 reflUVW;
};
//-------------------------------------------------------------------------------------
half3 NormalizePerVertexNormal (float3 n) // takes float to avoid overflow
{
#if (SHADER_TARGET < 30) || UNITY_STANDARD_SIMPLE
return normalize(n);
#else
return n; // will normalize per-pixel instead
#endif
}
half3 NormalizePerPixelNormal (half3 n)
{
#if (SHADER_TARGET < 30) || UNITY_STANDARD_SIMPLE
return n;
#else
return normalize(n);
#endif
}
//-------------------------------------------------------------------------------------
UnityLight MainLight ()
{
UnityLight l;
l.color = GetMainLight().color.rgb;
half3 hsvLightCol = RgbToHsv_SGame(GetMainLight().color.rgb);
hsvLightCol.b = clamp(hsvLightCol.b, 0.9, 1.1);
l.color = HsvToRgb_SGame(hsvLightCol);
l.dir = GetMainLight().direction;
return l;
}
UnityLight AdditiveLight (half3 lightDir, half atten)
{
UnityLight l;
l.color = GetMainLight().color.rgb;
l.dir = lightDir;
#ifndef USING_DIRECTIONAL_LIGHT
l.dir = NormalizePerPixelNormal(l.dir);
#endif
l.color *= atten;
return l;
}
UnityLight DummyLight ()
{
UnityLight l;
l.color = 0;
l.dir = half3 (0,1,0);
return l;
}
UnityIndirect ZeroIndirect ()
{
UnityIndirect ind;
ind.diffuse = 0;
ind.specular = 0;
return ind;
}
Unity_GlossyEnvironmentData UnityGlossyEnvironmentSetup(half Smoothness, half3 worldViewDir, half3 Normal, half3 fresnel0)
{
Unity_GlossyEnvironmentData g;
g.roughness /* perceptualRoughness */ = PerceptualSmoothnessToPerceptualRoughness(Smoothness);
g.reflUVW = reflect(-worldViewDir, Normal);
return g;
}
inline void ResetUnityLight(out UnityLight outLight)
{
outLight.color = half3(0, 0, 0);
outLight.dir = half3(0, 1, 0); // Irrelevant direction, just not null
outLight.ndotl = 0; // Not used
}
inline void ResetUnityGI(out UnityGI outGI)
{
ResetUnityLight(outGI.light);
outGI.indirect.diffuse = 0;
outGI.indirect.specular = 0;
}
half3 UnpackScaleNormalRGorAG(half4 packednormal, half bumpScale)
{
#if defined(UNITY_NO_DXT5nm)
half3 normal = packednormal.xyz * 2 - 1;
#if (SHADER_TARGET >= 30)
normal.xy *= bumpScale;
#endif
return normal;
#elif defined(UNITY_ASTC_NORMALMAP_ENCODING)
half3 normal;
normal.xy = (packednormal.wy * 2 - 1);
normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));
normal.xy *= bumpScale;
return normal;
#else
packednormal.x *= packednormal.w;
half3 normal;
normal.xy = (packednormal.xy * 2 - 1);
#if (SHADER_TARGET >= 30)
normal.xy *= bumpScale;
#endif
normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));
return normal;
#endif
}
half3 UnpackScaleNormal(half4 packednormal, half bumpScale)
{
return UnpackScaleNormalRGorAG(packednormal, bumpScale);
}
half3x3 CreateTangentToWorldPerVertex(half3 normal, half3 tangent, half tangentSign)
{
// For odd-negative scale transforms we need to flip the sign
half sign = tangentSign * unity_WorldTransformParams.w;
half3 binormal = cross(normal, tangent) * sign;
return half3x3(tangent, binormal, normal);
}
// ----------------------------------------------------------------------------
inline half3 DecodeHDR (half4 data, half4 decodeInstructions)
{
// Take into account texture alpha if decodeInstructions.w is true(the alpha value affects the RGB channels)
half alpha = decodeInstructions.w * (data.a - 1.0) + 1.0;
// If Linear mode is not supported we can skip exponent part
#if defined(UNITY_COLORSPACE_GAMMA)
return (decodeInstructions.x * alpha) * data.rgb;
#else
#if defined(UNITY_USE_NATIVE_HDR)
return decodeInstructions.x * data.rgb; // Multiplier for future HDRI relative to absolute conversion.
#else
return (decodeInstructions.x * pow(alpha, decodeInstructions.y)) * data.rgb;
#endif
#endif
}
inline half3 PreMultiplyAlpha (half3 diffColor, half alpha, half oneMinusReflectivity, out half outModifiedAlpha)
{
diffColor *= alpha;
outModifiedAlpha = 1-oneMinusReflectivity + alpha*oneMinusReflectivity;
return diffColor;
}
inline half OneMinusReflectivityFromMetallic(half metallic)
{
half oneMinusDielectricSpec = 0.56;
return oneMinusDielectricSpec - metallic * oneMinusDielectricSpec;
}
inline half3 DiffuseAndSpecularFromMetallic (half3 albedo, half metallic, out half3 specColor, out half oneMinusReflectivity)
{
specColor = lerp (UNITY_LIGHTMODEL_AMBIENT.xyz, albedo, metallic);
oneMinusReflectivity = OneMinusReflectivityFromMetallic(metallic);
return albedo * oneMinusReflectivity;
}
inline UnityGI UnityGI_Base(UnityGIInput data, half occlusion, half3 normalWorld)
{
UnityGI o_gi;
ResetUnityGI(o_gi);
o_gi.light = data.light;
o_gi.light.color *= data.atten;
o_gi.indirect.diffuse *= occlusion;
return o_gi;
}
inline half3 UnityGI_IndirectSpecular(UnityGIInput data, half occlusion, Unity_GlossyEnvironmentData glossIn)
{
half3 specular;
specular = unity_IndirectSpecColor.rgb;
return specular * occlusion;
}
inline half3 UnityGI_IndirectSpecular(UnityGIInput data, half occlusion, half3 normalWorld, Unity_GlossyEnvironmentData glossIn)
{
return UnityGI_IndirectSpecular(data, occlusion, glossIn);
}
inline UnityGI UnityGlobalIllumination (UnityGIInput data, half occlusion, half3 normalWorld)
{
return UnityGI_Base(data, occlusion, normalWorld);
}
inline UnityGI UnityGlobalIllumination (UnityGIInput data, half occlusion, half3 normalWorld, Unity_GlossyEnvironmentData glossIn)
{
UnityGI o_gi = UnityGI_Base(data, occlusion, normalWorld);
o_gi.indirect.specular = UnityGI_IndirectSpecular(data, occlusion, glossIn);
return o_gi;
}
inline UnityGI UnityGlobalIllumination (UnityGIInput data, half occlusion, half smoothness, half3 normalWorld, bool reflections)
{
Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(smoothness, data.worldViewDir, normalWorld, float3(0, 0, 0));
return UnityGlobalIllumination(data, occlusion, normalWorld, g);
}
inline UnityGI UnityGlobalIllumination (UnityGIInput data, half occlusion, half smoothness, half3 normalWorld)
{
bool sampleReflections = true;
return UnityGlobalIllumination (data, occlusion, smoothness, normalWorld, sampleReflections);
}
inline half3 GetSpecularColorGGX_Smoothness (half ndotH, half ndotL, half ldotH, half3 specularColor, half smoothness, half powFac = 64, half ggxClamp = 3)
{
half3 specular = 0;
#if defined(_SG_GGX_SMOOTH)
half perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness (smoothness);
perceptualRoughness = max(0.08, perceptualRoughness);
half roughness = PerceptualSmoothnessToPerceptualRoughness(perceptualRoughness);
half a = roughness;
half a2 = a * a;
half d = ndotH * ndotH * (a2 - 1) + 1.0001;
half specularTerm = a2 / (max(0.2, ldotH * ldotH) * (roughness + 0.5) * (d * d) * powFac);
specularTerm = specularTerm - 1e-4h;
specularTerm = clamp(specularTerm, 0, ggxClamp);
specular = specularTerm * specularColor.rgb;
#endif
return specular;
}
inline half3x3 GetDiffuseColor(half smoothness, half3 specularColor, half3 mainColor,
half3 worldNormal, half lightAtten, half3 NDotL)
{
half3 lightColor = lerp(half3(0,0,0), GetMainLight().color.rgb, lightAtten * NDotL);
specularColor = lerp(half3(0,0,0), GetMainLight().color.rgb, lightAtten) * specularColor;
half3 diffuse = mainColor * lightColor;
#if defined(SGAME_WET) && defined(SGAME_QUALITY_PERFECT) || defined(SGAME_QUALITY_HIGH)
mainColor = lerp(mainColor, mainColor * _SG_WetColor, _SG_WetFactor);
specularColor = lerp(specularColor, _SG_WetSpecularColor * _SG_WetSpecularStrength, _SG_WetFactor);
smoothness = lerp(lerp(smoothness, _SG_WetSmoothness, _SG_WetFactor), smoothness, smoothness > _SG_WetSmoothness);
half thunderNDotL = saturate(dot(worldNormal, _SG_ThunderDirection));
half3 thunderDiffuse = mainColor * lerp(half3(0, 0, 0), _SG_ThunderColor, max(lightAtten,0.1)) * thunderNDotL * _SG_ThunderStrength;
diffuse += thunderDiffuse;
#endif
half3x3 matrixColor;
matrixColor[0] = diffuse;
matrixColor[1] = specularColor;
matrixColor[2] = half3(smoothness, 0, 0);
return matrixColor;
}
inline half3 GetSumLightingColorSpecGGX_Smoothness(half3 mainColor, half3 specularColor, half3 shLight,
half3 worldNormal, half3 worldPos, half smoothness, half lightAtten, half powFac = 64, half ggxClamp = 3, half intensity = 1)
{
half3 worldViewDir = normalize(GetCameraPositionWS() - worldPos);
half3 worldLightDir = normalize(GetMainLight().direction);
half3 halfDir = normalize(worldLightDir + worldViewDir);
half ndotH = max(dot(worldNormal, halfDir), 0);
half NDotL = max(dot(worldNormal, worldLightDir), 0);
half ldotH = max(dot(worldLightDir, halfDir), 0);
half3x3 colorMatrix = GetDiffuseColor(smoothness, specularColor, mainColor, worldNormal, lightAtten, NDotL);
specularColor = colorMatrix[1];
smoothness = colorMatrix[2].x;
half3 ambient = mainColor * 0.5;
half3 diffuse = colorMatrix[0];
half3 specular = GetSpecularColorGGX_Smoothness(ndotH, NDotL, ldotH, specularColor, smoothness, powFac, ggxClamp);
return ambient + diffuse + specular * intensity;
}
inline half SGameShadowAtten(half atten)
{
return max(atten, 0.2);
}
inline half SGameStylizedAtten(half atten, half _DoubleSGameShadowAtten)
{
half stylizedAtten = (atten + _DoubleSGameShadowAtten) * 0.5;
stylizedAtten = saturate(stylizedAtten);
return stylizedAtten;
}
inline half SGameRoughness(half smoothness, out half perceptualRoughness )
{
perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness (smoothness);
perceptualRoughness = max(0.001, perceptualRoughness);
half roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
return roughness;
}
inline half SGameDirectSpecular(half3 normal, half3 viewDir, half NDotL, half metallic, half nh, half lh)
{
half3 backfaceLightDir = viewDir;
half3 backfaceHalfDir = viewDir;
half backface_nh = saturate(dot(normal, backfaceHalfDir));
half backface_lh = saturate(dot(backfaceLightDir, backfaceHalfDir));
//half notBackface = smoothstep(0,0.5,NDotL * 0.5 + 0.5); //0背光 -> 1受光
half notBackface = smoothstep(-1,0.5,NDotL); //0背光 -> 1受光
//nh = lerp(backface_nh, nh, notBackface);
//lh = lerp(backface_lh, lh, notBackface);
half isBackface = 1 - smoothstep(-1,0.5,NDotL);
//half ratio = isBackface * step(0.5, metallic);
half ratio = isBackface * lerp(0.3,1,metallic);
nh = lerp(nh, backface_nh, ratio);
lh = lerp(lh, backface_lh, ratio);
return isBackface;
}
inline half3 SGameStylizedSpecularColor( half3 specularColor, half metallic )
{
half3 linearSpecularColor = specularColor * specularColor;
specularColor = lerp( linearSpecularColor, specularColor, metallic );
return specularColor;
}
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 977622c8599f3d949b3d347f96c14d7e
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,193 @@
#ifndef CHARACTER_BASE
#define CHARACTER_BASE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap);
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST; float4 _NormalMap_ST; half _NormalMapScale;
half _Strength; half _Saturation; half _Contrast; half _ShLight; half4 _ColorTint;
half3 _SpecularColor; half _SpecularFactor; half _Smoothness;
half3 _EmissionColor; half _EmissionFactor; half _CameraLightIntensity;
half4 _CameraLightColor; half4 _Light2Dir;
CBUFFER_END
struct a2v
{
half4 vertex : POSITION;
half4 normal : NORMAL;
half4 tangent: TANGENT;
half2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 pos : SV_POSITION;
float4 uvTex0 : TEXCOORD0;
float3 worldPos : TEXCOORD1;
#if defined(_USENORMALMAP_OFF) || !defined(SGAME_QUALITY_PERFECT)
float3 worldNormal : TEXCOORD2;
half3 worldViewDir : TEXCOORD3;
#else
half4 worldTangentDir : TEXCOORD2;
half4 worldBitangentDir : TEXCOORD3;
half4 worldNormalDir : TEXCOORD4;
#endif
float4 shadowCoord : TEXCOORD5;
#if defined(_SG_EXPFOG)
half4 _fogCoord : TEXCOORD6;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
inline half3 GetAmbientColor_Custom(half3 mainColor, half3 shLight)
{
half3 ambient = lerp(mainColor, mainColor * UNITY_LIGHTMODEL_AMBIENT.xyz, shLight);
ambient *= 1;
ambient *= 1;
return ambient;
}
inline half3 CalculateColorAlter(half3 finalColor, half ligh, half saturation, half contrast)
{
half gray = 0.2125 * finalColor.r + 0.7154 * finalColor.g + 0.0721 * finalColor.b;
half3 grayColor = real3(gray, gray, gray);
finalColor = lerp(0.5, finalColor, contrast);
finalColor = lerp(grayColor, finalColor, saturation) * ligh;
return finalColor;
}
inline half3 BlinnPhoneLighting(half3 mainColor, half3 worldPos, half3 worldNormal, half3 worldViewDir, half3 specularColor, half smoothness, half lightAtten,
half lightClamp = 20, half dotResLerp = 0, half3 customLightDir = half3(0, 0, 0), half useCustomDir = 0)
{
#if defined(SGAME_WET) && defined(SGAME_QUALITY_PERFECT) || defined(SGAME_QUALITY_HIGH)
mainColor = lerp(mainColor, mainColor * _SG_WetColor, _SG_WetFactor);
specularColor = lerp(specularColor, _SG_WetSpecularColor * _SG_WetSpecularStrength, _SG_WetFactor);
smoothness = lerp(lerp(smoothness, _SG_WetSmoothness, _SG_WetFactor), smoothness, smoothness > _SG_WetSmoothness);
#endif
//Diffuse
Light mainLight = GetMainLight();
half3 worldLightDir = normalize(mainLight.direction) * (1 - useCustomDir) + useCustomDir * customLightDir;
half H = normalize(worldViewDir + worldLightDir);
half NDotL = max(0, saturate(dot(worldNormal, worldLightDir)));
half ndotH = max(0, dot(worldNormal, H));
half dotLerp = lerp(NDotL, ndotH, dotResLerp);
half3 lightColor = mainLight.color.rgb;
specularColor = mainLight.color.rgb * specularColor;
half3 diffuse = mainColor * lightColor;
#if defined(SGAME_WET) && defined(SGAME_QUALITY_PERFECT) || defined(SGAME_QUALITY_HIGH)
half thunderNDotL = saturate(dot(worldNormal, _SG_ThunderDirection));
half3 thunderDiffuse = mainColor * lerp(half3(0, 0, 0), _SG_ThunderColor, max(lightAtten, 0.1)) * thunderNDotL * _SG_ThunderStrength;
diffuse += thunderDiffuse;
#endif
#if defined(SGAME_QUALITY_PERFECT) || defined(SGAME_QUALITY_HIGH)
worldViewDir = normalize(worldViewDir);
half3 halfDir = normalize(worldLightDir + worldViewDir);
half NDotH = saturate(dot(worldNormal, halfDir));
half specularPow = SGamePow(NDotH, smoothness * 128.0);
half3 specular = specularColor.rgb * specularPow;
half3 finalColor = diffuse + specular;
#else
half3 finalColor = diffuse;
#endif
return finalColor;
}
inline half3 BlinnPhoneLightingFwdBase_CustomAmbient(half3 mainColor, half3 worldPos, half3 worldNormal, half3 worldViewDir, half3 shLight, half lightAtten, half3 specularColor, half smoothness)
{
half3 ambient = GetAmbientColor_Custom(mainColor, shLight);
half3 baseLighting = BlinnPhoneLighting(mainColor, worldPos, worldNormal, worldViewDir, specularColor, smoothness, lightAtten, 0.9);
half3 finalColor = clamp(ambient, 0, 0.65) + baseLighting;
return finalColor;
}
inline v2f VertexMain_SceneLight(a2v v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(v.normal, v.tangent);
o.pos = vertexInput.positionCS;
o.uvTex0.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
half3 worldPos = vertexInput.positionWS;
half3 worldNormal = normalInput.normalWS;
half3 worldViewDir = GetCameraPositionWS() - worldPos;
#if defined(_USENORMALMAP_OFF) || !defined(SGAME_QUALITY_PERFECT)
o.worldViewDir = worldViewDir;
o.worldNormal = normalize(worldNormal);
#else
o.worldTangentDir = half4(normalInput.tangentWS, worldViewDir.x);
o.worldBitangentDir = half4(normalInput.bitangentWS, worldViewDir.y);
o.worldNormalDir = half4(normalInput.normalWS, worldViewDir.z);
#endif
o.shadowCoord = GetShadowCoord(vertexInput);
o.worldPos.xyz = worldPos;
return o;
}
inline half4 FragMain_SceneLight(v2f i) : SV_TARGET
{
float3 worldPos = i.worldPos;
half4 normalCol = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, i.uvTex0);
half4 mainColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uvTex0) * _ColorTint;
#if defined(_USENORMALMAP_OFF) || !defined(SGAME_QUALITY_PERFECT)
float3 worldNormal = normalize(i.worldNormal);
half3 worldViewDir = normalize(i.worldViewDir);
#else
half3 worldViewDir = normalize(half3(i.worldTangentDir.w, i.worldBitangentDir.w, i.worldNormalDir.w));
// float3 tangentNormal = UnSampleNormalRG(normalCol.rg, i.uvTex0, _NormalMapScale);
float3 tangentNormal = normalCol.rgb * 2 - 1;
tangentNormal = lerp(half3(0, 0, 1), tangentNormal, _NormalMapScale);
float3 worldNormal = normalize(mul(tangentNormal, float3x3(i.worldTangentDir.xyz, i.worldBitangentDir.xyz, i.worldNormalDir.xyz)));
#endif
half smoothness = _Smoothness;
half3 specularColor = mainColor.a * _SpecularFactor * _SpecularColor;
#if defined(_USECUTOFF_ON)
clip(0.9 - step(normalCol.a, 1 / 255));
#endif
mainColor.rgb = CalculateColorAlter(mainColor.rgb, _Strength, _Saturation, _Contrast);
half3 shLight = _ShLight;
half atten = 1;
Light mainLight = GetMainLight(i.shadowCoord, worldPos, 0);
half3 worldLightDir = mainLight.direction;
atten = 1;
half3 finalColor = BlinnPhoneLightingFwdBase_CustomAmbient(mainColor, worldPos, worldNormal, worldViewDir, shLight, atten, specularColor, smoothness);
#if defined(_USECAMERALIGHT_ON)
half3 N = worldNormal;
half3 L = normalize(_Light2Dir.xyz);
half3 V = normalize(worldViewDir);
half3 H = normalize(L + V);
half NoL = max(dot(L, N), 0.175);
finalColor += _CameraLightColor * _CameraLightIntensity * mainColor.rgb * NoL;
#endif
#if defined(_USEEMISSION_ON)
finalColor += finalColor * _EmissionFactor * _EmissionColor.rgb * max(normalCol.a / 180 * 255 - 1, 0);
#endif
half alpha = min(1, (normalCol.a * 315 / 159 - 1 / 160)) * _ColorTint.a + 1 / 160;
return half4(finalColor, alpha);
}
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 6bb418d44a2859c4580262648d98b6af
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,12 @@
#ifndef COLORALTERING_BASE
#define COLORALTERING_BASE
half4 _BlendColor;
inline half4 GetResultColor(half4 color)
{
color.rgb *= _BlendColor.rgb;
color.a = _BlendColor.a;
return color;
}
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 6e9750fbc4324fe4aa3f6ff7cc7c1332
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,49 @@
#ifndef CUSTOMSHADOWMAP_BASE_INCLUDE
#define CUSTOMSHADOWMAP_BASE_INCLUDE
float4 tex2Dproj(sampler2D s, in float3 t) { return tex2D(s, t.xy / t.z); }
TEXTURE2D(_SGameShadowMap); SAMPLER(sampler_SGameShadowMap);
half _SGameShadowBias; half _SGameShadowStrength;
float4x4 _ShadowMatrix;
inline float4 GetCustomShadowCoords(float3 worldPos)
{
return mul(_ShadowMatrix, float4(worldPos, 1));
}
inline float GetCustomShadowAtten(float4 shadowCoords)
{
#if defined(SHADER_API_MOBILE)
float lightDepth = SAMPLE_TEXTURE2D(_SGameShadowMap, sampler_SGameShadowMap, shadowCoords.xy / shadowCoords.w).r;
#else
float lightDepth = 1 - SAMPLE_TEXTURE2D(_SGameShadowMap, sampler_SGameShadowMap, shadowCoords.xy / shadowCoords.w).r;
#endif
float atten = lerp(1, 0.35, step(lightDepth, (shadowCoords.z - _SGameShadowBias)));
// float atten = (shadowCoords.z - _SGameShadowBias) < lightDepth ? 1 : 0.5;
// atten = lerp(1, atten, _SGameShadowStrength);
// atten = pow(atten, 2);
atten = lerp(atten, 1, step(0.99 , shadowCoords.x));
atten = lerp(atten, 1, step(0.99 , shadowCoords.y));
return atten;
}
#if defined(_PROJECTOR_ON)
float4x4 _ProjectorVP;
TEXTURE2D(_ProjectorTex); SAMPLER(sampler_ProjectorTex);
inline float4 GetProjectorUV(float4 vertex, float4x4 o2wMat)
{
float4x4 propMVP = mul(_ProjectorVP, o2wMat);
float4 projProjPos = mul(propMVP, vertex);
projProjPos = ComputeScreenPos(projProjPos);
return projProjPos;
}
inline float3 GetProjectorColor(float3 oriCol, float4 projUV)
{
return oriCol + SAMPLE_TEXTURE2D(_ProjectorTex, sampler_ProjectorTex, projUV).rgb;
}
#endif
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 2e5a6c404bfbf9447bc8744b37541c5a
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,403 @@
#ifndef TOD_BASE_INCLUDED
#define TOD_BASE_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
TEXTURE2D(_CloudMainTex); SAMPLER(sampler_CloudMainTex);
TEXTURE2D(TOD_BayerTexture); SAMPLER(samplerTOD_BayerTexture);
TEXTURE2D(TOD_CloudTexture); SAMPLER(samplerTOD_CloudTexture);
TEXTURE2D(TOD_CloudAlphaTexture); SAMPLER(samplerTOD_CloudAlphaTexture);
TEXTURECUBE(_CubeTex); SAMPLER(sampler_CubeTex);
CBUFFER_START(UnityPerMaterial_TOD)
float _CubeBrightness;
half4 _MainTex_ST; half4 _TintColor;
half4 _CloudMainTex_ST; half4 _CloudTintColor; half _CloudBrightness;
half4x4 TOD_World2Sky, TOD_Sky2World, TOD_World2CloudCameraProjMatrix;
half3 TOD_SunLightColor, TOD_MoonLightColor, TOD_SunSkyColor, TOD_MoonSkyColor;
half3 TOD_SunMeshColor, TOD_MoonMeshColor, TOD_SunCloudColor, TOD_MoonCloudColor;
half3 TOD_FogColor, TOD_GroundColor, TOD_AmbientColor;
half3 TOD_SunDirection, TOD_MoonDirection, TOD_LightDirection;
half3 TOD_LocalSunDirection, TOD_LocalMoonDirection, TOD_LocalLightDirection;
half TOD_Contrast, TOD_Brightness, TOD_Fogginess;
half TOD_MoonHaloPower; half3 TOD_MoonHaloColor;
half TOD_CloudOpacity, TOD_CloudCoverage, TOD_CloudSharpness, TOD_CloudDensity, TOD_CloudColoring,
TOD_CloudAttenuation, TOD_CloudSaturation, TOD_CloudScattering, TOD_CloudBrightness;
half3 TOD_CloudOffset, TOD_CloudWind, TOD_CloudSize;
half TOD_CloudShadowCutoff, TOD_CloudShadowFade, TOD_CloudShadowIntensity;
half TOD_StarSize, TOD_StarBrightness, TOD_StarVisibility;
half TOD_SunMeshContrast, TOD_SunMeshBrightness;
half TOD_MoonMeshContrast, TOD_MoonMeshBrightness;
half3 TOD_ScatterDensity, TOD_kBetaMie;
half4 TOD_kSun, TOD_k4PI, TOD_kRadius, TOD_kScale;
half3 TOD_SunWorldPos, TOD_HeroWorldPos;
half TOD_IsDay;
half4 _SG_VirtualScatterLightColor; half _SG_AtmosphereFogDensityFactor;
CBUFFER_END
// Vertex transform used by the entire sky dome
#if UNITY_VERSION >= 540
#define TOD_TRANSFORM_VERT(vert) UnityObjectToClipPos(vert)
#else
#define TOD_TRANSFORM_VERT(vert) UnityObjectToClipPos(vert)
#endif
#define TOD_ROTATION_UV(angle) half2x2(cos(angle), -sin(angle), sin(angle), cos(angle)) // UV rotation matrix constructor
#define TOD_HDR2LDR(color) (1.0 - exp2(-TOD_Brightness * color)) // Fast and simple tonemapping
#define TOD_GAMMA2LINEAR(color) (color * color) // Approximates gamma by 2.0 instead of 2.2
#define TOD_LINEAR2GAMMA(color) sqrt(color)
#if UNITY_VERSION >= 540 // Matrices
#define TOD_Object2World unity_ObjectToWorld
#define TOD_World2Object unity_WorldToObject
#else
#define TOD_Object2World unity_ObjectToWorld
#define TOD_World2Object unity_WorldToObject
#endif
#if UNITY_VERSION >= 540 // Screen space adjust
#define TOD_UV(x, y) UnityStereoScreenSpaceUVAdjust(x, y)
#else
#define TOD_UV(x, y) x
#endif
#if UNITY_VERSION >= 540 // Stereo output
#define TOD_VERTEX_OUTPUT_STEREO UNITY_VERTEX_OUTPUT_STEREO
#define TOD_INITIALIZE_VERTEX_OUTPUT_STEREO(o) UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o)
#else
#define TOD_VERTEX_OUTPUT_STEREO
#define TOD_INITIALIZE_VERTEX_OUTPUT_STEREO(o)
#endif
#if UNITY_VERSION >= 540 // Instancing
#define TOD_INSTANCE_ID UNITY_VERTEX_INPUT_INSTANCE_ID
#define TOD_SETUP_INSTANCE_ID(o) UNITY_SETUP_INSTANCE_ID(o)
#else
#define TOD_INSTANCE_ID
#define TOD_SETUP_INSTANCE_ID(o)
#endif
#ifndef TOD_SCATTERING_MIE
#define TOD_SCATTERING_MIE 1
#endif
#ifndef TOD_SCATTERING_RAYLEIGH
#define TOD_SCATTERING_RAYLEIGH 1
#endif
#ifndef TOD_BAYER_DIM
#define TOD_BAYER_DIM 8.0
#endif
half4 Adjust(half4 color)
{
#if !TOD_OUTPUT_HDR
color = TOD_HDR2LDR(color);
#endif
#if !TOD_OUTPUT_LINEAR
color = TOD_LINEAR2GAMMA(color);
#endif
return color;
}
//////////////////////////////////////////CLOUD CALCULATION//////////////////////////////////////////////////
inline half3 CloudPosition(half3 viewDir, half3 offset)
{
half mult = 1.0 / lerp(0.1, 1.0, viewDir.y);
return (half3(viewDir.x * mult + offset.x, 0, viewDir.z * mult + offset.z)) / TOD_CloudSize;
}
inline half4 CloudUV(half3 viewDir, half3 offset)
{
half3 cloudPos = CloudPosition(viewDir, offset);
half2 uv1 = cloudPos.xz + TOD_CloudOffset.xz + TOD_CloudWind.xz;
half2 uv2 = mul(TOD_ROTATION_UV(radians(10.0)), cloudPos.xz) + TOD_CloudOffset.xz + TOD_CloudWind.xz;
return half4(uv1.x, uv1.y, uv2.x, uv2.y);
}
inline half4 CloudUV(half3 viewDir)
{
return CloudUV(viewDir, 0);
}
inline half3 CloudColor(half3 viewDir, half3 lightDir)
{
half lerpValue = saturate(1 + 4 * lightDir.y) * saturate(dot(viewDir, lightDir) + 1.25);
half3 cloudColor = lerp(TOD_MoonCloudColor, TOD_SunCloudColor, lerpValue);
half3 fogColor = TOD_FogColor;
return TOD_Brightness * lerp(cloudColor, fogColor, TOD_Fogginess);
}
inline half3 CloudLayerDensity(half4 uv, half3 viewDir)
{
half3 density = 0;
#if TOD_CLOUDS_DENSITY
const half thickness = 0.1;
const half4 stepoffset = half4(0.0, 1.0, 2.0, 3.0) * thickness;
const half4 sumy = half4(0.5000, 0.2500, 0.1250, 0.0625) / half4(1, 2, 3, 4);
const half4 sumz = half4(0.5000, 0.2500, 0.1250, 0.0625);
half2 uv1 = uv.xy + viewDir.xz * stepoffset.x;
half2 uv2 = uv.zw + viewDir.xz * stepoffset.y;
half2 uv3 = uv.xy + viewDir.xz * stepoffset.z;
half2 uv4 = uv.zw + viewDir.xz * stepoffset.w;
half4 n1 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv1);
half4 n2 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv2);
half4 n3 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv3);
half4 n4 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv4);
half4 ny = half4(n1.r, n1.g + n2.g, n1.b + n2.b + n3.b, n1.a + n2.a + n3.a + n4.a); // Noise when marching in up direction
half4 nz = half4(n1.r, n2.g, n3.b, n4.a); // Noise when marching in view direction
density.y += dot(ny, sumy); // Density when marching in up direction
density.z += dot(nz, sumz); // Density when marching in view direction
half2 stepA = TOD_CloudCoverage; // Coverage
half2 stepB = TOD_CloudCoverage + TOD_CloudSharpness;
half2 stepC = TOD_CloudDensity;
density.yz = smoothstep(stepA, stepB, density.yz) + saturate(density.yz - stepB) * stepC;
density.x = saturate(density.z); // Opacity
density.yz *= half2(TOD_CloudAttenuation, TOD_CloudSaturation); // Shading
density.yz = 1.0 - exp2(-density.yz); // Remap
#else
half4 n = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv.xy);
density.y += n.r; // Density when marching in up direction
density.z += n.r; // Density when marching in view direction
density.yz = (density.yz - TOD_CloudCoverage) * half2(TOD_CloudAttenuation, TOD_CloudDensity); // Coverage
density.x = saturate(density.z); // Opacity
#endif
return density;
}
inline half4 CloudLayerColor(half4 uv, half4 color, half3 viewDir, half3 lightDir, half3 lightCol)
{
half3 density = CloudLayerDensity(uv, viewDir);
half4 res = 0;
res.a = density.x;
res.rgb = 1.0 - density.y;
res *= color;
#if TOD_CLOUDS_BUMPED
res.rgb += saturate((1.0 - density.z) * (1.0 - TOD_Fogginess)) * lightCol;
#endif
return res;
}
inline half CloudShadow(half4 uv)
{
return CloudLayerDensity(uv, half3(0, 1, 0)).x;
}
inline half CloudShadow(half3 cameraToWorldPos)
{
half3 worldPos = _WorldSpaceCameraPos + cameraToWorldPos;
half3 skyPos = mul((half3x3)TOD_World2Sky, worldPos);
half4 cloudUV = CloudUV(TOD_LocalLightDirection, skyPos);
return TOD_CloudOpacity * CloudShadow(cloudUV);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////SCATTERING CALCULATION////////////////////////////////////////////
inline half3 ApplayVirtualScatterLight(half3 curColor, float3 worldPos)
{
float3 worldViewDir = _WorldSpaceCameraPos.xyz - worldPos.xyz;
half3 worldLightDir = normalize(GetMainLight().direction);
half angleFactor = 1.0 - saturate(dot(normalize(worldViewDir), worldLightDir) * 0.5 + 0.8);
half3 scatterLightColor = _SG_VirtualScatterLightColor.rgb * angleFactor;
half3 finalColor = curColor + scatterLightColor;
return finalColor;
}
inline half Scale(half inCos)
{
half x = 1.0 - inCos;
return 0.25 * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
}
inline half MiePhase(half eyeCos, half eyeCos2)
{
return TOD_kBetaMie.x * (1.0 + eyeCos2) / pow(TOD_kBetaMie.y + TOD_kBetaMie.z * eyeCos, 1.5);
}
inline half RayleighPhase(half eyeCos2)
{
return 0.75 + 0.75 * eyeCos2;
}
inline half RayleighPhase(half eyeCos2, half3 dir)
{
half groundPercent = 1-saturate(dir.y);
half base = lerp(1.5, 0.2, groundPercent);
half phase = base + 0.75 * eyeCos2;
half isBottom = dir.y < -0.5;
phase *= lerp(1, 0.2, isBottom);
return phase;
}
inline half CloudPhase(half eyeCos, half eyeCos2)
{
const half g = 0.3;
const half g2 = g * g;
return TOD_CloudScattering * (1.5 * (1.0 - g2) / (2.0 + g2) * (1.0 + eyeCos2) / (1.0 + g2 - 2.0 * g * eyeCos) + g * eyeCos);
}
inline half3 NightPhase(half3 dir)
{
dir.y = abs(dir.y);
return TOD_MoonSkyColor * (1.0 - 0.75 * dir.y);
}
inline half3 MoonPhase(half3 dir)
{
return TOD_MoonHaloColor * pow(max(0, dot(dir, TOD_LocalMoonDirection)), TOD_MoonHaloPower);
}
inline half3 PostProcess(half3 col, half3 dir)
{
col = pow(col * TOD_Brightness, TOD_Contrast);
return col;
}
#if TOD_SCATTERING_RAYLEIGH && TOD_SCATTERING_MIE
inline void ScatteringCoefficients(half3 dir, out half3 inscatter, out half3 outscatter)
#elif TOD_SCATTERING_RAYLEIGH
inline void ScatteringCoefficients(half3 dir, out half3 inscatter)
#else
inline void ScatteringCoefficients(half3 dir, out half3 outscatter)
#endif
{
dir = normalize(half3(dir.x, max(0, dir.y), dir.z));
half kInnerRadius = TOD_kRadius.x;
half kInnerRadius2 = TOD_kRadius.y;
half kOuterRadius2 = TOD_kRadius.w;
half kScale = TOD_kScale.x;
half kScaleOverScaleDepth = TOD_kScale.z;
half kCameraHeight = TOD_kScale.w;
half3 kKr4PI = TOD_k4PI.xyz;
half kKm4PI = TOD_k4PI.w;
half3 kKrESun = TOD_kSun.xyz;
half kKmESun = TOD_kSun.w;
half3 cameraPos = half3(0, kInnerRadius + kCameraHeight, 0); // Current camera position
half far = sqrt(kOuterRadius2 + kInnerRadius2 * dir.y * dir.y - kInnerRadius2) - kInnerRadius * dir.y; // Length of the atmosphere
half startDepth = exp(kScaleOverScaleDepth * (-kCameraHeight)); // Ray starting position and its scattering offset
half startAngle = dot(dir, cameraPos) / (kInnerRadius + kCameraHeight);
half startOffset = startDepth * Scale(startAngle);
half sampleLength = far / 2; // Scattering loop variables
half scaledLength = sampleLength * kScale;
half3 sampleRay = dir * sampleLength;
half3 samplePoint = cameraPos + sampleRay * 0.5;
half3 sunColor = half3(0.0, 0.0, 0.0);
half height = max(1, length(samplePoint));
half invHeight = 1.0 / height;
half depth = exp(kScaleOverScaleDepth * (kInnerRadius - height));
half atten = depth * scaledLength;
half cameraAngle = dot(dir, samplePoint) * invHeight;
half sunAngle = dot(TOD_LocalSunDirection, samplePoint) * invHeight;
half sunScatter = startOffset + depth * (Scale(sunAngle) - Scale(cameraAngle));
half3 sunAtten = exp(-sunScatter * (kKr4PI + kKm4PI));
sunColor += sunAtten * atten;
samplePoint += sampleRay;
height = max(1, length(samplePoint));
invHeight = 1.0 / height;
depth = exp(kScaleOverScaleDepth * (kInnerRadius - height));
atten = depth * scaledLength;
cameraAngle = dot(dir, samplePoint) * invHeight;
sunAngle = dot(TOD_LocalSunDirection, samplePoint) * invHeight;
sunScatter = startOffset + depth * (Scale(sunAngle) - Scale(cameraAngle));
sunAtten = exp(-sunScatter * (kKr4PI + kKm4PI));
sunColor += sunAtten * atten;
samplePoint += sampleRay;
#if TOD_SCATTERING_RAYLEIGH // Sun scattering
inscatter = TOD_SunSkyColor * sunColor * kKrESun;
#endif
#if TOD_SCATTERING_MIE
outscatter = TOD_SunSkyColor * sunColor * kKmESun;
#endif
}
#if TOD_SCATTERING_RAYLEIGH && TOD_SCATTERING_MIE
inline half4 ScatteringColor(half3 dir, half3 inscatter, half3 outscatter)
#elif TOD_SCATTERING_RAYLEIGH
inline half4 ScatteringColor(half3 dir, half3 inscatter)
#else
inline half4 ScatteringColor(half3 dir, half3 outscatter)
#endif
{
half3 resultColor = half3(0.05, 0.05, 0.1);
half sunCos = dot(TOD_LocalSunDirection, dir);
half sunCos2 = sunCos * sunCos;
#if TOD_SCATTERING_RAYLEIGH
resultColor += NightPhase(dir);
#endif
#if TOD_SCATTERING_MIE
resultColor += MoonPhase(dir);
#endif
#if TOD_SCATTERING_RAYLEIGH
resultColor += RayleighPhase(sunCos2, dir) * inscatter;
#endif
#if TOD_SCATTERING_MIE
resultColor += MiePhase(sunCos, sunCos2) * outscatter;
#endif
return half4(PostProcess(resultColor, dir), 1.0);
}
inline half4 ScatteringColor(half3 dir)
{
#if TOD_SCATTERING_RAYLEIGH && TOD_SCATTERING_MIE
half3 inscatter, outscatter;
ScatteringCoefficients(dir, inscatter, outscatter);
return ScatteringColor(dir, inscatter, outscatter);
#elif TOD_SCATTERING_RAYLEIGH
half3 inscatter;
ScatteringCoefficients(dir, inscatter);
return ScatteringColor(dir, inscatter);
#else
half3 outscatter;
ScatteringCoefficients(dir, outscatter);
return ScatteringColor(dir, outscatter);
#endif
}
inline half FogDensity(half3 worldPos)
{
half camDist = length(worldPos - _WorldSpaceCameraPos);
half globalDensity = TOD_ScatterDensity.z;
half heightDensity = TOD_ScatterDensity.x * (worldPos.y - TOD_ScatterDensity.y);
half heightDensityExpInv = exp(-heightDensity);
half fogIntensity = camDist * heightDensityExpInv; // Get base fog intensity at pixel
half clampRes = step(abs(heightDensity), 0.01); // Apply height falloff
fogIntensity *= ((1.0 - heightDensityExpInv) / heightDensity) * step(abs(heightDensity), 0.01) + step(0.01, abs(heightDensity));
fogIntensity = min(10, globalDensity * fogIntensity); // Clamp intensity
return 1.0 - exp(-fogIntensity);
}
inline half4 AtmosphericScattering(half3 cameraRay, half3 worldPos, half depth, half mask)
{
half3 dir = normalize(mul((half3x3)TOD_World2Sky, cameraRay));
#if TOD_SCATTERING_RAYLEIGH && TOD_SCATTERING_MIE
half3 inscatter, outscatter;
ScatteringCoefficients(dir, inscatter, outscatter);
#elif TOD_SCATTERING_RAYLEIGH
half3 inscatter;
ScatteringCoefficients(dir, inscatter);
#else
half3 outscatter;
ScatteringCoefficients(dir, outscatter);
#endif
depth = FogDensity(worldPos);
#if TOD_SCATTERING_MIE
outscatter = outscatter * depth * mask;
#endif
#if TOD_SCATTERING_RAYLEIGH
inscatter = inscatter * depth;
#endif
#if TOD_SCATTERING_RAYLEIGH && TOD_SCATTERING_MIE
half3 color = ScatteringColor(dir, inscatter, outscatter).rgb;
#elif TOD_SCATTERING_RAYLEIGH
half3 color = ScatteringColor(dir, inscatter).rgb;
#else
half3 color = ScatteringColor(dir, outscatter).rgb;
#endif
return half4(color, depth);
}
inline half4 AtmosphericScattering(half3 cameraRay, half3 worldPos, half depth)
{
const half mask = 1; // This should be sampled from the scattering occlusion mask
return AtmosphericScattering(cameraRay, worldPos, depth, mask);
}
inline half4 AtmosphericScattering(half3 cameraRay, half3 worldPos)
{
half3 dir = normalize(mul((half3x3)TOD_World2Sky, cameraRay));
half depth = FogDensity(worldPos);
half3 color = ScatteringColor(dir).rgb;
return half4(color, depth);
}
inline half2 DitheringCoords(half2 screenPos)
{
return screenPos * _ScreenParams.xy * (1.0 / TOD_BAYER_DIM);
}
inline half DitheringColor(half2 uv)
{
return SAMPLE_TEXTURE2D(TOD_BayerTexture, samplerTOD_BayerTexture, uv).a * (1.0 / (TOD_BAYER_DIM * TOD_BAYER_DIM + 1.0));
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 2545c0fe39d76e945a2fa147f900724e
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,88 @@
#ifndef EXPHEIGHTFOG_BASE
#define EXPHEIGHTFOG_BASE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#if defined(_SG_EXPFOG)
float4 _SG_ExpFogParams;
float4 _SG_ExpFogParams2;
float4 _SG_ExpFogParams3;
float4 _SG_ExpFogDirInscatteringCol;
float4 _SG_ExpFogLightDir;
float4 _SG_ExpFogColParams;
#define CUSTOM_FOG_COORDS(ID) float4 _fogCoord : TEXCOORD##ID;
#define CUSTOM_TRANSFER_FOG(v2f, vertex) v2f##._fogCoord = GetExponentialHeightFog(GetCameraPositionWS() - GetVertexPositionInputs(vertex.xyz).positionWS)
#define CUSTOM_APPLY_FOG(v2f, pixelColor, lerpVal) pixelColor = lerp(pixelColor, pixelColor.rgb * v2f._fogCoord.a + v2f._fogCoord.rgb, saturate(lerpVal / _SG_ExpFogParams3.w))
// UE 4.22 HeightFogCommon.ush
// Calculate the line integral of the ray from the camera to the receiver position through the fog density function
// The exponential fog density function is d = GlobalDensity * exp(-HeightFalloff * y)
inline float CalculateLineIntegralShared(float FogHeightFalloff, float RayDirectionY, float RayOriginTerms)
{
float Falloff = max(-127.0f, FogHeightFalloff * RayDirectionY); // if it's lower than -127.0, then exp2() goes crazy in OpenGL's GLSL.
float LineIntegral = (1.0f - exp2(-Falloff)) / Falloff;
return RayOriginTerms * LineIntegral;
}
// UE 4.22 HeightFogCommon.ush
// @param WorldPositionRelativeToCamera = WorldPosition - InCameraPosition
inline float4 GetExponentialHeightFog(float3 WorldPositionRelativeToCamera) // camera to vertex
{
float MinFogOpacity = _SG_ExpFogColParams.w;
// Receiver
float3 CameraToReceiver = -WorldPositionRelativeToCamera;
float CameraToReceiverLengthSqr = dot(CameraToReceiver, CameraToReceiver);
float CameraToReceiverLengthInv = rsqrt(CameraToReceiverLengthSqr);
float CameraToReceiverLength = CameraToReceiverLengthSqr * CameraToReceiverLengthInv;
float3 CameraToReceiverNormalized = CameraToReceiver * CameraToReceiverLengthInv;
float RayOriginTerms = _SG_ExpFogParams.x;
float RayLength = CameraToReceiverLength;
float RayDirectionY = CameraToReceiver.y;
// Factor in StartDistance
float ExcludeDistance = _SG_ExpFogParams.w;
float ExcludeIntersectionTime = ExcludeDistance * CameraToReceiverLengthInv;
float CameraToExclusionIntersectionY = ExcludeIntersectionTime * CameraToReceiver.y;
float ExclusionIntersectionY = GetCameraPositionWS().y + CameraToExclusionIntersectionY;
float ExclusionIntersectionToReceiverY = CameraToReceiver.y - CameraToExclusionIntersectionY;
float Exponent = max(-127.0f, _SG_ExpFogParams.y * (ExclusionIntersectionY - (GetCameraPositionWS().y + _SG_ExpFogParams3.y)));
RayLength = (1.0f - ExcludeIntersectionTime) * CameraToReceiverLength;
RayDirectionY = ExclusionIntersectionToReceiverY;
RayOriginTerms = _SG_ExpFogParams3.x * exp2(-Exponent);
float ExponentialHeightLineIntegralShared = CalculateLineIntegralShared(_SG_ExpFogParams.y, RayDirectionY, RayOriginTerms);
float ExponentialHeightLineIntegral = ExponentialHeightLineIntegralShared * RayLength;
float3 InscatteringColor = _SG_ExpFogColParams.xyz;
float3 DirectionalInscattering = 0;
float DirectionalInscatteringStartDistance = _SG_ExpFogLightDir.w;
// Setup a cosine lobe around the light direction to approximate inscattering from the directional light off of the ambient haze;
float3 DirectionalLightInscattering = _SG_ExpFogDirInscatteringCol.xyz * pow(saturate(dot(CameraToReceiverNormalized, _SG_ExpFogLightDir.xyz)), _SG_ExpFogDirInscatteringCol.w);
// Calculate the line integral of the eye ray through the haze, using a special starting distance to limit the inscattering to the distance
float DirExponentialHeightLineIntegral = ExponentialHeightLineIntegralShared * max(RayLength - DirectionalInscatteringStartDistance, 0.0f);
// Calculate the amount of light that made it through the fog using the transmission equation
float DirectionalInscatteringFogFactor = saturate(exp2(-DirExponentialHeightLineIntegral));
// Final inscattering from the light
DirectionalInscattering = DirectionalLightInscattering * (1 - DirectionalInscatteringFogFactor);
// Calculate the amount of light that made it through the fog using the transmission equation
float ExpFogFactor = max(saturate(exp2(-ExponentialHeightLineIntegral)), MinFogOpacity);
float3 FogColor = (InscatteringColor) * (1 - ExpFogFactor) + DirectionalInscattering;
return float4(FogColor, ExpFogFactor);
}
inline float3 ApplyFogUnrealExp2Fog(float3 finalColor, float3 worldPos)
{
float4 fogCoord = GetExponentialHeightFog(worldPos.xyz - GetCameraPositionWS().xyz);
float lerpVal = distance(GetCameraPositionWS().xyz, worldPos.xyz);
return lerp(finalColor, finalColor * fogCoord.a + fogCoord.rgb, saturate(lerpVal / _SG_ExpFogParams3.w));
}
inline float3 ApplyFogUnrealExp2FogWithOffset(float3 finalColor, float3 worldPos, float fogFactor)
{
float4 fogCoord = GetExponentialHeightFog(worldPos.xyz - GetCameraPositionWS().xyz);
float lerpVal = distance(GetCameraPositionWS().xyz, worldPos.xyz);
return lerp(finalColor, finalColor * fogCoord.a + fogCoord.rgb, saturate(lerpVal / _SG_ExpFogParams3.w) * fogFactor);
}
#endif
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 608c8f1839363ad428819528888b5c10
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,367 @@
#ifndef LIGHTING_BASE
#define LIGHTING_BASE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "ExpHeightFog_Base.hlsl"
#include "./CustomShadowMap_Base.hlsl"
CBUFFER_START(UnityPerMaterial_SCENE)
//线性雾
half4 _SG_FogHeightVector, _SG_FogHeightColor, _SG_FogRangeVector, _SG_FogColor;
half _SG_FogDensity;
//覆盖色
half4 _SG_CoverageColor; half _SG_CoverageLevel; half _SG_CoverageAmt; half _SG_CoverageFactor;
//环境光
half3 _SG_AmbientColor; half _SG_AmbientStrength; half3 _SG_ShadowColor;
//场景光
half _SG_DarkStrength;
//场景潮湿
half _SG_WetBumpHeightScale; half3 _SG_WetColor; half3 _SG_WetSpecularColor; half _SG_WetSpecularStrength; half _SG_WetSmoothness;
half _SG_WetFactor; half _SG_WetRippleSpeed; half4 _SG_WetBumpTilingOffset1; half4 _SG_WetBumpTilingOffset2;
half4 _SG_WetRippleTex_ST; half _SG_WetRippleStrength; half4 _SG_WetRippleTiling; half _SG_WetRippleBumpScale;
half3 _SG_ThunderDirection; half _SG_ThunderStrength; half3 _SG_ThunderColor;
CBUFFER_END
TEXTURE2D(_SG_WetRippleTex); SAMPLER(sampler_SG_WetRippleTex);
TEXTURE2D(_SG_WetBumpMap1); SAMPLER(sampler_SG_WetBumpMap1);
TEXTURE2D(_SG_WetBumpMap2); SAMPLER(sampler_SG_WetBumpMap2);
inline half SGamePow(half x, half n)
{
n = n * 1.4427f + 1.4427f; // 1.4427f --> 1/ln(2)
return exp2(x * n - n);
}
inline half3 RotationY(half3 pointP, half angle)
{
half radY = radians(angle);
half sinY = sin(radY);
half cosY = cos(radY);
return half3(pointP.x * cosY - pointP.z * sinY,
pointP.y,
pointP.x * sinY + pointP.z * cosY);
}
real ApplyMicroShadow(real ao, real3 N, real3 L, real shadow)
{
#if defined(_MICRO_SHADOW)
real aperture = 2.0 * ao * ao;
real microShadow = saturate(abs(dot(N, L)) + aperture - 1.0);
return shadow * microShadow;
#else
return shadow;
#endif
}
////APPLY_SCENE_EFFECT//////////////////////////////////////////////////////////////////////////////////////
half3 ApplyFog(half3 mainColor, half3 worldPos, half fogDensity)
{
half heightFade = 1 - saturate((worldPos.y - (_WorldSpaceCameraPos.y - _SG_FogHeightVector.x)) * _SG_FogHeightVector.y);
heightFade *= heightFade;
half3 finalColor = lerp(mainColor, _SG_FogHeightColor.rgb, heightFade * fogDensity);
half dist = length(_WorldSpaceCameraPos.xyz - worldPos.xyz);
half distFade = saturate((dist - _SG_FogRangeVector.x) * _SG_FogRangeVector.y);
finalColor = lerp(finalColor, _SG_FogColor.rgb, distFade * fogDensity);
return finalColor;
}
half3 ApplyFog_CustomOffset(half3 mainColor, half3 worldPos, half fogDensity, half offset)
{
half heightFade = 1 - saturate((worldPos.y + offset - (_WorldSpaceCameraPos.y - _SG_FogHeightVector.x)) * _SG_FogHeightVector.y);
heightFade *= heightFade;
half3 finalColor = lerp(mainColor, _SG_FogHeightColor.rgb, heightFade * fogDensity);
half dist = length(_WorldSpaceCameraPos.xyz - worldPos.xyz);
half distFade = saturate((dist - _SG_FogRangeVector.x) * _SG_FogRangeVector.y);
finalColor = lerp(finalColor, _SG_FogColor.rgb, distFade * fogDensity);
return finalColor;
}
half3 ApplyDark(half3 mainColor)
{
#if defined(SGAME_QUALITY_PERFECT) || defined(SGAME_QUALITY_HIGH)
return lerp(mainColor, half3(0, 0, 0), _SG_DarkStrength);
#else
return mainColor;
#endif
}
half3 ApplyCoverageColor (half3 mainColor, half worldNormalY, half offset)
{
return lerp(mainColor.rgb, _SG_CoverageColor.rgb, saturate(pow(worldNormalY, _SG_CoverageLevel * offset) * _SG_CoverageAmt));
}
half3 RgbToHsv_SGame(half3 c)
{
half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));
half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));
half d = q.x - min(q.w, q.y);
half e = 1.0e-4;
return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
half3 HsvToRgb_SGame(half3 c)
{
half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);
}
half3 FixedSHEvalLinearL0L1(half4 normal)
{
half3 x;
half4 fixedSHAr = half4(0.058, 0.25, 0.57, 0.34);
half4 fixedSHAg = half4(0.046, 0.29, 0.55, 0.37);
half4 fixedSHAb = half4(0.028, 0.33, 0.47, 0.37);
x.r = dot(fixedSHAr,normal);
x.g = dot(fixedSHAg,normal);
x.b = dot(fixedSHAb,normal);
return x;
}
half3 FixedSHEvalLinearL2 (half4 normal)
{
half3 x1, x2;
half4 vB = normal.xyzz * normal.yzzx;
half4 fixedSHBr = half4(0.058, 0.31, 0.5, 0.12);
half4 fixedSHBg = half4(0.05, 0.29, 0.46, 0.11);
half4 fixedSHBb = half4(0.038, 0.24, 0.36, 0.11);
half4 fixedSHC = half4(0.0047, 0.011, 0.013, 1);
x1.r = dot(fixedSHBr,vB);
x1.g = dot(fixedSHBg,vB);
x1.b = dot(fixedSHBb,vB);
half vC = normal.x*normal.x - normal.y*normal.y;
x2 = fixedSHC.rgb * vC;
return x1 + x2;
}
half3 FixedShadeSH9 (half4 normal)
{
half3 res = FixedSHEvalLinearL0L1 (normal);
res += FixedSHEvalLinearL2 (normal);
return res;
}
inline half3 fresnel(half3 F0, half NdotV, half roughness, half factor)
{
return F0 + (max(1.0 - roughness, F0) - F0) * pow(1 - NdotV, factor);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////APPLY_SCENE_WET/////////////////////////////////////////////////////////////////////////////////////////
inline half2 ComputeRipple(half2 UV, half currentTime, half weight)
{
half4 ripple = SAMPLE_TEXTURE2D(_SG_WetRippleTex, sampler_SG_WetRippleTex, UV);
ripple.yz = ripple.yz * 2 - 1;
half dropFrac = frac(ripple.w + currentTime); // Apply time shift
half timeFrac = dropFrac - 1.0f + ripple.x;
half dropFactor = saturate(0.2f + weight * 0.8f - dropFrac);
half finalFactor = dropFactor * ripple.x * sin(clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.141592653589793);
return ripple.yz * finalFactor;
}
// Add Water Ripples to Waterflow
inline half3 AddWetRipples(half3 worldPos, half3 worldNormal)
{
half weight = saturate(_SG_WetRippleStrength * 4);
half animSpeed = _Time.y * _SG_WetRippleSpeed;
half2 ripple = ComputeRipple(half2(worldPos.xz * _SG_WetRippleTiling), animSpeed, weight);
half3 rippleNormal = half3( weight * ripple.xy, 1) * _SG_WetRippleBumpScale;
return lerp( half3(0,0,1), rippleNormal, _SG_WetFactor * (worldNormal.y > 0.7));
}
half2 UnityFlipbook(half2 UV, half Width, half Height, half Tile)
{
Tile = Tile % (Width*Height);
half2 tileCount = half2(1.0, 1.0) / half2(Width, Height);
half tileY = max(Height - (floor(Tile * tileCount.x) + 1), 0);
half tileX = max(Tile - Width * floor(Tile * tileCount.x), 0);
return (UV + half2(tileX, tileY)) * tileCount;
}
inline half3 AddWetSheetRipples(half3 worldPos, half3 worldNormal)
{
half2 uv = worldPos.xz * _SG_WetRippleTiling;
half animSpeed = round(_Time.y * _SG_WetRippleSpeed);
half2 outUV = UnityFlipbook(uv, 4, 4, animSpeed);
half3 rippleNormal = SAMPLE_TEXTURE2D(_SG_WetRippleTex, sampler_SG_WetRippleTex, outUV) * 2 - 1;
return lerp( half3(0,0,1), rippleNormal * _SG_WetRippleBumpScale, _SG_WetFactor * worldNormal.y);
}
half3 SGameWetBump(half3 worldPos, half3 worldNormal)
{
half2 flowUV = half2(worldPos.x, worldPos.z);
half3 flowBump1 = SAMPLE_TEXTURE2D(_SG_WetBumpMap1, sampler_SG_WetBumpMap1, flowUV * _SG_WetBumpTilingOffset1.xy + _SG_WetBumpTilingOffset1.zw * _Time.y);
half3 flowBump2 = SAMPLE_TEXTURE2D(_SG_WetBumpMap2, sampler_SG_WetBumpMap2, flowUV * _SG_WetBumpTilingOffset2.xy + _SG_WetBumpTilingOffset2.zw * _Time.y);
half3 flowBump = flowBump1 - flowBump2;
half3 bumpNormal = lerp(half3(0,0,1), flowBump, _SG_WetFactor);
bumpNormal *= _SG_WetBumpHeightScale;
return bumpNormal;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////VERTEX_ANIMATION////////////////////////////////////////////////////////////////////////////////////////
inline void FastSinCos(half4 val, out half4 s, out half4 c)
{
val = val * 6.408849 - 3.1415927;
half4 r5 = val * val;
half4 r6 = r5 * r5;
half4 r7 = r6 * r5;
half4 r8 = r6 * r5;
half4 r1 = r5 * val;
half4 r2 = r1 * r5;
half4 r3 = r2 * r5;
half4 sin7 = { 1, -0.16161616, 0.0083333, -0.00019841 };
half4 cos8 = { -0.5, 0.041666666, -0.0013888889, 0.000024801587 };
s = val + r1 * sin7.y + r2 * sin7.z + r3 * sin7.w;
c = 1 + r5 * cos8.x + r6 * cos8.y + r7 * cos8.z + r8 * cos8.w;
}
inline half4 ApplyFastWind(half4 vertex, half texCoordY, half wdSpeed = 0, half windBlend = 0)
{
half speed = wdSpeed;
half4 _waveXmove = half4 (0.024, 0.04, -0.12, 0.096);
half4 _waveZmove = half4 (0.006, .02, -0.02, 0.1);
const half4 waveSpeed = half4 (1.2, 2, 1.6, 4.8);
half4 waves;
waves = vertex.x * windBlend;
waves += vertex.z * windBlend;
waves += _Time.x * (1 - 0.4) * waveSpeed * speed;
half4 s, c;
waves = frac(waves);
FastSinCos(waves, s, c);
half waveAmount = texCoordY * (1 + 0.4);
s *= waveAmount;
s *= normalize(waveSpeed);
s = s * s;
half fade = dot(s, 1.3);
s = s * s;
half3 waveMove = half3 (0, 0, 0);
waveMove.x = dot(s, _waveXmove);
waveMove.z = dot(s, _waveZmove);
vertex.xz -= waveMove.xz;
return vertex;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////LIGHTING_MODES/////////////////////////////////////////////////////////////////////////////////////////
inline half3 GetAmbientColor(half3 mainColor, half3 shLight)
{
#ifdef LIGHTMAP_ON
half3 ambient = mainColor * shLight;
#else
half3 ambient = mainColor * (UNITY_LIGHTMODEL_AMBIENT.xyz + shLight);
#endif
ambient *= _SG_AmbientColor;
ambient *= _SG_AmbientStrength;
return ambient;
}
inline half3 GetAmbientColor_Custom(half3 mainColor, half3 shLight)
{
half3 ambient = lerp(mainColor, mainColor * UNITY_LIGHTMODEL_AMBIENT.xyz, shLight);
ambient *= _SG_AmbientColor;
ambient *= _SG_AmbientStrength;
return ambient;
}
inline half3 BlinnPhoneLighting(half3 mainColor, half3 worldPos, half3 worldNormal, half3 worldViewDir, half3 specularColor, half smoothness, half lightAtten,
half lightClamp = 20, half dotResLerp = 0, half3 customLightDir = half3(0, 0, 0), half useCustomDir = 0)
{
#if defined(SGAME_WET) && defined(SGAME_QUALITY_PERFECT) || defined(SGAME_QUALITY_HIGH)
mainColor = lerp(mainColor, mainColor * _SG_WetColor, _SG_WetFactor);
specularColor = lerp(specularColor, _SG_WetSpecularColor * _SG_WetSpecularStrength, _SG_WetFactor);
smoothness = lerp(lerp(smoothness, _SG_WetSmoothness, _SG_WetFactor), smoothness, smoothness > _SG_WetSmoothness);
#endif
//Diffuse
Light mainLight = GetMainLight();
half3 worldLightDir = normalize(mainLight.direction) * (1 - useCustomDir) + useCustomDir * customLightDir;
half H = normalize(worldViewDir + worldLightDir);
half NDotL = max(0, saturate(dot(worldNormal, worldLightDir)));
half ndotH = max(0, dot(worldNormal, H));
half dotLerp = lerp(NDotL, ndotH, dotResLerp);
half3 lightColor = lerp(_SG_ShadowColor, clamp(mainLight.color.rgb, 0, lightClamp), lightAtten * dotLerp);
specularColor = lerp(_SG_ShadowColor, clamp(mainLight.color.rgb, 0, lightClamp), lightAtten) * specularColor;
half3 diffuse = mainColor * lightColor;
#if defined(SGAME_WET) && defined(SGAME_QUALITY_PERFECT) || defined(SGAME_QUALITY_HIGH)
half thunderNDotL = saturate(dot(worldNormal, _SG_ThunderDirection));
half3 thunderDiffuse = mainColor * lerp(half3(0, 0, 0), _SG_ThunderColor, max(lightAtten, 0.1)) * thunderNDotL * _SG_ThunderStrength;
diffuse += thunderDiffuse;
#endif
#if defined(SGAME_QUALITY_PERFECT) || defined(SGAME_QUALITY_HIGH)
worldViewDir = normalize(worldViewDir);
half3 halfDir = normalize(worldLightDir + worldViewDir);
half NDotH = saturate(dot(worldNormal, halfDir));
half specularPow = SGamePow(NDotH, smoothness * 128.0);
half3 specular = specularColor.rgb * specularPow;
half3 finalColor = diffuse + specular;
#else
half3 finalColor = diffuse;
#endif
return finalColor;
}
inline half3 LambertLighting(half3 mainColor, half3 worldPos, half3 worldNormal, half lightAtten)
{
#if defined(SGAME_WET) && defined(SGAME_QUALITY_PERFECT) || defined(SGAME_QUALITY_HIGH)
mainColor = lerp(mainColor, mainColor * _SG_WetColor, _SG_WetFactor);
#endif
//Diffuse
Light mainLight = GetMainLight();
half3 worldLightDir = normalize(mainLight.direction);
half NDotL = saturate(dot(worldNormal, worldLightDir));
half3 lightColor = lerp(_SG_ShadowColor, mainLight.color.rgb, lightAtten * NDotL);
half3 diffuse = mainColor * lightColor;
#if defined(SGAME_WET) && defined(SGAME_QUALITY_PERFECT) || defined(SGAME_QUALITY_HIGH)
half thunderNDotL = saturate(dot(worldNormal, _SG_ThunderDirection));
half3 thunderDiffuse = mainColor * lerp(half3(0, 0, 0), _SG_ThunderColor, lightAtten) * NDotL * _SG_ThunderStrength;
diffuse += thunderDiffuse;
#endif
return diffuse;
}
inline half3 LambertLightingFwdBase(half3 mainColor, half3 worldPos, half3 worldNormal, half3 shLight, half lightAtten)
{
half3 ambient = GetAmbientColor(mainColor, shLight);
half3 baseLighting = LambertLighting(mainColor, worldPos, worldNormal, lightAtten);
half3 finalColor = ambient + baseLighting;
return finalColor;
}
inline half3 BlinnPhoneLightingFwdBase_CustomAmbient(half3 mainColor, half3 worldPos, half3 worldNormal, half3 worldViewDir, half3 shLight, half lightAtten, half3 specularColor, half smoothness)
{
half3 ambient = GetAmbientColor_Custom(mainColor, shLight);
half3 baseLighting = BlinnPhoneLighting(mainColor, worldPos, worldNormal, worldViewDir, specularColor, smoothness, lightAtten, 0.9);
half3 finalColor = clamp(ambient, 0, 0.65) + baseLighting;
return finalColor;
}
inline half3 BlinnPhoneLightingFwdBase_CustomLight(half3 mainColor, half3 worldPos, half3 worldNormal, half3 worldViewDir, half3 shLight, half lightAtten, half3 specularColor, half smoothness, half3 lightDir)
{
half3 ambient = GetAmbientColor(mainColor, shLight);
half3 baseLighting = BlinnPhoneLighting(mainColor, worldPos, worldNormal, worldViewDir, specularColor, smoothness, lightAtten, 3, 1, lightDir, 1);
half3 finalColor = ambient + baseLighting;
return finalColor;
}
inline half3 BlinnPhoneLightingFwdBase_CustomLightTerrain(half3 mainColor, half3 worldPos, half3 worldNormal, half3 worldViewDir, half3 shLight, half lightAtten, half3 specularColor, half smoothness, half3 lightDir)
{
half3 ambient = GetAmbientColor(mainColor, shLight);
half3 baseLighting = BlinnPhoneLighting(mainColor, worldPos, worldNormal, worldViewDir, specularColor, smoothness, lightAtten, 3, 1, lightDir, 1);
half3 finalColor = ambient + baseLighting;
return finalColor;
}
inline half3 BlinnPhoneLightingFwdBase(half3 mainColor, half3 worldPos, half3 worldNormal, half3 worldViewDir, half3 shLight, half lightAtten, half3 specularColor, half smoothness)
{
half3 ambient = GetAmbientColor(mainColor, shLight);
half3 baseLighting = BlinnPhoneLighting(mainColor, worldPos, worldNormal, worldViewDir, specularColor, smoothness, lightAtten);
half3 finalColor = ambient + baseLighting;
return finalColor;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: b6798e2b8e38d5343b5c42c5a69ef5be
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,118 @@
#ifndef OPAQUECUSTOMLIGHTMAPOBJECT_BASE
#define OPAQUECUSTOMLIGHTMAPOBJECT_BASE
#include "./Lighting_Base.hlsl"
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
TEXTURE2D(_EmisMap); SAMPLER(sampler_EmisMap);
TEXTURE2D(_CustomLightmap); SAMPLER(sampler_CustomLightmap);
TEXTURE2D(_CustomShadowMask); SAMPLER(sampler_CustomShadowMask);
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
float4 _EmisMap_ST; half _EmissionMapScale;
half4 _SpecularColor; half _SpecularFactor; half _Smoothness;
half _LightMapIntensity;
float _TillingX; float _TillingY; float _OffsetX; float _OFfsetY;
CBUFFER_END
struct a2v
{
half4 vertex : POSITION;
half4 normal : NORMAL;
half4 tangent: TANGENT;
half2 texcoord : TEXCOORD0;
float4 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 pos : SV_POSITION;
half4 uvTex0 : TEXCOORD0;
half3 worldPos : TEXCOORD1;
half4 worldTangentDir : TEXCOORD2;
half4 worldBitangentDir : TEXCOORD3;
half4 worldNormalDir : TEXCOORD4;
half3 worldViewDir : TEXCOORD5;
float4 shadowCoord : TEXCOORD6;
#if defined(_SG_EXPFOG)
half4 _fogCoord : TEXCOORD7;
#endif
float4 lightmapUV : TEXCOORD8;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
v2f VertexCommon(a2v v)
{
v2f o = (v2f)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(v.normal, v.tangent);
o.pos = vertexInput.positionCS;
o.uvTex0.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
half3 worldPos = vertexInput.positionWS;
half3 worldNormal = normalInput.normalWS;
half3 worldViewDir = GetCameraPositionWS() - worldPos;
o.worldViewDir = worldViewDir;
o.worldTangentDir = float4(normalInput.tangentWS, worldViewDir.x);
o.worldBitangentDir = float4(normalInput.bitangentWS, worldViewDir.y);
o.worldNormalDir = float4(normalInput.normalWS, worldViewDir.z);
o.worldPos.xyz = worldPos;
return o;
}
// vertex shader
inline v2f VertexForwardBase (a2v v)
{
v2f o = VertexCommon(v);
o.lightmapUV.xy = v.lightmapUV.xy * float2(_TillingX, _TillingY) + float2(_OffsetX, _OFfsetY);
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
o.shadowCoord = GetShadowCoord(vertexInput);
#endif
#if defined(_SG_EXPFOG)
CUSTOM_TRANSFER_FOG(o, v.vertex);
#endif
return o;
}
half4 FragForwardBase(v2f i) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
float3 worldPos = i.worldPos;
half3 worldNormal = normalize(mul(half3(0, 0, 1), half3x3(i.worldTangentDir.xyz, i.worldBitangentDir.xyz, i.worldNormalDir.xyz)));
half3 worldViewDir = normalize(half3(i.worldTangentDir.w, i.worldBitangentDir.w, i.worldNormalDir.w));
half4 mainColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uvTex0);
half4 emissionCol = SAMPLE_TEXTURE2D(_EmisMap, sampler_EmisMap, i.uvTex0) * _EmissionMapScale;
half smoothness = _Smoothness;
half3 specularColor = mainColor.a * _SpecularFactor * _SpecularColor;
half4 shLight = SAMPLE_TEXTURE2D(_CustomLightmap, sampler_CustomLightmap, i.lightmapUV);
float atten = 1;
half bakedAtten = SAMPLE_TEXTURE2D(_CustomShadowMask, sampler_CustomShadowMask, i.lightmapUV);
atten = min(atten, bakedAtten);
half3 finalColor = BlinnPhoneLightingFwdBase(mainColor, worldPos, worldNormal, worldViewDir, shLight.rgb, atten, specularColor, smoothness);
finalColor = ApplyDark(finalColor);
#if defined(_SG_EXPFOG)
CUSTOM_APPLY_FOG(i, finalColor, distance(_WorldSpaceCameraPos, worldPos));
#endif
finalColor += emissionCol.rgb;
return half4(finalColor,1);
}
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 741e9e380b5dffe41824d750ef0ec8a0
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,165 @@
#ifndef OPAQUEOBJECT_BASE
#define OPAQUEOBJECT_BASE
#include "./Lighting_Base.hlsl"
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap);
CBUFFER_START(UnityPerMaterial)
half4 _MainTex_ST; half4 _NormalMap_ST; half4 _MainColor; half _NormalMapScale;
half4 _SpecularColor; half _SpecularFactor; half _Smoothness;
half4 _EmissionColor; half _EmissionFactor;
half _FogFactor;
half _EmissionAlphaThres;
half _totalAlpha;
CBUFFER_END
struct a2v
{
half4 vertex : POSITION;
half4 normal : NORMAL;
half4 tangent: TANGENT;
half2 texcoord : TEXCOORD0;
half2 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 pos : SV_POSITION;
half4 uvTex0 : TEXCOORD0;
half3 worldPos : TEXCOORD1;
#if defined(_USENORMALMAP_OFF) || !defined(SGAME_QUALITY_PERFECT)
half3 worldNormal : TEXCOORD2;
half3 worldViewDir : TEXCOORD3;
#else
half4 worldTangentDir : TEXCOORD2;
half4 worldBitangentDir : TEXCOORD3;
half4 worldNormalDir : TEXCOORD4;
#endif
float4 shadowCoord : TEXCOORD5;
#if defined(_SG_EXPFOG)
half4 _fogCoord : TEXCOORD7;
#endif
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 6);
#if defined(_PROJECTOR_ON)
half4 projectorUV : TEXCOORD9;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
v2f VertexCommon(a2v v)
{
v2f o = (v2f)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(v.normal, v.tangent);
o.pos = vertexInput.positionCS;
o.uvTex0.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
half3 worldPos = vertexInput.positionWS;
half3 worldNormal = normalInput.normalWS;
half3 worldViewDir = GetCameraPositionWS() - worldPos;
#if defined(_USENORMALMAP_OFF) || !defined(SGAME_QUALITY_PERFECT)
o.worldViewDir = worldViewDir;
o.worldNormal = normalize(worldNormal);
#else
o.worldTangentDir = half4(normalInput.tangentWS, worldViewDir.x);
o.worldBitangentDir = half4(normalInput.bitangentWS, worldViewDir.y);
o.worldNormalDir = half4(normalInput.normalWS, worldViewDir.z);
#endif
#if defined(_PROJECTOR_ON)
o.projectorUV = GetProjectorUV(v.vertex, unity_ObjectToWorld);
#endif
o.shadowCoord = GetShadowCoord(vertexInput);
OUTPUT_LIGHTMAP_UV(v.lightmapUV, unity_LightmapST, o.lightmapUV);
OUTPUT_SH(worldNormal, o.vertexSH);
o.worldPos.xyz = worldPos;
return o;
}
// vertex shader
inline v2f VertexForwardBase (a2v v)
{
v2f o = VertexCommon(v);
#if defined(_SG_EXPFOG)
CUSTOM_TRANSFER_FOG(o, v.vertex);
#endif
return o;
}
// fragment shader
inline half4 FragForwardBase (v2f i) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
////法线相关/////////////////////////////////////////////////////////////////////////
half4 normalCol = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, i.uvTex0);
half4 mainColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uvTex0);
half3 worldPos = i.worldPos;
#if defined(_USENORMALMAP_OFF) || !defined(SGAME_QUALITY_PERFECT)
half3 worldNormal = normalize(i.worldNormal);
half3 worldViewDir = normalize(i.worldViewDir);
#else
half3 tangentNormal = normalCol.rgb * 2 - 1;
tangentNormal = lerp(half3(0, 0, 1), tangentNormal, _NormalMapScale);
half3 worldNormal = normalize(mul(tangentNormal, half3x3(i.worldTangentDir.xyz, i.worldBitangentDir.xyz, i.worldNormalDir.xyz)));
half3 worldViewDir = normalize(half3(i.worldTangentDir.w, i.worldBitangentDir.w, i.worldNormalDir.w));
#endif
#if defined(SGAME_WET) && (defined(SGAME_QUALITY_PERFECT) || defined(SGAME_QUALITY_HIGH))
#if defined(_USENORMALMAP_OFF) || !defined(SGAME_QUALITY_PERFECT)
// do nothing
#else
half3 wetRippleNormal = AddWetSheetRipples(worldPos, worldNormal);
half3 wetRippleNormal2 = SGameWetBump(worldPos, worldNormal);
tangentNormal.xy += (wetRippleNormal.xy + wetRippleNormal2.xy);
worldNormal = normalize(mul(tangentNormal, half3x3(i.worldTangentDir.xyz, i.worldBitangentDir.xyz, i.worldNormalDir.xyz)));
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////
half smoothness = _Smoothness;
half3 specularColor = mainColor.a * _SpecularFactor * _SpecularColor;
mainColor.rgb = ApplyCoverageColor(mainColor.rgb, worldNormal.y, _SG_CoverageFactor);
mainColor.rgb *= _MainColor;
////阴影相关、烘焙相关/////////////////////////////////////////////////////////////////////////
half atten = 1;
float3 shLight = 1;
#if defined(LIGHTMAP_ON)
shLight = SAMPLE_GI(i.lightmapUV, i.vertexSH, worldNormal);
float shadowMask = SAMPLE_SHADOWMASK(i.lightmapUV);
Light mainLight = GetMainLight(i.shadowCoord, worldPos, shadowMask);
MixRealtimeAndBakedGI(mainLight, worldNormal, shLight, half4(0, 0, 0, 0));
atten = GetMainLight(i.shadowCoord, worldPos, shadowMask).shadowAttenuation;
atten = min(atten, shadowMask);
#endif
//////////////////////////////////////////////////////////////////////////////////////////////
//前向渲染——Lighting
half3 finalColor = BlinnPhoneLightingFwdBase(mainColor, worldPos, worldNormal, worldViewDir, shLight, atten, specularColor, smoothness);
half3 emissionColor = mainColor.rgb * _EmissionColor.rgb * _EmissionFactor * normalCol.a;
finalColor += emissionColor * step(_EmissionAlphaThres, normalCol.a);
//环境效果:暗、雾效
finalColor = ApplyDark(finalColor);
#if defined(_SG_EXPFOG)
CUSTOM_APPLY_FOG(i, finalColor, distance(_WorldSpaceCameraPos, worldPos));
#endif
#if defined(_PROJECTOR_ON)
finalColor.rgb = GetProjectorColor(finalColor.rgb, i.projectorUV).rgb;
#endif
return half4(finalColor, _totalAlpha);
}
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 051d010d22588eb439e4318dbc36a86e
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,189 @@
#ifndef OPAQUEOBJECT_BASE
#define OPAQUEOBJECT_BASE
#include "./Lighting_Base.hlsl"
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap);
CBUFFER_START(UnityPerMaterial)
half4 _MainColor; half _FogFactor; half4 _MainTex_ST;
half _NormalMapScale;
half4 _SpecularColor; half _SpecularFactor; half _Smoothness;
half _UseCustomLight; half4 _CustomLightDir; half _CameraLightIntensity;
half4 _CameraLightColor; half3 _Light2Dir; half _totalAlpha;
half _EnvironmentOffset; half _EnvIntensity; half _EnvSmoothness;
half4 _EnvColor; half _EnvironmentYOffset;
CBUFFER_END
struct a2v
{
half4 vertex : POSITION;
half4 normal : NORMAL;
half4 tangent: TANGENT;
half2 texcoord : TEXCOORD0;
half2 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 pos : SV_POSITION;
half4 uvTex0 : TEXCOORD0;
half3 worldPos : TEXCOORD1;
#if defined(_USENORMALMAP_OFF) || !defined(SGAME_QUALITY_PERFECT)
half3 worldNormal : TEXCOORD2;
half3 worldViewDir : TEXCOORD3;
#else
half4 worldTangentDir : TEXCOORD2;
half4 worldBitangentDir : TEXCOORD3;
half4 worldNormalDir : TEXCOORD4;
#endif
float4 shadowCoord : TEXCOORD5;
#if defined(_SG_EXPFOG)
half4 _fogCoord : TEXCOORD7;
#endif
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 6);
half3 vertexNormal : TEXCOORD8;
#if defined(_PROJECTOR_ON)
half4 projectorUV : TEXCOORD9;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
v2f VertexCommon(a2v v)
{
v2f o = (v2f)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(v.normal, v.tangent);
o.pos = vertexInput.positionCS;
o.uvTex0.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
half3 worldPos = vertexInput.positionWS;
half3 worldNormal = normalInput.normalWS;
half3 worldViewDir = GetCameraPositionWS() - worldPos;
#if defined(_USENORMALMAP_OFF) || !defined(SGAME_QUALITY_PERFECT)
o.worldViewDir = worldViewDir;
o.worldNormal = normalize(worldNormal);
#else
o.worldTangentDir = half4(normalInput.tangentWS, worldViewDir.x);
o.worldBitangentDir = half4(normalInput.bitangentWS, worldViewDir.y);
o.worldNormalDir = half4(normalInput.normalWS, worldViewDir.z);
#endif
o.shadowCoord = GetShadowCoord(vertexInput);
o.worldPos.xyz = worldPos;
#if defined(_PROJECTOR_ON)
o.projectorUV = GetProjectorUV(v.vertex, unity_ObjectToWorld);
#endif
OUTPUT_LIGHTMAP_UV(v.lightmapUV, unity_LightmapST, o.lightmapUV);
OUTPUT_SH(worldNormal, o.vertexSH);
return o;
}
// vertex shader
inline v2f VertexForwardBase (a2v v)
{
v2f o = VertexCommon(v);
#if defined(_SG_EXPFOG)
CUSTOM_TRANSFER_FOG(o, v.vertex);
#endif
return o;
}
// fragment shader
inline half4 FragForwardBase (v2f i) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
////法线相关/////////////////////////////////////////////////////////////////////////
half4 normalCol = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, i.uvTex0);
half4 mainColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uvTex0);
half3 worldPos = i.worldPos;
#if defined(_USENORMALMAP_OFF) || !defined(SGAME_QUALITY_PERFECT)
half3 worldNormal = normalize(i.worldNormal);
half3 worldViewDir = normalize(i.worldViewDir);
#else
half3 tangentNormal = normalCol.rgb * 2 - 1;
tangentNormal = lerp(half3(0, 0, 1), tangentNormal, _NormalMapScale);
half3 worldNormal = normalize(mul(tangentNormal, half3x3(i.worldTangentDir.xyz, i.worldBitangentDir.xyz, i.worldNormalDir.xyz)));
half3 worldViewDir = normalize(half3(i.worldTangentDir.w, i.worldBitangentDir.w, i.worldNormalDir.w));
#endif
#if defined(SGAME_WET) && (defined(SGAME_QUALITY_PERFECT) || defined(SGAME_QUALITY_HIGH))
#if defined(_USENORMALMAP_OFF) || !defined(SGAME_QUALITY_PERFECT)
// do nothing
#else
half3 wetRippleNormal = AddWetSheetRipples(worldPos, worldNormal);
half3 wetRippleNormal2 = SGameWetBump(worldPos, worldNormal);
tangentNormal.xy += (wetRippleNormal.xy + wetRippleNormal2.xy);
worldNormal = normalize(mul(tangentNormal, half3x3(i.worldTangentDir.xyz, i.worldBitangentDir.xyz, i.worldNormalDir.xyz)));
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////
half smoothness = _Smoothness;
half3 specularColor = mainColor.a * _SpecularFactor * _SpecularColor;
mainColor.rgb = ApplyCoverageColor(mainColor.rgb, worldNormal.y, _SG_CoverageFactor);
mainColor.rgb *= _MainColor;
////阴影相关、烘焙相关/////////////////////////////////////////////////////////////////////////
half atten = 1;
float3 shLight = 1;
#if defined(LIGHTMAP_ON)
i.shadowCoord = TransformWorldToShadowCoord(worldNormal);
shLight = SAMPLE_GI(i.lightmapUV, i.vertexSH, worldNormal);
float shadowMask = SAMPLE_SHADOWMASK(i.lightmapUV);
atten = GetMainLight(i.shadowCoord, worldPos, shadowMask).shadowAttenuation;
atten = min(atten, shadowMask);
#endif
//////////////////////////////////////////////////////////////////////////////////////////////
//前向渲染——Lighting
half3 finalColor = BlinnPhoneLightingFwdBase(mainColor, worldPos, worldNormal, worldViewDir, shLight, atten, specularColor, smoothness);
//自定义漫反射光加强
#if defined(_USECAMERALIGHT_ON)
half3 N = worldNormal;
half3 L = normalize(_Light2Dir.xyz);
half3 V = normalize(worldViewDir);
half3 H = normalize(L + V);
half NoL = max(dot(L, N), 0.135);
finalColor += _CameraLightColor * _CameraLightIntensity * mainColor.rgb * NoL;
#endif
//反向光加强
#if defined(SGAME_QUALITY_PERFECT) && defined(_USEENVIRONMENTLIGHT_ON)
half3 LightDirCustom = _MainLightPosition.xyz - worldPos.xyz * _MainLightPosition.w;
half3 customLight = reflect(-LightDirCustom, half3(0, 1, 0));
customLight = RotationY(customLight, _EnvironmentOffset) + half3(0, _EnvironmentYOffset, 0);
half3 finalColorAdd = BlinnPhoneLightingFwdBase_CustomLight(
mainColor, worldPos, worldNormal, worldViewDir, shLight, atten,
mainColor.a * _EnvColor * _SpecularFactor, smoothness * _EnvSmoothness, customLight) * _EnvIntensity * max(0, dot(LightDirCustom, worldViewDir));
finalColor += finalColorAdd;
#endif
//环境效果:暗、雾效
finalColor = ApplyDark(finalColor);
#if defined(_SG_EXPFOG)
CUSTOM_APPLY_FOG(i, finalColor, distance(_WorldSpaceCameraPos, worldPos));
#endif
#if defined(_PROJECTOR_ON)
finalColor.rgb = GetProjectorColor(finalColor.rgb, i.projectorUV).rgb;
#endif
return half4(finalColor, _totalAlpha);
}
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 8f9cc15580abf52418c253ab257dbdc2
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,67 @@
#ifndef SGAME_ENV_MAP_BASE
#define SGAME_ENV_MAP_BASE
#define SGAME_ENV_MAP_OUTPUT 0.5
#if defined(SGAME_ENV_MAP_GEN)
float4x4 _MWorldToView;
float _FarPlane;
half _SGameEnvMapGenBoost;
#endif
#if defined(SGAME_ENV_MAP_GEN)
inline float4 EnvMap_WorldToClipPos(float4 worldPos)
{
float4 pos = mul(_MWorldToView, worldPos);
float distance = - pos.z;
pos.xyz = normalize(pos.xyz);
pos.xy /= (1 - pos.z);
#if UNITY_UV_STARTS_AT_TOP
pos.y = - pos.y;
#endif
float farPlane = _FarPlane;
pos.z = (distance/farPlane);
#if defined(SHADER_API_D3D11) || defined(SHADER_API_D3D11_9X)
#else
pos.z = pos.z * 2.0 - 1.0;
#endif
#if UNITY_REVERSED_Z
pos.z = 1 - pos.z;
#endif
pos.w = 1.0;
return pos;
}
inline float3 EnvMap_Normal( float3 normal)
{
float dir = _MWorldToView[2][2] * -1;
float3 n = float3(normal.x, normal.y, normal.z * dir);
return n;
}
inline half3 EnvMapGen_Output(half3 col)
{
half3 output = col.rgb * SGAME_ENV_MAP_OUTPUT;
return output;
}
#endif
#if defined(SGAME_ENV_MAP)
TEXTURECUBE(_SGameEnvMap); SAMPLER(sampler_SGameEnvMap);
TEXTURECUBE(_SGameEnvLerpMap); SAMPLER(sampler_SGameEnvLerpMap);
half _SGameEnvLerp; half _SGameEnvMapStrength;
inline half3 SGameEnvMapIBL(half roughness, half3 normal, half3 viewDir, half giIntensity = 1, half smoothness = 1)
{
half3 R = reflect(-viewDir, normal);
// float4 uvs = EnvMap_UVs(R, roughness, smoothness);
half4 srcColor = SAMPLE_TEXTURECUBE_LOD(_SGameEnvMap, sampler_SGameEnvMap, R, saturate(roughness) * 2);
half4 dstColor = SAMPLE_TEXTURECUBE_LOD(_SGameEnvLerpMap, sampler_SGameEnvLerpMap, R, saturate(roughness) * 2);
srcColor = lerp(srcColor, dstColor, clamp(_SGameEnvLerp, 0, 1));
#if defined(SGAME_ENV_MAP_STRENGTH)
half3 specIBL = srcColor.rgb * giIntensity;
specIBL *= _SGameEnvMapStrength;
#else
half3 specIBL = srcColor.rgb;
#endif
return specIBL;
}
#endif
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 6a25c2991dae41a49bba8c3b32490521
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,389 @@
//修改说明
//1)加上StylizedLambert
//2)加上高光颜色和阴影颜色(HColor和SColor) + SGAME_HS_COLOR_STYLIZED(光照颜色主要影响亮面,不影响暗面)
//3)加上WrapNL对Skin的处理
//4)atten改为由BRDF处理,添加SGameShadowAtten(atten);
//5)添加SGAME_DIRECT_SPECULAR,背光面也有微弱的高光
//6)添加SGAME_INDIRECT_SPECULAR,间接高光gi.specular改用gi.diffuse计算,由于gi.specular依赖的反射探头/天空盒不会随着光照和天空盒改变而变化
#ifndef SGAME_STANDARD_BRDF_INCLUDED
#define SGAME_STANDARD_BRDF_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "SGameEnvMapBase.hlsl"
#include "SGameVLight.hlsl"
//一些自定义的函数,对BRDF进行拓展
//----------------------------------------------------------------------------------------
/////////////////////////////////////SHADOW ATTEN//////////////////////////////////////////
inline half3 BlendMode_Add( half3 s, half3 d)
{
return s + d;
}
inline half3 BlendMode_Screen( half3 s, half3 d)
{
return s + d - s*d;
}
inline half3 ACESToneMapping( half3 x )
{
half tA = 2.51f;
half tB = 0.03f;
half tC = 2.43f;
half tD = 0.59f;
half tE = 0.14f;
return saturate((x*(tA*x+tB))/(x*(tC*x+tD)+tE));
}
#if defined(SGAME_TONEMAPPING_LIGHT_BOOST)
inline half3 ApplyToneMappingLightBoost(half3 col, half3 lightColor)
{
return col * 1 * lightColor;
}
#endif
#if defined(SGAME_TONEMAPPING_GI_DIFFUSE_ATTEN)
inline half3 ApplyToneMappingGIDiffuseAtten(half3 col)
{
return col * 1;
}
#endif
inline half3 SGameOutputTonemapping(half3 col)
{
half3 output = col;
return output;
}
inline half SGameShadowAtten(half atten)
{
return max(atten, 0.2);
}
inline half SGameStylizedAtten(half atten)
{
half stylizedAtten = (atten + 1) * 0.5;
stylizedAtten = saturate(stylizedAtten);
return stylizedAtten;
}
///////////////////////////////////////////////////////////////////////////////////////////
inline half3 EnvBRDFApprox(half3 specularColor, half roughness, half NDotV)
{
half4 c0 = half4(-1, -0.0275, -0.572, 0.022);
half4 c1 = half4(1, 0.0425, 1.04, -0.04);
half4 r = roughness*c0 + c1;
half a004 = min(r.x * r.x, exp2(-9.28 * NDotV)) * r.x + r.y;
half2 AB = half2(-1.04,1.04) * a004 + r.zw;
return specularColor*AB.x + AB.y;
}
inline half3 SGameGISpecular(half roughness, half3 normal, half3 viewDir, UnityIndirect gi, half giIntensity = 1, half smoothness = 1)
{
return 1;
}
inline half3 SGameDiffuseColor( half3 diffColor, half3 specColor )
{
half3 diffuseColor = diffColor;
return diffuseColor;
}
inline half3 SGameSpecularColor( half3 specColor )
{
return specColor;
}
inline half3 SGameStylizedSpecularColor( half3 specularColor, half metallic )
{
half3 linearSpecularColor = specularColor * specularColor;
specularColor = lerp( linearSpecularColor, specularColor, metallic );
return specularColor;
}
inline half SGameDirectSpecular(half3 normal, half3 viewDir, half NDotL, half metallic, half nh, half lh)
{
half3 backfaceLightDir = viewDir;
half3 backfaceHalfDir = viewDir;
half backface_nh = saturate(dot(normal, backfaceHalfDir));
half backface_lh = saturate(dot(backfaceLightDir, backfaceHalfDir));
half notBackface = smoothstep(-1,0.5,NDotL); //0背光 -> 1受光
half isBackface = 1 - smoothstep(-1,0.5,NDotL);
half ratio = isBackface * lerp(0.3,1,metallic);
nh = lerp(nh, backface_nh, ratio);
lh = lerp(lh, backface_lh, ratio);
return isBackface;
}
inline half SGameRoughness(half smoothness, out half perceptualRoughness )
{
perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness (smoothness);
perceptualRoughness = max(0.001, perceptualRoughness);
half roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
return roughness;
}
#if defined(_SKIN_CALCULATION)
inline float FresnelReflectance (float3 H, float3 V, float F0)
{
float base = 1.0 - dot(V, H);
float exponential = pow(base, 5.0);
return exponential + F0 * saturate(1.0 - exponential);
}
inline float SkinSpecular( float3 N, // Bumped surface normal
float3 L, // Points to light
float3 V, // Points to eye
float m, // Roughness
float rho_s // Specular brightness
)
{
float ndotl = max(dot(N, L), 0);
float3 h = L + V; // Unnormalized half-way vector
float3 H = normalize(h);
float ndoth = dot(N, H);
float4 PH = pow(1.85, 10);
float F = FresnelReflectance(H, V, 0.028);
float frSpec = max(PH.x * F / dot(h, h), 0.0);
return ndotl * rho_s * frSpec;
}
#endif
//-------------------------------------------------------------------------------------
// Note: BRDF entry points use smoothness and oneMinusReflectivity for optimization
// purposes, mostly for DX9 SM2.0 level. Most of the math is being done on these (1-x) values, and that saves
// a few precious ALU slots.
// Based on Minimalist CookTorrance BRDF
// Implementation is slightly different from original derivation: http://www.thetenthplanet.de/archives/255
//
// * NDF (depending on UNITY_BRDF_GGX):
// a) BlinnPhong
// b) [Modified] GGX
// * Modified Kelemen and Szirmay-Kalos for Visibility term
// * Fresnel approximated with 1/LdotH
half4 SGame_BRDF2_Unity_PBS (half3 diffColor, half3 specColor, half oneMinusReflectivity, half smoothness,
half3 normal, half3 viewDir, UnityLight light, UnityIndirect gi, half atten, half metallic,
half3 worldTangent = half3(0, 0, 0), half isSkin = 0, half anisotrophic = 0)
{
half3 halfDir = normalize (light.dir + viewDir);
half NDotL = dot(normal,light.dir);
half nl = saturate((dot(normal, light.dir) + _DiffuseWrap) / ((1 + _DiffuseWrap) * (1 + _DiffuseWrap)));
half nh = saturate(dot(normal, halfDir));
half NDotV = dot(normal, viewDir);
half nv = saturate(NDotV);
half lh = saturate(dot(light.dir, halfDir));
#if defined(_ANISOGGX_ON) && defined(UNITY_PASS_FORWARDBASE)
smoothness = smoothness + (_AnisotrophicSmooth) * anisotrophic;
metallic = metallic + (_AnisotrophicMetallic) * anisotrophic;
#endif
half perceptualRoughness = 0;
half roughness = SGameRoughness(smoothness, /*out*/ perceptualRoughness);
half isBackface = SGameDirectSpecular(normal, viewDir, NDotL, metallic, /*inout*/ nh, /*inout*/ lh);
half a = roughness;
half a2 = a * a;
half d = nh * nh * (a2 - 1.h) + 1.00001h;
half specularTerm = a / (max(0.32h, lh) * (1.5h + roughness) * d);
#if defined(_ANISOGGX_ON) && defined(UNITY_PASS_FORWARDBASE)
half3 worldBiTangent = cross(normal, worldTangent);
worldTangent = cross(worldBiTangent, normal);
half roughnessT = SGameRoughness(smoothness, /*out*/ perceptualRoughness);;
half roughnessB = 1;
half anisoSpecularTerm = GGXSpecularTermAniso_SGame(worldTangent, worldBiTangent, roughnessT, roughnessB, halfDir, light.dir, viewDir, nl, nh, nv);
specularTerm = lerp(specularTerm, anisoSpecularTerm, anisotrophic);
#endif
#if defined (SHADER_API_MOBILE)
specularTerm = specularTerm - 1e-4h;
#endif
#if defined (SHADER_API_MOBILE)
specularTerm = clamp(specularTerm, 0.0, 100.0); // Prevent FP16 overflow on mobiles
#endif
#ifdef UNITY_COLORSPACE_GAMMA
half surfaceReduction = 0.28;
#else
half surfaceReduction = (0.6 - 0.08 * perceptualRoughness);
#endif
surfaceReduction = 1.0 - roughness * perceptualRoughness * surfaceReduction;
//--------------------------------------------------------------------------------
//基础
//--------------------------------------------------------------------------------
half shadowAtten = SGameShadowAtten(atten);
half stylizedAtten = SGameStylizedAtten(atten);
half3 lightColor = light.color;
lightColor *= shadowAtten;
half3 lightDir = light.dir; //光照方向
//--------------------------------------------------------------------------------
//处理漫反射和高光颜色
//--------------------------------------------------------------------------------
half3 diffuseColor = SGameDiffuseColor(diffColor, specColor);
half3 specularColor = SGameSpecularColor(specColor);
#if defined(UNITY_PASS_FORWARDBASE)
half3 stylizedSpecularColor = SGameStylizedSpecularColor(specularColor, metallic);
#endif
//--------------------------------------------------------------------------------
//直接光照漫反射
//--------------------------------------------------------------------------------
half3 diffuseTerm = nl;
#if defined(_SKIN_CALCULATION)
diffuseTerm = lerp(diffuseTerm, BeckmannTexCol(half2(nl * 0.5 + 0.5, 1)).rgb * 1.5, isSkin);
lightColor = lerp(lightColor, lerp(lightColor, 1, 0.5), isSkin);
#endif
//直接光照漫反射
half3 diffuseLighting = diffuseColor * diffuseTerm * lightColor;
#if defined(_SKIN_CALCULATION)
float specularWeight = SkinSpecular(normal, lightDir, viewDir, _SkinRoughness, _SkinSpecIntensity * isSkin);
#if defined(BACK_FACE_ADD)
specularColor += lerp(specularColor, specularWeight * lightColor * _Color.rgb, isSkin) * 0.5;
#else
specularColor = lerp(specularColor, specularWeight * lightColor * _Color.rgb, isSkin);
#endif
#endif
//--------------------------------------------------------------------------------
//直接光照高光
//--------------------------------------------------------------------------------
half3 specDiffuseTerm = nl;
half3 specularLighting = specularTerm * specDiffuseTerm * lightColor;
#if defined(UNITY_PASS_FORWARDBASE)
specularLighting *= stylizedSpecularColor;
#else
specularLighting *= specularColor;
#endif
//--------------------------------------------------------------------------------
//间接光照漫反射
//--------------------------------------------------------------------------------
#if defined(UNITY_PASS_FORWARDBASE)
half3 diffuseIndirect = gi.diffuse * diffColor;
#endif
//--------------------------------------------------------------------------------
//间接光照高光
//--------------------------------------------------------------------------------
#if defined(UNITY_PASS_FORWARDBASE)
half giRoughness = perceptualRoughness;
half3 giSpec = SGameGISpecular(giRoughness, normal, viewDir, gi, _IBLInensity, smoothness);
#if defined(_SKIN_CALCULATION)
giSpec = lerp(giSpec, 1, isSkin);
#endif
half3 giSpecularColor = stylizedSpecularColor;
half3 specularIndirect = surfaceReduction * giSpec * giSpecularColor;
specularIndirect *= stylizedAtten;
#endif
//--------------------------------------------------------------------------------
//虚拟光
//--------------------------------------------------------------------------------
//VLight, 只有Base Pass计算
#if defined(UNITY_PASS_FORWARDBASE)
half3 vDiffuseTerm = SGameVLightDiffuse(normal) * stylizedAtten;
half3 diffuseVLight = vDiffuseTerm * diffuseColor;
half3 specularVLight = SGameVLightSpecular(perceptualRoughness, normal, viewDir, specularColor, vDiffuseTerm);
#if defined(_SKIN_CALCULATION)
#if defined(BACK_FACE_ADD)
diffuseVLight += diffuseVLight * isSkin;
specularVLight += specularVLight * 3 * isSkin;
#else
specularVLight += specularVLight * 5 * isSkin;
#endif
#endif
#endif
//计算结果颜色
half3 output = 0;
//--------------------------------------------------------------------------------
// Add Pass 直接返回直接光照
//--------------------------------------------------------------------------------
#if defined(UNITY_PASS_FORWARDADD)
output = diffuseLighting + specularLighting;
return half4(output, 1);
#endif
//--------------------------------------------------------------------------------
// Base Pass 根据不同风格计算
//--------------------------------------------------------------------------------
#if defined(UNITY_PASS_FORWARDBASE)
diffuseIndirect = ApplyToneMappingGIDiffuseAtten(diffuseIndirect); //对漫反射进行ToneMapping
half3 outputDiffuse = BlendMode_Screen(saturate(diffuseVLight), saturate(diffuseIndirect)); //补光和环境光
diffuseLighting = ApplyToneMappingLightBoost(diffuseLighting, lightColor);//主光
outputDiffuse = outputDiffuse + diffuseLighting;
outputDiffuse = SGameOutputTonemapping(outputDiffuse); //ToneMaping
half3 outputSpecular = specularLighting + specularIndirect; //对高光直接相加
outputSpecular += specularVLight * (1 + _SpecularBloomAdd * metallic);
output = outputDiffuse + outputSpecular;
half3 overflow = saturate(outputSpecular - 1);
output += overflow;
return half4(output,1);
#endif
//--------------------------------------------------------------------------------
// 其他 Pass 根据不同风格计算
//--------------------------------------------------------------------------------
output = diffuseLighting + specularLighting;
#if defined(UNITY_PASS_FORWARDBASE)
output += ( diffuseIndirect + specularIndirect);
#endif
return half4(output, 1);
}
inline half3 GetSpecularColorGGX_Smoothness (half ndotH, half ndotL, half ldotH, half3 specularColor, half smoothness, half powFac = 64, half ggxClamp = 3)
{
half3 specular = 0;
#if defined(SGAME_QUALITY_PERFECT)
half perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness (smoothness);
perceptualRoughness = max(0.08, perceptualRoughness);
half roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
half a = roughness;
half a2 = a * a;
half d = ndotH * ndotH * (a2 - 1) + 1.0001;
half specularTerm = a2 / (max(0.2, ldotH * ldotH) * (roughness + 0.5) * (d * d) * powFac);
specularTerm = specularTerm - 1e-4h;
specularTerm = clamp(specularTerm, 0, ggxClamp);
specular = specularTerm * specularColor.rgb;
#endif
return specular;
}
inline half3x3 GetDiffuseColor(half smoothness, half3 specularColor, half3 mainColor,
half3 worldNormal, half lightAtten, half3 NDotL)
{
half3 lightColor = lerp(half3(0,0,0), GetMainLight().color.rgb, lightAtten * NDotL);
specularColor = lerp(half3(0,0,0), GetMainLight().color.rgb, lightAtten) * specularColor;
half3 diffuse = mainColor * lightColor;
#if defined(SGAME_WET)
mainColor = lerp(mainColor, mainColor * _SG_WetColor, _SG_WetFactor);
specularColor = lerp(specularColor, _SG_WetSpecularColor * _SG_WetSpecularStrength, _SG_WetFactor);
smoothness = lerp(lerp(smoothness, _SG_WetSmoothness, _SG_WetFactor), smoothness, smoothness > _SG_WetSmoothness);
half thunderNDotL = saturate(dot(worldNormal, _SG_ThunderDirection));
half3 thunderDiffuse = mainColor * lerp(half3(0, 0, 0), _SG_ThunderColor, max(lightAtten,0.1)) * thunderNDotL * _SG_ThunderStrength;
diffuse += thunderDiffuse;
#endif
half3x3 matrixColor;
matrixColor[0] = diffuse;
matrixColor[1] = specularColor;
matrixColor[2] = half3(smoothness, 0, 0);
return matrixColor;
}
inline half3 GetSumLightingColorSpecGGX_Smoothness(half3 mainColor, half3 specularColor, half3 shLight,
half3 worldNormal, half3 worldPos, half smoothness, half lightAtten, half powFac = 64, half ggxClamp = 3, half intensity = 1)
{
half3 worldViewDir = normalize(GetCameraPositionWS() - worldPos);
half3 worldLightDir = normalize(GetMainLight().direction);
half3 halfDir = normalize(worldLightDir + worldViewDir);
half ndotH = max(dot(worldNormal, halfDir), 0);
half NDotL = max(dot(worldNormal, worldLightDir), 0);
half ldotH = max(dot(worldLightDir, halfDir), 0);
half3x3 colorMatrix = GetDiffuseColor(smoothness, specularColor, mainColor, worldNormal, lightAtten, NDotL);
specularColor = colorMatrix[1];
smoothness = colorMatrix[2].x;
half3 ambient = mainColor * 0.5;
half3 diffuse = colorMatrix[0];
half3 specular = GetSpecularColorGGX_Smoothness(ndotH, NDotL, ldotH, specularColor, smoothness, powFac, ggxClamp);
return ambient + diffuse + specular * intensity;
}
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 258dd86918649994ebc32b90141305e4
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,361 @@
#ifndef SGAME_UNITY_STANDARD_CORE_INCLUDED
#define SGAME_UNITY_STANDARD_CORE_INCLUDED
#include "SGameUnityStandardInput.hlsl"
#include "SGameStandardBRDF.hlsl"
#if UNITY_REQUIRE_FRAG_WORLDPOS
#if UNITY_PACK_WORLDPOS_WITH_TANGENT
#define IN_WORLDPOS(i) half3(i.tangentToWorldAndPackedData[0].w,i.tangentToWorldAndPackedData[1].w,i.tangentToWorldAndPackedData[2].w)
#else
#define IN_WORLDPOS(i) i.posWorld
#endif
#define IN_WORLDPOS_FWDADD(i) i.posWorld
#else
#define IN_WORLDPOS(i) half3(0,0,0)
#define IN_WORLDPOS_FWDADD(i) half3(0,0,0)
#endif
#define IN_LIGHTDIR_FWDADD(i) half3(i.tangentToWorldAndLightDir[0].w, i.tangentToWorldAndLightDir[1].w, i.tangentToWorldAndLightDir[2].w)
#define FRAGMENT_SETUP(x) FragmentCommonData x = \
FragmentSetup(i.tex, i.eyeVec, IN_VIEWDIR4PARALLAX(i), i.tangentToWorldAndPackedData, IN_WORLDPOS(i));
#define FRAGMENT_SETUP_FWDADD(x) FragmentCommonData x = \
FragmentSetup(i.tex, i.eyeVec, IN_VIEWDIR4PARALLAX_FWDADD(i), i.tangentToWorldAndLightDir, IN_WORLDPOS_FWDADD(i));
inline half3 PreMultiplyAlpha (half3 diffColor, half alpha, half oneMinusReflectivity, out half outModifiedAlpha)
{
diffColor *= alpha;
outModifiedAlpha = 1-oneMinusReflectivity + alpha*oneMinusReflectivity;
return diffColor;
}
inline half OneMinusReflectivityFromMetallic(half metallic)
{
half oneMinusDielectricSpec = 0.56;
return oneMinusDielectricSpec - metallic * oneMinusDielectricSpec;
}
inline half3 DiffuseAndSpecularFromMetallic (half3 albedo, half metallic, out half3 specColor, out half oneMinusReflectivity)
{
specColor = lerp (UNITY_LIGHTMODEL_AMBIENT.xyz, albedo, metallic);
oneMinusReflectivity = OneMinusReflectivityFromMetallic(metallic);
return albedo * oneMinusReflectivity;
}
inline FragmentCommonData MetallicSetup (float4 i_tex)
{
half4 metallicGlossSkin = MetallicGloss(i_tex.xy);
half metallic = metallicGlossSkin.x;
half smoothness = metallicGlossSkin.y; // this is 1 minus the square root of real roughness m.
half isSkin = 0;
half skinDepth = 0;
half4 mainColor = Albedo(i_tex);
half oneMinusReflectivity;
half3 specColor;
half3 diffColor = DiffuseAndSpecularFromMetallic (mainColor.rgb, metallic, /*out*/ specColor, /*out*/ oneMinusReflectivity);
half4 mask2 = GetMask2(i_tex.xy);
#if defined(_SKIN_CALCULATION)
isSkin = IsSkin(mask2.r);
diffColor = SGameSkinAlbedo(isSkin, mainColor.rgb * _SkinColor.rgb, diffColor);
#endif
FragmentCommonData o = (FragmentCommonData)0;
o.albedo = mainColor;
o.diffColor = diffColor;
o.specColor = specColor;
o.oneMinusReflectivity = oneMinusReflectivity;
o.smoothness = smoothness;
o.skinDepth = skinDepth;
o.metallic = metallic;
o.emissive = mask2.g * _EmissiveMapScale * _EmissiveColor.rgb * 5;
o.isSkin = 0;
o.anisotrophic = 0;
o.occlusion = metallicGlossSkin.a;
#if defined(_ANISOGGX_ON)
o.anisotrophic = metallicGlossSkin.z;
specColor = lerp(specColor, lerp(0.04, mainColor, _AnisotrophicScale), o.anisotrophic);
#endif
return o;
}
// parallax transformed texcoord is used to sample occlusion
inline FragmentCommonData FragmentSetup (inout float4 i_tex, half3 i_eyeVec, half3 i_viewDirForParallax, half4 tangentToWorld[3], float3 i_posWorld)
{
i_tex = Parallax(i_tex, i_viewDirForParallax);
half alpha = Alpha(i_tex.xy);
#if defined(_ALPHATEST_ON)
clip (alpha - _Cutoff);
#endif
FragmentCommonData o = MetallicSetup (i_tex);
o.normalWorld = PerPixelWorldNormal(i_tex, tangentToWorld);
o.eyeVec = NormalizePerPixelNormal(i_eyeVec);
o.posWorld = i_posWorld;
// NOTE: shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha)
// o.diffColor = PreMultiplyAlpha (o.diffColor, alpha, o.oneMinusReflectivity, /*out*/ );
o.alpha = alpha;
return o;
}
inline UnityGI FragmentGI (FragmentCommonData s, half occlusion, half4 i_ambientOrLightmapUV, half atten, UnityLight light, bool reflections)
{
UnityGIInput d;
d.light = light;
d.worldPos = s.posWorld;
d.worldViewDir = s.eyeVec;
d.atten = atten;
#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
d.ambient = 0;
d.lightmapUV = i_ambientOrLightmapUV;
#else
d.ambient = i_ambientOrLightmapUV.rgb;
d.lightmapUV = 0;
#endif
d.probeHDR[0] = unity_SpecCube0_HDR;
Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(s.smoothness, s.eyeVec, s.normalWorld, s.specColor);
return UnityGlobalIllumination (d, occlusion, s.normalWorld, g);
}
inline UnityGI FragmentGI (FragmentCommonData s, half occlusion, half4 i_ambientOrLightmapUV, half atten, UnityLight light)
{
return FragmentGI(s, occlusion, i_ambientOrLightmapUV, atten, light, true);
}
//-------------------------------------------------------------------------------------
half4 OutputForward (half4 output, half alphaFromSurface)
{
output.a = alphaFromSurface;
return output;
}
inline half4 VertexGIForward(VertexInput v, float3 posWorld, half3 normalWorld)
{
half4 ambientOrLightmapUV = 0;
#ifdef LIGHTMAP_ON
ambientOrLightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
ambientOrLightmapUV.zw = 0;
#elif UNITY_SHOULD_SAMPLE_SH
#ifdef VERTEXLIGHT_ON
ambientOrLightmapUV.rgb = Shade4PointLights (
unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb,
unity_4LightAtten0, posWorld, normalWorld);
#endif
ambientOrLightmapUV.rgb = ShadeSHPerVertex (normalWorld, ambientOrLightmapUV.rgb);
#endif
#ifdef DYNAMICLIGHTMAP_ON
ambientOrLightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
#endif
return ambientOrLightmapUV;
}
#if defined(UNITY_PASS_FORWARDBASE)
// ------------------------------------------------------------------
// Base forward pass (directional light, emission, lightmaps, ...)
struct VertexOutputForwardBase
{
float4 pos : POSITION;
float4 tex : TEXCOORD0;
half3 eyeVec : TEXCOORD1;
half4 tangentToWorldAndPackedData[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax or worldPos]
half4 ambientOrLightmapUV : TEXCOORD5; // SH or Lightmap UV
float4 shadowCoord : TEXCOORD6;
// next ones would not fit into SM2.0 limits, but they are always for SM3.0+
#if UNITY_REQUIRE_FRAG_WORLDPOS && !UNITY_PACK_WORLDPOS_WITH_TANGENT
float3 posWorld : TEXCOORD8;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
VertexOutputForwardBase vertForwardBase (VertexInput v)
{
VertexOutputForwardBase o = (VertexOutputForwardBase)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
float4 posWorld = mul(unity_ObjectToWorld, v.vertex);
#if UNITY_REQUIRE_FRAG_WORLDPOS
#if UNITY_PACK_WORLDPOS_WITH_TANGENT
o.tangentToWorldAndPackedData[0].w = posWorld.x;
o.tangentToWorldAndPackedData[1].w = posWorld.y;
o.tangentToWorldAndPackedData[2].w = posWorld.z;
#else
o.posWorld = posWorld.xyz;
#endif
#endif
o.tex = TexCoords(v);
VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(v.normal, v.tangent);
o.pos = vertexInput.positionCS;
o.eyeVec = GetCameraPositionWS() - vertexInput.positionWS;
float3 normalWorld = normalInput.normalWS;
#ifdef _TANGENT_TO_WORLD
float4 tangentWorld = float4(normalInput.tangentWS, v.tangent.w);
float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w);
o.tangentToWorldAndPackedData[0].xyz = tangentToWorld[0];
o.tangentToWorldAndPackedData[1].xyz = tangentToWorld[1];
o.tangentToWorldAndPackedData[2].xyz = tangentToWorld[2];
#else
o.tangentToWorldAndPackedData[0].xyz = 0;
o.tangentToWorldAndPackedData[1].xyz = 0;
o.tangentToWorldAndPackedData[2].xyz = normalWorld;
#endif
o.shadowCoord = GetShadowCoord(vertexInput);
o.ambientOrLightmapUV = VertexGIForward(v, posWorld, normalWorld);
#ifdef _PARALLAXMAP
TANGENT_SPACE_ROTATION;
half3 viewDirForParallax = mul (rotation, ObjSpaceViewDir(v.vertex));
o.tangentToWorldAndPackedData[0].w = viewDirForParallax.x;
o.tangentToWorldAndPackedData[1].w = viewDirForParallax.y;
o.tangentToWorldAndPackedData[2].w = viewDirForParallax.z;
#endif
return o;
}
half4 fragForwardBaseInternal (VertexOutputForwardBase i)
{
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
FRAGMENT_SETUP(s)
UnityLight mainLight = MainLight ();
half atten = 1;
#if defined(_ANISOGGX_ON)
half3 tangentWorld = normalize(half3(i.tangentToWorldAndPackedData[0].x, i.tangentToWorldAndPackedData[1].x, i.tangentToWorldAndPackedData[2].x));
#else
half3 tangentWorld = half3(0, 0, 0);
#endif
#if !defined(_EMISSION_ON)
s.emissive = 0;
#endif
#if defined(_BRDF_CALCULATION)
UnityGI gi = FragmentGI (s, s.occlusion, i.ambientOrLightmapUV, atten, mainLight);
half4 c = SGame_BRDF2_Unity_PBS (s.diffColor * s.occlusion, s.specColor, s.oneMinusReflectivity,
s.smoothness, s.normalWorld, s.eyeVec, gi.light, gi.indirect, atten, s.metallic, tangentWorld, s.isSkin, s.anisotrophic);
c.rgb += s.emissive;
#elif defined(_BLINNING_PHONG)
half3 blinnphong = GetSumLightingColorSpecGGX_Smoothness(s.albedo.rgb, s.specColor * 10, 2, s.normalWorld, s.posWorld, s.albedo.a * _GlossMapScale, atten, 128, 3, _BlinnphongIntensity);
half3 refVec = reflect(s.eyeVec, s.normalWorld);
refVec = RotationY(refVec, _CubeMapRot);
half3 cubeRef = SAMPLE_TEXTURECUBE_LOD(_IBLCubeMap, sampler_IBLCubeMap, refVec, 1).rgb * _CubeMapIntensity * s.albedo.a;
half4 c = half4(blinnphong + cubeRef, 1);
c.rgb += s.emissive;
#else
half4 c = half4(s.albedo.rgb, 1);
#endif
c.rgb = lerp(c.rgb, c.rgb + pow(1 - saturate(dot(s.normalWorld, s.eyeVec)), 2.5) * _HighLightLerpColor * 4, _HighLightLerp);
return OutputForward (c, s.alpha);
}
half4 fragForwardBase (VertexOutputForwardBase i) : SV_TARGET
{
return fragForwardBaseInternal(i);
}
#endif
// ------------------------------------------------------------------
// Additive forward pass (one light per pass)
#if defined(UNITY_PASS_FORWARDADD)
struct VertexOutputForwardAdd
{
float4 pos : POSITION;
float4 tex : TEXCOORD0;
half3 eyeVec : TEXCOORD1;
half4 tangentToWorldAndLightDir[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:lightDir]
float3 posWorld : TEXCOORD5;
float4 shadowCoord : TEXCOORD6;
#if defined(_PARALLAXMAP)
half3 viewDirForParallax : TEXCOORD8;
#endif
UNITY_VERTEX_OUTPUT_STEREO
};
inline VertexOutputForwardAdd vertForwardAdd (VertexInput v)
{
VertexOutputForwardAdd o = (VertexOutputForwardAdd)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
float4 posWorld = mul(unity_ObjectToWorld, v.vertex);
VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(v.normal, v.tangent);
o.pos = vertexInput.positionCS;
o.eyeVec = GetCameraPositionWS() - vertexInput.positionWS;
o.tex = TexCoords(v);
o.posWorld = vertexInput.positionWS.xyz;
float3 normalWorld = normalInput.normalWS;
#ifdef _TANGENT_TO_WORLD
float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);
float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w);
o.tangentToWorldAndLightDir[0].xyz = tangentToWorld[0];
o.tangentToWorldAndLightDir[1].xyz = tangentToWorld[1];
o.tangentToWorldAndLightDir[2].xyz = tangentToWorld[2];
#else
o.tangentToWorldAndLightDir[0].xyz = 0;
o.tangentToWorldAndLightDir[1].xyz = 0;
o.tangentToWorldAndLightDir[2].xyz = normalWorld;
#endif
//We need this for shadow receiving
o.shadowCoord = GetShadowCoord(vertexInput);
float3 lightDir = GetMainLight().direction.xyz;
#ifndef USING_DIRECTIONAL_LIGHT
lightDir = NormalizePerVertexNormal(lightDir);
#endif
o.tangentToWorldAndLightDir[0].w = lightDir.x;
o.tangentToWorldAndLightDir[1].w = lightDir.y;
o.tangentToWorldAndLightDir[2].w = lightDir.z;
#ifdef _PARALLAXMAP
TANGENT_SPACE_ROTATION;
o.viewDirForParallax = mul (rotation, ObjSpaceViewDir(v.vertex));
#endif
return o;
}
inline half4 fragForwardAddInternal (VertexOutputForwardAdd i)
{
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
FRAGMENT_SETUP_FWDADD(s)
UnityLight light = AdditiveLight (IN_LIGHTDIR_FWDADD(i), 1);
UnityIndirect noIndirect = ZeroIndirect ();
half brdfAtten = 1;
#if defined(_BRDF_CALCULATION)
half4 c = SGame_BRDF2_Unity_PBS (s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, s.eyeVec, light, noIndirect, brdfAtten, s.metallic, 0, 0, s.anisotrophic);
#elif defined(_BLINNING_PHONG)
half3 blinnphong = GetSumLightingColorSpecGGX_Smoothness(s.albedo, s.specColor * 10, 0, s.normalWorld, s.posWorld, s.albedo.a * _GlossMapScale, 1, 128, 2, _BlinnphongIntensity);
half4 c = half4(blinnphong, 1);
#else
half4 c = half4(0, 0, 0, 1);
#endif
c.rgb = lerp(c.rgb, c.rgb + pow(1 - saturate(dot(s.normalWorld, s.eyeVec)), 2.5) * _HighLightLerpColor * 4, _HighLightLerp);
return OutputForward (c, s.alpha);
}
inline half4 fragForwardAdd (VertexOutputForwardAdd i) : SV_TARGET
{
return fragForwardAddInternal(i);
}
#endif
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: de1e7a3121bd97c42a0432d342f51991
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,413 @@
#ifndef SGAME_UNITY_STANDARD_INPUT_INCLUDED
#define SGAME_UNITY_STANDARD_INPUT_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
//--------------------------------------------------------------------------------
#if defined(UNITY_PASS_FORWARDBASE)
#define SGAME_ENV_MAP_STRENGTH 1
#define SGAME_TONEMAPPING_ACES 1
#define SGAME_LINEAR_DIFFUSE_COLOR 1
#define SGAME_TONEMAPPING_LIGHT_BOOST 1
#define SGAME_STYLIZED_ATTEN 1
#define SGAME_VLIGHT_DIFFUSE 1
#define SGAME_VLIGHT_SPECULAR 1
#define SGAME_TONEMAPPING_GI_DIFFUSE_ATTEN 1
#endif
#if defined(UNITY_PASS_FORWARDADD)
#define SGAME_LINEAR_DIFFUSE_COLOR 1
#endif
#define SGAME_VLIGHT 1
#define SGAME_VLIGHT_DIFFUSE 1
#if !defined(SGAME_QUALITY_PERFECT) && !defined(SGAME_QUALITY_HIGH)
#define _NORMALMAP_ON 0
#define _EMISSION_ON 0
#endif
#if defined(_SKIN_CALCULATION)
#define SGAME_ENV_MAP 0
#endif
// Directional lightmaps & Parallax require tangent space too
#if (_NORMALMAP_ON || DIRLIGHTMAP_COMBINED || _PARALLAXMAP)
#define _TANGENT_TO_WORLD 1
#endif
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
TEXTURE2D(_NrmMap); SAMPLER(sampler_NrmMap);
TEXTURE2D(_MetallicGlossMap); SAMPLER(sampler_MetallicGlossMap);
TEXTURE2D(_SkinMask); SAMPLER(sampler_SkinMask);
#if defined(_SKIN_CALCULATION)
TEXTURE2D(_BeckmannTex); SAMPLER(sampler_BeckmannTex);
#endif
#if defined(_BLINNING_PHONG)
TEXTURECUBE(_IBLCubeMap); SAMPLER(sampler_IBLCubeMap);
#endif
#if defined(_ANISOGGX_ON)
TEXTURE2D(_AnisotrophicMask); SAMPLER(sampler_AnisotrophicMask);
#endif
CBUFFER_START(UnityPerMaterial)
half4 _Color; half _Cutoff;
half _SpecularBloomAdd;
float4 _MainTex_ST; half4 _NrmMap_ST; half _BumpScale;
half _MetallicMapScale; half _GlossMapScale; half _OcclusionScale;
#if defined(_SKIN_CALCULATION)
half _SkinSpecIntensity; half _SkinRoughness; half4 _SkinColor;
#endif
#if defined(_BLINNING_PHONG)
half _CubeMapIntensity; half _CubeMapRot;
#endif
#if defined(_ANISOGGX_ON)
half _AnisotrophicScale; half _AnisotrophicMetallic; half _AnisotrophicSmooth;
#endif
half _EmissiveMapScale; half4 _EmissiveColor;
half _IBLInensity; half _DiffuseWrap;
half _ColorLerpMask; half4 _LerpMaskColor;
half _HighLightLerp; half4 _HighLightLerpColor;
half _BlinnphongIntensity;
CBUFFER_END
// Input functions//------------------------------------------------------------------
struct VertexInput
{
float4 vertex : POSITION;
half3 normal : NORMAL;
float2 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
#if defined(DYNAMICLIGHTMAP_ON) || defined(UNITY_PASS_META)
float2 uv2 : TEXCOORD2;
#endif
half4 tangent : TANGENT;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct FragmentCommonData
{
// Note: smoothness & oneMinusReflectivity for optimization purposes, mostly for DX9 SM2.0 level.
// Most of the math is being done on these (1-x) values, and that saves a few precious ALU slots.
half4 albedo;
half3 diffColor, specColor, emissive;
half4 mainColor;
half oneMinusReflectivity, smoothness;
half3 normalWorld, eyeVec;
half alpha;
float3 posWorld;
half skinDepth;
half metallic;
half isSkin;
half anisotrophic;
half occlusion;
};
struct UnityLight
{
half3 color;
half3 dir;
half ndotl; // Deprecated: Ndotl is now calculated on the fly and is no longer stored. Do not used it.
};
struct UnityIndirect
{
half3 diffuse;
half3 specular;
};
struct UnityGI
{
UnityLight light;
UnityIndirect indirect;
};
struct UnityGIInput
{
UnityLight light; // pixel light, sent from the engine
float3 worldPos;
half3 worldViewDir;
half atten;
half3 ambient;
float4 lightmapUV; // .xy = static lightmap UV, .zw = dynamic lightmap UV
#if defined(UNITY_SPECCUBE_BLENDING) || defined(UNITY_SPECCUBE_BOX_PROJECTION) || defined(UNITY_ENABLE_REFLECTION_BUFFERS)
float4 boxMin[2];
#endif
#ifdef UNITY_SPECCUBE_BOX_PROJECTION
float4 boxMax[2];
float4 probePosition[2];
#endif
// HDR cubemap properties, use to decompress HDR texture
float4 probeHDR[2];
};
struct Unity_GlossyEnvironmentData
{
half roughness; // CAUTION: This is perceptualRoughness but because of compatibility this name can't be change :(
half3 reflUVW;
};
half3 WorldNormal(half4 tan2world[3])
{
return normalize(tan2world[2].xyz);
}
// counterpart for NormalizePerPixelNormal
// skips normalization per-vertex and expects normalization to happen per-pixel
half3 NormalizePerVertexNormal (float3 n) // takes float to avoid overflow
{
#if (SHADER_TARGET < 30) || UNITY_STANDARD_SIMPLE
return normalize(n);
#else
return n; // will normalize per-pixel instead
#endif
}
half3 NormalizePerPixelNormal (half3 n)
{
#if (SHADER_TARGET < 30) || UNITY_STANDARD_SIMPLE
return n;
#else
return normalize(n);
#endif
}
inline half3 RgbToHsv_SGame(half3 c)
{
half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));
half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));
half d = q.x - min(q.w, q.y);
half e = 1.0e-4;
return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
inline half3 HsvToRgb_SGame(half3 c)
{
half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);
}
//-------------------------------------------------------------------------------------
UnityLight MainLight ()
{
UnityLight l;
l.color = GetMainLight().color.rgb;
l.dir = GetMainLight().direction;
return l;
}
UnityLight AdditiveLight (half3 lightDir, half atten)
{
UnityLight l;
l.color = GetMainLight().color.rgb;
l.dir = lightDir;
#ifndef USING_DIRECTIONAL_LIGHT
l.dir = NormalizePerPixelNormal(l.dir);
#endif
// shadow the light
l.color *= atten;
return l;
}
UnityLight DummyLight ()
{
UnityLight l;
l.color = 0;
l.dir = half3 (0,1,0);
return l;
}
UnityIndirect ZeroIndirect ()
{
UnityIndirect ind;
ind.diffuse = 0;
ind.specular = 0;
return ind;
}
Unity_GlossyEnvironmentData UnityGlossyEnvironmentSetup(half Smoothness, half3 worldViewDir, half3 Normal, half3 fresnel0)
{
Unity_GlossyEnvironmentData g;
g.roughness /* perceptualRoughness */ = PerceptualSmoothnessToPerceptualRoughness(Smoothness);
g.reflUVW = reflect(-worldViewDir, Normal);
return g;
}
inline void ResetUnityLight(out UnityLight outLight)
{
outLight.color = half3(0, 0, 0);
outLight.dir = half3(0, 1, 0); // Irrelevant direction, just not null
outLight.ndotl = 0; // Not used
}
inline void ResetUnityGI(out UnityGI outGI)
{
ResetUnityLight(outGI.light);
outGI.indirect.diffuse = 0;
outGI.indirect.specular = 0;
}
inline half3 UnityGI_IndirectSpecular(UnityGIInput data, half occlusion, Unity_GlossyEnvironmentData glossIn)
{
half3 specular;
specular = unity_IndirectSpecColor.rgb;
return specular * occlusion;
}
inline half3 UnityGI_IndirectSpecular(UnityGIInput data, half occlusion, half3 normalWorld, Unity_GlossyEnvironmentData glossIn)
{
return UnityGI_IndirectSpecular(data, occlusion, glossIn);
}
inline UnityGI UnityGI_Base(UnityGIInput data, half occlusion, half3 normalWorld)
{
UnityGI o_gi;
ResetUnityGI(o_gi);
o_gi.light = data.light;
o_gi.light.color *= data.atten;
o_gi.indirect.diffuse *= occlusion;
return o_gi;
}
inline UnityGI UnityGlobalIllumination (UnityGIInput data, half occlusion, half3 normalWorld)
{
return UnityGI_Base(data, occlusion, normalWorld);
}
inline UnityGI UnityGlobalIllumination (UnityGIInput data, half occlusion, half3 normalWorld, Unity_GlossyEnvironmentData glossIn)
{
UnityGI o_gi = UnityGI_Base(data, occlusion, normalWorld);
o_gi.indirect.specular = UnityGI_IndirectSpecular(data, occlusion, glossIn);
return o_gi;
}
inline UnityGI UnityGlobalIllumination (UnityGIInput data, half occlusion, half smoothness, half3 normalWorld, bool reflections)
{
Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(smoothness, data.worldViewDir, normalWorld, float3(0, 0, 0));
return UnityGlobalIllumination(data, occlusion, normalWorld, g);
}
inline UnityGI UnityGlobalIllumination (UnityGIInput data, half occlusion, half smoothness, half3 normalWorld)
{
bool sampleReflections = true;
return UnityGlobalIllumination (data, occlusion, smoothness, normalWorld, sampleReflections);
}
half3x3 CreateTangentToWorldPerVertex(half3 normal, half3 tangent, half tangentSign)
{
// For odd-negative scale transforms we need to flip the sign
half sign = tangentSign * unity_WorldTransformParams.w;
half3 binormal = cross(normal, tangent) * sign;
return half3x3(tangent, binormal, normal);
}
//-------------------------------------------------------------------------------------
float4 TexCoords(VertexInput v)
{
float4 texcoord;
texcoord.xy = TRANSFORM_TEX(v.uv0, _MainTex); // Always source from uv0
#ifdef _INVERT_UV
texcoord.y = 1 - texcoord.y;
#endif
return texcoord;
}
inline half3 SGameSkinAlbedo(half isSkin, half3 albedo, half3 diffColor )
{
half3 skinDiffColor = lerp(diffColor, albedo, isSkin);
return skinDiffColor;
}
inline half IsSkin(half skinParam)
{
return step(0.5, skinParam);
}
//-------------------------------------------------------------------------------------
// Common fragment setup
#ifdef _PARALLAXMAP
#define IN_VIEWDIR4PARALLAX(i) NormalizePerPixelNormal(half3(i.tangentToWorldAndPackedData[0].w,i.tangentToWorldAndPackedData[1].w,i.tangentToWorldAndPackedData[2].w))
#define IN_VIEWDIR4PARALLAX_FWDADD(i) NormalizePerPixelNormal(i.viewDirForParallax.xyz)
#else
#define IN_VIEWDIR4PARALLAX(i) half3(0,0,0)
#define IN_VIEWDIR4PARALLAX_FWDADD(i) half3(0,0,0)
#endif
#ifdef _TANGENT_TO_WORLD
half3x3 ExtractTangentToWorldPerPixel(half4 tan2world[3])
{
half3 t = tan2world[0].xyz;
half3 b = tan2world[1].xyz;
half3 n = tan2world[2].xyz;
#if UNITY_TANGENT_ORTHONORMALIZE
n = NormalizePerPixelNormal(n);
t = normalize (t - n * dot(t, n));
half3 newB = cross(n, t);
b = newB * sign (dot (newB, b));
#endif
return half3x3(t, b, n);
}
#else
half3x3 ExtractTangentToWorldPerPixel(half4 tan2world[3])
{
return half3x3(0,0,0,0,0,0,0,0,0);
}
#endif
#ifdef _NORMALMAP_ON
half3 NormalInTangentSpace(float4 texcoords)
{
half3 normalTangent = SAMPLE_TEXTURE2D(_NrmMap, sampler_NrmMap, texcoords.xy).rgb * 2 - 1;
normalTangent.xy *= _BumpScale;
return normalTangent;
}
#endif
half3 PerPixelWorldNormal(float4 i_tex, half4 tangentToWorld[3])
{
#ifdef _NORMALMAP_ON
half3 tangent = tangentToWorld[0].xyz;
half3 binormal = tangentToWorld[1].xyz;
half3 normal = tangentToWorld[2].xyz;
half3 normalTangent = NormalInTangentSpace(i_tex);
half3 normalWorld = NormalizePerPixelNormal(tangent * normalTangent.x + binormal * normalTangent.y + normal * normalTangent.z); // @TODO: see if we can squeeze this normalize on SM2.0 as well
#else
half3 normalWorld = normalize(tangentToWorld[2].xyz);
#endif
return normalWorld;
}
half4 Albedo(float4 texcoords)
{
half4 main_color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, texcoords.xy).rgba;
#if defined(_SKIN_CALCULATION)
half3 colorAddLerp = lerp(1, _LerpMaskColor.rgb * 0.8, main_color.a);
#else
half3 colorAddLerp = lerp(_Color.rgb, _LerpMaskColor.rgb * 0.8, main_color.a);
#endif
half3 albedo = main_color.rgb * colorAddLerp;
return half4(albedo, main_color.a);
}
half Alpha(float2 uv)
{
return SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv).a * _Color.a;
}
half4 MetallicGloss(float2 uv)
{
half4 mg_skin;
mg_skin = SAMPLE_TEXTURE2D(_MetallicGlossMap, sampler_MetallicGlossMap, uv).ragb;
mg_skin.r *= _MetallicMapScale + 0.03;
mg_skin.g *= _GlossMapScale;
#if defined(_ANISOGGX_ON)
mg_skin.b *= _AnisotrophicScale;
#endif
mg_skin.a = pow(mg_skin.a, _OcclusionScale);
mg_skin = saturate(mg_skin);
return mg_skin;
}
float4 Parallax (float4 texcoords, half3 viewDir)
{
return texcoords;
}
float4 GetMask2(float2 texcoord)
{
return SAMPLE_TEXTURE2D(_SkinMask, sampler_SkinMask, texcoord);
}
#if defined(_SKIN_CALCULATION)
float4 BeckmannTexCol (float2 texcoord)
{
return SAMPLE_TEXTURE2D(_BeckmannTex, sampler_BeckmannTex, texcoord);
}
#endif
inline half3 RotationY(half3 pointP, half angle)
{
half radY = radians(angle);
half sinY = sin(radY);
half cosY = cos(radY);
return half3(pointP.x * cosY - pointP.z * sinY,
pointP.y,
pointP.x * sinY + pointP.z * cosY);
}
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 238c15df977b96044bc40ebe66919f00
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,78 @@
#ifndef SGAME_VLIGHT_INCLUDED
#define SGAME_VLIGHT_INCLUDED
#if defined(_ANISOGGX_ON)
inline half D_GGXAniso_SGame(half TdotH, half BdotH, half mt, half mb, half nh)
{
half d = TdotH * TdotH / (mt * mt) + BdotH * BdotH / (mb * mb) + nh * nh;
return (1.0 / (3.14159 * mt * mb * d * d));
}
inline half V_SmithJointGGXAniso_SGame(half TdotV, half BdotV, half NdotV, half TdotL, half BdotL, half NdotL, half roughnessT, half roughnessB)
{
half lambdaV = NdotL * sqrt(roughnessT * TdotV * TdotV + roughnessB * BdotV * BdotV + NdotV * NdotV);
half lambdaL = NdotV * sqrt(roughnessT * TdotL * TdotL + roughnessB * BdotL * BdotL + NdotL * NdotL);
return 0.5 / max(1e-5f, (lambdaV + lambdaL));
}
inline half GGXSpecularTermAniso_SGame(half3 worldTangent, half3 worldBiTangent, half roughnessT,
half roughnessB, half3 halfDir, half3 lightDir, half3 viewDir, half nl, half nh, half nv)
{
half mt = roughnessT;
half mb = roughnessB;
half TdotH = dot(worldTangent, halfDir);
half BdotH = dot(worldBiTangent, halfDir);
half TdotV = dot(worldTangent, viewDir);
half BdotV = dot(worldBiTangent, viewDir);
half TdotL = dot(worldTangent, lightDir);
half BdotL = dot(worldBiTangent, lightDir);
half D = D_GGXAniso_SGame(TdotH, BdotH, mt, mb, nh);
half V = V_SmithJointGGXAniso_SGame(TdotV, BdotV, nv, TdotL, BdotL, nl, mt, mb);
half specularTerm = (V * D) * 3.14159;
return clamp(specularTerm, 0, 10);
}
#endif
#define VLIGHT_BY_PERCEPTUALROUGHNESS 1
inline half3 VLightDiffuse(half3 normal)
{
half3 lightDir = GetMainLight().direction;
half3 NDotL = saturate( dot(normal, lightDir) );
NDotL = 0.444 + NDotL * 0.556;
half3 lightColor = 1;
half3 vLightDiff = lightColor * NDotL;
return vLightDiff;
}
inline half3 Unreal4SpecBRDF_Simple(half roughness, half3 normal, half3 viewDir, half3 lightDir, half3 specularColor, half3 diffuseTerm )
{
roughness = max(0.08, roughness);
half3 H = normalize(viewDir + lightDir);
half NoH = saturate(dot(normal, H));
half m2 = roughness * roughness;
m2 *= m2;
half D = (NoH * m2 - NoH) * NoH + 1;
D = D * D + (1e-06);
D = (0.25 * m2) / D;
half3 specLighting = specularColor * D * diffuseTerm;
return specLighting;
}
#define SGameVLightDiffuse VLightDiffuse
#define VLightSpecular Unreal4SpecBRDF_Simple
inline half3 SGameVLightSpecular(half roughness, half3 normal, half3 viewDir, half3 specularColor, half3 diffuseTerm)
{
half3 lightDir = GetMainLight().direction;
roughness = max(roughness, 0.3);
return VLightSpecular(roughness, normal, viewDir, lightDir, specularColor, diffuseTerm);
}
#if defined(_ANISOGGX_ON)
inline half3 SGameVLightSpecularAniso(half roughness, half3 normal, half3 viewDir, half3 specularColor, half3 diffuseTerm, half3 worldTangent, half3 worldBitangent)
{
half3 lightDir = GetMainLight().direction;
half3 halfDir = normalize (lightDir + GetMainLight().direction);
half nl = dot(normal, lightDir);
half nh = saturate(dot(normal, halfDir));
half nv = dot(normal, viewDir);
return GGXSpecularTermAniso_SGame(worldTangent, worldBitangent, roughness, 0, halfDir, lightDir, GetMainLight().direction, nl, nh, nv);
}
#endif
#endif //SGAME_VLIGHT_INCLUDED
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 3b116c01cff89bf4abfea14029eaae37
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,450 @@
#ifndef TOD_BASE
#define TOD_BASE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
TEXTURE2D(TOD_BayerTexture); SAMPLER(samplerTOD_BayerTexture);
TEXTURE2D(TOD_CloudTexture); SAMPLER(samplerTOD_CloudTexture);
TEXTURE2D(TOD_CloudAlphaTexture); SAMPLER(samplerTOD_CloudAlphaTexture);
CBUFFER_START(UnityPerMaterial_TOD)
half4x4 TOD_World2Sky, TOD_Sky2World, TOD_World2CloudCameraProjMatrix;
half3 TOD_FogColor;
half3 TOD_SunLightColor; half3 TOD_GroundColor;
half3 TOD_MoonLightColor; half3 TOD_AmbientColor;
half3 TOD_SunSkyColor; half3 TOD_SunDirection;
half3 TOD_MoonSkyColor; half3 TOD_MoonDirection;
half3 TOD_SunMeshColor; half3 TOD_LightDirection;
half3 TOD_MoonMeshColor; half3 TOD_LocalSunDirection;
half3 TOD_SunCloudColor; half3 TOD_LocalMoonDirection;
half3 TOD_MoonCloudColor; half3 TOD_LocalLightDirection;
half TOD_Contrast; half TOD_CloudDensity;
half TOD_Brightness; half TOD_CloudColoring;
half TOD_Fogginess; half TOD_CloudAttenuation;
half TOD_MoonHaloPower; half TOD_CloudSaturation;
half3 TOD_MoonHaloColor; half TOD_CloudScattering;
half TOD_CloudOpacity; half TOD_CloudBrightness;
half TOD_CloudCoverage; half3 TOD_CloudOffset;
half TOD_CloudSharpness; half3 TOD_CloudWind;
half3 TOD_CloudSize; half TOD_SunMeshContrast;
half TOD_CloudShadowCutoff; half TOD_SunMeshBrightness;
half TOD_CloudShadowFade; half TOD_MoonMeshContrast;
half TOD_CloudShadowIntensity; half TOD_MoonMeshBrightness;
half TOD_StarSize; half3 TOD_ScatterDensity;
half TOD_StarBrightness; half3 TOD_kBetaMie;
half TOD_StarVisibility; half4 TOD_kSun;
half4 TOD_k4PI; half3 TOD_SunWorldPos;
half4 TOD_kRadius; half3 TOD_HeroWorldPos;
half4 TOD_kScale; half TOD_IsDay;
CBUFFER_END
#define TOD_ROTATION_UV(angle) half2x2(cos(angle), -sin(angle), sin(angle), cos(angle)) // UV rotation matrix constructor
#define TOD_HDR2LDR(color) (1.0 - exp2(-TOD_Brightness * color)) // Fast and simple tonemapping
#define TOD_GAMMA2LINEAR(color) (color * color) // Approximates gamma by 2.0 instead of 2.2
#define TOD_LINEAR2GAMMA(color) sqrt(color)
#define TOD_Object2World unity_ObjectToWorld
#define TOD_World2Object unity_WorldToObject
#define TOD_UV(x, y) x // Screen space adjust
#define TOD_VERTEX_OUTPUT_STEREO // Stereo output
#define TOD_INITIALIZE_VERTEX_OUTPUT_STEREO(o)
#define TOD_INSTANCE_ID // Instancing
#define TOD_SETUP_INSTANCE_ID(o)
//////////////////////////////////////////CLOUD CALCULATION//////////////////////////////////////////////////
inline half3 CloudPosition(half3 viewDir, half3 offset)
{
half mult = 1.0 / lerp(0.1, 1.0, viewDir.y);
return (half3(viewDir.x * mult + offset.x, 0, viewDir.z * mult + offset.z)) / TOD_CloudSize;
}
inline half4 CloudUV(half3 viewDir, half3 offset)
{
half3 cloudPos = CloudPosition(viewDir, offset);
half2 uv1 = cloudPos.xz + TOD_CloudOffset.xz + TOD_CloudWind.xz;
half2 uv2 = mul(TOD_ROTATION_UV(radians(10.0)), cloudPos.xz) + TOD_CloudOffset.xz + TOD_CloudWind.xz;
return half4(uv1.x, uv1.y, uv2.x, uv2.y);
}
inline half4 CloudUV(half3 viewDir)
{
return CloudUV(viewDir, 0);
}
inline half3 CloudColor(half3 viewDir, half3 lightDir)
{
half lerpValue = saturate(1 + 4 * lightDir.y) * saturate(dot(viewDir, lightDir) + 1.25);
half3 cloudColor = lerp(TOD_MoonCloudColor, TOD_SunCloudColor, lerpValue);
half3 fogColor = TOD_FogColor;
return TOD_Brightness * lerp(cloudColor, fogColor, TOD_Fogginess);
}
inline half3 CloudLayerDensity(half4 uv, half3 viewDir)
{
half3 density = 0;
#if TOD_CLOUDS_DENSITY
const half thickness = 0.1;
const half4 stepoffset = half4(0.0, 1.0, 2.0, 3.0) * thickness;
const half4 sumy = half4(0.5000, 0.2500, 0.1250, 0.0625) / half4(1, 2, 3, 4);
const half4 sumz = half4(0.5000, 0.2500, 0.1250, 0.0625);
half2 uv1 = uv.xy + viewDir.xz * stepoffset.x;
half2 uv2 = uv.zw + viewDir.xz * stepoffset.y;
half2 uv3 = uv.xy + viewDir.xz * stepoffset.z;
half2 uv4 = uv.zw + viewDir.xz * stepoffset.w;
half4 n1 = SAMPLE_TEXTURE2D(TOD_CloudTexture, samplerTOD_CloudTexture, uv1);
half4 n2 = SAMPLE_TEXTURE2D(TOD_CloudTexture, samplerTOD_CloudTexture, uv2);
half4 n3 = SAMPLE_TEXTURE2D(TOD_CloudTexture, samplerTOD_CloudTexture, uv3);
half4 n4 = SAMPLE_TEXTURE2D(TOD_CloudTexture, samplerTOD_CloudTexture, uv4);
// Noise when marching in up direction
half4 ny = half4(n1.r, n1.g + n2.g, n1.b + n2.b + n3.b, n1.a + n2.a + n3.a + n4.a);
// Noise when marching in view direction
half4 nz = half4(n1.r, n2.g, n3.b, n4.a);
// Density when marching in up direction
density.y += dot(ny, sumy);
// Density when marching in view direction
density.z += dot(nz, sumz);
// Coverage
half2 stepA = TOD_CloudCoverage;
half2 stepB = TOD_CloudCoverage + TOD_CloudSharpness;
half2 stepC = TOD_CloudDensity;
density.yz = smoothstep(stepA, stepB, density.yz) + saturate(density.yz - stepB) * stepC;
// Opacity
density.x = saturate(density.z);
// Shading
density.yz *= half2(TOD_CloudAttenuation, TOD_CloudSaturation);
// Remap
density.yz = 1.0 - exp2(-density.yz);
#else
half4 n = SAMPLE_TEXTURE2D(TOD_CloudTexture, samplerTOD_CloudTexture, uv.xy);
// Density when marching in up direction
density.y += n.r;
// Density when marching in view direction
density.z += n.r;
// Coverage
density.yz = (density.yz - TOD_CloudCoverage) * half2(TOD_CloudAttenuation, TOD_CloudDensity);
// Opacity
density.x = saturate(density.z);
#endif
return density;
}
inline half4 CloudLayerColor(half4 uv, half4 color, half3 viewDir, half3 lightDir, half3 lightCol)
{
half3 density = CloudLayerDensity(uv, viewDir);
half4 res = 0;
res.a = density.x;
res.rgb = 1.0 - density.y;
res *= color;
#if TOD_CLOUDS_BUMPED
res.rgb += saturate((1.0 - density.z) * (1.0 - TOD_Fogginess)) * lightCol;
#endif
return res;
}
inline half CloudShadow(half4 uv)
{
return CloudLayerDensity(uv, half3(0, 1, 0)).x;
}
inline half3 CloudBillboardDensity(half2 uv, half3 viewDir)
{
half3 density = 0;
half4 tex = SAMPLE_TEXTURE2D(TOD_CloudTexture, samplerTOD_CloudTexture, uv.xy);
// Density when marching in up direction
density.y = tex.a;
// Density when marching in view direction
#if TOD_CLOUDS_DENSITY
density.z = lerp(lerp(tex.r, tex.g, saturate(viewDir.x)), tex.b, saturate(-viewDir.x));
#else
density.z = tex.r;
#endif
// Opacity
density.x = saturate(density.z);
// Shading
density.y *= TOD_CloudAttenuation;
return density;
}
// inline half4 CloudBillboardColor(sampler2D normalTex, half4 uv, half4 color, half3 viewDir, half3 lightDir, half3 lightCol)
// {
// half3 density = CloudBillboardDensity(uv.xy, viewDir);
// half4 res = 0;
// res.a = density.x;
// res.rgb = 1.0 - density.y;
// #if TOD_CLOUDS_DENSITY
// half3 normal = UnpackNormal(tex2D(normalTex, uv.zw));
// half NdotS = dot(normal, lightDir);
// res.rgb += 0.25 * (1.0 - TOD_Fogginess) * NdotS;
// #endif
// res *= color;
// #if TOD_CLOUDS_BUMPED
// res.rgb += saturate((1.0 - density.z) * (1.0 - TOD_Fogginess)) * lightCol;
// #endif
// return res;
// }
inline half CloudShadow(half3 cameraToWorldPos)
{
half3 worldPos = _WorldSpaceCameraPos + cameraToWorldPos;
half3 skyPos = mul((half3x3)TOD_World2Sky, worldPos);
half4 cloudUV = CloudUV(TOD_LocalLightDirection, skyPos);
return TOD_CloudOpacity * CloudShadow(cloudUV);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////SCATTERING CALCULATION////////////////////////////////////////////
#ifndef TOD_SCATTERING_MIE
#define TOD_SCATTERING_MIE 1
#endif
#ifndef TOD_SCATTERING_RAYLEIGH
#define TOD_SCATTERING_RAYLEIGH 1
#endif
#ifndef TOD_BAYER_DIM
#define TOD_BAYER_DIM 8.0
#endif
half4 _SG_VirtualScatterLightColor;
inline half3 ApplayVirtualScatterLight(half3 curColor, float3 worldPos)
{
float3 worldViewDir = _WorldSpaceCameraPos.xyz - worldPos.xyz;
half3 worldLightDir = normalize(GetMainLight().direction);
half angleFactor = 1.0 - saturate(dot(normalize(worldViewDir), worldLightDir) * 0.5 + 0.8);
half3 scatterLightColor = _SG_VirtualScatterLightColor.rgb * angleFactor;
half3 finalColor = curColor + scatterLightColor;
return finalColor;
}
inline half Scale(half inCos)
{
half x = 1.0 - inCos;
return 0.25 * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
}
inline half MiePhase(half eyeCos, half eyeCos2)
{
return TOD_kBetaMie.x * (1.0 + eyeCos2) / pow(TOD_kBetaMie.y + TOD_kBetaMie.z * eyeCos, 1.5);
}
inline half RayleighPhase(half eyeCos2)
{
return 0.75 + 0.75 * eyeCos2;
}
inline half RayleighPhase(half eyeCos2, half3 dir)
{
half groundPercent = 1-saturate(dir.y);
half base = lerp(1.5, 0.2, groundPercent);
half phase = base + 0.75 * eyeCos2;
half isBottom = dir.y < -0.5;
phase *= lerp(1, 0.2, isBottom);
return phase;
}
inline half CloudPhase(half eyeCos, half eyeCos2)
{
const half g = 0.3;
const half g2 = g * g;
return TOD_CloudScattering * (1.5 * (1.0 - g2) / (2.0 + g2) * (1.0 + eyeCos2) / (1.0 + g2 - 2.0 * g * eyeCos) + g * eyeCos);
}
inline half3 NightPhase(half3 dir)
{
dir.y = abs(dir.y);
return TOD_MoonSkyColor * (1.0 - 0.75 * dir.y);
}
inline half3 MoonPhase(half3 dir)
{
return TOD_MoonHaloColor * pow(max(0, dot(dir, TOD_LocalMoonDirection)), TOD_MoonHaloPower);
}
inline half3 PostProcess(half3 col, half3 dir)
{
col = pow(col * TOD_Brightness, TOD_Contrast);
return col;
}
#if TOD_SCATTERING_RAYLEIGH && TOD_SCATTERING_MIE
inline void ScatteringCoefficients(half3 dir, out half3 inscatter, out half3 outscatter)
#elif TOD_SCATTERING_RAYLEIGH
inline void ScatteringCoefficients(half3 dir, out half3 inscatter)
#else
inline void ScatteringCoefficients(half3 dir, out half3 outscatter)
#endif
{
dir = normalize(half3(dir.x, max(0, dir.y), dir.z));
half kInnerRadius = TOD_kRadius.x;
half kInnerRadius2 = TOD_kRadius.y;
half kOuterRadius2 = TOD_kRadius.w;
half kScale = TOD_kScale.x;
half kScaleOverScaleDepth = TOD_kScale.z;
half kCameraHeight = TOD_kScale.w;
half3 kKr4PI = TOD_k4PI.xyz;
half kKm4PI = TOD_k4PI.w;
half3 kKrESun = TOD_kSun.xyz;
half kKmESun = TOD_kSun.w;
// Current camera position
half3 cameraPos = half3(0, kInnerRadius + kCameraHeight, 0);
// Length of the atmosphere
half far = sqrt(kOuterRadius2 + kInnerRadius2 * dir.y * dir.y - kInnerRadius2) - kInnerRadius * dir.y;
// Ray starting position and its scattering offset
half startDepth = exp(kScaleOverScaleDepth * (-kCameraHeight));
half startAngle = dot(dir, cameraPos) / (kInnerRadius + kCameraHeight);
half startOffset = startDepth * Scale(startAngle);
// Scattering loop variables
half sampleLength = far / 2;
half scaledLength = sampleLength * kScale;
half3 sampleRay = dir * sampleLength;
half3 samplePoint = cameraPos + sampleRay * 0.5;
half3 sunColor = half3(0.0, 0.0, 0.0);
half height = max(1, length(samplePoint));
half invHeight = 1.0 / height;
half depth = exp(kScaleOverScaleDepth * (kInnerRadius - height));
half atten = depth * scaledLength;
half cameraAngle = dot(dir, samplePoint) * invHeight;
half sunAngle = dot(TOD_LocalSunDirection, samplePoint) * invHeight;
half sunScatter = startOffset + depth * (Scale(sunAngle) - Scale(cameraAngle));
half3 sunAtten = exp(-sunScatter * (kKr4PI + kKm4PI));
sunColor += sunAtten * atten;
samplePoint += sampleRay;
height = max(1, length(samplePoint));
invHeight = 1.0 / height;
depth = exp(kScaleOverScaleDepth * (kInnerRadius - height));
atten = depth * scaledLength;
cameraAngle = dot(dir, samplePoint) * invHeight;
sunAngle = dot(TOD_LocalSunDirection, samplePoint) * invHeight;
sunScatter = startOffset + depth * (Scale(sunAngle) - Scale(cameraAngle));
sunAtten = exp(-sunScatter * (kKr4PI + kKm4PI));
sunColor += sunAtten * atten;
samplePoint += sampleRay;
// Sun scattering
#if TOD_SCATTERING_RAYLEIGH
inscatter = TOD_SunSkyColor * sunColor * kKrESun;
#endif
#if TOD_SCATTERING_MIE
outscatter = TOD_SunSkyColor * sunColor * kKmESun;
#endif
}
#if TOD_SCATTERING_RAYLEIGH && TOD_SCATTERING_MIE
inline half4 ScatteringColor(half3 dir, half3 inscatter, half3 outscatter)
#elif TOD_SCATTERING_RAYLEIGH
inline half4 ScatteringColor(half3 dir, half3 inscatter)
#else
inline half4 ScatteringColor(half3 dir, half3 outscatter)
#endif
{
half3 resultColor = half3(0.05, 0.05, 0.1);
half sunCos = dot(TOD_LocalSunDirection, dir);
half sunCos2 = sunCos * sunCos;
#if TOD_SCATTERING_RAYLEIGH
resultColor += NightPhase(dir);
#endif
#if TOD_SCATTERING_MIE
resultColor += MoonPhase(dir);
#endif
#if TOD_SCATTERING_RAYLEIGH
//resultColor += RayleighPhase(sunCos2) * inscatter;
resultColor += RayleighPhase(sunCos2, dir) * inscatter;
#endif
#if TOD_SCATTERING_MIE
resultColor += MiePhase(sunCos, sunCos2) * outscatter;
#endif
return half4(PostProcess(resultColor, dir), 1.0);
}
inline half4 ScatteringColor(half3 dir)
{
#if TOD_SCATTERING_RAYLEIGH && TOD_SCATTERING_MIE
half3 inscatter, outscatter;
ScatteringCoefficients(dir, inscatter, outscatter);
return ScatteringColor(dir, inscatter, outscatter);
#elif TOD_SCATTERING_RAYLEIGH
half3 inscatter;
ScatteringCoefficients(dir, inscatter);
return ScatteringColor(dir, inscatter);
#else
half3 outscatter;
ScatteringCoefficients(dir, outscatter);
return ScatteringColor(dir, outscatter);
#endif
}
inline half FogDensity(half3 worldPos)
{
half camDist = length(worldPos - _WorldSpaceCameraPos);
half globalDensity = TOD_ScatterDensity.z;
half heightDensity = TOD_ScatterDensity.x * (worldPos.y - TOD_ScatterDensity.y);
half heightDensityExpInv = exp(-heightDensity);
// Get base fog intensity at pixel
half fogIntensity = camDist * heightDensityExpInv;
// Apply height falloff
half clampRes = step(abs(heightDensity), 0.01);
fogIntensity *= ((1.0 - heightDensityExpInv) / heightDensity) * step(abs(heightDensity), 0.01) + step(0.01, abs(heightDensity));
// Clamp intensity
fogIntensity = min(10, globalDensity * fogIntensity);
return 1.0 - exp(-fogIntensity);
}
inline half4 AtmosphericScattering(half3 cameraRay, half3 worldPos, half depth, half mask)
{
half3 dir = normalize(mul((half3x3)TOD_World2Sky, cameraRay));
#if TOD_SCATTERING_RAYLEIGH && TOD_SCATTERING_MIE
half3 inscatter, outscatter;
ScatteringCoefficients(dir, inscatter, outscatter);
#elif TOD_SCATTERING_RAYLEIGH
half3 inscatter;
ScatteringCoefficients(dir, inscatter);
#else
half3 outscatter;
ScatteringCoefficients(dir, outscatter);
#endif
depth = FogDensity(worldPos);
#if TOD_SCATTERING_MIE
outscatter = outscatter * depth * mask;
#endif
#if TOD_SCATTERING_RAYLEIGH
inscatter = inscatter * depth;
#endif
#if TOD_SCATTERING_RAYLEIGH && TOD_SCATTERING_MIE
half3 color = ScatteringColor(dir, inscatter, outscatter).rgb;
#elif TOD_SCATTERING_RAYLEIGH
half3 color = ScatteringColor(dir, inscatter).rgb;
#else
half3 color = ScatteringColor(dir, outscatter).rgb;
#endif
return half4(color, depth);
}
inline half4 AtmosphericScattering(half3 cameraRay, half3 worldPos, half depth)
{
const half mask = 1; // This should be sampled from the scattering occlusion mask
return AtmosphericScattering(cameraRay, worldPos, depth, mask);
}
inline half4 AtmosphericScattering(half3 cameraRay, half3 worldPos)
{
half3 dir = normalize(mul((half3x3)TOD_World2Sky, cameraRay));
half depth = FogDensity(worldPos);
half3 color = ScatteringColor(dir).rgb;
return half4(color, depth);
}
inline half2 DitheringCoords(half2 screenPos)
{
return screenPos * _ScreenParams.xy * (1.0 / TOD_BAYER_DIM);
}
inline half DitheringColor(half2 uv)
{
return SAMPLE_TEXTURE2D(TOD_BayerTexture, samplerTOD_BayerTexture, uv.xy).a * (1.0 / (TOD_BAYER_DIM * TOD_BAYER_DIM + 1.0));
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 8d121450798930844ad7afe0531dc66f
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,297 @@
#ifndef T4M_TEXTURE_BASE
#define T4M_TEXTURE_BASE
#include "./Lighting_Base.hlsl"
TEXTURE2D(_Splat0); SAMPLER(sampler_Splat0);
TEXTURE2D(_Splat1); SAMPLER(sampler_Splat1);
TEXTURE2D(_Splat2); SAMPLER(sampler_Splat2);
TEXTURE2D(_Splat3); SAMPLER(sampler_Splat3);
TEXTURE2D(_NormalMap0); SAMPLER(sampler_NormalMap0);
TEXTURE2D(_NormalMap1); SAMPLER(sampler_NormalMap1);
TEXTURE2D(_NormalMap2); SAMPLER(sampler_NormalMap2);
TEXTURE2D(_NormalMap3); SAMPLER(sampler_NormalMap3);
TEXTURE2D(_Control); SAMPLER(sampler_Control);
TEXTURECUBE(_WetEnvCube); SAMPLER(sampler_WetEnvCube);
CBUFFER_START(UnityPerMaterial)
half4 _Splat0_ST; half4 _NormalMap0_ST; half _NormalMap0Scale;
half4 _Splat1_ST; half4 _NormalMap1_ST; half _NormalMap1Scale;
half4 _Splat2_ST; half4 _NormalMap2_ST; half _NormalMap2Scale;
half4 _Splat3_ST; half4 _NormalMap3_ST; half _NormalMap3Scale;
half4 _Control_ST; half4 _TerrainTint;
half _Smoothness; half _SpecularFactor; half3 _SpecularColor;
half4 _EnvColor; half _EnvIntensity; half _EnvSmoothness;
half _EnvironmentOffset; half _EnvironmentYOffset; half _SG_FogFactorOffset;
half _WetUseAlpha; half _WetSmoothness; half _WetSpecularFactor; half _WetEnvStrength; half3 _WetColor;
CBUFFER_END
struct a2v
{
half4 vertex : POSITION;
half4 normal : NORMAL;
half4 tangent: TANGENT;
half2 texcoord : TEXCOORD0;
half2 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 pos : SV_POSITION;
half4 uvTex0 : TEXCOORD0;
half4 uvTex1 : TEXCOORD1;
half4 uvTex2 : TEXCOORD2;
half4 uvTex3 : TEXCOORD3;
half4 uvTex4 : TEXCOORD4;
half3 worldPos : TEXCOORD5;
half4 worldTangentDir : TEXCOORD6;
half4 worldBitangentDir : TEXCOORD7;
half4 worldNormalDir : TEXCOORD8;
float4 shadowCoord : TEXCOORD9;
#if defined(_SG_EXPFOG)
half4 _fogCoord : TEXCOORD10;
#endif
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 11);
#if defined(_PROJECTOR_ON)
half4 projectorUV : TEXCOORD13;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
inline half3 GetMainColor43(half4 control, half waterMask, half4 splat0, half4 splat1, half4 splat2, half4 splat3, half4 wetColor)
{
return ((splat0 * control.r) + (splat1 * control.g) + (splat2 * control.b) + splat3 * (1 - control.r - control.g - control.b) + wetColor * waterMask).rgb;
}
inline half3 GetMainColor44(half4 control, half waterMask, half4 splat0, half4 splat1, half4 splat2, half4 splat3)
{
return lerp((splat0 * control.r) + (splat1 * control.g) + (splat2 * control.b), (splat3), control.a).rgb;
}
inline v2f VertexCommon43(a2v v)
{
v2f o = (v2f)0;
VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(v.normal, v.tangent);
o.pos = vertexInput.positionCS;
half3 worldPos = vertexInput.positionWS;
half3 worldNormal = normalInput.normalWS;
half3 worldViewDir = GetCameraPositionWS() - worldPos;
o.uvTex0.xy = TRANSFORM_TEX(v.texcoord, _Splat0);
o.uvTex0.zw = TRANSFORM_TEX(v.texcoord, _NormalMap0);
o.uvTex1.xy = TRANSFORM_TEX(v.texcoord, _Splat1);
o.uvTex1.zw = TRANSFORM_TEX(v.texcoord, _NormalMap1);
o.uvTex2.xy = TRANSFORM_TEX(v.texcoord, _Splat2);
o.uvTex2.zw = TRANSFORM_TEX(v.texcoord, _NormalMap2);
o.uvTex3.xy = TRANSFORM_TEX(v.texcoord, _Splat3);
o.uvTex3.zw = TRANSFORM_TEX(v.texcoord, _NormalMap3);
o.uvTex4.zw = TRANSFORM_TEX(v.texcoord, _Control);
o.worldTangentDir = half4(normalInput.tangentWS, worldViewDir.x);
o.worldBitangentDir = half4(normalInput.bitangentWS, worldViewDir.y);
o.worldNormalDir = half4(normalInput.normalWS, worldViewDir.z);
o.shadowCoord = GetShadowCoord(vertexInput);
o.worldPos.xyz = worldPos;
OUTPUT_LIGHTMAP_UV(v.lightmapUV, unity_LightmapST, o.lightmapUV);
OUTPUT_SH(worldNormal, o.vertexSH);
#if defined(_SG_EXPFOG)
CUSTOM_TRANSFER_FOG(o, v.vertex);
#endif
#if defined(_PROJECTOR_ON)
o.projectorUV = GetProjectorUV(v.vertex, unity_ObjectToWorld);
#endif
return o;
}
inline v2f VertexForwardBase43(a2v v)
{
v2f o = VertexCommon43(v);
return o;
}
inline v2f VertexForwardBase44(a2v v)
{
v2f o = VertexCommon43(v);
return o;
}
inline half4 FragForwardBase43 (v2f i) : SV_TARGET
{
half2 uvSplat0 = i.uvTex0.xy;
half2 uvNormalMap0 = i.uvTex0.zw;
half2 uvSplat1 = i.uvTex1.xy;
half2 uvNormalMap1 = i.uvTex1.zw;
half2 uvSplat2 = i.uvTex2.xy;
half2 uvNormalMap2 = i.uvTex2.zw;
half2 uvSplat3 = i.uvTex3.xy;
half2 uvNormalMap3 = i.uvTex3.zw;
half2 uvWaterMask = i.uvTex4.xy;
half2 uvControl = i.uvTex4.zw;
half4 splat0 = SAMPLE_TEXTURE2D(_Splat0, sampler_Splat0, uvSplat0);
half4 splat1 = SAMPLE_TEXTURE2D(_Splat1, sampler_Splat1, uvSplat1);
half4 splat2 = SAMPLE_TEXTURE2D(_Splat2, sampler_Splat2, uvSplat2);
half4 splat3 = SAMPLE_TEXTURE2D(_Splat3, sampler_Splat3, uvSplat3);
half4 control = SAMPLE_TEXTURE2D(_Control, sampler_Control, uvControl);
half waterMask = control.a * _WetUseAlpha + (1 - _WetUseAlpha) * splat3.r;
half3 worldPos = i.worldPos;
half3 nrmMap0 = SAMPLE_TEXTURE2D(_NormalMap0, sampler_NormalMap0, uvNormalMap0).rgb * 2 - 1;
half3 nrmMap1 = SAMPLE_TEXTURE2D(_NormalMap1, sampler_NormalMap1, uvNormalMap1).rgb * 2 - 1;
half3 nrmMap2 = SAMPLE_TEXTURE2D(_NormalMap2, sampler_NormalMap2, uvNormalMap2).rgb * 2 - 1;
half3 nrmMap3 = SAMPLE_TEXTURE2D(_NormalMap3, sampler_NormalMap3, uvNormalMap3).rgb * 2 - 1;
nrmMap0 = lerp(half3(0, 0, 1), nrmMap0, _NormalMap0Scale);
nrmMap1 = lerp(half3(0, 0, 1), nrmMap1, _NormalMap1Scale);
nrmMap2 = lerp(half3(0, 0, 1), nrmMap2, _NormalMap2Scale);
nrmMap3 = lerp(half3(0, 0, 1), nrmMap3, _NormalMap3Scale);
float3 tangentNormal = normalize( nrmMap0 * control.r + nrmMap1 * control.g + nrmMap2 * control.b
+ nrmMap3 * control.a + (1 - control.r - control.g - control.b - control.a) * half3(0, 0, 1) + half3(0, 0, 1) * waterMask);
float3 worldNormal = normalize(mul(tangentNormal, float3x3(i.worldTangentDir.xyz, i.worldBitangentDir.xyz, i.worldNormalDir.xyz)));
half3 worldViewDir = normalize(half3(i.worldTangentDir.w, i.worldBitangentDir.w, i.worldNormalDir.w));
#if defined(SGAME_WET) && (defined(SGAME_QUALITY_PERFECT) || defined(SGAME_QUALITY_HIGH))
half3 wetRippleNormal = AddWetSheetRipples(worldPos, worldNormal);
half3 wetRippleNormal2 = SGameWetBump(worldPos, worldNormal);
tangentNormal.xy += (wetRippleNormal.xy + wetRippleNormal2.xy);
worldNormal = normalize(mul(tangentNormal, half3x3(i.worldTangentDir.xyz, i.worldBitangentDir.xyz, i.worldNormalDir.xyz)));
#endif
worldNormal = lerp(worldNormal, float3(0, 1, 0), waterMask);
half4 mainColor_temp = ( splat0 * control.r ) + ( splat1 * control.g ) + ( splat2 * control.b ) + ( splat3 * control.a );
half3 mainColor = GetMainColor43(control, waterMask, splat0, splat1, splat2, splat3, -0.003);
half specularIntensity = (splat0.a * control.r) + (splat1.a * control.g) + (splat2.a * control.b) + (splat3.a * control.a) + (waterMask);
half smoothness = _Smoothness * max(0.2, waterMask) + _WetSmoothness * max(0.001, waterMask * waterMask) ;
half3 specularColor = (_SpecularFactor + _WetSpecularFactor * waterMask) * _SpecularColor * specularIntensity;
mainColor.rgb = ApplyCoverageColor(mainColor.rgb, worldNormal.y, _SG_CoverageFactor);
////阴影相关、烘焙相关/////////////////////////////////////////////////////////////////////////
half atten = 1;
float3 shLight = 1;
#if defined(LIGHTMAP_ON)
i.shadowCoord = TransformWorldToShadowCoord(worldNormal);
shLight = SAMPLE_GI(i.lightmapUV, i.vertexSH, worldNormal);
float shadowMask = SAMPLE_SHADOWMASK(i.lightmapUV);
atten = GetMainLight(i.shadowCoord, worldPos, shadowMask).shadowAttenuation;
atten = min(atten, shadowMask);
#endif
//////////////////////////////////////////////////////////////////////////////////////////////
half3 finalColor = BlinnPhoneLightingFwdBase(mainColor, worldPos, worldNormal, worldViewDir, shLight, atten, specularColor, smoothness);
#if defined(SGAME_QUALITY_PERFECT) && defined(_USEENVIRONMENTLIGHT_ON) //背光
half3 LightDirCustom = normalize(GetMainLight().direction);
half3 customLight = reflect(-LightDirCustom, half3(0, 1, 0));
customLight = RotationY(customLight, _EnvironmentOffset) + half3(0, _EnvironmentYOffset, 0);
half3 finalColorAdd = BlinnPhoneLightingFwdBase_CustomLightTerrain(mainColor, worldPos, worldNormal, worldViewDir, shLight, atten,
specularIntensity * _EnvColor * _EnvIntensity, _EnvSmoothness, customLight) * max(0, dot(LightDirCustom, worldViewDir));
finalColor += finalColorAdd;
#endif
half3 reflectDir = reflect(-worldViewDir, worldNormal);
half3 reflectColor = waterMask * _WetEnvStrength * _WetColor *
SAMPLE_TEXTURECUBE_LOD(_WetEnvCube, sampler_WetEnvCube, reflectDir, 1); //这里计算的是CubeMap
finalColor *= _TerrainTint;
finalColor = lerp(finalColor, finalColor * 0.5 + reflectColor, waterMask);
finalColor = ApplyDark(finalColor);
#if defined(_SG_EXPFOG)
CUSTOM_APPLY_FOG(i, finalColor, distance(_WorldSpaceCameraPos, worldPos));
#endif
#if defined(_PROJECTOR_ON)
finalColor.rgb = GetProjectorColor(finalColor.rgb, i.projectorUV).rgb;
#endif
return half4(finalColor, 1);
}
inline half4 FragForwardBase44(v2f i) : SV_TARGET
{
half3 worldPos = i.worldPos;
float3 tangentNormal = 0;
half2 uvSplat0 = i.uvTex0.xy;
half2 uvNormalMap0 = i.uvTex0.zw;
half2 uvSplat1 = i.uvTex1.xy;
half2 uvNormalMap1 = i.uvTex1.zw;
half2 uvSplat2 = i.uvTex2.xy;
half2 uvNormalMap2 = i.uvTex2.zw;
half2 uvSplat3 = i.uvTex3.xy;
half2 uvNormalMap3 = i.uvTex3.zw;
half2 uvControl = i.uvTex4.zw;
half4 splat0 = SAMPLE_TEXTURE2D(_Splat0, sampler_Splat0, uvSplat0);
half4 splat1 = SAMPLE_TEXTURE2D(_Splat1, sampler_Splat1, uvSplat1);
half4 splat2 = SAMPLE_TEXTURE2D(_Splat2, sampler_Splat2, uvSplat2);
half4 splat3 = SAMPLE_TEXTURE2D(_Splat3, sampler_Splat3, uvSplat3);
half4 control = SAMPLE_TEXTURE2D(_Control, sampler_Control, uvControl);
half4 nrmMapColor0 = SAMPLE_TEXTURE2D(_NormalMap0, sampler_NormalMap0, uvNormalMap0);
half4 nrmMapColor1 = SAMPLE_TEXTURE2D(_NormalMap1, sampler_NormalMap1, uvNormalMap1);
half4 nrmMapColor2 = SAMPLE_TEXTURE2D(_NormalMap2, sampler_NormalMap2, uvNormalMap2);
half4 nrmMapColor3 = SAMPLE_TEXTURE2D(_NormalMap3, sampler_NormalMap3, uvNormalMap3);
float3 nrmMap0 = nrmMapColor0.rgb * 2 - 1;
float3 nrmMap1 = nrmMapColor1.rgb * 2 - 1;
float3 nrmMap2 = nrmMapColor2.rgb * 2 - 1;
float3 nrmMap3 = nrmMapColor3.rgb * 2 - 1;
nrmMap0 = lerp(float3(0, 1, 0), nrmMap0, _NormalMap0Scale);
nrmMap1 = lerp(float3(0, 1, 0), nrmMap1, _NormalMap1Scale);
nrmMap2 = lerp(float3(0, 1, 0), nrmMap2, _NormalMap2Scale);
nrmMap3 = lerp(float3(0, 1, 0), nrmMap3, _NormalMap3Scale);
tangentNormal = normalize(lerp(nrmMap0.rgb * control.r + nrmMap1.rgb * control.g + nrmMap2.rgb * control.b, nrmMap3.rgb, control.a));
float3 worldNormal = normalize(mul(tangentNormal, float3x3(i.worldTangentDir.xyz, i.worldBitangentDir.xyz, i.worldNormalDir.xyz)));
half3 worldViewDir = normalize(half3(i.worldTangentDir.w, i.worldBitangentDir.w, i.worldNormalDir.w));
#if defined(SGAME_WET) && defined(SGAME_QUALITY_PERFECT) || defined(SGAME_QUALITY_HIGH)
half3 wetRippleNormal = AddWetSheetRipples(worldPos, worldNormal);
half3 wetRippleNormal2 = SGameWetBump(worldPos, worldNormal);
tangentNormal.xy += (wetRippleNormal.xy + wetRippleNormal2.xy);
worldNormal = normalize(mul(tangentNormal, half3x3(i.worldTangentDir.xyz, i.worldBitangentDir.xyz, i.worldNormalDir.xyz)));
#endif
worldNormal = lerp(worldNormal, float3(0, 1, 0), 0);
half4 mainColor_temp = (splat0 * control.r) + (splat1 * control.g) + (splat2 * control.b) + (splat3 * control.a);
half3 mainColor = GetMainColor44(control, 0, splat0, splat1, splat2, splat3);
half specularIntensity = (splat0.a * control.r) + (splat1.a * control.g) + (splat2.a * control.b) + (splat3.a * control.a) + (0);
half smoothness = _Smoothness;
half3 specularColor = _SpecularFactor * _SpecularColor * specularIntensity;
mainColor.rgb = ApplyCoverageColor(mainColor.rgb, worldNormal.y, _SG_CoverageFactor);
////阴影相关、烘焙相关/////////////////////////////////////////////////////////////////////////
half atten = 1;
float3 shLight = 1;
#if defined(LIGHTMAP_ON)
i.shadowCoord = TransformWorldToShadowCoord(worldNormal);
shLight = SAMPLE_GI(i.lightmapUV, i.vertexSH, worldNormal);
float shadowMask = SAMPLE_SHADOWMASK(i.lightmapUV);
atten = GetMainLight(i.shadowCoord, worldPos, shadowMask).shadowAttenuation;
atten = min(atten, shadowMask);
#endif
//////////////////////////////////////////////////////////////////////////////////////////////
half3 finalColor = BlinnPhoneLightingFwdBase(mainColor, worldPos, worldNormal, worldViewDir, shLight, atten, specularColor, smoothness);
#if defined(_USEENVIRONMENTLIGHT_ON)
half3 LightDirCustom = normalize(GetMainLight().direction);
half3 customLight = reflect(-LightDirCustom, half3(0, 1, 0));
customLight = RotationY(customLight, _EnvironmentOffset) + half3(0, _EnvironmentYOffset, 0);
half3 finalColorAdd = BlinnPhoneLightingFwdBase_CustomLightTerrain(mainColor, worldPos, worldNormal, worldViewDir, shLight, atten,
specularIntensity * _EnvColor * _EnvIntensity, _EnvSmoothness, customLight) * max(0, dot(LightDirCustom, worldViewDir));
finalColor += finalColorAdd;
#endif
finalColor *= _TerrainTint;
finalColor = ApplyDark(finalColor);
#if defined(_SG_EXPFOG)
CUSTOM_APPLY_FOG(i, finalColor, distance(_WorldSpaceCameraPos, worldPos));
#endif
return half4(finalColor, 1);
}
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 04ac820b0a02a3e42bfb961d983a0ac3
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,133 @@
#ifndef OPAQUEOBJECT_BASE
#define OPAQUEOBJECT_BASE
#include "./Lighting_Base.hlsl"
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
TEXTURE2D(_SpecularTex); SAMPLER(sampler_SpecularTex);
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
float4 _SpecularTex_ST;
half4 _SpecularColor;
half _SpecularFactor;
half _Smoothness;
half4 _MainColor;
half _UseCustomLight;
half4 _CustomLightDir;
half _TintStrength;
half _FogFactor;
half3 _lightDir;
half3 _lightColor;
half _lightStrength;
CBUFFER_END
struct a2v
{
half4 vertex : POSITION;
half4 normal : NORMAL;
half4 tangent: TANGENT;
half2 texcoord : TEXCOORD0;
half2 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 pos : SV_POSITION;
half4 uvTex0 : TEXCOORD0;
half3 worldPos : TEXCOORD1;
half3 worldNormal : TEXCOORD2;
half3 worldViewDir : TEXCOORD3;
float4 shadowCoord : TEXCOORD5;
#if defined(_SG_EXPFOG)
half4 _fogCoord : TEXCOORD7;
#endif
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 6);
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
v2f VertexCommon(a2v v)
{
v2f o = (v2f)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(v.normal, v.tangent);
o.pos = vertexInput.positionCS;
o.uvTex0.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
half3 worldPos = vertexInput.positionWS;
half3 worldNormal = normalInput.normalWS;
o.worldPos.xyz = worldPos;
o.worldNormal = worldNormal;
o.worldViewDir = GetCameraPositionWS() - worldPos;
o.shadowCoord = GetShadowCoord(vertexInput);
OUTPUT_LIGHTMAP_UV(v.lightmapUV, unity_LightmapST, o.lightmapUV);
OUTPUT_SH(worldNormal, o.vertexSH);
return o;
}
// vertex shader
v2f VertexForwardBase (a2v v)
{
v2f o = VertexCommon(v);
#if defined(_SG_EXPFOG)
CUSTOM_TRANSFER_FOG(o, v.vertex);
#endif
return o;
}
// fragment shader
half4 FragForwardBase (v2f i) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
half4 mainColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uvTex0) * _MainColor * _TintStrength;
half4 specularTex = SAMPLE_TEXTURE2D(_SpecularTex, sampler_SpecularTex, i.uvTex0);
float3 worldPos = i.worldPos;
float3 worldNormal = normalize(i.worldNormal);
half3 worldViewDir = normalize(i.worldViewDir);
half smoothness = _Smoothness;
half3 specularColor = _SpecularFactor * _SpecularColor * specularTex.a;
////阴影相关、烘焙相关/////////////////////////////////////////////////////////////////////////
half atten = 1;
float3 shLight = 1;
#if defined(LIGHTMAP_ON)
i.shadowCoord = TransformWorldToShadowCoord(worldNormal);
shLight = SAMPLE_GI(i.lightmapUV, i.vertexSH, worldNormal);
float shadowMask = SAMPLE_SHADOWMASK(i.lightmapUV);
atten = GetMainLight(i.shadowCoord, worldPos, shadowMask).shadowAttenuation;
atten = min(atten, shadowMask);
#endif
//////////////////////////////////////////////////////////////////////////////////////////////
#ifdef _LIGHTSWITCH_ON
specularColor *= _lightColor * _lightStrength;
half3 finalColor = BlinnPhoneLightingFwdBase_CustomLight(mainColor, worldPos, worldNormal, worldViewDir, shLight, atten, specularColor, smoothness, _lightDir);
#else
half3 finalColor = BlinnPhoneLightingFwdBase(mainColor, worldPos, worldNormal, worldViewDir, shLight, atten, specularColor, smoothness);
#endif
finalColor = ApplyDark(finalColor);
#if defined(_SG_EXPFOG)
CUSTOM_APPLY_FOG(i, finalColor, distance(_WorldSpaceCameraPos, worldPos));
#endif
return half4(finalColor, mainColor.a * _MainColor.a);
}
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: b65793891e51c0444b4c82e11152169f
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,170 @@
#ifndef SGAME_WATER_BASE
#define SGAME_WATER_BASE
#include "./ExpHeightFog_Base.hlsl"
#include "./Lighting_Base.hlsl"
TEXTURE2D(_ReflectionTex); SAMPLER(sampler_ReflectionTex);
TEXTURE2D(_NormalTexture); SAMPLER(sampler_NormalTexture);
TEXTURECUBE(_ReflectionCubeMap); SAMPLER(sampler_ReflectionCubeMap);
TEXTURE2D(_CameraDepthTexture); SAMPLER(sampler_CameraDepthTexture);
CBUFFER_START(UnityPerMaterial)
half4 _DeepWaterColor; half4 _ShallowWaterColor; half _ShallowDeepBlend; half _ShallowDeepFade;
float4 _ReflectionTex_ST; half _ReflectionIntensity; half _DepthTransparency; half _Specular; half _Gloss;
half _LightWrapping; float4 _NormalTexture_ST; half _Refraction; float4 _MainWaveTilingOffset; float4 _SecondWaveTilingOffset;
half _SpecularRefraction; half _SpecularOffset; half _ReflectionDistortion;
half4 _SpecularColor; half _FogFactor; half _MaxTransparency;
half _ReflectionCubeMapOffset; half _CubeMapReflectionIntensity;
CBUFFER_END
struct VertexInput
{
float4 vertex : POSITION;
half3 normal : NORMAL;
half4 tangent : TANGENT;
float2 texcoord0 : TEXCOORD0;
};
struct VertexOutput
{
float4 pos : SV_POSITION;
float4 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float4 posWorld : TEXCOORD2;
float4 screenPos : TEXCOORD3;
float4 projPos : TEXCOORD4;
#if defined(_SG_EXPFOG)
half4 _fogCoord : TEXCOORD5;
#endif
#if defined(_PROJECTOR_ON)
half4 projectorUV : TEXCOORD6;
#endif
};
inline float3 UnityObjectToViewPos( in float3 pos )
{
return mul(UNITY_MATRIX_V, mul(unity_ObjectToWorld, float4(pos, 1.0))).xyz;
}
#define COMPUTE_EYEDEPTH(o, vert) o = -UnityObjectToViewPos( vert ).z
VertexOutput vert (VertexInput v)
{
VertexOutput o = (VertexOutput)0;
VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(v.normal, v.tangent);
float4 worldPos = half4(vertexInput.positionWS, 1);
o.posWorld = worldPos;
o.pos = vertexInput.positionCS;
o.projPos = ComputeScreenPos (o.pos);
COMPUTE_EYEDEPTH(o.projPos.z, v.vertex.xyz);
o.screenPos = o.pos;
o.uv0.xy = v.texcoord0 * _MainWaveTilingOffset.xy + _MainWaveTilingOffset.zw * _Time.r * 0.1;
o.uv1.xy = v.texcoord0 * _SecondWaveTilingOffset.xy + _SecondWaveTilingOffset.zw * _Time.r * 0.1;
#if defined(_SG_EXPFOG)
CUSTOM_TRANSFER_FOG(o, v.vertex);
#endif
#if defined(_PROJECTOR_ON)
o.projectorUV = GetProjectorUV(v.vertex, unity_ObjectToWorld);
#endif
return o;
}
half4 frag(VertexOutput i) : SV_TARGET
{
float3 worldNormal = half3(0, 1, 0);
half3x3 tangentTransform = half3x3(half3(1, 0, 0), half3(0, 0, 1), worldNormal);
/////// Vectors:
half3 viewDirection = GetCameraPositionWS() - i.posWorld.xyz;
half4 _texture1 = SAMPLE_TEXTURE2D(_NormalTexture, sampler_NormalTexture, i.uv0.xy);
half4 _texture2 = SAMPLE_TEXTURE2D(_NormalTexture, sampler_NormalTexture, i.uv1.xy);
half3 _subtractor1 = (_texture1.rgb-_texture2.rgb);
half3 normalLocal = lerp(half3(0,0,1),_subtractor1,_Refraction);
half3 specularNormalLocal = lerp(half3(0,_SpecularOffset,1), _subtractor1, _SpecularRefraction);
half3 normalDirection = normalize(mul( normalLocal, tangentTransform )); // Perturbed normals
half3 specularNormalDirection = normalize(mul( specularNormalLocal, tangentTransform )); // Perturbed normals
Light mainLight = GetMainLight();
half3 lightDirection = normalize(mainLight.direction);
half3 lightColor = mainLight.color.rgb;
float sceneZ = 0;
float partZ = max(0,i.projPos.z - _ProjectionParams.g);
float diffZ = 0;
float sampleDepth = SAMPLE_TEXTURE2D(_CameraDepthTexture, sampler_CameraDepthTexture, i.projPos.xy / i.projPos.z).r;
sampleDepth = 1.0 / (_ZBufferParams.z * sampleDepth + _ZBufferParams.w);
sceneZ = max(0, sampleDepth - _ProjectionParams.g);
diffZ = sceneZ - partZ;
half finalAlpha = clamp((diffZ / _DepthTransparency), 0, _MaxTransparency);
half NDotL = dot( normalDirection, lightDirection );
half NL = saturate(NDotL);
half3 attenColor = lightColor;
half3 ambientColor = UNITY_LIGHTMODEL_AMBIENT.rgb;
///////// Gloss:
half gloss = _Gloss;
half specPow = gloss * 128;
////// Specular:
#if defined(SGAME_QUALITY_PERFECT) || defined(SGAME_QUALITY_HIGH)
half3 specularColor = (_Specular*_SpecularColor.rgb);
half3 specularHalfDirection = normalize(lightDirection + viewDirection);
half NH = max(0,dot(specularHalfDirection,specularNormalDirection));
float specAtten = SGamePow(NH, specPow);
half3 directSpecular = specAtten*specularColor*attenColor*NL;
half3 specular = directSpecular;
#else
half3 specular = half3(0,0,0);
#endif
/////// Diffuse:
half3 directDiffuse = NL * attenColor * _LightWrapping;
half3 indirectDiffuse = ambientColor;
half3 totalDiffuse = (directDiffuse + indirectDiffuse);
half shallowRatio = 1 - saturate((sceneZ - partZ)/_ShallowDeepBlend); //1ʾDZˮ,0ʶˮ
shallowRatio = SGamePow(shallowRatio, _ShallowDeepFade);
half3 waterColor = lerp(_DeepWaterColor.rgb, _ShallowWaterColor.rgb, shallowRatio);
half3 diffuseWater = totalDiffuse * waterColor;
half3 planarReflect = 0;
i.screenPos = float4( i.screenPos.xy / i.screenPos.w, 0, 0 );
i.screenPos.y *= _ProjectionParams.x;
half2 _componentMask = _subtractor1.rg;
half2 remap = ((i.screenPos.rg+()*0.5+0.5);
planarReflect = SAMPLE_TEXTURE2D(_ReflectionTex, sampler_ReflectionTex, TRANSFORM_TEX(remap, _ReflectionTex));
half3 cubeMapRefl = 0;
#if defined(_CUBEMAPTOGGLE_ON)
half3 R = reflect(-viewDirection, normalDirection);
half3 cubeSampleUV = RotationY(R, _ReflectionCubeMapOffset);
half4 refectionMap_Var = SAMPLE_TEXTURECUBE_LOD(_ReflectionCubeMap, sampler_ReflectionCubeMap, cubeSampleUV, 1); //这里计算的是CubeMap
refectionMap_Var *= _CubeMapReflectionIntensity;
cubeMapRefl = refectionMap_Var.rgb;
#endif
half3 ReflectionRGB = planarReflect + cubeMapRefl;
half3 diffuse = lerp(diffuseWater, ReflectionRGB, _ReflectionIntensity);
/// Final Color:
half3 finalColor = diffuse + specular;
finalColor.rgb = ApplyDark(finalColor.rgb);
#if defined(_PROJECTOR_ON)
finalColor.rgb = GetProjectorColor(finalColor.rgb, i.projectorUV).rgb;
#endif
#if defined(_SG_EXPFOG)
CUSTOM_APPLY_FOG(i, finalColor.rgb, distance(_WorldSpaceCameraPos, i.posWorld.xyz));
#endif
finalAlpha *= clamp(length(_WorldSpaceCameraPos.xyz - i.posWorld.xyz) / 3, 0, 1);
half4 finalRGBA = half4(finalColor, finalAlpha);
return finalRGBA;
}
#endif
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 6b5b23fd9a2a69a4582fad6e501b6366
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant: