#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