res-avatar-unity/Assets/_PoiyomiShaders/TPS/Dev Resources/VRLT_TPS.poiTemplateCollection

377 lines
18 KiB
Plaintext
Raw Permalink Normal View History

2023-07-16 02:51:23 +00:00
#T#TPSProperties
//ifex _TPSPenetratorEnabled==0
[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)]
[ToggleUI]_TPS_AnimatedToggle("Animatable Toggle--{tooltip:This is a toggle that can be animated}", Float) = 1
[ThryRichLabel(13)]_TPSBezierHeader("Bezier--{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
[ThryRichLabel(13)]_TPSSqueezeHeader("Squeeze--{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
[ThryRichLabel(13)]_TPSBuldgeHeader("Buldge--{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
[ThryRichLabel(13)]_TPSPulsingHeader("Pulsing--{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
[ThryRichLabel(13)]_TPSIdleHeader("Idle--{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
[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _TPS_BufferedDepthGlobalMaskIndex ("TPS Depth to Global Mask--{reference_property:_TPS_BufferedDepthGlobalMaskBlendType}", Int) = 0
[HideInInspector][ThryWideEnum(Replace, 0, Darken, 1, Multiply, 2, Color Burn, 3, Linear Burn, 4, Lighten, 5, Screen, 6, Color Dodge, 7, Linear Dodge(Add), 8, Overlay, 9, Soft Lighten, 10, Hard Light, 11, Vivid Light, 12, Linear Light, 13, Pin Light, 14, Hard Mix, 15, Difference, 16, Exclusion, 17, Subtract, 18, Divide, 19)]_TPS_BufferedDepthGlobalMaskBlendType ("Blending", Range(0, 1)) = 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
//endex
#T#TPSKeywords
//ifex _TPSPenetratorEnabled==0
#pragma shader_feature_local TPS_Penetrator
#pragma shader_feature_local TPS_IsSkinnedMesh
//endex
#T#TPSVariables
//ifex _TPSPenetratorEnabled==0
#ifdef TPS_Penetrator
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;
float _TPS_Buldge;
float _TPS_BuldgeDistance;
float _TPS_BuldgeFalloffDistance;
float _TPS_PumpingStrength;
float _TPS_PumpingSpeed;
float _TPS_PumpingWidth;
float _TPS_IdleSkrinkWidth;
float _TPS_IdleSkrinkLength;
float _TPS_BufferedDepthGlobalMaskIndex;
float _TPS_BufferedDepthGlobalMaskBlendType;
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_HOLE 0.41
#define ID_RING 0.42
#define ID_NORM 0.45
#define TPS_RECIEVER_DIST 0.01
#define PENETRATORTYPE_RING 1
#define PENETRATORTYPE_HOLE 2
#endif
//endex
#T#TPSFunctions
//ifex _TPSPenetratorEnabled==0
#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 IsLightOrificeType(range,type) (abs(range - type) < 0.001)
#define IsLightAnyOrificeType(range) ((IsLightOrificeType(range,ID_RING)) || (IsLightOrificeType(range,ID_HOLE)))
#define VectorLengthIntoDirection(v,d) dot(v,d)
float FindTPSSystem(inout float3 orificePosition, inout float3 orificeNormal, inout float penetratorType, float penetratorLength) {
//find lights
float lightRanges[4];
float3 lightPositions[4];
float3 lightPositionsWorld[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] = LightRange(f);
}
//orifice hole + type
float closestOrfDist = 100000000;
[loop]for (int i = 0; i < 4; i++) {
if (abs(lightRanges[i] - ID_RING) < 0.001 || abs(lightRanges[i] - ID_HOLE) < 0.001) {
//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 (IsLightOrificeType(lightRanges[n], ID_NORM) && distance(lightPositionsWorld[n] , lightPositionsWorld[i]) < 0.05f) {
foundNormal = normalize(lightPositions[n] - lightPositions[i]);
hasNormal = true;
}
}
//if normal right direction and is cloest orifice
if (dot(foundNormal, _TPS_PenetratorForward) < 0 && length(lightPositions[i]) < closestOrfDist) {
closestOrfDist = length(lightPositions[i]);
orificePosition = lightPositions[i];
penetratorType = abs(lightRanges[i] - ID_HOLE) < 0.001 ? PENETRATORTYPE_HOLE : PENETRATORTYPE_RING;
orificeNormal = (float3)0 * (1 - hasNormal) + foundNormal * hasNormal;
}
}
}
}
//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 == PENETRATORTYPE_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, _TPS_Squeeze, saturate(penetrationDepth * 20));
sizeChange *= lerp(1, 1 - squeeze, saturate(1 - abs(bezierStrengthUncapped - 1) / _TPS_SqueezeDistance) * tpsSmoothStart);
sizeChange *= lerp(1, 1 + _TPS_Buldge, 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
}
}
float TPSBufferedDepth(float3 vertex, float4 vertexColor) {
return saturate((vertexColor.a - (1 - _TPS_BufferedDepth)) * 10) * _TPS_BufferedStrength;
}
#endif
//endex
#T#TPSImplementation
//ifex _TPSPenetratorEnabled==0
#ifdef TPS_Penetrator
ApplyTPSPenetrator(v.vertex, v.normal, v.color, v.vertexId, v.uv0);
#endif
//endex
#T#TPSFragImplementation
//ifex _TPSPenetratorEnabled==0
#ifdef TPS_Penetrator
if (_TPS_BufferedDepthGlobalMaskIndex > 0)
{
applyToGlobalMask(poiMods, _TPS_BufferedDepthGlobalMaskIndex-1, _TPS_BufferedDepthGlobalMaskBlendType, TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor));
}
#endif
//endex