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 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 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 RTEXT "Settings.Video.Downscale",IDC_STATIC,4,61,138,8
COMBOBOX IDC_DOWNSCALE,144,59,151,126,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_DOWNSCALE,144,59,144,126,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
RTEXT "Settings.Video.FPS",IDC_STATIC,4,80,138,8 RTEXT "Settings.Video.Filter",IDC_STATIC,4,78,138,8
EDITTEXT IDC_FPS_EDIT,144,77,40,14,ES_AUTOHSCROLL | ES_NUMBER COMBOBOX IDC_FILTER,144,76,234,126,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "",IDC_FPS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,185,77,10,14 RTEXT "Settings.Video.FPS",IDC_STATIC,4,96,138,8
LTEXT "Settings.Info",IDC_INFO,7,117,418,37,NOT WS_VISIBLE EDITTEXT IDC_FPS_EDIT,144,93,40,14,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "Settings.Video.DisableAero",IDC_DISABLEAERO,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,4,96,149,10,WS_EX_RIGHT 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 END
IDD_SETTINGS_GENERAL DIALOGEX 0, 0, 427, 336 IDD_SETTINGS_GENERAL DIALOGEX 0, 0, 427, 336

View File

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

View File

@ -139,6 +139,7 @@ void OBS::Start()
int defCX = screenRect.right - screenRect.left; int defCX = screenRect.right - screenRect.left;
int defCY = screenRect.bottom - screenRect.top; int defCY = screenRect.bottom - screenRect.top;
downscaleType = AppConfig->GetInt(TEXT("Video"), TEXT("Filter"), 0);
downscale = AppConfig->GetFloat(TEXT("Video"), TEXT("Downscale"), 1.0f); downscale = AppConfig->GetFloat(TEXT("Video"), TEXT("Downscale"), 1.0f);
baseCX = AppConfig->GetInt(TEXT("Video"), TEXT("BaseWidth"), defCX); baseCX = AppConfig->GetInt(TEXT("Video"), TEXT("BaseWidth"), defCX);
baseCY = AppConfig->GetInt(TEXT("Video"), TEXT("BaseHeight"), defCY); 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)) if(CloseFloat(downscale, 1.0))
lpShader = TEXT("shaders/DrawYUVTexture.pShader"); lpShader = TEXT("shaders/DrawYUVTexture.pShader");
else if(CloseFloat(downscale, 1.5)) else if(downscale < 2.01)
lpShader = TEXT("shaders/DownscaleYUV1.5.pShader"); {
else if(CloseFloat(downscale, 2.0)) switch(downscaleType)
lpShader = TEXT("shaders/DownscaleYUV2.pShader"); {
else if(CloseFloat(downscale, 2.25)) case 0: lpShader = TEXT("shaders/DownscaleBilinear1YUV.pShader"); break;
lpShader = TEXT("shaders/DownscaleYUV2.25.pShader"); case 1: lpShader = TEXT("shaders/DownscaleBicubicYUV.pShader"); break;
else if(CloseFloat(downscale, 3.0)) case 2: lpShader = TEXT("shaders/DownscaleLanczos6tapYUV.pShader"); break;
lpShader = TEXT("shaders/DownscaleYUV3.pShader"); }
}
else if(downscale < 3.01)
lpShader = TEXT("shaders/DownscaleBilinear9YUV.pShader");
else else
CrashError(TEXT("Invalid downscale value (must be either 1.0, 1.5, 2.0, 2.25, or 3.0)")); 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) 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 // 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 else
SetViewport(0.0f, 0.0f, renderFrameCtrlSize.x, renderFrameCtrlSize.y); SetViewport(0.0f, 0.0f, renderFrameCtrlSize.x, renderFrameCtrlSize.y);
@ -653,7 +653,10 @@ void OBS::MainCaptureLoop()
Texture *yuvRenderTexture = yuvRenderTextures[curRenderTarget]; Texture *yuvRenderTexture = yuvRenderTextures[curRenderTarget];
SetRenderTarget(yuvRenderTexture); SetRenderTarget(yuvRenderTexture);
if(downscale < 2.01)
yuvScalePixelShader->SetVector2(hScaleVal, 1.0f/baseSize); 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); Ortho(0.0f, outputSize.x, outputSize.y, 0.0f, -100.0f, 100.0f);
SetViewport(0.0f, 0.0f, outputSize.x, outputSize.y); SetViewport(0.0f, 0.0f, outputSize.x, outputSize.y);
@ -664,11 +667,11 @@ void OBS::MainCaptureLoop()
if(bTransitioning) if(bTransitioning)
{ {
BlendFunction(GS_BLEND_ONE, GS_BLEND_ZERO); 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); 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: private:
void RefreshDownscales(HWND hwnd, int cx, int cy); void RefreshDownscales(HWND hwnd, int cx, int cy);
void RefreshFilters(HWND hwndParent, bool bGetConfig);
public: public:
// Interface // Interface

View File

@ -52,8 +52,8 @@ LRESULT WINAPI ResolutionEditSubclassProc(HWND hwnd, UINT message, WPARAM wParam
return CallWindowProc((WNDPROC)editProc, hwnd, message, wParam, lParam); return CallWindowProc((WNDPROC)editProc, hwnd, message, wParam, lParam);
} }
const int multiplierCount = 5; const int multiplierCount = 9;
const float downscaleMultipliers[multiplierCount] = {1.0f, 1.5f, 2.0f, 2.25f, 3.0f}; const float downscaleMultipliers[multiplierCount] = {1.0f, 1.25f, 1.5f, 1.75f, 2.0f, 2.25f, 2.5f, 2.75f, 3.0f};
//============================================================================ //============================================================================
// SettingsVideo class // SettingsVideo class
@ -132,6 +132,41 @@ void SettingsVideo::RefreshDownscales(HWND hwnd, int cx, int cy)
SendMessage(hwnd, CB_SETCURSEL, lastID, 0); 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() void SettingsVideo::ApplySettings()
{ {
int curSel = (int)SendMessage(GetDlgItem(hwnd, IDC_MONITOR), CB_GETCURSEL, 0, 0); int curSel = (int)SendMessage(GetDlgItem(hwnd, IDC_MONITOR), CB_GETCURSEL, 0, 0);
@ -157,6 +192,10 @@ void SettingsVideo::ApplySettings()
if(curSel != CB_ERR) if(curSel != CB_ERR)
AppConfig->SetFloat(TEXT("Video"), TEXT("Downscale"), downscaleMultipliers[curSel]); 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); int gammaVal = (int)SendMessage(GetDlgItem(hwnd, IDC_GAMMA), TBM_GETPOS, 0, 0);
AppConfig->SetInt(TEXT("Video"), TEXT("Gamma"), gammaVal); 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); ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_HIDE);
SetChangedSettings(false); SetChangedSettings(false);
@ -396,10 +439,18 @@ INT_PTR SettingsVideo::ProcMessage(UINT message, WPARAM wParam, LPARAM lParam)
bDataChanged = true; bDataChanged = true;
break; break;
case IDC_DOWNSCALE: case IDC_FILTER:
if(HIWORD(wParam) == CBN_SELCHANGE) if(HIWORD(wParam) == CBN_SELCHANGE)
bDataChanged = true; bDataChanged = true;
break; break;
case IDC_DOWNSCALE:
if(HIWORD(wParam) == CBN_SELCHANGE)
{
bDataChanged = true;
RefreshFilters(hwnd, false);
}
break;
} }
if(bDataChanged) if(bDataChanged)

