Added bicubic and lanczos downscale shaders, optimized existing bilinear downscale shaders

This commit is contained in:
jp9000 2013-03-20 17:10:05 -07:00
parent 10b43836bf
commit 3cd334b61e
14 changed files with 306 additions and 217 deletions

14
OBS.rc
View File

@ -139,12 +139,14 @@ BEGIN
CONTROL "Settings.Video.Monitor",IDC_USEMONITOR,"Button",BS_AUTORADIOBUTTON,22,31,116,10
COMBOBOX IDC_MONITOR,144,30,36,126,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
RTEXT "Settings.Video.Downscale",IDC_STATIC,4,61,138,8
COMBOBOX IDC_DOWNSCALE,144,59,151,126,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
RTEXT "Settings.Video.FPS",IDC_STATIC,4,80,138,8
EDITTEXT IDC_FPS_EDIT,144,77,40,14,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_FPS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,185,77,10,14
LTEXT "Settings.Info",IDC_INFO,7,117,418,37,NOT WS_VISIBLE
CONTROL "Settings.Video.DisableAero",IDC_DISABLEAERO,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,4,96,149,10,WS_EX_RIGHT
COMBOBOX IDC_DOWNSCALE,144,59,144,126,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
RTEXT "Settings.Video.Filter",IDC_STATIC,4,78,138,8
COMBOBOX IDC_FILTER,144,76,234,126,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
RTEXT "Settings.Video.FPS",IDC_STATIC,4,96,138,8
EDITTEXT IDC_FPS_EDIT,144,93,40,14,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_FPS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,185,93,10,14
LTEXT "Settings.Info",IDC_INFO,7,133,418,37,NOT WS_VISIBLE
CONTROL "Settings.Video.DisableAero",IDC_DISABLEAERO,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,4,112,149,10,WS_EX_RIGHT
END
IDD_SETTINGS_GENERAL DIALOGEX 0, 0, 427, 336

View File

@ -536,6 +536,7 @@ private:
UINT scaleCX, scaleCY;
UINT outputCX, outputCY;
float downscale;
int downscaleType;
UINT frameTime, fps;
bool bUsing444;

View File

@ -139,6 +139,7 @@ void OBS::Start()
int defCX = screenRect.right - screenRect.left;
int defCY = screenRect.bottom - screenRect.top;
downscaleType = AppConfig->GetInt(TEXT("Video"), TEXT("Filter"), 0);
downscale = AppConfig->GetFloat(TEXT("Video"), TEXT("Downscale"), 1.0f);
baseCX = AppConfig->GetInt(TEXT("Video"), TEXT("BaseWidth"), defCX);
baseCY = AppConfig->GetInt(TEXT("Video"), TEXT("BaseHeight"), defCY);
@ -179,17 +180,20 @@ void OBS::Start()
//------------------------------------------------------------------
CTSTR lpShader = NULL;
CTSTR lpShader;
if(CloseFloat(downscale, 1.0))
lpShader = TEXT("shaders/DrawYUVTexture.pShader");
else if(CloseFloat(downscale, 1.5))
lpShader = TEXT("shaders/DownscaleYUV1.5.pShader");
else if(CloseFloat(downscale, 2.0))
lpShader = TEXT("shaders/DownscaleYUV2.pShader");
else if(CloseFloat(downscale, 2.25))
lpShader = TEXT("shaders/DownscaleYUV2.25.pShader");
else if(CloseFloat(downscale, 3.0))
lpShader = TEXT("shaders/DownscaleYUV3.pShader");
else if(downscale < 2.01)
{
switch(downscaleType)
{
case 0: lpShader = TEXT("shaders/DownscaleBilinear1YUV.pShader"); break;
case 1: lpShader = TEXT("shaders/DownscaleBicubicYUV.pShader"); break;
case 2: lpShader = TEXT("shaders/DownscaleLanczos6tapYUV.pShader"); break;
}
}
else if(downscale < 3.01)
lpShader = TEXT("shaders/DownscaleBilinear9YUV.pShader");
else
CrashError(TEXT("Invalid downscale value (must be either 1.0, 1.5, 2.0, 2.25, or 3.0)"));

