iFactory.Cutting.Unity/Assets/Plugins/CW/PaintIn3D/Required/Resources/P3D Decal.cginc

157 lines
4.5 KiB
HLSL

#include "../../../PaintCore/Required/Resources/P3dShared.cginc"
#include "../../../PaintCore/Required/Resources/P3dMasking.cginc"
#include "../../../PaintCore/Required/Resources/P3dBlendModes.cginc"
#include "../../../PaintCore/Required/Resources/P3dExtrusions.cginc"
#include "../../../PaintCore/Required/Resources/P3dOverlap.cginc"
float4 _Coord;
float4 _Channels;
float4x4 _Matrix;
float3 _Direction;
sampler2D _Texture;
sampler2D _Shape;
float4 _ShapeChannel;
float4 _Color;
float _Opacity;
float _Hardness;
float _Wrapping;
float _In3D;
float2 _NormalFront;
float2 _NormalBack;
sampler2D _TileTexture;
float4x4 _TileMatrix;
float _TileOpacity;
float _TileTransition;
struct a2v
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float3 tangent : TANGENT;
float2 texcoord0 : TEXCOORD0;
float2 texcoord1 : TEXCOORD1;
float2 texcoord2 : TEXCOORD2;
float2 texcoord3 : TEXCOORD3;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
float3 position : TEXCOORD1;
float2 dot_rot : TEXCOORD2;
float3 tile : TEXCOORD3;
float3 weights : TEXCOORD4;
float3 mask : TEXCOORD5;
float4 vpos : TEXCOORD6;
};
struct f2g
{
float4 color : SV_TARGET;
};
void Vert(a2v i, out v2f o)
{
float2 texcoord = i.texcoord0 * _Coord.x + i.texcoord1 * _Coord.y + i.texcoord2 * _Coord.z + i.texcoord3 * _Coord.w;
float4 worldPos = mul(unity_ObjectToWorld, i.vertex);
float3 worldNormal = normalize(mul((float3x3)unity_ObjectToWorld, i.normal));
float3 worldTangent = normalize(mul((float3x3)unity_ObjectToWorld, i.tangent));
o.vertex = float4(texcoord.xy * 2.0f - 1.0f, 0.5f, 1.0f);
o.texcoord = texcoord;
o.position = lerp(float3(texcoord, 0.0f), worldPos.xyz, _In3D);
o.position = mul((float3x3)_Matrix, o.position);
o.tile = mul(_TileMatrix, worldPos).xyz;
o.mask = mul(_MaskMatrix, worldPos).xyz;
o.vpos = mul(_DepthMatrix, worldPos);
o.weights = pow(abs(worldNormal), _TileTransition);
o.weights /= o.weights.x + o.weights.y + o.weights.z;
float3 loc_tan = mul((float3x3)_Matrix, worldTangent);
o.dot_rot.x = dot(worldNormal, _Direction);
o.dot_rot.y = -atan2(loc_tan.y, loc_tan.x);
#if UNITY_UV_STARTS_AT_TOP
o.vertex.y = -o.vertex.y;
#endif
}
float P3D_GetStrength(float3 position, float normal)
{
// Fade OOB
float3 box = saturate(abs(position));
box.xy = pow(box.xy, 1000.0f);
box.z = pow(box.z, _Hardness);
// Fade slopes
float front = (_NormalFront.x - normal) * _NormalFront.y;
float back = (_NormalBack.x - normal) * _NormalBack.y;
float fade = saturate(max(front, back));
// Shape
float2 coord = position.xy * 0.5f + 0.5f;
float shape = dot(tex2D(_Shape, coord), _ShapeChannel);
// Combine
float strength = 1.0f;
strength -= max(box.x, max(box.y, box.z));
strength *= smoothstep(0.0f, 1.0f, fade);
strength *= _Opacity;
strength *= shape;
return strength;
}
float P3D_GetStrength(v2f i, float3 position)
{
float strength = P3D_GetStrength(position, i.dot_rot.x);
#if P3D_LINE_CLIP || P3D_QUAD_CLIP
#if P3D_LINE_CLIP
float3 f_position = i.position - _Position;
#elif P3D_QUAD_CLIP
float3 f_position = i.position - P3D_GetClosestPosition_Edge(_Position, _EndPosition, i.position);
#endif
float f_depth = f_position.z * _Wrapping; f_position.xy /= 1.0f - f_depth * f_depth;
float f_strength = P3D_GetStrength(f_position, i.dot_rot.x);
return P3D_GetOverlapStrength(strength, f_strength);
#else
return strength;
#endif
}
void Frag(v2f i, out f2g o)
{
float3 position = i.position - P3D_GetClosestPosition(i.position);
float3 absPos = abs(position);
// You can remove this to improve performance if you don't care about overlapping UV support
if (max(max(absPos.x, absPos.y), absPos.z) > 1.0f)
{
discard;
}
float depth = position.z * _Wrapping; position.xy /= 1.0f - depth * depth;
float strength = P3D_GetStrength(i, position);
float2 coord = position.xy * 0.5f + 0.5f;
float4 color = tex2D(_Texture, coord) * _Color;
// Fade mask
strength *= P3D_GetMask(i.mask);
// Fade local mask
strength *= P3D_GetLocalMask(i.texcoord);
// Fade depth
strength *= P3D_GetDepthMask(i.vpos);
// Mix in tiling
float4 textureX = tex2D(_TileTexture, i.tile.yz) * i.weights.x;
float4 textureY = tex2D(_TileTexture, i.tile.xz) * i.weights.y;
float4 textureZ = tex2D(_TileTexture, i.tile.xy) * i.weights.z;
color *= lerp(float4(1.0f, 1.0f, 1.0f, 1.0f), textureX + textureY + textureZ, _TileOpacity);
o.color = P3D_Blend(color, strength, i.texcoord, i.dot_rot.y, _Channels);
}