修复技能输入并更新战斗资源
This commit is contained in:
@@ -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:
|
||||
Reference in New Issue
Block a user