View File

@ -602,7 +602,7 @@ void OBS::MainCaptureLoop()
if(renderFrameCtrlSize.x != oldRenderFrameCtrlWidth || renderFrameCtrlSize.y != oldRenderFrameCtrlHeight)
{
// User is drag resizing the window. We don't recreate the swap chains so our coordinates are wrong
SetViewport(0.0f, 0.0f, oldRenderFrameCtrlWidth, oldRenderFrameCtrlHeight);
SetViewport(0.0f, 0.0f, (float)oldRenderFrameCtrlWidth, (float)oldRenderFrameCtrlHeight);
}
else
SetViewport(0.0f, 0.0f, renderFrameCtrlSize.x, renderFrameCtrlSize.y);
@ -653,7 +653,10 @@ void OBS::MainCaptureLoop()
Texture *yuvRenderTexture = yuvRenderTextures[curRenderTarget];
SetRenderTarget(yuvRenderTexture);
if(downscale < 2.01)
yuvScalePixelShader->SetVector2(hScaleVal, 1.0f/baseSize);
else if(downscale < 3.01)
yuvScalePixelShader->SetVector2(hScaleVal, 1.0f/(outputSize*3.0f));
Ortho(0.0f, outputSize.x, outputSize.y, 0.0f, -100.0f, 100.0f);
SetViewport(0.0f, 0.0f, outputSize.x, outputSize.y);
@ -664,11 +667,11 @@ void OBS::MainCaptureLoop()
if(bTransitioning)
{
BlendFunction(GS_BLEND_ONE, GS_BLEND_ZERO);
DrawSpriteEx(transitionTexture, 0xFFFFFFFF, 0.0f, 0.0f, scaleSize.x, scaleSize.y, 0.0f, 0.0f, scaleSize.x, scaleSize.y);
DrawSpriteEx(transitionTexture, 0xFFFFFFFF, 0.0f, 0.0f, scaleSize.x, scaleSize.y, 0.0f, 0.0f, 1.0f, 1.0f);
BlendFunction(GS_BLEND_FACTOR, GS_BLEND_INVFACTOR, transitionAlpha);
}
DrawSpriteEx(mainRenderTextures[curRenderTarget], 0xFFFFFFFF, 0.0f, 0.0f, outputSize.x, outputSize.y, 0.0f, 0.0f, outputSize.x, outputSize.y);
DrawSpriteEx(mainRenderTextures[curRenderTarget], 0xFFFFFFFF, 0.0f, 0.0f, outputSize.x, outputSize.y, 0.0f, 0.0f, 1.0f, 1.0f);
//------------------------------------

View File

@ -140,6 +140,7 @@ public:
private:
void RefreshDownscales(HWND hwnd, int cx, int cy);
void RefreshFilters(HWND hwndParent, bool bGetConfig);
public:
// Interface

View File

