309 lines
8.7 KiB
Plaintext
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
|
|
}
|
|
*/
|
|
}
|
|
}
|