Rasagar/Library/PackageCache/com.unity.render-pipelines.high-definition/Runtime/Compositor/Shaders/ChromaKeying.shader
2024-08-26 23:07:20 +03:00

126 lines
4.1 KiB
Plaintext

Shader "Hidden/Shader/ChromaKeying"
{
HLSLINCLUDE
#pragma target 4.5
#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/FXAA.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/RTUpscale.hlsl"
struct Attributes
{
uint vertexID : SV_VertexID;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings Vert(Attributes input)
{
Varyings output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
output.texcoord = GetFullScreenTriangleTexCoord(input.vertexID);
return output;
}
// List of properties to control your post process effect
float3 _KeyColor;
float4 _KeyParams;
TEXTURE2D_X(_InputTexture);
// RGB <-> YCgCo color space conversion
float3 RGB2YCgCo(float3 rgb)
{
float3x3 m = {
0.25, 0.5, 0.25,
-0.25, 0.5, -0.25,
0.50, 0.0, -0.50
};
return mul(m, rgb);
}
float3 YCgCo2RGB(float3 ycgco)
{
return float3(
ycgco.x - ycgco.y + ycgco.z,
ycgco.x + ycgco.y,
ycgco.x - ycgco.y - ycgco.z
);
}
// Adapted from https://github.com/keijiro/ProcAmp
// Main difference is that we do the chroma keying in linear space (not gamma)
float ChromaKeyAt(float3 keyColorYCoCg, float2 uv)
{
float3 rgb = LOAD_TEXTURE2D_X_LOD(_InputTexture, uv, 0).xyz;
float3 inputColor = LinearToSRGB(rgb);
float d = distance(RGB2YCgCo(inputColor).yz, keyColorYCoCg.yz) * 10 ;
return smoothstep(_KeyParams.x, _KeyParams.x + _KeyParams.y, d);
}
float4 CustomPostProcess(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
uint2 positionSS = input.texcoord * _ScreenSize.xy;
float3 outColor = LOAD_TEXTURE2D_X_LOD(_InputTexture, positionSS, 0).xyz;
float3 keyColorYCoCg = RGB2YCgCo(_KeyColor);
// Calculate keys for surrounding four points and get the minima of them.
// This works like a blur and dilate filter.
float4 duv = _ScreenSize.zwzw * float4(-0.5, -0.5, 0.5, 0.5);
float alpha = ChromaKeyAt(keyColorYCoCg, positionSS + duv.xy);
alpha = min(alpha, ChromaKeyAt(keyColorYCoCg, positionSS + duv.zy));
alpha = min(alpha, ChromaKeyAt(keyColorYCoCg, positionSS + duv.xw));
alpha = min(alpha, ChromaKeyAt(keyColorYCoCg, positionSS + duv.zw));
if (_KeyParams.z > 0)
{
// Spill removal
// What the following lines do is flattening the CgCo chroma values
// so that dot(ycgco, _KeyCgCo) == 0.5. This shifts colors toward
// the anticolor of the key color.
outColor = RGB2YCgCo(LinearToSRGB(outColor));
float sub = dot(keyColorYCoCg.yz, outColor.yz) / dot(keyColorYCoCg.yz, keyColorYCoCg.yz);
outColor.yz -= keyColorYCoCg.yz * (sub + 0.5) * _KeyParams.z;
outColor = SRGBToLinear(YCgCo2RGB(outColor));
}
return float4(outColor, alpha);
}
ENDHLSL
SubShader
{
Tags{ "RenderPipeline" = "HDRenderPipeline" }
Pass
{
Name "ChromaKeying"
ZWrite Off
ZTest Always
Blend Off
Cull Off
HLSLPROGRAM
#pragma fragment CustomPostProcess
#pragma vertex Vert
ENDHLSL
}
}
Fallback Off
}