@ -52,8 +52,8 @@ LRESULT WINAPI ResolutionEditSubclassProc(HWND hwnd, UINT message, WPARAM wParam
return CallWindowProc((WNDPROC)editProc, hwnd, message, wParam, lParam);
}
const int multiplierCount = 5;
const float downscaleMultipliers[multiplierCount] = {1.0f, 1.5f, 2.0f, 2.25f, 3.0f};
const int multiplierCount = 9;
const float downscaleMultipliers[multiplierCount] = {1.0f, 1.25f, 1.5f, 1.75f, 2.0f, 2.25f, 2.5f, 2.75f, 3.0f};
//============================================================================
// SettingsVideo class
@ -132,6 +132,41 @@ void SettingsVideo::RefreshDownscales(HWND hwnd, int cx, int cy)
SendMessage(hwnd, CB_SETCURSEL, lastID, 0);
}
void SettingsVideo::RefreshFilters(HWND hwndParent, bool bGetConfig)
{
HWND hwndFilter = GetDlgItem(hwndParent, IDC_FILTER);
HWND hwndDownscale = GetDlgItem(hwndParent, IDC_DOWNSCALE);
int curFilter;
if(bGetConfig)
curFilter = AppConfig->GetInt(TEXT("Video"), TEXT("Filter"), 0);
else
curFilter = (int)SendMessage(GetDlgItem(hwnd, IDC_FILTER), CB_GETCURSEL, 0, 0);
float downscale = 1.0f;
int curSel = (int)SendMessage(GetDlgItem(hwnd, IDC_DOWNSCALE), CB_GETCURSEL, 0, 0);
if(curSel != CB_ERR)
downscale = downscaleMultipliers[curSel];
SendMessage(hwndFilter, CB_RESETCONTENT, 0, 0);
if(downscale < 2.01)
{
SendMessage(hwndFilter, CB_ADDSTRING, 0, (LPARAM)Str("Settings.Video.Filter.Bilinear"));
SendMessage(hwndFilter, CB_ADDSTRING, 0, (LPARAM)Str("Settings.Video.Filter.Bicubic"));
SendMessage(hwndFilter, CB_ADDSTRING, 0, (LPARAM)Str("Settings.Video.Filter.Lanczos"));
SendMessage(hwndFilter, CB_SETCURSEL, curFilter, 0);
}
else
{
SendMessage(hwndFilter, CB_ADDSTRING, 0, (LPARAM)Str("Settings.Video.Filter.Bilinear"));
SendMessage(hwndFilter, CB_SETCURSEL, 0, 0);
}
EnableWindow(hwndFilter, (downscale > 1.01));
}
void SettingsVideo::ApplySettings()
{
int curSel = (int)SendMessage(GetDlgItem(hwnd, IDC_MONITOR), CB_GETCURSEL, 0, 0);
@ -157,6 +192,10 @@ void SettingsVideo::ApplySettings()
if(curSel != CB_ERR)
AppConfig->SetFloat(TEXT("Video"), TEXT("Downscale"), downscaleMultipliers[curSel]);
curSel = (int)SendMessage(GetDlgItem(hwnd, IDC_FILTER), CB_GETCURSEL, 0, 0);
if(curSel == CB_ERR) curSel = 0;
AppConfig->SetInt(TEXT("Video"), TEXT("Filter"), curSel);
int gammaVal = (int)SendMessage(GetDlgItem(hwnd, IDC_GAMMA), TBM_GETPOS, 0, 0);
AppConfig->SetInt(TEXT("Video"), TEXT("Gamma"), gammaVal);
@ -297,6 +336,10 @@ INT_PTR SettingsVideo::ProcMessage(UINT message, WPARAM wParam, LPARAM lParam)
//--------------------------------------------
RefreshFilters(hwnd, true);
//--------------------------------------------
ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_HIDE);
SetChangedSettings(false);
@ -396,10 +439,18 @@ INT_PTR SettingsVideo::ProcMessage(UINT message, WPARAM wParam, LPARAM lParam)
bDataChanged = true;
break;
case IDC_DOWNSCALE:
case IDC_FILTER:
if(HIWORD(wParam) == CBN_SELCHANGE)
bDataChanged = true;
break;
case IDC_DOWNSCALE:
if(HIWORD(wParam) == CBN_SELCHANGE)
{
bDataChanged = true;
RefreshFilters(hwnd, false);
}
break;
}
if(bDataChanged)

View File

@ -48,6 +48,8 @@
#define IDC_BINDIP 1014
#define IDC_MAXBITRATE 1015
#define IDC_COLORPICKER 1015
#define IDC_DOWNSCALE2 1015
#define IDC_FILTER 1015
#define IDC_BUFFERSIZE 1016
#define IDC_AUDIOCODEC 1017
#define IDC_USECOLORKEY 1017

View File

@ -196,10 +196,15 @@ Settings.Video.DisableAero "Disable Aero at startup:"
Settings.Video.DisableAeroTooltip "Disabling Aero is recommended if using software monitor capture"
Settings.Video.Downscale "Resolution Downscale:"
Settings.Video.DownscaleTooltip "Downscale can improve video quality at the cost of resolution."
Settings.Video.Filter "Filter:"
Settings.Video.FPS "FPS:"
Settings.Video.Monitor "Monitor:"
Settings.Video.Resolution "Base Resolution:"
Settings.Video.Filter.Bilinear "Bilinear (fastest)"
Settings.Video.Filter.Bicubic "Bicubic sharper (good detail, 16 samples)"
Settings.Video.Filter.Lanczos "Lanczos (best detail, 36 samples)"
Sources.BitmapSource "Image"
Sources.GameCaptureSource "Game Capture"
Sources.GlobalSource "Global Source"

