如何使用着色器裁剪 WebcamTexture?
How to crop WebcamTexture with shader?
我有一个在 Unity 2018.3 中完美运行的色键着色器。我需要向着色器添加顶部、底部、左侧、右侧属性,并使用这些参数使不需要的纹理部分透明。这是来自纹理的图像;
所有过程都需要在着色器中完成,因为这是一个网络摄像头纹理,GetPixels()
,Update()
中 mainTexture
的 SetPixels()
非常昂贵。
这是我的着色器代码:
shader "Custom/chroma"
{
Properties{
_MainTex("Base (RGB)", 2D) = "white" {}
_MaskCol("Mask Color", Color) = (1.0, 0.0, 0.0, 1.0)
_Sensitivity("Threshold Sensitivity", Range(0,1)) = 0.5
_Smooth("Smoothing", Range(0,1)) = 0.5
_Top("Top", Range(0,1)) = 0
_Bottom("Bottom", Range(0,1)) = 0
_Left("Left", Range(0,1)) = 0
_Right("Right", Range(0,1)) = 0
}
SubShader{
Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
LOD 100
Lighting Off
ZWrite Off
AlphaTest Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma surface surf Lambert alpha
struct Input {
float2 uv_MainTex;
float4 screenPos;
float3 worldPos;
};
sampler2D _MainTex;
float4 _MaskCol;
float _Sensitivity;
float _Smooth;
float _Top;
float _Bottom;
float _Left;
float _Right;
void surf(Input IN, inout SurfaceOutput o) {
half4 c = tex2D(_MainTex, IN.uv_MainTex);
float maskY = 0.2989 * _MaskCol.r + 0.5866 * _MaskCol.g + 0.1145 * _MaskCol.b;
float maskCr = 0.7132 * (_MaskCol.r - maskY);
float maskCb = 0.5647 * (_MaskCol.b - maskY);
float Y = 0.2989 * c.r + 0.5866 * c.g + 0.1145 * c.b;
float Cr = 0.7132 * (c.r - Y);
float Cb = 0.5647 * (c.b - Y);
float d = abs(length(abs(float2(Cr, Cb) - float2(maskCr, maskCb))));
float edge0 = _Sensitivity * (1 - _Smooth);
float alpha = smoothstep(edge0, _Sensitivity, d);
if (IN.uv_MainTex.x<_Left || IN.uv_MainTex.x>(1-_Right))
{
alpha = 0;
};
if (IN.uv_MainTex.y<_Bottom || IN.uv_MainTex.y>(1 - _Top))
{
alpha = 0;
};
o.Alpha = alpha * 1;
o.Emission = c.rgb * alpha;
}
ENDCG
}
FallBack "Unlit/Texture"
}
IN.uv_MainTex 包含您的标准化屏幕位置。
if (IN.uv_MainTex.x<0.3||IN.uv_MainTex.x>0.8) return float4(0,0,0,0);
会将您的图像裁剪为在 0.3-0.8 范围之外透明 - 您可以对 y 执行相同的操作并通过 material 属性
对两者进行参数化
我有一个在 Unity 2018.3 中完美运行的色键着色器。我需要向着色器添加顶部、底部、左侧、右侧属性,并使用这些参数使不需要的纹理部分透明。这是来自纹理的图像;
所有过程都需要在着色器中完成,因为这是一个网络摄像头纹理,GetPixels()
,Update()
中 mainTexture
的 SetPixels()
非常昂贵。
这是我的着色器代码:
shader "Custom/chroma"
{
Properties{
_MainTex("Base (RGB)", 2D) = "white" {}
_MaskCol("Mask Color", Color) = (1.0, 0.0, 0.0, 1.0)
_Sensitivity("Threshold Sensitivity", Range(0,1)) = 0.5
_Smooth("Smoothing", Range(0,1)) = 0.5
_Top("Top", Range(0,1)) = 0
_Bottom("Bottom", Range(0,1)) = 0
_Left("Left", Range(0,1)) = 0
_Right("Right", Range(0,1)) = 0
}
SubShader{
Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
LOD 100
Lighting Off
ZWrite Off
AlphaTest Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma surface surf Lambert alpha
struct Input {
float2 uv_MainTex;
float4 screenPos;
float3 worldPos;
};
sampler2D _MainTex;
float4 _MaskCol;
float _Sensitivity;
float _Smooth;
float _Top;
float _Bottom;
float _Left;
float _Right;
void surf(Input IN, inout SurfaceOutput o) {
half4 c = tex2D(_MainTex, IN.uv_MainTex);
float maskY = 0.2989 * _MaskCol.r + 0.5866 * _MaskCol.g + 0.1145 * _MaskCol.b;
float maskCr = 0.7132 * (_MaskCol.r - maskY);
float maskCb = 0.5647 * (_MaskCol.b - maskY);
float Y = 0.2989 * c.r + 0.5866 * c.g + 0.1145 * c.b;
float Cr = 0.7132 * (c.r - Y);
float Cb = 0.5647 * (c.b - Y);
float d = abs(length(abs(float2(Cr, Cb) - float2(maskCr, maskCb))));
float edge0 = _Sensitivity * (1 - _Smooth);
float alpha = smoothstep(edge0, _Sensitivity, d);
if (IN.uv_MainTex.x<_Left || IN.uv_MainTex.x>(1-_Right))
{
alpha = 0;
};
if (IN.uv_MainTex.y<_Bottom || IN.uv_MainTex.y>(1 - _Top))
{
alpha = 0;
};
o.Alpha = alpha * 1;
o.Emission = c.rgb * alpha;
}
ENDCG
}
FallBack "Unlit/Texture"
}
IN.uv_MainTex 包含您的标准化屏幕位置。
if (IN.uv_MainTex.x<0.3||IN.uv_MainTex.x>0.8) return float4(0,0,0,0);
会将您的图像裁剪为在 0.3-0.8 范围之外透明 - 您可以对 y 执行相同的操作并通过 material 属性
对两者进行参数化