#T#TPSProperties
[HideInInspector] m_start_tps_penetrator("Penetrator--{reference_property:_TPSPenetratorEnabled,tooltip:Enable TPS Penetrator: Requires the TPS Setup Wizard to be run (under Poi/TPS)}", Float) = 0
[HideInInspector] m_start_pen_autoConfig("Configured By Tool", Float) = 0
_TPS_PenetratorLength("Length of Penetrator Model--{tooltip:The length from the root of the P to the very tip}", Float) = 1
[Vector3]_TPS_PenetratorScale("Scale of Penetrator Model", Vector) = (1,1,1,1)
[Vector3]_TPS_PenetratorRight("Right Vector", Vector) = (1,0,0,0)
[Vector3]_TPS_PenetratorUp("Up Vector", Vector) = (0,1,0,0)
[Vector3]_TPS_PenetratorForward("Forward Vector", Vector) = (0,0,1,0)
[Toggle(TPS_IsSkinnedMesh)]_TPS_IsSkinnedMeshRenderer("Baked Vertex Colors", Float) = 0
_TPS_BakedMesh("Baked Mesh / Mask", 2D) = "white" {}
[HideInInspector] m_end_pen_autoConfig("TPS", Float) = 0
[Helpbox(1)]_TPSHelpbox("Penetrator allows your mesh to bend in the direction of an orifice. It is fully compatible with DPS. Requires the TPS Setup Wizard to be run afterwards. Click here to open the setup window.--{onClick:Thry.TPS.TPS_Setup}", Float) = 0
[HideInInspector][ThryToggle(TPS_Penetrator)]_TPSPenetratorEnabled("Enabled", Float) = 0

[Space(10)]
[Toggle]_TPS_AnimatedToggle("Animatable Toggle--{tooltip:This is a toggle that can be animated}", Float) = 1
[ThryIntRange]_TPS_Channel("Channel--{tooltip:Channel of the penetrator. Channel -1 is DPS Channel 1}", Range(-1,17)) = 0
[Helpbox(2)]_TPS_ChannelWarning("DPS Channel -1 may be deprecated in the future. It does not support animator features. Use channels 0-8 instead.--{condition_show:_TPS_Channel==-1}", Float) = 0

[HideInInspector]g_start_tps_bezier("Bezier (Bending)--{draw_border:true,margin_top:10,tooltip: Changes how the penetrator bends}", Float) = 0
_TPS_BezierStart("Bezier Start--{tooltip:Start later down the penetrator}", Range(0,5)) = 0.0
_TPS_BezierSmoothness("Bezier Smoothness--{tooltip:Smoothness of bending}", Range(0.49,0.01)) = 0.4
_TPS_SmoothStart("Smooth Start--{tooltip:When penetrator starts moving towards orifice}", Range(0.01,1)) = 1
[HideInInspector]g_end_tps_bezier("", Float) = 0

[HideInInspector]g_start_tps_squeeze("Squeeze--{draw_border:true,margin_top:10,tooltip:Penetrator contracts when entering an orifice}", Float) = 0
_TPS_Squeeze("Squeeze Strength--{tooltip:Percentage penetrator squeezes}", Range(0,1)) = 0.3
_TPS_SqueezeDistance("Squeeze Distance--{tooltip:Width of the squeezing}", Range(0.01,1)) = 0.2
[Space(5)]
[VectorToSliders(Hole Multiplier,0,1,Ring Multiplier,0,1)]_TPS_SqueezeTypeMultiplier("--{tooltip:Multiplies the squeeze depending on the orifice type}", Vector) = (1,1,1,1)
[HideInInspector]g_end_tps_squeeze("", Float) = 0

[HideInInspector]g_start_tps_buldge("Buldge--{draw_border:true,margin_top:10,tooltip:Penetrator expands in front of the orifice}", Float) = 0
_TPS_Buldge("Buldge--{tooltip:Amount in percentage}", Range(0,3)) = 0.3
_TPS_BuldgeDistance("Buldge Distance--{tooltip:Width of the buldging}", Range(0.01,1)) = 0.2
_TPS_BuldgeFalloffDistance("Buldge Falloff--{tooltip:Width of bulding in front of orifice}", Range(0.01,0.5)) = 0.05
[Space(5)]
[VectorToSliders(Hole Multiplier,0,1,Ring Multiplier,0,1)]_TPS_BuldgeTypeMultiplier("--{tooltip:Multiplies the buldge depending on the orifice type}", Vector) = (1,1,1,1)
[HideInInspector]g_end_tps_buldge("", Float) = 0

