Update
This commit is contained in:
79
apps/LoopThroughWithOpenGLCompositing/video_effect.slang
Normal file
79
apps/LoopThroughWithOpenGLCompositing/video_effect.slang
Normal file
@@ -0,0 +1,79 @@
|
||||
// Source-of-truth shader in Slang.
|
||||
// The current OpenGL sample still runs the checked-in GLSL fallback because it uses
|
||||
// legacy fixed-function texture coordinates in its fragment stage.
|
||||
|
||||
struct FragmentInput
|
||||
{
|
||||
float4 position : SV_Position;
|
||||
float2 texCoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
Texture2D<float4> UYVYtex;
|
||||
|
||||
float4 rec709YCbCr2rgba(float Y, float Cb, float Cr, float a)
|
||||
{
|
||||
Y = (Y * 256.0 - 16.0) / 219.0;
|
||||
Cb = (Cb * 256.0 - 16.0) / 224.0 - 0.5;
|
||||
Cr = (Cr * 256.0 - 16.0) / 224.0 - 0.5;
|
||||
|
||||
float r = Y + 1.5748 * Cr;
|
||||
float g = Y - 0.1873 * Cb - 0.4681 * Cr;
|
||||
float b = Y + 1.8556 * Cb;
|
||||
return float4(r, g, b, a);
|
||||
}
|
||||
|
||||
float4 bilinear(float4 W, float4 X, float4 Y, float4 Z, float2 weight)
|
||||
{
|
||||
float4 m0 = lerp(W, Z, weight.x);
|
||||
float4 m1 = lerp(X, Y, weight.x);
|
||||
return lerp(m0, m1, weight.y);
|
||||
}
|
||||
|
||||
void textureGatherYUV(Texture2D<float4> textureSampler, float2 tc, out float4 W, out float4 X, out float4 Y, out float4 Z)
|
||||
{
|
||||
uint width = 0;
|
||||
uint height = 0;
|
||||
textureSampler.GetDimensions(width, height);
|
||||
|
||||
int2 tx = int2(tc * float2(width, height));
|
||||
int2 tmin = int2(0, 0);
|
||||
int2 tmax = int2(int(width), int(height)) - int2(1, 1);
|
||||
|
||||
W = textureSampler.Load(int3(tx, 0));
|
||||
X = textureSampler.Load(int3(clamp(tx + int2(0, 1), tmin, tmax), 0));
|
||||
Y = textureSampler.Load(int3(clamp(tx + int2(1, 1), tmin, tmax), 0));
|
||||
Z = textureSampler.Load(int3(clamp(tx + int2(1, 0), tmin, tmax), 0));
|
||||
}
|
||||
|
||||
[shader("fragment")]
|
||||
float4 fragmentMain(FragmentInput input) : SV_Target
|
||||
{
|
||||
float2 tc = input.texCoord;
|
||||
float alpha = 0.7;
|
||||
|
||||
float4 macro, macroU, macroR, macroUR;
|
||||
float4 pixel, pixelR, pixelU, pixelUR;
|
||||
textureGatherYUV(UYVYtex, tc, macro, macroU, macroUR, macroR);
|
||||
|
||||
uint width = 0;
|
||||
uint height = 0;
|
||||
UYVYtex.GetDimensions(width, height);
|
||||
|
||||
float2 off = frac(tc * float2(width, height));
|
||||
if (off.x > 0.5)
|
||||
{
|
||||
pixel = rec709YCbCr2rgba(macro.a, macro.b, macro.r, alpha);
|
||||
pixelR = rec709YCbCr2rgba(macroR.g, macroR.b, macroR.r, alpha);
|
||||
pixelU = rec709YCbCr2rgba(macroU.a, macroU.b, macroU.r, alpha);
|
||||
pixelUR = rec709YCbCr2rgba(macroUR.g, macroUR.b, macroUR.r, alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
pixel = rec709YCbCr2rgba(macro.g, macro.b, macro.r, alpha);
|
||||
pixelR = rec709YCbCr2rgba(macro.a, macro.b, macro.r, alpha);
|
||||
pixelU = rec709YCbCr2rgba(macroU.g, macroU.b, macroU.r, alpha);
|
||||
pixelUR = rec709YCbCr2rgba(macroU.a, macroU.b, macroU.r, alpha);
|
||||
}
|
||||
|
||||
return bilinear(pixel, pixelU, pixelUR, pixelR, off);
|
||||
}
|
||||
Reference in New Issue
Block a user