Files
AIC-Project/Client/Assets/Game/shader/SGame/Base/OpaqueEmissionObject_Base.hlsl

165 lines
5.8 KiB
HLSL

#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