[HideInInspector]g_start_tps_pulsing("Pulsing--{draw_border:true,margin_top:10,tooltip: Penetrator expands in pulses while entering orifice}", Float) = 0
_TPS_PumpingStrength("Pumping Strength--{tooltip:Amount in percentage}", Range(0,1)) = 0
_TPS_PumpingSpeed("Pumping Speed--{tooltip:Frequenzy of pulsing}", Range(0,10)) = 1
_TPS_PumpingWidth("Pumping Width--{tooltip:Width of pulsing}", Range(0.01,1)) = 0.2
[HideInInspector]g_end_tps_pulsing("", Float) = 0

[HideInInspector]g_start_tps_idle("Idle--{draw_border:true,margin_top:10,tooltip: Changes how the penetrator bends while no orifice is near}", Float) = 0
[Helpbox(0)]_TPS_IdleGravity("Tip: For idle gravity & movement use physbones gravity & other functions", Float) = 0
_TPS_IdleSkrinkWidth("Idle Shrink Width--{tooltip:P shrinks while not penetrating}", Range(0,1)) = 1
_TPS_IdleSkrinkLength("Idle Shrink Length--{tooltip:P shrinks while not penetrating}", Range(0,1)) = 1
[HideInInspector]g_end_tps_idle("", Float) = 0

//Hide These, animated only
[HideInInspector]_TPS_BufferedDepth   ("_TPS2_BufferedDepth NL", Float) = 0
[HideInInspector]_TPS_BufferedStrength("_TPS2_BufferedStrength NL", Float) = 0
[HideInInspector] m_end_tps_penetrator("", Float) = 0

#T#TPSKeywords
#pragma shader_feature TPS_Penetrator
#pragma shader_feature TPS_IsSkinnedMesh

#T#TPSVariables
#ifdef TPS_Penetrator
	int _TPS_Channel;
    float _TPS_AnimatedToggle;
	float _TPS_PenetratorLength;
	float3 _TPS_PenetratorScale;
	float3 _TPS_PenetratorForward;
	float3 _TPS_PenetratorRight;
	float3 _TPS_PenetratorUp;
	float _TPS_VertexColors;
	float _TPS_MinimumOrificeDistance;
	float _TPS_BezierStart;
	float _TPS_SmoothStart;
	float _TPS_BezierSmoothness;
	float _TPS_Squeeze;
	float _TPS_SqueezeDistance;
	float4 _TPS_SqueezeTypeMultiplier;
	float _TPS_Buldge;
	float _TPS_BuldgeDistance;
	float _TPS_BuldgeFalloffDistance;
	float4 _TPS_BuldgeTypeMultiplier;

	float _TPS_PumpingStrength;
	float _TPS_PumpingSpeed;
	float _TPS_PumpingWidth;

	float _TPS_IdleSkrinkWidth;
	float _TPS_IdleSkrinkLength;

	float _TPS_BufferedDepth;
	float _TPS_BufferedStrength;

	UNITY_DECLARE_SCREENSPACE_TEXTURE(_TPS_Grabpass);
#ifdef TPS_IsSkinnedMesh
UNITY_DECLARE_TEX2D_NOSAMPLER(_TPS_BakedMesh);
#else
sampler2D _TPS_BakedMesh;
#endif

	#define ID_DEFAULT_HOLE 0.41 * 500
	#define ID_DEFAULT_RING 0.42 * 500
	#define ID_DEFAULT_NORM 0.45 * 500

	#define ID_DPS_CHANNEL_HOLE 0.43 * 500
	#define ID_DPS_CHANNEL_RING 0.44 * 500
	#define ID_DPS_CHANNEL_NORM 0.46 * 500

	#define ID_ENHANCED_MIN 0.452 * 500
	#define ID_ENHANCED_STEPS 0.002 * 500

	#define TPS_ALPHA_ENHANCED_MASK 192
	#define TPS_ALPHA_ENHANCED_CHECK 64
	#define TPS_ALPHA_TYPE_MASK 48

	#define ORIFICE_TYPE_HOLE 0
	#define ORIFICE_TYPE_RING 1
	#define ORIFICE_TYPE_NORMAL 2
#endif