View File

@ -0,0 +1,91 @@
uniform Texture2D diffuseTexture;
uniform float2 baseDimensionI;
SamplerState textureSampler
{
AddressU = Clamp;
AddressV = Clamp;
Filter = Linear;
};
struct VertData
{
float4 pos : SV_Position;
float2 texCoord : TexCoord0;
};
float weight(float x)
{
float ax = abs(x);
// Sharper version.
// May look better in some cases.
const float B = 0.0;
const float C = 0.75;
if (ax < 1.0)
return (pow(x, 2.0) * ((12.0 - 9.0 * B - 6.0 * C) * ax + (-18.0 + 12.0 * B + 6.0 * C)) + (6.0 - 2.0 * B)) / 6.0;
else if ((ax >= 1.0) && (ax < 2.0))
return (pow(x, 2.0) * ((-B - 6.0 * C) * ax + (6.0 * B + 30.0 * C)) + (-12.0 * B - 48.0 * C) * ax + (8.0 * B + 24.0 * C)) / 6.0;
else
return 0.0;
}
float4 weight4(float x)
{
return float4(
weight(x - 2.0),
weight(x - 1.0),
weight(x),
weight(x + 1.0));
}
float3 pixel(float xpos, float ypos)
{
return diffuseTexture.Sample(textureSampler, float2(xpos, ypos)).rgb;
}
float3 get_line(float ypos, float4 xpos, float4 linetaps)
{
return
pixel(xpos.r, ypos) * linetaps.r +
pixel(xpos.g, ypos) * linetaps.g +
pixel(xpos.b, ypos) * linetaps.b +
pixel(xpos.a, ypos) * linetaps.a;
}
float4 main(VertData input) : SV_Target
{
float2 stepxy = baseDimensionI;
float2 pos = input.texCoord + stepxy * 0.5;
float2 f = frac(pos / stepxy);
float4 linetaps = weight4(1.0 - f.x);
float4 columntaps = weight4(1.0 - f.y);
//make sure all taps added together is exactly 1.0, otherwise some (very small) distortion can occur
linetaps /= linetaps.r + linetaps.g + linetaps.b + linetaps.a;
columntaps /= columntaps.r + columntaps.g + columntaps.b + columntaps.a;
float2 xystart = (-1.5 - f) * stepxy + pos;
float4 xpos = float4(xystart.x, xystart.x + stepxy.x, xystart.x + stepxy.x * 2.0, xystart.x + stepxy.x * 3.0);
float4 rgba;
rgba.rgb =
get_line(xystart.y , xpos, linetaps) * columntaps.r +
get_line(xystart.y + stepxy.y , xpos, linetaps) * columntaps.g +
get_line(xystart.y + stepxy.y * 2.0, xpos, linetaps) * columntaps.b +
get_line(xystart.y + stepxy.y * 3.0, xpos, linetaps) * columntaps.a;
rgba.a = 1.0;
//-------------------------------------------------------------
const float4x4 yuvMat = {0.257, -0.148, 0.439, 0.0,
0.504, -0.291, -0.368, 0.0,
0.098, 0.439, -0.071, 0.0,
0.0625, 0.50, 0.50, 1.0};
//a nice quick colorspace conversion
float4 yuvx = mul(float4(rgba.rgb, 1.0), yuvMat);
return float4(saturate(yuvx.zxy), rgba.a);
}

View File