View File

@ -48,6 +48,8 @@
#define IDC_BINDIP 1014 #define IDC_BINDIP 1014
#define IDC_MAXBITRATE 1015 #define IDC_MAXBITRATE 1015
#define IDC_COLORPICKER 1015 #define IDC_COLORPICKER 1015
#define IDC_DOWNSCALE2 1015
#define IDC_FILTER 1015
#define IDC_BUFFERSIZE 1016 #define IDC_BUFFERSIZE 1016
#define IDC_AUDIOCODEC 1017 #define IDC_AUDIOCODEC 1017
#define IDC_USECOLORKEY 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.DisableAeroTooltip "Disabling Aero is recommended if using software monitor capture"
Settings.Video.Downscale "Resolution Downscale:" Settings.Video.Downscale "Resolution Downscale:"
Settings.Video.DownscaleTooltip "Downscale can improve video quality at the cost of resolution." Settings.Video.DownscaleTooltip "Downscale can improve video quality at the cost of resolution."
Settings.Video.Filter "Filter:"
Settings.Video.FPS "FPS:" Settings.Video.FPS "FPS:"
Settings.Video.Monitor "Monitor:" Settings.Video.Monitor "Monitor:"
Settings.Video.Resolution "Base Resolution:" 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.BitmapSource "Image"
Sources.GameCaptureSource "Game Capture" Sources.GameCaptureSource "Game Capture"
Sources.GlobalSource "Global Source" 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 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 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 float4 main(VertData input) : SV_Target
{ {
float2 texAdjust = (input.texCoord-0.5)*2.0;
float2 floorVal = floor(texAdjust+0.001);
float4 rgba; float4 rgba;
rgba = diffuseTexture.Sample(textureSampler, (floorVal+float2(0.5f, 0.5f)) * baseDimensionI); rgba.rgb = diffuseTexture.Sample(textureSampler, input.texCoord);
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(1.5f, 0.5f)) * baseDimensionI); rgba.a = 1.0;
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;
const float4x4 yuvMat = {0.257, -0.148, 0.439, 0.0, const float4x4 yuvMat = {0.257, -0.148, 0.439, 0.0,
0.504, -0.291, -0.368, 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 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 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 Texture2D diffuseTexture;
uniform float2 baseDimensionI; uniform float2 baseDimensionI;
@ -37,28 +35,24 @@ struct VertData
float4 main(VertData input) : SV_Target float4 main(VertData input) : SV_Target
{ {
float2 texAdjust = (input.texCoord-0.5)*1.5; float2 texCoord = input.texCoord;
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 adjust = baseDimensionI;
float4 rgba; float4 rgba;
rgba = diffuseTexture.Sample(textureSampler, (floorVal+float2(0.5, 0.5)) * baseDimensionI) * pixelMat._11; rgba.rgb = diffuseTexture.Sample(textureSampler, texCoord).rgb;
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(1.5, 0.5)) * baseDimensionI) * pixelMat._12; rgba.rgb += diffuseTexture.Sample(textureSampler, texCoord + float2(-adjust.x, -adjust.y)).rgb;
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(0.5, 1.5)) * baseDimensionI) * pixelMat._21; rgba.rgb += diffuseTexture.Sample(textureSampler, texCoord + float2(-adjust.x, 0.0)).rgb;
rgba += diffuseTexture.Sample(textureSampler, (floorVal+float2(1.5, 1.5)) * baseDimensionI) * pixelMat._22; rgba.rgb += diffuseTexture.Sample(textureSampler, texCoord + float2(-adjust.x, adjust.y)).rgb;
rgba /= 2.25; 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, const float4x4 yuvMat = {0.257, -0.148, 0.439, 0.0,
0.504, -0.291, -0.368, 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);
}