forked from BilalY/Rasagar
126 lines
4.1 KiB
Plaintext
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
|
|
}
|