@ -1,5 +1,5 @@
/********************************************************************************
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
Copyright (C) 2013 Hugh Bailey <obs.jim@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -35,15 +35,11 @@ struct VertData
float4 main(VertData input) : SV_Target
{
float2 texAdjust = (input.texCoord-0.5)*2.0;
float2 floorVal = floor(texAdjust+0.001);
float4 rgba;
rgba = diffuseTexture.Sample(textureSampler, (floorVal+float2(0.5f, 0.5f)) * baseDimensionI);
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(1.5f, 0.5f)) * baseDimensionI);
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(0.5f, 1.5f)) * baseDimensionI);
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(1.5f, 1.5f)) * baseDimensionI);
rgba *= 0.25;
rgba.rgb = diffuseTexture.Sample(textureSampler, input.texCoord);
rgba.a = 1.0;
//-------------------------------------------------------------
const float4x4 yuvMat = {0.257, -0.148, 0.439, 0.0,
0.504, -0.291, -0.368, 0.0,

View File

@ -1,5 +1,5 @@
/********************************************************************************
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
Copyright (C) 2013 Hugh Bailey <obs.jim@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -17,8 +17,6 @@
********************************************************************************/
//1.5 downscale requires kind of a lot of sampling, more sampling than there are pixels on the base texture
uniform Texture2D diffuseTexture;
uniform float2 baseDimensionI;
@ -37,28 +35,24 @@ struct VertData
float4 main(VertData input) : SV_Target
{
float2 texAdjust = (input.texCoord-0.5)*1.5;
float2 floorVal = floor(texAdjust+0.001);
float2 offset = (texAdjust-floorVal);
float2x2 pixelMat = {1.0, 1.0, 1.0, 1.0};
if(offset.x > 0.4)
pixelMat._11_21 = 0.5;
else
pixelMat._12_22 = 0.5;
if(offset.y > 0.4)
pixelMat._11_12 *= 0.5;
else
pixelMat._21_22 *= 0.5;
float2 texCoord = input.texCoord;
float2 adjust = baseDimensionI;
float4 rgba;
rgba = diffuseTexture.Sample(textureSampler, (floorVal+float2(0.5, 0.5)) * baseDimensionI) * pixelMat._11;
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(1.5, 0.5)) * baseDimensionI) * pixelMat._12;
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(0.5, 1.5)) * baseDimensionI) * pixelMat._21;
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(1.5, 1.5)) * baseDimensionI) * pixelMat._22;
rgba /= 2.25;
rgba.rgb = diffuseTexture.Sample(textureSampler, texCoord).rgb;
rgba.rgb += diffuseTexture.Sample(textureSampler, texCoord + float2(-adjust.x, -adjust.y)).rgb;
rgba.rgb += diffuseTexture.Sample(textureSampler, texCoord + float2(-adjust.x, 0.0)).rgb;
rgba.rgb += diffuseTexture.Sample(textureSampler, texCoord + float2(-adjust.x, adjust.y)).rgb;
rgba.rgb += diffuseTexture.Sample(textureSampler, texCoord + float2( 0.0, -adjust.y)).rgb;
rgba.rgb += diffuseTexture.Sample(textureSampler, texCoord + float2( 0.0, adjust.y)).rgb;
rgba.rgb += diffuseTexture.Sample(textureSampler, texCoord + float2( adjust.x, -adjust.y)).rgb;
rgba.rgb += diffuseTexture.Sample(textureSampler, texCoord + float2( adjust.x, 0.0)).rgb;
rgba.rgb += diffuseTexture.Sample(textureSampler, texCoord + float2( adjust.x, adjust.y)).rgb;
rgba.rgb /= 9.0;
rgba.a = 1.0;
//-------------------------------------------------------------
const float4x4 yuvMat = {0.257, -0.148, 0.439, 0.0,
0.504, -0.291, -0.368, 0.0,

View File

@ -0,0 +1,102 @@
uniform Texture2D diffuseTexture;
uniform float2 baseDimensionI;
SamplerState textureSampler
{
AddressU = Clamp;
AddressV = Clamp;
Filter = Linear;
};
struct VertData
{
float4 pos : SV_Position;
float2 texCoord : TexCoord0;
};
float sinc(float x)
{
const float PIval = 3.1415926535897932384626433832795;
return sin(x * PIval) / (x * PIval);
}
float weight(float x, float radius)
{
float ax = abs(x);
if (x == 0.0)
return 1.0;
else if (ax < radius)
return sinc(x) * sinc(x / radius);
else
return 0.0;
}
float3 weight3(float x)
{
return float3(
weight(x * 2.0 + 0.0 * 2.0 - 3.0, 3.0),
weight(x * 2.0 + 1.0 * 2.0 - 3.0, 3.0),
weight(x * 2.0 + 2.0 * 2.0 - 3.0, 3.0));
}
float3 pixel(float xpos, float ypos)
{
return diffuseTexture.Sample(textureSampler, float2(xpos, ypos)).rgb;
}
float3 get_line(float ypos, float3 xpos1, float3 xpos2, float3 linetaps1, float3 linetaps2)
{
return
pixel(xpos1.r, ypos) * linetaps1.r +
pixel(xpos1.g, ypos) * linetaps2.r +
pixel(xpos1.b, ypos) * linetaps1.g +
pixel(xpos2.r, ypos) * linetaps2.g +
pixel(xpos2.g, ypos) * linetaps1.b +
pixel(xpos2.b, ypos) * linetaps2.b;
}
float4 main(VertData input) : SV_Target
{
float2 stepxy = baseDimensionI;
float2 pos = input.texCoord + stepxy * 0.5;
float2 f = frac(pos / stepxy);
float3 linetaps1 = weight3((1.0 - f.x) / 2.0);
float3 linetaps2 = weight3((1.0 - f.x) / 2.0 + 0.5);
float3 columntaps1 = weight3((1.0 - f.y) / 2.0);
float3 columntaps2 = weight3((1.0 - f.y) / 2.0 + 0.5);
//make sure all taps added together is exactly 1.0, otherwise some (very small) distortion can occur
float suml = linetaps1.r + linetaps1.g + linetaps1.b + linetaps2.r + linetaps2.g + linetaps2.b;
float sumc = columntaps1.r + columntaps1.g + columntaps1.b + columntaps2.r + columntaps2.g + columntaps2.b;
linetaps1 /= suml;
linetaps2 /= suml;
columntaps1 /= sumc;
columntaps2 /= sumc;
float2 xystart = (-2.5 - f) * stepxy + pos;
float3 xpos1 = float3(xystart.x, xystart.x + stepxy.x, xystart.x + stepxy.x * 2.0);
float3 xpos2 = float3(xystart.x + stepxy.x * 3.0, xystart.x + stepxy.x * 4.0, xystart.x + stepxy.x * 5.0);
float4 rgba;
rgba.rgb =
get_line(xystart.y , xpos1, xpos2, linetaps1, linetaps2) * columntaps1.r +
get_line(xystart.y + stepxy.y , xpos1, xpos2, linetaps1, linetaps2) * columntaps2.r +
get_line(xystart.y + stepxy.y * 2.0, xpos1, xpos2, linetaps1, linetaps2) * columntaps1.g +
get_line(xystart.y + stepxy.y * 3.0, xpos1, xpos2, linetaps1, linetaps2) * columntaps2.g +
get_line(xystart.y + stepxy.y * 4.0, xpos1, xpos2, linetaps1, linetaps2) * columntaps1.b +
get_line(xystart.y + stepxy.y * 5.0, xpos1, xpos2, linetaps1, linetaps2) * columntaps2.b;
rgba.a = 1.0;
//-------------------------------------------------------------
const float4x4 yuvMat = {0.257, -0.148, 0.439, 0.0,
0.504, -0.291, -0.368, 0.0,
0.098, 0.439, -0.071, 0.0,
0.0625, 0.50, 0.50, 1.0};
//a nice quick colorspace conversion
float4 yuvx = mul(float4(rgba.rgb, 1.0), yuvMat);
return float4(saturate(yuvx.zxy), rgba.a);
}

View File

@ -1,102 +0,0 @@
/********************************************************************************
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
********************************************************************************/
//2.25 is also pretty bad
uniform Texture2D diffuseTexture;
uniform float2 baseDimensionI;
SamplerState textureSampler
{
AddressU = Clamp;
AddressV = Clamp;
Filter = Linear;
};
struct VertData
{
float4 pos : SV_Position;
float2 texCoord : TexCoord0;
};
float4 main(VertData input) : SV_Target
{
float2 texAdjust = (input.texCoord-0.5)*2.25;
float2 floorVal = floor(texAdjust+0.001);
float2 offset = (texAdjust-floorVal);
float3x3 pixelMat =
{
1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, 1.0
};
if(offset.x < 0.25)
pixelMat._13_23_33 = 0.25;
else if(offset.x < 0.5) //0.25
{
pixelMat._11_21_31 = 0.75;
pixelMat._13_23_33 = 0.5;
}
else if(offset.x < 0.75) //0.5
{
pixelMat._11_21_31 = 0.5;
pixelMat._13_23_33 = 0.75;
}
else if(offset.x < 1.0) //0.75
pixelMat._11_21_31 = 0.25;
if(offset.y < 0.25)
pixelMat._31_32_33 *= 0.25;
else if(offset.y < 0.5) //0.25
{
pixelMat._11_12_13 *= 0.75;
pixelMat._31_32_33 *= 0.5;
}
else if(offset.y < 0.75) //0.5
{
pixelMat._11_12_13 *= 0.5;
pixelMat._31_32_33 *= 0.75;
}
else if(offset.y < 1.0) //0.75
pixelMat._11_12_13 *= 0.25;
float4 rgba;
rgba = diffuseTexture.Sample(textureSampler, (floorVal+float2(0.5, 0.5)) * baseDimensionI) * pixelMat._11;
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(1.5, 0.5)) * baseDimensionI) * pixelMat._12;
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(2.5, 0.5)) * baseDimensionI) * pixelMat._13;
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(0.5, 1.5)) * baseDimensionI) * pixelMat._21;
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(1.5, 1.5)) * baseDimensionI) * pixelMat._22;
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(2.5, 1.5)) * baseDimensionI) * pixelMat._23;
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(0.5, 2.5)) * baseDimensionI) * pixelMat._31;
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(1.5, 2.5)) * baseDimensionI) * pixelMat._32;
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(2.5, 2.5)) * baseDimensionI) * pixelMat._33;
rgba /= 5.0625;
const float4x4 yuvMat = {0.257, -0.148, 0.439, 0.0,
0.504, -0.291, -0.368, 0.0,
0.098, 0.439, -0.071, 0.0,
0.0625, 0.50, 0.50, 1.0};
//a nice quick colorspace conversion
float4 yuvx = mul(float4(rgba.rgb, 1.0), yuvMat);
return float4(saturate(yuvx.zxy), rgba.a);
}

