Project_WL/Assets/ThirdParty/Toon Shaders Pro/Shaders/Outline/Resources/MaskObject.shader

309 lines
8.7 KiB
Plaintext

Shader "Hidden/ToonShadersPro/URP/MaskObject"
{
SubShader
{
Tags
{
"RenderType" = "Opaque"
"Queue" = "Geometry"
"RenderPipeline" = "UniversalPipeline"
}
HLSLINCLUDE
#pragma target 3.0
#pragma fragment frag
#pragma multi_compile_instancing
#pragma shader_feature_local_fragment _IGNORE_DEPTH
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"
#include "OutlineUtils.hlsl"
struct appdata
{
float4 positionOS : POSITION;
float4 color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
nointerpolation float3 gameObjectPositionWS : TEXCOORD0;
nointerpolation float4 color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert (appdata v, out float4 positionCS : SV_Position)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
positionCS = TransformObjectToHClip(v.positionOS.xyz);
o.gameObjectPositionWS = GetObjectToWorldMatrix()._m03_m13_m23;
o.color = v.color;
return o;
}
// Hashing algorithms modified from: https://tips.orels.sh/optimized-hash-for-shaders
float hash1to1(float p)
{
p = frac(p * .1031);
p *= p + 33.33;
p *= p + p;
return frac(p) * 0.995f + 0.005f;
}
float hash3to1(float3 p3)
{
p3 = frac(p3 * .1031);
p3 += dot(p3, p3.zyx + 31.32);
return frac((p3.x + p3.y) * p3.z);
}
ENDHLSL
Pass
{
Name "MaskObjects"
ZTest Always
Cull Off
ZWrite Off
HLSLPROGRAM
#pragma vertex vert
// Thanks to this for the note on using VPOS: https://gamedev.stackexchange.com/questions/157922/depth-intersection-shader
float frag (v2f i, float4 positionSS : VPOS) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
#ifndef _IGNORE_DEPTH
// Get the depth of the pixel being rendered and the pixel already rendered.
float2 screenUV = positionSS.xy / _ScreenSize.xy;
float screenDepth = Linear01Depth(GetSceneDepth(screenUV), _ZBufferParams);
float objectDepth = Linear01Depth(positionSS.z, _ZBufferParams);
// Compare the two pixels - if depthMask is 1, the object is visible in the final image.
float depthMask = 1.0f - step(0.0000001f, abs(objectDepth - screenDepth));
if(depthMask < 0.5f)
{
discard;
}
#endif
// Render random value based on object world position.
float maskColor = hash3to1(i.gameObjectPositionWS + float3(17.34f, 271.4f, 94.247f));
return maskColor * 0.999f + 0.001f;
}
ENDHLSL
}
Pass
{
Name "MaskTriangles"
ZTest Always
Cull Off
ZWrite Off
HLSLPROGRAM
#pragma vertex vert
// Thanks to this for the note on using VPOS: https://gamedev.stackexchange.com/questions/157922/depth-intersection-shader
float frag (v2f i, float4 positionSS : VPOS, uint primitiveID : SV_PrimitiveID) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
#ifndef _IGNORE_DEPTH
// Get the depth of the pixel being rendered and the pixel already rendered.
float2 screenUV = positionSS.xy / _ScreenSize.xy;
float screenDepth = Linear01Depth(GetSceneDepth(screenUV), _ZBufferParams);
float objectDepth = Linear01Depth(positionSS.z, _ZBufferParams);
// Compare the two pixels - if depthMask is 1, the object is visible in the final image.
float depthMask = 1.0f - step(0.0000001f, abs(objectDepth - screenDepth));
if(depthMask < 0.5f)
{
discard;
}
#endif
// Render random value based on object world position and primitiveID.
float maskColor = hash3to1(primitiveID + i.gameObjectPositionWS + float3(17.34f, 271.4f, 94.247f));
return maskColor * 0.999f + 0.001f;
}
ENDHLSL
}
Pass
{
Name "MaskOnce"
ZTest Always
Cull Off
ZWrite Off
HLSLPROGRAM
#pragma vertex vert
// Thanks to this for the note on using VPOS: https://gamedev.stackexchange.com/questions/157922/depth-intersection-shader
float frag (v2f i, float4 positionSS : VPOS) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
#ifndef _IGNORE_DEPTH
// Get the depth of the pixel being rendered and the pixel already rendered.
float2 screenUV = positionSS.xy / _ScreenSize.xy;
float screenDepth = Linear01Depth(GetSceneDepth(screenUV), _ZBufferParams);
float objectDepth = Linear01Depth(positionSS.z, _ZBufferParams);
// Compare the two pixels - if depthMask is 1, the object is visible in the final image.
float depthMask = 1.0f - step(0.0000001f, abs(objectDepth - screenDepth));
if(depthMask < 0.5f)
{
discard;
}
#endif
// Render just one mask value for anything that fits.
return 0.5f;
}
ENDHLSL
}
Pass
{
Name "MaskVertexColors"
ZTest Always
Cull Off
ZWrite Off
HLSLPROGRAM
#pragma vertex vert
// Thanks to this for the note on using VPOS: https://gamedev.stackexchange.com/questions/157922/depth-intersection-shader
float frag (v2f i, float4 positionSS : VPOS) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
#ifndef _IGNORE_DEPTH
// Get the depth of the pixel being rendered and the pixel already rendered.
float2 screenUV = positionSS.xy / _ScreenSize.xy;
float screenDepth = Linear01Depth(GetSceneDepth(screenUV), _ZBufferParams);
float objectDepth = Linear01Depth(positionSS.z, _ZBufferParams);
// Compare the two pixels - if depthMask is 1, the object is visible in the final image.
float depthMask = 1.0f - step(0.0000001f, abs(objectDepth - screenDepth));
if(depthMask < 0.5f)
{
discard;
}
#endif
// Render random value based on object world position.
float maskColor = hash3to1(i.color.rgb + float3(17.34f, 271.4f, 94.247f));
return maskColor * 0.999f + 0.001f;
}
ENDHLSL
}
Pass
{
Name "MaskRSUV"
ZTest Always
Cull Off
ZWrite Off
HLSLPROGRAM
#pragma vertex vert
// Thanks to this for the note on using VPOS: https://gamedev.stackexchange.com/questions/157922/depth-intersection-shader
float frag (v2f i, float4 positionSS : VPOS) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
#if UNITY_VERSION >= 60030000
#ifndef _IGNORE_DEPTH
// Get the depth of the pixel being rendered and the pixel already rendered.
float2 screenUV = positionSS.xy / _ScreenSize.xy;
float screenDepth = Linear01Depth(GetSceneDepth(screenUV), _ZBufferParams);
float objectDepth = Linear01Depth(positionSS.z, _ZBufferParams);
// Compare the two pixels - if depthMask is 1, the object is visible in the final image.
float depthMask = 1.0f - step(0.0000001f, abs(objectDepth - screenDepth));
if(depthMask < 0.5f)
{
discard;
}
#endif
float rsuv = unity_RendererUserValue;
// Render random value based on RSUV.
float maskColor = hash3to1(rsuv.xxx + float3(17.34f, 271.4f, 94.247f));
return maskColor * 0.999f + 0.001f;
#else
// Unity versions before RSUV will do nothing.
return 0.0f;
#endif
}
ENDHLSL
}
/*
Pass
{
Name "MaskObjectsTransparent"
Blend One One
HLSLPROGRAM
#pragma vertex vert
// Thanks to this for the note on using VPOS: https://gamedev.stackexchange.com/questions/157922/depth-intersection-shader
float frag (v2f i, float4 positionSS : VPOS) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
// Get the depth of the pixel being rendered and the pixel already rendered.
float2 screenUV = positionSS.xy / _ScreenSize.xy;
float screenDepth = Linear01Depth(GetSceneDepth(screenUV), _ZBufferParams);
float objectDepth = Linear01Depth(positionSS.z, _ZBufferParams);
// Compare the two pixels - if depthMask is 1, the object is visible in the final image.
float depthMask = step(objectDepth, screenDepth);
if(depthMask < 0.5f)
{
discard;
}
return 0.001f;
}
ENDHLSL
}
*/
}
}