140 lines
3.9 KiB
HLSL
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 |