#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