#T#TPSFunctions
#ifdef TPS_Penetrator

//https://forum.unity.com/threads/point-light-in-v-f-shader.499717/ UGA BUGA, Unity Forums pogggggggg
float LightRange(int i) {
	return (0.005 * sqrt(1000000.0 - unity_4LightAtten0[i])) / sqrt(unity_4LightAtten0[i]);
}

float4 GetLightPositionInObjectSpace(int i) {
	return mul(unity_WorldToObject, float4(unity_4LightPosX0[i], unity_4LightPosY0[i], unity_4LightPosZ0[i], 1));
}

uint4 f32touint8(float4 input)
{
	input.r = LinearToGammaSpaceExact(input.r);
	input.g = LinearToGammaSpaceExact(input.g);
	input.b = LinearToGammaSpaceExact(input.b);
	return round(input * 255);
}

float decodeFloatFromARGB8(float4 rgba)
{
	uint4 u = f32touint8(rgba);
	return asfloat(u.x + (u.y << 8) + (u.z << 16) + (u.w << 24));
}

float decodeFloatFromARGB8File(float4 rgba)
{
	uint4 u = round(rgba * 255);
	return asfloat(u.x + (u.y << 8) + (u.z << 16) + (u.w << 24));
}

#if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
	#define SampleGrabpass(tex,uv) UNITY_SAMPLE_TEX2DARRAY_LOD(tex, float3(uv.xy, 0), 0)
#elif UNITY_SINGLE_PASS_STEREO
	#define SampleGrabpass(tex,uv) tex2Dlod(tex, float4(uv.x * 0.5, uv.y,0,0))
#else
	#define SampleGrabpass(tex,uv) tex2Dlod(tex, float4(uv.xy,0,0))
#endif

#define RoundLightRange(range) (round(range / 0.002))
#define BitValueCheck(value,mask,bits) ((value & mask) == bits)

#define ID_ENHANCED ((_TPS_Channel - 1) * ID_ENHANCED_STEPS + ID_ENHANCED_MIN)
#define ID_HOLE (_TPS_Channel == -1 ? ID_DPS_CHANNEL_HOLE : (_TPS_Channel > 0 ? ID_ENHANCED : ID_DEFAULT_HOLE))
#define ID_RING (_TPS_Channel == -1 ? ID_DPS_CHANNEL_RING : (_TPS_Channel > 0 ? ID_ENHANCED : ID_DEFAULT_RING))
#define ID_NORM (_TPS_Channel == -1 ? ID_DPS_CHANNEL_NORM : (_TPS_Channel > 0 ? ID_ENHANCED : ID_DEFAULT_NORM))

#define IsLightEnhancedAlpha(alpha) (BitValueCheck(alpha,TPS_ALPHA_ENHANCED_MASK,TPS_ALPHA_ENHANCED_CHECK))

#define VectorLengthIntoDirection(v,d) dot(v,d)

#define BuldgeStrength(type) _TPS_Buldge * (type == ORIFICE_TYPE_HOLE ? _TPS_BuldgeTypeMultiplier[0] : _TPS_BuldgeTypeMultiplier[1])
#define SqueezeStrength(type) _TPS_Squeeze * (type == ORIFICE_TYPE_HOLE ? _TPS_SqueezeTypeMultiplier[0] : _TPS_SqueezeTypeMultiplier[1])

