#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