View File

@ -1,61 +0,0 @@
/********************************************************************************
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
********************************************************************************/
uniform Texture2D diffuseTexture;
uniform float2 baseDimensionI;
SamplerState textureSampler
{
AddressU = Clamp;
AddressV = Clamp;
Filter = Linear;
};
struct VertData
{
float4 pos : SV_Position;
float2 texCoord : TexCoord0;
};
float4 main(VertData input) : SV_Target
{
float2 texAdjust = (input.texCoord-0.5)*3.0;
float2 floorVal = floor(texAdjust+0.001);
float4 rgba;
rgba = diffuseTexture.Sample(textureSampler, (floorVal+float2(0.5f, 0.5f)) * baseDimensionI);
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(1.5f, 0.5f)) * baseDimensionI);
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(2.5f, 0.5f)) * baseDimensionI);
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(0.5f, 1.5f)) * baseDimensionI);
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(1.5f, 1.5f)) * baseDimensionI);
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(2.5f, 1.5f)) * baseDimensionI);
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(0.5f, 2.5f)) * baseDimensionI);
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(1.5f, 2.5f)) * baseDimensionI);
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(2.5f, 2.5f)) * baseDimensionI);
rgba /= 9.0;
const float4x4 yuvMat = {0.257, -0.148, 0.439, 0.0,
0.504, -0.291, -0.368, 0.0,
0.098, 0.439, -0.071, 0.0,
0.0625, 0.50, 0.50, 1.0};
//a nice quick colorspace conversion
float4 yuvx = mul(float4(rgba.rgb, 1.0), yuvMat);
return float4(saturate(yuvx.zxy), rgba.a);
}