Files
2026-02-23 22:01:07 +07:00

140 lines
3.9 KiB
HLSL

#ifndef ALLIN13DSHADER_OUTLINE_PASS_INCLUDED
#define ALLIN13DSHADER_OUTLINE_PASS_INCLUDED
#if defined(_OUTLINETYPE_SIMPLE) || defined(_OUTLINETYPE_FADEWITHDISTANCE)
#define OUTLINE_FACTOR 0.01
#else
#define OUTLINE_FACTOR 1.0
#endif
float3 GetObjectScale()
{
float3 res = float3(length(float3(UNITY_MATRIX_M[0].x, UNITY_MATRIX_M[1].x, UNITY_MATRIX_M[2].x)),
length(float3(UNITY_MATRIX_M[0].y, UNITY_MATRIX_M[1].y, UNITY_MATRIX_M[2].y)),
length(float3(UNITY_MATRIX_M[0].z, UNITY_MATRIX_M[1].z, UNITY_MATRIX_M[2].z)));
return res;
}
#ifdef OUTLINE_ON
float4 Outline_Constant(float4 vertexPos, float3 normalOS, float3 thicknessScaled)
{
float3 vertexWS = GetPositionWS(vertexPos);
float3 vertexToCameraWS = _WorldSpaceCameraPos.xyz - vertexWS;
float distanceToCamera = length(vertexToCameraWS);
float4 res = vertexPos;
float normalizedDistanceToCamera = distanceToCamera / ACCESS_PROP_FLOAT(_MaxCameraDistance);
float displacement = thicknessScaled.x * normalizedDistanceToCamera;
res.xyz += normalOS * displacement;
return res;
}
float4 Outline_Simple(float4 vertexPos, float3 normalOS, float3 thicknessScaled)
{
float4 res = vertexPos;
res.xyz += normalOS * thicknessScaled;
return res;
}
float4 Outline_FadeWithDistance(float4 vertexPos, float3 normalOS, float3 thicknessScaled)
{
float4 res = vertexPos;
float3 vertexWS = GetPositionWS(vertexPos);
float3 vertexToCameraWS = _WorldSpaceCameraPos.xyz - vertexWS;
float distanceToCamera = length(vertexToCameraWS);
float normalizedDistanceToCamera = saturate(distanceToCamera / ACCESS_PROP_FLOAT(_MaxFadeDistance));
float3 correctedThickness = (1 - normalizedDistanceToCamera) * thicknessScaled;
res.xyz += normalOS * correctedThickness;
return res;
}
#endif
FragmentDataOutline OutlinePass_Vertex(VertexData v)
{
FragmentDataOutline o;
o.interpolator_01 = 0;
o.interpolator_02 = 0;
o.interpolator_03 = 0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
#if defined(OUTLINE_ON)
float3 _Object_Scale = GetObjectScale();
float3 thicknessScaled = (ACCESS_PROP_FLOAT(_OutlineThickness) / _Object_Scale) * OUTLINE_FACTOR;
#endif
#if defined(_SPHERIZE_NORMALS_ON)
float3 normalOS = normalize(v.vertex);
#else
float3 normalOS = v.normal;
#endif
#if defined(_USE_CUSTOM_TIME)
SHADER_TIME(o) = allIn13DShader_globalTime.xyz + ACCESS_PROP_FLOAT(_TimingSeed);
#else
SHADER_TIME(o) = _Time.xyz + ACCESS_PROP_FLOAT(_TimingSeed);
#endif
v.vertex = ApplyVertexEffects(v.vertex, normalOS, SHADER_TIME(o));
#if defined(_OUTLINETYPE_SIMPLE)
v.vertex = Outline_Simple(v.vertex, v.normal, thicknessScaled);
#elif defined(_OUTLINETYPE_CONSTANT)
v.vertex = Outline_Constant(v.vertex, v.normal, thicknessScaled);
#elif defined(_OUTLINETYPE_FADEWITHDISTANCE)
v.vertex = Outline_FadeWithDistance(v.vertex, v.normal, thicknessScaled);
#endif
o.normalWS = GetNormalWS(v.normal);
o.mainUV = SIMPLE_CUSTOM_TRANSFORM_TEX(v.uv, _MainTex);
o.pos = OBJECT_TO_CLIP_SPACE(v);
o.positionWS = GetPositionWS(v.vertex);
UV_LIGHTMAP(o) = v.uvLightmap;
FOGCOORD(o) = GetFogFactor(o.pos);
return o;
}
float4 OutlinePass_Fragment(FragmentDataOutline i) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
float4 col = float4(0, 0, 0, 0);
#ifdef OUTLINE_ON
col = ACCESS_PROP_FLOAT4(_OutlineColor);
#endif
float camDistance = distance(i.positionWS, _WorldSpaceCameraPos);
float4 screenPos = ComputeScreenPos(i.pos);
col = ApplyAlphaEffects(col,
SCALED_MAIN_UV(i), UV_LIGHTMAP(i), i.positionWS,
1.0, camDistance, screenPos);
#ifdef _ALPHA_CUTOFF_ON
clip((col.a - ACCESS_PROP_FLOAT(_AlphaCutoffValue)) - 0.001);
#endif
#if defined(FOG_ENABLED)
col = CustomMixFog(FOGCOORD(i), col);
#endif
col.a *= ACCESS_PROP_FLOAT(_GeneralAlpha);
return col;
}
#endif