float FindTPSSystem(inout float3 orificePosition, inout float3 orificeNormal, inout float penetratorType, float penetratorLength) {
	//find lights
	int lightRanges[4];
	float3 lightPositions[4];
	float3 lightPositionsWorld[4];
	int lightAlpha[4];
	
	int tpsType[4];
	bool isEnhanced[4];
	[loop] for (int f = 0; f < 4; f++) {
		lightPositions[f] = GetLightPositionInObjectSpace(f);
		lightPositionsWorld[f] = length(mul(unity_ObjectToWorld, float4(lightPositions[f], 1)));
		lightRanges[f] = RoundLightRange(LightRange(f));
		lightAlpha[f] = int((unity_LightColor[f].a) * 255);

		tpsType[f] = -1;
		isEnhanced[f] = IsLightEnhancedAlpha(lightAlpha[f]);
		if(lightRanges[f] == ID_HOLE || lightRanges[f] == ID_RING || lightRanges[f] == ID_NORM)
		{
			if(isEnhanced[f])
				tpsType[f] = (lightAlpha[f] & TPS_ALPHA_TYPE_MASK) >> 4;
			else
				tpsType[f] = lightRanges[f] == ID_HOLE ? ORIFICE_TYPE_HOLE : (lightRanges[f] == ID_RING ? ORIFICE_TYPE_RING : ORIFICE_TYPE_NORMAL);
		}
	}

	//Find closest orifice light
	float closestOrfDist = 100000000;
	[loop]for (int i = 0; i < 4; i++) {
		if(tpsType[i] > -1 && tpsType[i] != ORIFICE_TYPE_NORMAL)
		{
			//Ceck if orifice light is in forward direction
			if (dot(_TPS_PenetratorForward, lightPositions[i]) > 0) {
				//Check if normal exisits
				float3 foundNormal = -_TPS_PenetratorForward;
				bool hasNormal = false;
				[loop] for (int n = 0; n < 4; n++) {
					//orifice normal
					if (tpsType[n] == ORIFICE_TYPE_NORMAL && distance(lightPositionsWorld[n] , lightPositionsWorld[i]) < 0.05) {
						foundNormal = normalize(lightPositions[n] - lightPositions[i]);
						hasNormal = true;
					}
				}
				//if normal light direction and is cloest orifice
				if (dot(foundNormal, _TPS_PenetratorForward) < 0 && length(lightPositions[i]) < closestOrfDist) {
					closestOrfDist = length(lightPositions[i]);
					orificePosition = lightPositions[i];
					penetratorType = tpsType[i];
					orificeNormal = (float3)0 * (1 - hasNormal) + foundNormal * hasNormal;
				}
			}
		}
	}
	// Fallback: Get position from normal if no position light found

	// Guess normal of normal not existing
	if (length(orificeNormal) == 0) {
		orificeNormal = lerp(normalize(-orificePosition), -_TPS_PenetratorForward, max(dot(normalize(orificePosition), _TPS_PenetratorForward), 0.5));
	}

#ifdef TPS_IsSkinnedMesh
	return (closestOrfDist) < ((_TPS_SmoothStart+1) * penetratorLength);
#else
	return (closestOrfDist) < (min(_TPS_SmoothStart+1,1.5) * penetratorLength);
#endif
}

//https://vicrucann.github.io/tutorials/bezier-shader/
float3 toBezier(float t, float3 P0, float3 P1, float3 P2, float3 P3)
{
	float t2 = t * t;
	float one_minus_t = 1.0 - t;
	float one_minus_t2 = one_minus_t * one_minus_t;
	return (P0 * one_minus_t2 * one_minus_t + P1 * 3.0 * t * one_minus_t2 + P2 * 3.0 * t2 * one_minus_t + P3 * t2 * t);
}

void ApplyTPSPenetrator(inout float4 vertex, inout float3 normal, inout float4 vertexColor, uint vertexId, float2 uv) {
	float orificeType = (float3)0;
	float3 orificePosition = (float3)0;
	float3 orificeNormal = (float3)0;

	// SMR Scale. Might be something to look into in the future, although fucked normals or different scaling into axis would mess with this
	// scale = length(normal);

	// Adjust pen length for scaled non skinned renderers
	float penetratorLength = _TPS_PenetratorLength;
#ifndef TPS_IsSkinnedMesh
	/*float3 scale = float3(
		length(float3(unity_ObjectToWorld[0].x, unity_ObjectToWorld[1].x, unity_ObjectToWorld[2].x)), // scale x axis
		length(float3(unity_ObjectToWorld[0].y, unity_ObjectToWorld[1].y, unity_ObjectToWorld[2].y)), // scale y axis
		length(float3(unity_ObjectToWorld[0].z, unity_ObjectToWorld[1].z, unity_ObjectToWorld[2].z))  // scale z axis
		);*/
	// Mesh Renderers arent getting skinned => verticies are still in object space => _TPS_PenetratorLength needs to be scaled to object space
	penetratorLength = _TPS_PenetratorLength / abs(VectorLengthIntoDirection(_TPS_PenetratorScale, _TPS_PenetratorForward));
#endif

	//Idle shrinkage
	float2 shrinkage = float2(_TPS_IdleSkrinkWidth, _TPS_IdleSkrinkLength);

	//Idle Position
	//Fix idle gravity
	float3 targetPosition = _TPS_PenetratorForward * penetratorLength;
	float3 targetNormal = -_TPS_PenetratorForward;

	//Default values
	float tpsSmoothStart = 0;
	float tpsSmoothStart2 = 0;

	float bezierSmoothness = _TPS_BezierSmoothness * penetratorLength;
	float penetrationDepth = 0;

	//Find tps system, calculate values
	[branch] if (FindTPSSystem(orificePosition, orificeNormal, orificeType, penetratorLength) )
	{
#ifdef TPS_IsSkinnedMesh
		float smoothStartStart = _TPS_SmoothStart;
#else
		float smoothStartStart = min(_TPS_SmoothStart,0.5);
#endif
		tpsSmoothStart = saturate((penetratorLength * (1+smoothStartStart) - length(orificePosition)) / (penetratorLength * smoothStartStart));
		tpsSmoothStart2 = saturate((penetratorLength - length(orificePosition)) / penetratorLength * 10);

		float3 orifceTargetPos = normalize(orificePosition) * min(penetratorLength,length(orificePosition));
		targetPosition = lerp(targetPosition, orifceTargetPos, tpsSmoothStart);
		targetNormal = lerp(targetNormal, orificeNormal, tpsSmoothStart);

		penetrationDepth = 1 - saturate(length(orificePosition) / penetratorLength);
		//smoothness goes to 0 when close to oriface to prevent weird batching
		bezierSmoothness = lerp(bezierSmoothness, 0, penetrationDepth);

		shrinkage = lerp(float2(_TPS_IdleSkrinkWidth, _TPS_IdleSkrinkLength), float2(1, 1), saturate(tpsSmoothStart * 2));
	}

	//Vertex for skinned penetrators is read from texture
	float3 penetratorVertex = vertex;
	float3 penetratorNormal = normal;
#ifdef TPS_IsSkinnedMesh
	//_TPS_BakedMesh = 
	int uvY = (vertexId * 6) / 8190.0;
	int baseX = (vertexId * 6) % 8190;
	penetratorVertex.x = decodeFloatFromARGB8File(_TPS_BakedMesh.Load(int3(baseX + 0, uvY, 0)));
	penetratorVertex.y = decodeFloatFromARGB8File(_TPS_BakedMesh.Load(int3(baseX + 1, uvY, 0)));
	penetratorVertex.z = decodeFloatFromARGB8File(_TPS_BakedMesh.Load(int3(baseX + 2, uvY, 0)));
	penetratorNormal.x = decodeFloatFromARGB8File(_TPS_BakedMesh.Load(int3(baseX + 3, uvY, 0)));
	penetratorNormal.y = decodeFloatFromARGB8File(_TPS_BakedMesh.Load(int3(baseX + 4, uvY, 0)));
	penetratorNormal.z = decodeFloatFromARGB8File(_TPS_BakedMesh.Load(int3(baseX + 5, uvY, 0)));
	penetratorVertex = penetratorVertex * _TPS_PenetratorScale;
#endif

	float penZ = VectorLengthIntoDirection(penetratorVertex, _TPS_PenetratorForward);
	vertexColor.a = penZ / penetratorLength;
	 
	float3 bezier0 = _TPS_PenetratorForward * _TPS_BezierStart;
	float3 bezier0Out = bezier0 + _TPS_PenetratorForward * bezierSmoothness;
	float3 bezier1 = targetPosition;
	float3 bezier1In = bezier1 + targetNormal * bezierSmoothness;

	float bezierStrengthUncapped = ((penZ - _TPS_BezierStart) / distance(bezier0, bezier1));
	float bezierStrength = saturate(bezierStrengthUncapped);

	//Bezier curve, calculate two points, calculate forward, right, up vectors
	float3 bezierPoint = toBezier(bezierStrength, bezier0, bezier0Out, bezier1In, bezier1);
	float3 bezierPoint2 = toBezier(bezierStrength + 0.01f, bezier0, bezier0Out, bezier1In, bezier1);

	if (orificeType == ORIFICE_TYPE_RING && bezierStrength == 1 && tpsSmoothStart == 1) {
		bezierPoint = orificePosition + (penZ - _TPS_BezierStart - length(orificePosition.xyz)) * -orificeNormal;
		bezierPoint2 = bezierPoint - orificeNormal;
	}

	float3 penDirectionRight = normalize(cross(_TPS_PenetratorUp, normalize(bezier1 - bezier0)));
	float3 penDirectionUp = normalize(cross(normalize(bezier1 - bezier0), penDirectionRight));

	float3 bezierForward = normalize(bezierPoint2 - bezierPoint);
	float3 bezierRight = normalize(cross(penDirectionUp, bezierForward));
	float3 bezierUp = normalize(cross(bezierForward, bezierRight));	

//Mask for skinned mesh renderer
#ifdef TPS_IsSkinnedMesh
	if(length(penetratorNormal) == 0){
		bezierStrength = 0;
		vertexColor.a = 0;
	}
#else
	float4 mask = tex2Dlod(_TPS_BakedMesh, float4(uv.xy, 0, 0));
	bezierStrength *= mask.r;
	vertexColor.a *= mask.r;
#endif
	if(_TPS_AnimatedToggle == 0){
		bezierStrength = 0;
	}

	//calculate new position and normal
	if (bezierStrength > 0) {
		//pumping
		float sizeChange = 1;
		if (_TPS_PumpingStrength > 0) {
			sizeChange *= lerp(1 - _TPS_PumpingStrength * tpsSmoothStart2, 1 + _TPS_PumpingStrength * tpsSmoothStart2, abs(sin(_Time.y * -_TPS_PumpingSpeed + bezierStrengthUncapped / _TPS_PumpingWidth)));
		}
		//buldging + squeezing
		float buldgeLerp = 0;
		if (bezierStrength < 1 - _TPS_BuldgeFalloffDistance)
			buldgeLerp = saturate((bezierStrength - 1 + _TPS_BuldgeDistance + _TPS_BuldgeFalloffDistance) / _TPS_BuldgeDistance);
		else
			buldgeLerp = saturate((-bezierStrength + 1) / _TPS_BuldgeFalloffDistance);

		//Squeezing while outside oriface makes penetrator looks weirly streched
		float squeeze = lerp(0, SqueezeStrength(orificeType), saturate(penetrationDepth * 20));
		sizeChange *= lerp(1, 1 - squeeze, saturate(1 - abs(bezierStrengthUncapped - 1) / _TPS_SqueezeDistance) * tpsSmoothStart);
		sizeChange *= lerp(1, 1 + BuldgeStrength(orificeType), buldgeLerp * tpsSmoothStart2);

		//Calc idle shrinkage
		shrinkage = lerp(1, shrinkage, saturate((penZ - _TPS_BezierStart) * 20));
		//Apply vertex + normal
		float x = VectorLengthIntoDirection(penetratorVertex, _TPS_PenetratorRight);
		float y = VectorLengthIntoDirection(penetratorVertex, _TPS_PenetratorUp);
		float3 normalX = VectorLengthIntoDirection(normal, _TPS_PenetratorRight);
		float3 normalY = VectorLengthIntoDirection(normal, _TPS_PenetratorUp);
		float3 normalZ = VectorLengthIntoDirection(normal, _TPS_PenetratorForward);

		//TODO This is technically not correct for skinned meshes. Might want to revisit idle stuff in the future
		float3 vertexZ = _TPS_PenetratorForward * VectorLengthIntoDirection(vertex, _TPS_PenetratorForward);
		float3 vertexXY = vertex.xyz - vertexZ;
		vertex.xyz = shrinkage.y * vertexZ + shrinkage.x * vertexXY;

		vertex.xyz = lerp(vertex.xyz, bezierPoint + x * bezierRight * sizeChange + y * bezierUp * sizeChange, tpsSmoothStart); //for dynamic bones, lerp between original and skinned vertecies
		normal.xyz = lerp(normal.xyz, normalX * bezierRight + normalY * bezierUp + normalZ * bezierForward, tpsSmoothStart); //for dynamic bones, lerp between original and skinned vertecies
	}

	if ((bezierStrengthUncapped * tpsSmoothStart) > 1 && orificeType == ORIFICE_TYPE_HOLE) //Disc fix
		vertex.xyz = lerp(vertex.xyz, bezierPoint, tpsSmoothStart);
}

float TPSBufferedDepth(float3 vertex, float4 vertexColor) {
	return saturate((vertexColor.a - (1 - _TPS_BufferedDepth)) * 10) * _TPS_BufferedStrength;
}
#endif

#T#TPSImplementation
#ifdef TPS_Penetrator
    ApplyTPSPenetrator(v.vertex, v.normal, v.color, v.vertexId, v.uv0);
#endif
