From 98e9d6d50f446833862ce0786a8a7ccbcd8a3c8c Mon Sep 17 00:00:00 2001 From: Alexandru Macocian Date: Thu, 1 Apr 2021 11:53:42 +0200 Subject: [PATCH] Add project files. --- .gitattributes | 63 ++++ .gitignore | 340 ++++++++++++++++++ WpfExtended.sln | 25 ++ .../Effects/BandedSwirl/BandedSwirl.fx | 65 ++++ .../Effects/BandedSwirl/BandedSwirl.ps | Bin 0 -> 1352 bytes .../Effects/BandedSwirl/BandedSwirlEffect.cs | 62 ++++ WpfExtended/Effects/Bloom/Bloom.fx | 51 +++ WpfExtended/Effects/Bloom/Bloom.ps | Bin 0 -> 592 bytes WpfExtended/Effects/Bloom/BloomEffect.cs | 76 ++++ .../Effects/BrightExtract/BrightExtract.fx | 33 ++ .../Effects/BrightExtract/BrightExtract.ps | Bin 0 -> 348 bytes .../BrightExtract/BrightExtractEffect.cs | 52 +++ .../Effects/ColorKeyAlpha/ColorKeyAlpha.fx | 26 ++ .../Effects/ColorKeyAlpha/ColorKeyAlpha.ps | Bin 0 -> 296 bytes .../ColorKeyAlpha/ColorKeyAlphaEffect.cs | 38 ++ WpfExtended/Effects/ColorTone/ColorTone.fx | 39 ++ WpfExtended/Effects/ColorTone/ColorTone.ps | Bin 0 -> 508 bytes .../Effects/ColorTone/ColorToneEffect.cs | 76 ++++ .../Effects/ContrastAdjust/ContrastAdjust.fx | 39 ++ .../Effects/ContrastAdjust/ContrastAdjust.ps | Bin 0 -> 384 bytes .../ContrastAdjust/ContrastAdjustEffect.cs | 57 +++ .../DirectionalBlur/DirectionalBlur.fx | 40 +++ .../DirectionalBlur/DirectionalBlur.ps | Bin 0 -> 1592 bytes .../DirectionalBlur/DirectionalBlurEffect.cs | 54 +++ WpfExtended/Effects/Embossed/Embossed.fx | 36 ++ WpfExtended/Effects/Embossed/Embossed.ps | Bin 0 -> 468 bytes .../Effects/Embossed/EmbossedEffect.cs | 57 +++ WpfExtended/Effects/Gloom/Gloom.fx | 53 +++ WpfExtended/Effects/Gloom/Gloom.ps | Bin 0 -> 624 bytes WpfExtended/Effects/Gloom/GloomEffect.cs | 71 ++++ .../GrowablePoissonDisk.fx | 59 +++ .../GrowablePoissonDisk.ps | Bin 0 -> 1152 bytes .../GrowablePoissonDiskEffect.cs | 64 ++++ .../Effects/InvertColor/InvertColor.fx | 24 ++ .../Effects/InvertColor/InvertColor.ps | Bin 0 -> 260 bytes .../Effects/InvertColor/InvertColorEffect.cs | 38 ++ .../Effects/LightStreak/LightStreak.fx | 50 +++ .../Effects/LightStreak/LightStreak.ps | Bin 0 -> 548 bytes .../Effects/LightStreak/LightStreakEffect.cs | 64 ++++ WpfExtended/Effects/Magnify/Magnify.fx | 46 +++ WpfExtended/Effects/Magnify/Magnify.ps | Bin 0 -> 512 bytes WpfExtended/Effects/Magnify/MagnifyEffect.cs | 163 +++++++++ WpfExtended/Effects/MonoChrome/Monochrome.fx | 33 ++ WpfExtended/Effects/MonoChrome/Monochrome.ps | Bin 0 -> 360 bytes .../Effects/MonoChrome/MonochromeEffect.cs | 47 +++ .../Effects/MotionBlur/MotionBlurEffect.cs | 62 ++++ .../Effects/MotionBlur/MotionBlurEffect.fx | 28 ++ .../Effects/MotionBlur/MotionBlurEffect.ps | Bin 0 -> 1324 bytes .../Effects/Negative/NegativeEffect.cs | 45 +++ .../Effects/Negative/NegativeEffect.fx | 11 + .../Effects/Negative/NegativeEffect.ps | Bin 0 -> 284 bytes WpfExtended/Effects/Pinch/Pinch.fx | 35 ++ WpfExtended/Effects/Pinch/Pinch.ps | Bin 0 -> 728 bytes WpfExtended/Effects/Pinch/PinchEffect.cs | 70 ++++ WpfExtended/Effects/PixelShaderUtility.cs | 51 +++ WpfExtended/Effects/Pixelate/Pixelate.fx | 45 +++ WpfExtended/Effects/Pixelate/Pixelate.ps | Bin 0 -> 656 bytes .../Effects/Pixelate/PixelateEffect.cs | 57 +++ WpfExtended/Effects/Ripple/Ripple.fx | 52 +++ WpfExtended/Effects/Ripple/Ripple.ps | Bin 0 -> 1328 bytes WpfExtended/Effects/Ripple/RippleEffect.cs | 68 ++++ WpfExtended/Effects/Sharpen/Sharpen.fx | 33 ++ WpfExtended/Effects/Sharpen/Sharpen.ps | Bin 0 -> 376 bytes WpfExtended/Effects/Sharpen/SharpenEffect.cs | 56 +++ .../Effects/SmoothMagnify/SmoothMagnify.fx | 60 ++++ .../Effects/SmoothMagnify/SmoothMagnify.ps | Bin 0 -> 808 bytes .../SmoothMagnify/SmoothMagnifyEffect.cs | 68 ++++ WpfExtended/Effects/Swirl/Swirl.fx | 40 +++ WpfExtended/Effects/Swirl/Swirl.ps | Bin 0 -> 1184 bytes WpfExtended/Effects/Swirl/SwirlEffect.cs | 150 ++++++++ .../Effects/ToneMapping/ToneMapping.fx | 47 +++ .../Effects/ToneMapping/ToneMapping.ps | Bin 0 -> 800 bytes .../Effects/ToneMapping/ToneMappingEffect.cs | 92 +++++ WpfExtended/Effects/ToonShader/ToonShader.fx | 27 ++ WpfExtended/Effects/ToonShader/ToonShader.ps | Bin 0 -> 288 bytes .../Effects/ToonShader/ToonShaderEffect.cs | 44 +++ .../Effects/ZoomBlur/ZoomBlurEffect.cs | 62 ++++ .../Effects/ZoomBlur/ZoomBlurEffect.fx | 27 ++ .../Effects/ZoomBlur/ZoomBlurEffect.ps | Bin 0 -> 1476 bytes WpfExtended/License.txt | 8 + WpfExtended/ShaderCompiler.target | 19 + WpfExtended/WpfExtended.csproj | 20 ++ tools/fxc.exe | Bin 0 -> 153032 bytes 83 files changed, 3218 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 WpfExtended.sln create mode 100644 WpfExtended/Effects/BandedSwirl/BandedSwirl.fx create mode 100644 WpfExtended/Effects/BandedSwirl/BandedSwirl.ps create mode 100644 WpfExtended/Effects/BandedSwirl/BandedSwirlEffect.cs create mode 100644 WpfExtended/Effects/Bloom/Bloom.fx create mode 100644 WpfExtended/Effects/Bloom/Bloom.ps create mode 100644 WpfExtended/Effects/Bloom/BloomEffect.cs create mode 100644 WpfExtended/Effects/BrightExtract/BrightExtract.fx create mode 100644 WpfExtended/Effects/BrightExtract/BrightExtract.ps create mode 100644 WpfExtended/Effects/BrightExtract/BrightExtractEffect.cs create mode 100644 WpfExtended/Effects/ColorKeyAlpha/ColorKeyAlpha.fx create mode 100644 WpfExtended/Effects/ColorKeyAlpha/ColorKeyAlpha.ps create mode 100644 WpfExtended/Effects/ColorKeyAlpha/ColorKeyAlphaEffect.cs create mode 100644 WpfExtended/Effects/ColorTone/ColorTone.fx create mode 100644 WpfExtended/Effects/ColorTone/ColorTone.ps create mode 100644 WpfExtended/Effects/ColorTone/ColorToneEffect.cs create mode 100644 WpfExtended/Effects/ContrastAdjust/ContrastAdjust.fx create mode 100644 WpfExtended/Effects/ContrastAdjust/ContrastAdjust.ps create mode 100644 WpfExtended/Effects/ContrastAdjust/ContrastAdjustEffect.cs create mode 100644 WpfExtended/Effects/DirectionalBlur/DirectionalBlur.fx create mode 100644 WpfExtended/Effects/DirectionalBlur/DirectionalBlur.ps create mode 100644 WpfExtended/Effects/DirectionalBlur/DirectionalBlurEffect.cs create mode 100644 WpfExtended/Effects/Embossed/Embossed.fx create mode 100644 WpfExtended/Effects/Embossed/Embossed.ps create mode 100644 WpfExtended/Effects/Embossed/EmbossedEffect.cs create mode 100644 WpfExtended/Effects/Gloom/Gloom.fx create mode 100644 WpfExtended/Effects/Gloom/Gloom.ps create mode 100644 WpfExtended/Effects/Gloom/GloomEffect.cs create mode 100644 WpfExtended/Effects/GrowablePoissonDisk/GrowablePoissonDisk.fx create mode 100644 WpfExtended/Effects/GrowablePoissonDisk/GrowablePoissonDisk.ps create mode 100644 WpfExtended/Effects/GrowablePoissonDisk/GrowablePoissonDiskEffect.cs create mode 100644 WpfExtended/Effects/InvertColor/InvertColor.fx create mode 100644 WpfExtended/Effects/InvertColor/InvertColor.ps create mode 100644 WpfExtended/Effects/InvertColor/InvertColorEffect.cs create mode 100644 WpfExtended/Effects/LightStreak/LightStreak.fx create mode 100644 WpfExtended/Effects/LightStreak/LightStreak.ps create mode 100644 WpfExtended/Effects/LightStreak/LightStreakEffect.cs create mode 100644 WpfExtended/Effects/Magnify/Magnify.fx create mode 100644 WpfExtended/Effects/Magnify/Magnify.ps create mode 100644 WpfExtended/Effects/Magnify/MagnifyEffect.cs create mode 100644 WpfExtended/Effects/MonoChrome/Monochrome.fx create mode 100644 WpfExtended/Effects/MonoChrome/Monochrome.ps create mode 100644 WpfExtended/Effects/MonoChrome/MonochromeEffect.cs create mode 100644 WpfExtended/Effects/MotionBlur/MotionBlurEffect.cs create mode 100644 WpfExtended/Effects/MotionBlur/MotionBlurEffect.fx create mode 100644 WpfExtended/Effects/MotionBlur/MotionBlurEffect.ps create mode 100644 WpfExtended/Effects/Negative/NegativeEffect.cs create mode 100644 WpfExtended/Effects/Negative/NegativeEffect.fx create mode 100644 WpfExtended/Effects/Negative/NegativeEffect.ps create mode 100644 WpfExtended/Effects/Pinch/Pinch.fx create mode 100644 WpfExtended/Effects/Pinch/Pinch.ps create mode 100644 WpfExtended/Effects/Pinch/PinchEffect.cs create mode 100644 WpfExtended/Effects/PixelShaderUtility.cs create mode 100644 WpfExtended/Effects/Pixelate/Pixelate.fx create mode 100644 WpfExtended/Effects/Pixelate/Pixelate.ps create mode 100644 WpfExtended/Effects/Pixelate/PixelateEffect.cs create mode 100644 WpfExtended/Effects/Ripple/Ripple.fx create mode 100644 WpfExtended/Effects/Ripple/Ripple.ps create mode 100644 WpfExtended/Effects/Ripple/RippleEffect.cs create mode 100644 WpfExtended/Effects/Sharpen/Sharpen.fx create mode 100644 WpfExtended/Effects/Sharpen/Sharpen.ps create mode 100644 WpfExtended/Effects/Sharpen/SharpenEffect.cs create mode 100644 WpfExtended/Effects/SmoothMagnify/SmoothMagnify.fx create mode 100644 WpfExtended/Effects/SmoothMagnify/SmoothMagnify.ps create mode 100644 WpfExtended/Effects/SmoothMagnify/SmoothMagnifyEffect.cs create mode 100644 WpfExtended/Effects/Swirl/Swirl.fx create mode 100644 WpfExtended/Effects/Swirl/Swirl.ps create mode 100644 WpfExtended/Effects/Swirl/SwirlEffect.cs create mode 100644 WpfExtended/Effects/ToneMapping/ToneMapping.fx create mode 100644 WpfExtended/Effects/ToneMapping/ToneMapping.ps create mode 100644 WpfExtended/Effects/ToneMapping/ToneMappingEffect.cs create mode 100644 WpfExtended/Effects/ToonShader/ToonShader.fx create mode 100644 WpfExtended/Effects/ToonShader/ToonShader.ps create mode 100644 WpfExtended/Effects/ToonShader/ToonShaderEffect.cs create mode 100644 WpfExtended/Effects/ZoomBlur/ZoomBlurEffect.cs create mode 100644 WpfExtended/Effects/ZoomBlur/ZoomBlurEffect.fx create mode 100644 WpfExtended/Effects/ZoomBlur/ZoomBlurEffect.ps create mode 100644 WpfExtended/License.txt create mode 100644 WpfExtended/ShaderCompiler.target create mode 100644 WpfExtended/WpfExtended.csproj create mode 100644 tools/fxc.exe diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4ce6fdd --- /dev/null +++ b/.gitignore @@ -0,0 +1,340 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- Backup*.rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb \ No newline at end of file diff --git a/WpfExtended.sln b/WpfExtended.sln new file mode 100644 index 0000000..cd79c8f --- /dev/null +++ b/WpfExtended.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WpfExtended", "WpfExtended\WpfExtended.csproj", "{E822AE0D-5EA1-4C61-A1DC-76CF73C8A524}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E822AE0D-5EA1-4C61-A1DC-76CF73C8A524}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E822AE0D-5EA1-4C61-A1DC-76CF73C8A524}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E822AE0D-5EA1-4C61-A1DC-76CF73C8A524}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E822AE0D-5EA1-4C61-A1DC-76CF73C8A524}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DE159EB4-7D6E-46D0-9366-391E9FDD37DC} + EndGlobalSection +EndGlobal diff --git a/WpfExtended/Effects/BandedSwirl/BandedSwirl.fx b/WpfExtended/Effects/BandedSwirl/BandedSwirl.fx new file mode 100644 index 0000000..9fd6de0 --- /dev/null +++ b/WpfExtended/Effects/BandedSwirl/BandedSwirl.fx @@ -0,0 +1,65 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- BandedSwirlEffect +// Swirl shader with bands going in different directions +//-------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------------- +// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.) +//----------------------------------------------------------------------------------------- + +float2 center : register(C0); +float spiralStrength : register(C1); +float distanceThreshold : register(C2); + +//-------------------------------------------------------------------------------------- +// Sampler Inputs (Brushes, including ImplicitInput) +//-------------------------------------------------------------------------------------- + +sampler2D implicitInputSampler : register(S0); + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + float2 dir = uv - center; + float l = length(dir); + + dir = dir/l; + float angle = atan2(dir.y, dir.x); + + float remainder = frac(l / distanceThreshold); + + float preTransitionWidth = 0.25; + float fac; + + if (remainder < .25) + { + fac = 1.0; + } + else if (remainder < 0.5) + { + // transition zone - go smoothly from previous zone to next. + fac = 1 - 8 * (remainder - preTransitionWidth); + } + else if (remainder < 0.75) + { + fac = -1.0; + } + else + { + // transition zone - go smoothly from previous zone to next. + fac = -(1 - 8 * (remainder - 0.75)); + } + + float newAng = angle + fac * spiralStrength * l; + + float xAmt = cos(newAng) * l; + float yAmt = sin(newAng) * l; + + float2 newCoord = center + float2(xAmt, yAmt); + + return tex2D( implicitInputSampler, newCoord ); +} diff --git a/WpfExtended/Effects/BandedSwirl/BandedSwirl.ps b/WpfExtended/Effects/BandedSwirl/BandedSwirl.ps new file mode 100644 index 0000000000000000000000000000000000000000..718c413883c55dc1db96451c3d671d4ef309a1f1 GIT binary patch literal 1352 zcmY*YJ#Q015S_En_Qe6Ypao%pkbnXu6etlW&WDhQ6bf)oLTN0^HuxmRw(NtJji3k} zCFQw;J1I&7G?2KZOP>M>S^Nb=!|~p(FTU6s@6Ovdvomkjl8NJg@k80zUR%E`BEMk* z%*H}r)A*5D3%@>Ae%`_|_*znw4;m5qh&2l%Z#>0Lu##m-{*2dXb^X>rA`5JC zttq$Z4gGqz(b{egTElj))08M;Mn)$bZ@1s^8lJz|?Z5P^b$HAaMYdcx#~b#&LA_J; z2d(Z4zb*Y??QU&B9(#>JZ`gb8mv273RerQp-6~hx^=4~O-stW2J>)7cF5Fo}!Y3lR ztds(lRyznE+}k<${_EA!3UM2_edW{9(x2BAQ@W}U&l&#swDg0xIxTIEiRU%0j({D* zpsL{)G`@QL=I^x?;5rxi4shgHWjt{GAwCD(x_I)rKL6!w6yCo7ZhwE7coBFMhTlNM z9g2A>SIx*2^gEpH--}ZUFh`6i3w&}28|{c-+%|n}I1CCpmRP8AXZ%o~=Tm3b_1*#Q zD()@eUer8dGI}2?OJcT|82l;5TrP~5o4Su!lHc5iT5#^_I6;q$V;|(P zcGfA_=TJiqcc%K&9QuY6>o{t~UZ^4Cs1JMLo|w^ty}OE9P?H(Pz9b-*z2TpS7~ws8 ztjWwOL(Nc&fSTMBs!Muy#-G*bD$G7$uB67igrhv}P0xk-QOju7i;KJ5X|E+PnG$^4DQJeyTLIH+4vVswo5<7C7g3kOw+EBTUCCC@# z6Zi)te*zs6X6}pvIeWD?v%9l*dr-^rySzmAw&NTE_@aTFK_@Uez$aZwQ=#zN!JK=s zGMWmF+}?(JlN`vY8*VK*QC-_`@8mR^$Sdf@a=fYE3ll$_2FVlhTx5ujN)?uI*Gp!x zmjqD=XB0)_zkCV*g@f^A6byr;7fxo0>k;`eavi%{nv?0^bkM+6FpQ&V^pMy`H^=rx z-|gG(qj&Geb~hSN0+!m%#z_l{xbIRtgj=m_=q1D=-C44HVfvpsTP_&L|U{f-jo(&^GApI~Y?e3ZX~ z%j`K#?zE4Y*}dCE%i4>*!*ns8^ZKbO;q3_3E6`E!OQ3jYerkNb8M)vb=fC_1o?lMf*gpCC46iP^7uRr@ l98QXT3ZCRn;|_&_{Ul#rJ54Z(j_d2Qu69`Z_`bu|0>8x!KTZGu literal 0 HcmV?d00001 diff --git a/WpfExtended/Effects/BrightExtract/BrightExtractEffect.cs b/WpfExtended/Effects/BrightExtract/BrightExtractEffect.cs new file mode 100644 index 0000000..065b538 --- /dev/null +++ b/WpfExtended/Effects/BrightExtract/BrightExtractEffect.cs @@ -0,0 +1,52 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Permissive License. +// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx. +// All other rights reserved. + +using LiteWare.Wpf.ShaderEffects; +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Effects; + +namespace WpfExtended.Effects +{ +#if SILVERLIGHT + using UIPropertyMetadata = System.Windows.PropertyMetadata ; +#endif + public class BrightExtractEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = + ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(BrightExtractEffect), 0); + public static readonly DependencyProperty ThresholdProperty = + DependencyProperty.Register("Threshold", typeof(double), typeof(BrightExtractEffect), new UIPropertyMetadata(0.25, PixelShaderConstantCallback(0))); + + private readonly static PixelShader pixelShader = new PixelShader(); + + static BrightExtractEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("BrightExtract/BrightExtract.ps"); + } + + public BrightExtractEffect() + { + this.PixelShader = pixelShader; + + // Update each DependencyProperty that's registered with a shader register. This + // is needed to ensure the shader gets sent the proper default value. + UpdateShaderValue(InputProperty); + UpdateShaderValue(ThresholdProperty); + } + + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + public double Threshold + { + get { return (double)GetValue(ThresholdProperty); } + set { SetValue(ThresholdProperty, value); } + } + } +} diff --git a/WpfExtended/Effects/ColorKeyAlpha/ColorKeyAlpha.fx b/WpfExtended/Effects/ColorKeyAlpha/ColorKeyAlpha.fx new file mode 100644 index 0000000..09c8f65 --- /dev/null +++ b/WpfExtended/Effects/ColorKeyAlpha/ColorKeyAlpha.fx @@ -0,0 +1,26 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- ColorKeyAlphaEffect +// +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +// Sampler Inputs (Brushes, including ImplicitInput) +//-------------------------------------------------------------------------------------- + +sampler2D implicitInputSampler : register(S0); + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + float4 color = tex2D( implicitInputSampler, uv ); + + if( color.r + color.g + color.b < 0.3 ) { + color.rgba = 0; + } + + return color; +} diff --git a/WpfExtended/Effects/ColorKeyAlpha/ColorKeyAlpha.ps b/WpfExtended/Effects/ColorKeyAlpha/ColorKeyAlpha.ps new file mode 100644 index 0000000000000000000000000000000000000000..dc927077356002cfc329637196d760abbda80a0d GIT binary patch literal 296 zcmX|6L5jja5UfcQa#+X*1P8pV7m5Bry(s8Gqu?!wMjTi-A;x>2uvhmqXLIod`-XSvZs7al4N*IZjTg;$_(ndVQ1&pb7Z; z_j>(%uc%X-&PWP6xxe`jJYSD$Yd-7M9bTn5ZJBD}klN;vV^e)jX(2P4ma@^iF$jph!3Zz_nDXjF^_@I@0-4VVzv!~=aL z&s2jdc)lor@d^N#7wHUNG$+_N%z?2cewG zo5&a(bO}JY;Ma;Pt zOaBpeC28t4E5x$}>@4BCngTkGxp`viyd7Kg1u|OjU)MQu?ty%T@tTBKtm?S8VJz#m c$T8`wTK0@h_EMN2#=3+ta|MSpX?~sqzr1~B@&Et; literal 0 HcmV?d00001 diff --git a/WpfExtended/Effects/ColorTone/ColorToneEffect.cs b/WpfExtended/Effects/ColorTone/ColorToneEffect.cs new file mode 100644 index 0000000..5be22a1 --- /dev/null +++ b/WpfExtended/Effects/ColorTone/ColorToneEffect.cs @@ -0,0 +1,76 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Permissive License. +// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx. +// All other rights reserved. + +using LiteWare.Wpf.ShaderEffects; +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Effects; + +namespace WpfExtended.Effects +{ +#if SILVERLIGHT + using UIPropertyMetadata = System.Windows.PropertyMetadata ; +#endif + public class ColorToneEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = + ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(ColorToneEffect), 0); + public static readonly DependencyProperty DesaturationProperty = + DependencyProperty.Register("Desaturation", typeof(double), typeof(ColorToneEffect), new UIPropertyMetadata(0.5, PixelShaderConstantCallback(0))); + public static readonly DependencyProperty TonedProperty = + DependencyProperty.Register("Toned", typeof(double), typeof(ColorToneEffect), new UIPropertyMetadata(1.0, PixelShaderConstantCallback(1))); + public static readonly DependencyProperty LightColorProperty = + DependencyProperty.Register("LightColor", typeof(Color), typeof(ColorToneEffect), new UIPropertyMetadata(Color.FromArgb(255, 255, 229, 128), PixelShaderConstantCallback(2))); + public static readonly DependencyProperty DarkColorProperty = + DependencyProperty.Register("DarkColor", typeof(Color), typeof(ColorToneEffect), new UIPropertyMetadata(Color.FromArgb(255, 51, 128, 0), PixelShaderConstantCallback(3))); + + private readonly static PixelShader pixelShader = new PixelShader(); + + static ColorToneEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("ColorTone/ColorTone.ps"); + } + + public ColorToneEffect() + { + this.PixelShader = pixelShader; + + // Update each DependencyProperty that's registered with a shader register. This + // is needed to ensure the shader gets sent the proper default value. + UpdateShaderValue(InputProperty); + UpdateShaderValue(DesaturationProperty); + UpdateShaderValue(TonedProperty); + UpdateShaderValue(LightColorProperty); + UpdateShaderValue(DarkColorProperty); + } + + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + public double Desaturation + { + get { return (double)GetValue(DesaturationProperty); } + set { SetValue(DesaturationProperty, value); } + } + public double Toned + { + get { return (double)GetValue(TonedProperty); } + set { SetValue(TonedProperty, value); } + } + public Color LightColor + { + get { return (Color)GetValue(LightColorProperty); } + set { SetValue(LightColorProperty, value); } + } + public Color DarkColor + { + get { return (Color)GetValue(DarkColorProperty); } + set { SetValue(DarkColorProperty, value); } + } + } +} diff --git a/WpfExtended/Effects/ContrastAdjust/ContrastAdjust.fx b/WpfExtended/Effects/ContrastAdjust/ContrastAdjust.fx new file mode 100644 index 0000000..a93db54 --- /dev/null +++ b/WpfExtended/Effects/ContrastAdjust/ContrastAdjust.fx @@ -0,0 +1,39 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- ContrastAdjustEffect +// +//-------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------------- +// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.) +//----------------------------------------------------------------------------------------- + +float Brightness : register(C0); +float Contrast : register(C1); + +//-------------------------------------------------------------------------------------- +// Sampler Inputs (Brushes, including ImplicitInput) +//-------------------------------------------------------------------------------------- + +sampler2D implicitInputSampler : register(S0); + + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + float4 pixelColor = tex2D(implicitInputSampler, uv); + + //contrast + pixelColor.rgb = ((pixelColor.rgb - 0.5f) * max(Contrast, 0)) + 0.5f; + + //brightness + pixelColor.rgb = pixelColor.rgb + Brightness; + + // return final pixel color + return pixelColor; +} + + diff --git a/WpfExtended/Effects/ContrastAdjust/ContrastAdjust.ps b/WpfExtended/Effects/ContrastAdjust/ContrastAdjust.ps new file mode 100644 index 0000000000000000000000000000000000000000..7f8ffc4a3c60193e8196efd69968e7698114316e GIT binary patch literal 384 zcmY+9u};G<5Qcv{0V08v7eK-zEU0B*MNJlv$^Ze0t%}+}Ezu-O%!t%SVBi5fFp;Hi zz{~VGFu&8P5|+;Y-FJ7sGo*9B?h@(4C^-hu(LfeZe2fwBMR}r0n&3U7`eSI4L|}i% z-pPEguluC>lQjBeZpxx<{qsTJAvP(bRcV^MHPDOtRZq3KDeE_r<&263T^Hi$Uwz$9 zE+zxq>S)N0I;l literal 0 HcmV?d00001 diff --git a/WpfExtended/Effects/ContrastAdjust/ContrastAdjustEffect.cs b/WpfExtended/Effects/ContrastAdjust/ContrastAdjustEffect.cs new file mode 100644 index 0000000..0e11091 --- /dev/null +++ b/WpfExtended/Effects/ContrastAdjust/ContrastAdjustEffect.cs @@ -0,0 +1,57 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Permissive License. +// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx. +// All other rights reserved. + +using LiteWare.Wpf.ShaderEffects; +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Effects; + +namespace WpfExtended.Effects +{ +#if SILVERLIGHT + using UIPropertyMetadata = System.Windows.PropertyMetadata ; +#endif + public class ContrastAdjustEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(ContrastAdjustEffect), 0); + public static readonly DependencyProperty BrightnessProperty = DependencyProperty.Register("Brightness", typeof(double), typeof(ContrastAdjustEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(0))); + public static readonly DependencyProperty ContrastProperty = DependencyProperty.Register("Contrast", typeof(double), typeof(ContrastAdjustEffect), new UIPropertyMetadata(1.0, PixelShaderConstantCallback(1))); + + private readonly static PixelShader pixelShader = new PixelShader(); + + static ContrastAdjustEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("ContrastAdjust/ContrastAdjust.ps"); + } + + public ContrastAdjustEffect() + { + this.PixelShader = pixelShader; + + // Update each DependencyProperty that's registered with a shader register. This + // is needed to ensure the shader gets sent the proper default value. + UpdateShaderValue(InputProperty); + UpdateShaderValue(BrightnessProperty); + UpdateShaderValue(ContrastProperty); + } + + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + public double Brightness + { + get { return (double)GetValue(BrightnessProperty); } + set { SetValue(BrightnessProperty, value); } + } + public double Contrast + { + get { return (double)GetValue(ContrastProperty); } + set { SetValue(ContrastProperty, value); } + } + } +} diff --git a/WpfExtended/Effects/DirectionalBlur/DirectionalBlur.fx b/WpfExtended/Effects/DirectionalBlur/DirectionalBlur.fx new file mode 100644 index 0000000..86e96f1 --- /dev/null +++ b/WpfExtended/Effects/DirectionalBlur/DirectionalBlur.fx @@ -0,0 +1,40 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- DirectionalBlurEffect +// +//-------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------------- +// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.) +//----------------------------------------------------------------------------------------- + +float Angle : register(C0); +float BlurAmount : register(C1); + +//-------------------------------------------------------------------------------------- +// Sampler Inputs (Brushes, including ImplicitInput) +//-------------------------------------------------------------------------------------- + +sampler2D implicitInputSampler : register(S0); + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + float4 c = 0; + float rad = Angle * 0.0174533f; + float xOffset = cos(rad); + float yOffset = sin(rad); + + for(int i=0; i<16; i++) + { + uv.x = uv.x - BlurAmount * xOffset; + uv.y = uv.y - BlurAmount * yOffset; + c += tex2D(implicitInputSampler, uv); + } + c /= 16; + + return c; +} \ No newline at end of file diff --git a/WpfExtended/Effects/DirectionalBlur/DirectionalBlur.ps b/WpfExtended/Effects/DirectionalBlur/DirectionalBlur.ps new file mode 100644 index 0000000000000000000000000000000000000000..f135258211e349a139164f50e5d21f0d904c52b0 GIT binary patch literal 1592 zcmdUvJ8u(F5QS&okAPgzMq(Qzpg;){NGOVoorXxE0AqkK5dOA^YM%Z zqkK3x7|eFZ`Fz&tLG`EP)3qynezbpoe}kS54yKc%$>A)!{rpb$WUsTAb>8+~_ovy; zWRwpOnQd;|+obXtQQ%UeI9z+Ug_O?Ow%m$c*!ST(*MEHMt$q4j zF79rf93MYoKY(8@7GD5 zJs0=NIec{T=8 zT%x#GxKwe8aH--FaBVy04fJSfC|(wBoOT4TnHr!;2Epr7?VX3C(qwGN>}r6cG_ z=@>dzI)P3^qt9r~>VEhhF0{?Bw9T)y&9Ai0ue8mtw9T)y%@6(iET&R7SJf?*`u=G? yJ;nVGbI1L5Q12Aa{xAA}(NCT?N7diXo6>))-}qnF^MoG--Z3uTZHDt#711wOcoG3OZGxr0Lh-waT*2*Tk4pM*z-W+?ujh;kx^rlPR7)n2Jd zt@z%Fa@-(XFB24!5x1&kJovL@0Y8Xd{HdQ@Eu(efO~~dkiWUz3d85_%Y~01QKaImx z_?$S$w5+Hp9*Q;hQul}Fd>3iE>bYOtIb0?^I4iwnY7FoT^D0tn literal 0 HcmV?d00001 diff --git a/WpfExtended/Effects/Embossed/EmbossedEffect.cs b/WpfExtended/Effects/Embossed/EmbossedEffect.cs new file mode 100644 index 0000000..54cdf43 --- /dev/null +++ b/WpfExtended/Effects/Embossed/EmbossedEffect.cs @@ -0,0 +1,57 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Permissive License. +// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx. +// All other rights reserved. + +using LiteWare.Wpf.ShaderEffects; +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Effects; + +namespace WpfExtended.Effects +{ +#if SILVERLIGHT + using UIPropertyMetadata = System.Windows.PropertyMetadata ; +#endif + public class EmbossedEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(EmbossedEffect), 0, SamplingMode.Bilinear); + public static readonly DependencyProperty AmountProperty = DependencyProperty.Register("Amount", typeof(double), typeof(EmbossedEffect), new UIPropertyMetadata(15.0, PixelShaderConstantCallback(0))); + public static readonly DependencyProperty WidthProperty = DependencyProperty.Register("Width", typeof(double), typeof(EmbossedEffect), new UIPropertyMetadata(0.0001, PixelShaderConstantCallback(1))); + + private readonly static PixelShader pixelShader = new PixelShader(); + + static EmbossedEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("Embossed/Embossed.ps"); + } + + public EmbossedEffect() + { + this.PixelShader = pixelShader; + + // Update each DependencyProperty that's registered with a shader register. This + // is needed to ensure the shader gets sent the proper default value. + UpdateShaderValue(InputProperty); + UpdateShaderValue(AmountProperty); + UpdateShaderValue(WidthProperty); + } + + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + public double Amount + { + get { return (double)GetValue(AmountProperty); } + set { SetValue(AmountProperty, value); } + } + public double Width + { + get { return (double)GetValue(WidthProperty); } + set { SetValue(WidthProperty, value); } + } + } +} diff --git a/WpfExtended/Effects/Gloom/Gloom.fx b/WpfExtended/Effects/Gloom/Gloom.fx new file mode 100644 index 0000000..22d5b92 --- /dev/null +++ b/WpfExtended/Effects/Gloom/Gloom.fx @@ -0,0 +1,53 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- GloomEffect +// +//-------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------------- +// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.) +//----------------------------------------------------------------------------------------- + +float GloomIntensity : register(C0); +float BaseIntensity : register(C1); +float GloomSaturation : register(C2); +float BaseSaturation : register(C3); + +//-------------------------------------------------------------------------------------- +// Sampler Inputs (Brushes, including ImplicitInput) +//-------------------------------------------------------------------------------------- + +sampler2D implicitInputSampler : register(S0); + + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- + +float4 AdjustSaturation(float4 color, float saturation) +{ + float grey = dot(color, float3(0.3, 0.59, 0.11)); + return lerp(grey, color, saturation); +} + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + float GloomThreshold = 0.25f; + + float4 base = 1.0 - tex2D(implicitInputSampler, uv); + float4 gloom = saturate((base - GloomThreshold) / (1 - GloomThreshold)); + + + // Adjust color saturation and intensity. + gloom = AdjustSaturation(gloom, GloomSaturation) * GloomIntensity; + base = AdjustSaturation(base, BaseSaturation) * BaseIntensity; + + // Darken down the base image in areas where there is a lot of bloom, + // to prevent things looking excessively burned-out. + base *= (1 - saturate(gloom)); + + // Combine the two images. + return 1.0 - (base + gloom); +} + + diff --git a/WpfExtended/Effects/Gloom/Gloom.ps b/WpfExtended/Effects/Gloom/Gloom.ps new file mode 100644 index 0000000000000000000000000000000000000000..06bc3df76b48fad003019bf10367701f107b7c32 GIT binary patch literal 624 zcmY*Wu}%U(5Pi3I7($FBHZ~?)sf_`9M4&(n7K+y7f@i!0I08puhkrne)z)01e1V_f zKbY_db|#*07INa=O=jPld9$;#P)YKWT%vwktsMgRrh#0BPB5y#7u}SmVDa0*jC)y{ zreKrXOSw10ft*UYcf*M~mvSHEY?|b)=w;QsvELj-{$LzLPl#j5kQ1$S*u>jjG#PnO z5Dw7jg<=0M-@vVK&>!}KZV)vG!%5Wki2M;^2fP1j4#%C-P7zl@cNC7phsZs;Id(5v z?Uvhq^zQwUTMzrgfKsk_7k#B7J^l literal 0 HcmV?d00001 diff --git a/WpfExtended/Effects/Gloom/GloomEffect.cs b/WpfExtended/Effects/Gloom/GloomEffect.cs new file mode 100644 index 0000000..a977ef5 --- /dev/null +++ b/WpfExtended/Effects/Gloom/GloomEffect.cs @@ -0,0 +1,71 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Permissive License. +// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx. +// All other rights reserved. + +using LiteWare.Wpf.ShaderEffects; +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Effects; + +namespace WpfExtended.Effects +{ +#if SILVERLIGHT + using UIPropertyMetadata = System.Windows.PropertyMetadata ; +#endif + public class GloomEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(GloomEffect), 0); + public static readonly DependencyProperty GloomIntensityProperty = DependencyProperty.Register("GloomIntensity", typeof(double), typeof(GloomEffect), new UIPropertyMetadata(1.0, PixelShaderConstantCallback(0))); + public static readonly DependencyProperty BaseIntensityProperty = DependencyProperty.Register("BaseIntensity", typeof(double), typeof(GloomEffect), new UIPropertyMetadata(1.0, PixelShaderConstantCallback(1))); + public static readonly DependencyProperty GloomSaturationProperty = DependencyProperty.Register("GloomSaturation", typeof(double), typeof(GloomEffect), new UIPropertyMetadata(1.0, PixelShaderConstantCallback(2))); + public static readonly DependencyProperty BaseSaturationProperty = DependencyProperty.Register("BaseSaturation", typeof(double), typeof(GloomEffect), new UIPropertyMetadata(1.0, PixelShaderConstantCallback(3))); + + private readonly static PixelShader pixelShader = new PixelShader(); + + static GloomEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("Gloom/Gloom.ps"); + } + + public GloomEffect() + { + this.PixelShader = pixelShader; + + // Update each DependencyProperty that's registered with a shader register. This + // is needed to ensure the shader gets sent the proper default value. + UpdateShaderValue(InputProperty); + UpdateShaderValue(GloomIntensityProperty); + UpdateShaderValue(BaseIntensityProperty); + UpdateShaderValue(GloomSaturationProperty); + UpdateShaderValue(BaseSaturationProperty); + } + + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + public double GloomIntensity + { + get { return (double)GetValue(GloomIntensityProperty); } + set { SetValue(GloomIntensityProperty, value); } + } + public double BaseIntensity + { + get { return (double)GetValue(BaseIntensityProperty); } + set { SetValue(BaseIntensityProperty, value); } + } + public double GloomSaturation + { + get { return (double)GetValue(GloomSaturationProperty); } + set { SetValue(GloomSaturationProperty, value); } + } + public double BaseSaturation + { + get { return (double)GetValue(BaseSaturationProperty); } + set { SetValue(BaseSaturationProperty, value); } + } + } +} diff --git a/WpfExtended/Effects/GrowablePoissonDisk/GrowablePoissonDisk.fx b/WpfExtended/Effects/GrowablePoissonDisk/GrowablePoissonDisk.fx new file mode 100644 index 0000000..5dbbd48 --- /dev/null +++ b/WpfExtended/Effects/GrowablePoissonDisk/GrowablePoissonDisk.fx @@ -0,0 +1,59 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- GrowablePoissonDiskEffect +// +//-------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------------- +// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.) +//----------------------------------------------------------------------------------------- + +float DiscRadius : register(C0); +float Width : register(C1); +float Height : register(C2); + +static const float2 poisson[12] = +{ + float2(-0.326212f, -0.40581f), + float2(-0.840144f, -0.07358f), + float2(-0.695914f, 0.457137f), + float2(-0.203345f, 0.620716f), + float2(0.96234f, -0.194983f), + float2(0.473434f, -0.480026f), + float2(0.519456f, 0.767022f), + float2(0.185461f, -0.893124f), + float2(0.507431f, 0.064425f), + float2(0.89642f, 0.412458f), + float2(-0.32194f, -0.932615f), + float2(-0.791559f, -0.59771f) +}; + +//-------------------------------------------------------------------------------------- +// Sampler Inputs (Brushes, including ImplicitInput) +//-------------------------------------------------------------------------------------- + +sampler2D implicitInputSampler : register(S0); + + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + float4 cOut; + float2 ScreenSize = { Width, Height }; + + // Center tap + cOut = tex2D(implicitInputSampler, uv); + for(int tap = 0; tap < 12; tap++) + { + float2 coord= uv.xy + (poisson[tap] / ScreenSize * DiscRadius); + // Sample pixel + cOut += tex2D(implicitInputSampler, coord); + } + + return(cOut / 13.0f); +} + + diff --git a/WpfExtended/Effects/GrowablePoissonDisk/GrowablePoissonDisk.ps b/WpfExtended/Effects/GrowablePoissonDisk/GrowablePoissonDisk.ps new file mode 100644 index 0000000000000000000000000000000000000000..117f1d1cdac31ac4b27056fbdd2a75d72d9758c7 GIT binary patch literal 1152 zcmZvaPiPZS5XNW!C7YlG^i(XGn|e^%-UO2+X~8NLG%57ZLkUSVi)|BOW*(_Q@FzG;vx}wj zBoV#AA}}2rYbp`F!nTT~Vk!8)hMlk5SSo%BWd*wzG6gIp*aI*Pi*vWI^EGGp>Xll< z-ssVQpK^v0J)-%heYw@ACA-mYk-gSgwd;2O?0RRTU#&qkyEGW+wC|ssPH$yqWs1(* z^=`Y@zSPejs~peIFH{%u)mE+1?B-|NYaJW8`RS>X(=@n9WN4Ig%f?f0ar?bD`QqX0 z=LeU3<~sP5qci@O{X50tx5L)fsS6%+1AJ%ss^vaAq&>UitXM`|Pj#x3mfW(dN1EyBY9LcODnw zHiX-esO=7VG>q@>lbLfIy|#qmc_fWTpysNH8sC zx)i4iHjXo5W=L@MLzbf ZHOc3g=sZU6%iuiXys9|A;roMt=r1v43n%~p literal 0 HcmV?d00001 diff --git a/WpfExtended/Effects/GrowablePoissonDisk/GrowablePoissonDiskEffect.cs b/WpfExtended/Effects/GrowablePoissonDisk/GrowablePoissonDiskEffect.cs new file mode 100644 index 0000000..a7fa25f --- /dev/null +++ b/WpfExtended/Effects/GrowablePoissonDisk/GrowablePoissonDiskEffect.cs @@ -0,0 +1,64 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Permissive License. +// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx. +// All other rights reserved. + +using LiteWare.Wpf.ShaderEffects; +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Effects; + +namespace WpfExtended.Effects +{ +#if SILVERLIGHT + using UIPropertyMetadata = System.Windows.PropertyMetadata ; +#endif + public class GrowablePoissonDiskEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(GrowablePoissonDiskEffect), 0); + public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register("Radius", typeof(double), typeof(GrowablePoissonDiskEffect), new UIPropertyMetadata(0.5, PixelShaderConstantCallback(0))); + public static readonly DependencyProperty WidthProperty = DependencyProperty.Register("Width", typeof(double), typeof(GrowablePoissonDiskEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(1))); + public static readonly DependencyProperty HeightProperty = DependencyProperty.Register("Height", typeof(double), typeof(GrowablePoissonDiskEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(2))); + + private readonly static PixelShader pixelShader = new PixelShader(); + + static GrowablePoissonDiskEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("GrowablePoissonDisk/GrowablePoissonDisk.ps"); + } + + public GrowablePoissonDiskEffect() + { + this.PixelShader = pixelShader; + + // Update each DependencyProperty that's registered with a shader register. This + // is needed to ensure the shader gets sent the proper default value. + UpdateShaderValue(InputProperty); + UpdateShaderValue(RadiusProperty); + UpdateShaderValue(WidthProperty); + UpdateShaderValue(HeightProperty); + } + + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + public double Radius + { + get { return (double)GetValue(RadiusProperty); } + set { SetValue(RadiusProperty, value); } + } + public double Width + { + get { return (double)GetValue(WidthProperty); } + set { SetValue(WidthProperty, value); } + } + public double Height + { + get { return (double)GetValue(HeightProperty); } + set { SetValue(HeightProperty, value); } + } + } +} diff --git a/WpfExtended/Effects/InvertColor/InvertColor.fx b/WpfExtended/Effects/InvertColor/InvertColor.fx new file mode 100644 index 0000000..d1f6407 --- /dev/null +++ b/WpfExtended/Effects/InvertColor/InvertColor.fx @@ -0,0 +1,24 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- InvertColorEffect +// +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +// Sampler Inputs (Brushes, including ImplicitInput) +//-------------------------------------------------------------------------------------- + +sampler2D implicitInputSampler : register(S0); + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + float4 color = tex2D( implicitInputSampler, uv ); + float4 inverted_color = 1 - color; + inverted_color.a = color.a; + inverted_color.rgb *= inverted_color.a; + return inverted_color; +} diff --git a/WpfExtended/Effects/InvertColor/InvertColor.ps b/WpfExtended/Effects/InvertColor/InvertColor.ps new file mode 100644 index 0000000000000000000000000000000000000000..8b02f7aa24b99c64b338e0da3ebd330e005a4105 GIT binary patch literal 260 zcmXX=O$vfg7##Z{7l9WDdeEjepyfwQDnpsC@5v+g0;(uQRaG7I z>C^8wN#@Ud8(SHsaTcF*G2TzaYU6E$cL`2WD%|*%NPZTMJ#|p+fG%K_Kr#PEG&E#0 tE(M#s|N9H3RW6%q7Vq^NW?je7^mOteMMw6j^2;iFqat$tmF$6xjge;v?!yX=m=Xhr6 zEREkk?p1Lbxz>(*BWKjQ53VwXY3eQ4ZW=^OB7=IF)v%M`!A~cC;;sBBoWq&9p@(1* zhrujJub1&UbzCAZ!KQ)zf8KaCJ)8D$6U>rm72T)S(cQ6iHFn09 1) + { + texuv = origUv; + } + else + { + texuv = center + amount * ray; + } + + return tex2D(implicitInputSampler, texuv); +} + diff --git a/WpfExtended/Effects/Magnify/Magnify.ps b/WpfExtended/Effects/Magnify/Magnify.ps new file mode 100644 index 0000000000000000000000000000000000000000..3a8a7677502c98fb1e1bad2c8f5367ff8d3f8cc5 GIT binary patch literal 512 zcmY*VJ5Iwu5PfSWAwrRIfFR)#8kBGWNYa25iV%#@Cj6a{UJ5)<&WAT6MY4JQvJx zACJ4y=az5GzhS7ca!&LfBK4!*KURfpS^FK)~61%mgqM<$7xDz OP|vOO=lm`&3g8{ z#iKBOoxUV8jIu>8_;J|noOMw>0Br|>>g^x)*Q?d#&-HH)DEr5@a>d!(j&VSQ&2F9@&O$LuU5OFY)PmcSmz4&(x~f^KI4|_y--z BM~eUe literal 0 HcmV?d00001 diff --git a/WpfExtended/Effects/MonoChrome/MonochromeEffect.cs b/WpfExtended/Effects/MonoChrome/MonochromeEffect.cs new file mode 100644 index 0000000..15010ef --- /dev/null +++ b/WpfExtended/Effects/MonoChrome/MonochromeEffect.cs @@ -0,0 +1,47 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Permissive License. +// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx. +// All other rights reserved. + +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Effects; +using LiteWare.Wpf.ShaderEffects; + +namespace WpfExtended.Effects +{ +#if SILVERLIGHT + using UIPropertyMetadata = System.Windows.PropertyMetadata ; +#endif + public class MonochromeEffect : ShaderEffect + { + public static readonly DependencyProperty FilterColorProperty = DependencyProperty.Register("FilterColor", typeof(Color), typeof(MonochromeEffect), new UIPropertyMetadata(Colors.White, PixelShaderConstantCallback(0))); + public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(MonochromeEffect), 0); + + private readonly static PixelShader pixelShader; + + static MonochromeEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("MonoChrome/Monochrome.ps"); + } + public MonochromeEffect() + { + this.PixelShader = pixelShader; + + UpdateShaderValue(FilterColorProperty); + UpdateShaderValue(InputProperty); + } + + public Color FilterColor + { + get { return (Color)GetValue(FilterColorProperty); } + set { SetValue(FilterColorProperty, value); } + } + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + } +} \ No newline at end of file diff --git a/WpfExtended/Effects/MotionBlur/MotionBlurEffect.cs b/WpfExtended/Effects/MotionBlur/MotionBlurEffect.cs new file mode 100644 index 0000000..6869f94 --- /dev/null +++ b/WpfExtended/Effects/MotionBlur/MotionBlurEffect.cs @@ -0,0 +1,62 @@ +// MIT License +// +// Copyright (c) 2020 Hisham Maudarbocus +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Effects; + +namespace WpfExtended.Effects +{ + public class MotionBlurEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty(nameof(Input), typeof(MotionBlurEffect), 0); + public static readonly DependencyProperty BlurAngleProperty = + DependencyProperty.Register(nameof(BlurAngle), typeof(double), typeof(MotionBlurEffect), new UIPropertyMetadata(0d, PixelShaderConstantCallback(0))); + public static readonly DependencyProperty BlurMagnitudeProperty = + DependencyProperty.Register(nameof(BlurMagnitude), typeof(double), typeof(MotionBlurEffect), new UIPropertyMetadata(10d, PixelShaderConstantCallback(1))); + + public Brush Input + { + get => (Brush)GetValue(InputProperty); + set => SetValue(InputProperty, value); + } + public double BlurAngle + { + get => (double)GetValue(BlurAngleProperty); + set => SetValue(BlurAngleProperty, value); + } + public double BlurMagnitude + { + get => (double)GetValue(BlurMagnitudeProperty); + set => SetValue(BlurMagnitudeProperty, value); + } + + public MotionBlurEffect() + { + PixelShader = PixelShaderUtility.LoadPixelShader("MotionBlur/MotionBlurEffect.ps"); + + UpdateShaderValue(InputProperty); + UpdateShaderValue(BlurAngleProperty); + UpdateShaderValue(BlurMagnitudeProperty); + } + } +} \ No newline at end of file diff --git a/WpfExtended/Effects/MotionBlur/MotionBlurEffect.fx b/WpfExtended/Effects/MotionBlur/MotionBlurEffect.fx new file mode 100644 index 0000000..8c67a14 --- /dev/null +++ b/WpfExtended/Effects/MotionBlur/MotionBlurEffect.fx @@ -0,0 +1,28 @@ +// Sampler Registers // + +sampler2D implicitInputSampler : register(S0); + +// Constants Registers // + +float blurAngle : register(C0); +float blurMagnitude : register(C1); + +// Pixel Shader // + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + const float STRENGTH = 0.0001; + + float2 offset; + sincos(radians(blurAngle), offset.y, offset.x); + offset *= blurMagnitude * STRENGTH; + + float4 output = 0; + for (int i = 0; i < 15; i++) + { + output += tex2D(implicitInputSampler, uv - offset * i); + } + output /= 15; + + return output; +} \ No newline at end of file diff --git a/WpfExtended/Effects/MotionBlur/MotionBlurEffect.ps b/WpfExtended/Effects/MotionBlur/MotionBlurEffect.ps new file mode 100644 index 0000000000000000000000000000000000000000..2f92effe52dae56f198fab1b484e0d2a9daa7ba7 GIT binary patch literal 1324 zcmb7@y>Ami5XIk}eP=rX8Hs`hiEEI60yz|XC_?^7L!?9kOeDHsViQhsY|F9xg(`HE zlt+hr1!*7+LTTxsPDA0pgX7KK?cE|FAuNyA@3%9vvom*aljK)&2OCe?oy!0|(m+W>kAwz?;#?3Xvj{wg_J?gFAUgxpRv--EzS$*?Vc!~Vd$&b6_Eq-aLCA>@y zMAWCWpER_EdzxQhR{~mt*3#V9{2}$T_M4-l`}BwSSIC|7-#_(MKcB>l8|&P=C%j4? zFBV_u_LXNgxi+t)EmrK&arXZ$s*KmXq+BecGQh7xA4D{+JL;m|*GyUa^j}0SlISX9 z9F*t_Rbh@QEzRjD&MNZs$kKT7NOHLJcd(S0SHSW(^+|IG7oRlek~wzXi;u99K1bLh zXXTtFIrB2cn4I}JEAmxxR^+SZtjJf(80*yeI=mBSE4z<2xw$EpQ zbr=4826)dxbN0%!G-s}SOLNwW{mswgj1_yG>l$?})2>zD3YlnAkJN0m)FU+-E%n%1 z>an%dV{56$)>4nHr5@2{=IjseSoGh_)BDRjJrw;n^YpEG@=8kb`B}b>b!Rh!fAt*f nndC73_6$r<()$!W`k$Ve{E{Pm#?$kBzB>-!^8M52CkgNy$e0(h literal 0 HcmV?d00001 diff --git a/WpfExtended/Effects/Negative/NegativeEffect.cs b/WpfExtended/Effects/Negative/NegativeEffect.cs new file mode 100644 index 0000000..d770174 --- /dev/null +++ b/WpfExtended/Effects/Negative/NegativeEffect.cs @@ -0,0 +1,45 @@ +// MIT License +// +// Copyright (c) 2020 Hisham Maudarbocus +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Effects; + +namespace WpfExtended.Effects +{ + public class NegativeEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty(nameof(Input), typeof(NegativeEffect), 0); + + public Brush Input + { + get => (Brush)GetValue(InputProperty); + set => SetValue(InputProperty, value); + } + + public NegativeEffect() + { + PixelShader = PixelShaderUtility.LoadPixelShader("Negative/NegativeEffect.ps"); + UpdateShaderValue(InputProperty); + } + } +} \ No newline at end of file diff --git a/WpfExtended/Effects/Negative/NegativeEffect.fx b/WpfExtended/Effects/Negative/NegativeEffect.fx new file mode 100644 index 0000000..1cae292 --- /dev/null +++ b/WpfExtended/Effects/Negative/NegativeEffect.fx @@ -0,0 +1,11 @@ +// Sampler Registers // + +sampler2D implicitInputSampler : register(S0); + +// Pixel Shader // + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + float4 color = tex2D(implicitInputSampler, uv); + return float4(1 - color.r, 1 - color.g, 1 - color.b, color.a); +} \ No newline at end of file diff --git a/WpfExtended/Effects/Negative/NegativeEffect.ps b/WpfExtended/Effects/Negative/NegativeEffect.ps new file mode 100644 index 0000000000000000000000000000000000000000..027e032583a05933ae34ac8f6b2547cc17919f86 GIT binary patch literal 284 zcmYjLF%E)25F8K_3llzI;w3iP81Mr`Z7|V7v9KdXFL+Q(#AOh!$bMgiqEb3yLT@B!7B BJk056r4Tj&LVNF!mS|(A&}S*Y{mE6na=Sb1L>Nm& z6jVl|+Ui8D{>F6O#Cmfl91ak+dmqE?FsgNW!>G|@*6JgV**m?x!Pe^5GTwyS{qCUq zA@ZNCKlj(_jk@31ZSJ)Cezn`~h3xcKmS3!3{1$NYD4I#};`O9hJLk!|KQ%UsZQx}HZsjSo=oFI6xeTh zPrFD=9=ryW=4=fRaBr;VZCx>jzN$}S?hnjU_HdTA?onfg;2UzpN-G3=qV?pK26I~z z4Hv2L?$tPb(K;oJ?9H@;Q~EUTtv`pli3QK$d3;EFexNfg@egQ}7xRAQ_KpW%|!AZsXFJ^fmF?N21EKgJ5KY^ZuKL7v# literal 0 HcmV?d00001 diff --git a/WpfExtended/Effects/Pinch/PinchEffect.cs b/WpfExtended/Effects/Pinch/PinchEffect.cs new file mode 100644 index 0000000..7871a14 --- /dev/null +++ b/WpfExtended/Effects/Pinch/PinchEffect.cs @@ -0,0 +1,70 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Permissive License. +// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx. +// All other rights reserved. + +using LiteWare.Wpf.ShaderEffects; +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Effects; + +namespace WpfExtended.Effects +{ +#if SILVERLIGHT + using UIPropertyMetadata = System.Windows.PropertyMetadata ; +#endif + public class PinchEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(PinchEffect), 0); + public static readonly DependencyProperty CenterXProperty = DependencyProperty.Register("CenterX", typeof(double), typeof(PinchEffect), new UIPropertyMetadata(0.5, PixelShaderConstantCallback(0))); + public static readonly DependencyProperty CenterYProperty = DependencyProperty.Register("CenterY", typeof(double), typeof(PinchEffect), new UIPropertyMetadata(0.5, PixelShaderConstantCallback(1))); + public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register("Radius", typeof(double), typeof(PinchEffect), new UIPropertyMetadata(0.25, PixelShaderConstantCallback(2))); + public static readonly DependencyProperty AmountProperty = DependencyProperty.Register("Amount", typeof(double), typeof(PinchEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(3))); + + private readonly static PixelShader pixelShader = new PixelShader(); + + static PinchEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("Pinch/Pinch.ps"); + } + public PinchEffect() + { + this.PixelShader = pixelShader; + + // Update each DependencyProperty that's registered with a shader register. This + // is needed to ensure the shader gets sent the proper default value. + UpdateShaderValue(InputProperty); + UpdateShaderValue(CenterXProperty); + UpdateShaderValue(CenterYProperty); + UpdateShaderValue(RadiusProperty); + UpdateShaderValue(AmountProperty); + } + + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + public double CenterX + { + get { return (double)GetValue(CenterXProperty); } + set { SetValue(CenterXProperty, value); } + } + public double CenterY + { + get { return (double)GetValue(CenterYProperty); } + set { SetValue(CenterYProperty, value); } + } + public double Radius + { + get { return (double)GetValue(RadiusProperty); } + set { SetValue(RadiusProperty, value); } + } + public double Amount + { + get { return (double)GetValue(AmountProperty); } + set { SetValue(AmountProperty, value); } + } + } +} diff --git a/WpfExtended/Effects/PixelShaderUtility.cs b/WpfExtended/Effects/PixelShaderUtility.cs new file mode 100644 index 0000000..10ad8fc --- /dev/null +++ b/WpfExtended/Effects/PixelShaderUtility.cs @@ -0,0 +1,51 @@ +// MIT License +// +// Copyright (c) 2020 Hisham Maudarbocus +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +using System; +using System.Windows.Media.Effects; + +namespace WpfExtended.Effects +{ + internal static class PixelShaderUtility + { + public static readonly string AssemblyShortName; + + static PixelShaderUtility() + { + AssemblyShortName = typeof(PixelShaderUtility) + .Assembly + .GetName() + .Name; + } + + public static PixelShader LoadPixelShader(string shaderFile) + { + string uriString = $"pack://application:,,,/{AssemblyShortName};component/{shaderFile}"; + PixelShader pixelShader = new PixelShader + { + UriSource = new Uri(uriString) + }; + + return pixelShader; + } + } +} \ No newline at end of file diff --git a/WpfExtended/Effects/Pixelate/Pixelate.fx b/WpfExtended/Effects/Pixelate/Pixelate.fx new file mode 100644 index 0000000..a9da121 --- /dev/null +++ b/WpfExtended/Effects/Pixelate/Pixelate.fx @@ -0,0 +1,45 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- PixelateEffect +// +//-------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------------- +// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.) +//----------------------------------------------------------------------------------------- + +float HorizontalPixelCounts : register(C0); +float VerticalPixelCounts : register(C1); + +//-------------------------------------------------------------------------------------- +// Sampler Inputs (Brushes, including ImplicitInput) +//-------------------------------------------------------------------------------------- + +sampler2D implicitInputSampler : register(S0); + + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + float2 brickCounts = { HorizontalPixelCounts, VerticalPixelCounts }; + float2 brickSize = 1.0 / brickCounts; + + // Offset every other row of bricks + float2 offsetuv = uv; + bool oddRow = floor(offsetuv.y / brickSize.y) % 2.0 >= 1.0; + if (oddRow) + { + offsetuv.x += brickSize.x / 2.0; + } + + float2 brickNum = floor(offsetuv / brickSize); + float2 centerOfBrick = brickNum * brickSize + brickSize / 2; + float4 color = tex2D(implicitInputSampler, centerOfBrick); + + return color; +} + + diff --git a/WpfExtended/Effects/Pixelate/Pixelate.ps b/WpfExtended/Effects/Pixelate/Pixelate.ps new file mode 100644 index 0000000000000000000000000000000000000000..5a5202cdf1d7f2626ec4be7828c73fd539f5398d GIT binary patch literal 656 zcmY*VO-sW-5S^qSE-2)=}Mi8(HHqNO-^oi{r;UXOTW9+;# zgbT!>`WAZ!##-imVCU7367do((#dQnp2Jx$S}oEgKUm(5^=ZFpC6^&;bDhpWd22fhb4y^Q)_1kO PsWI|OseL_@D@F7RfcJAX literal 0 HcmV?d00001 diff --git a/WpfExtended/Effects/Pixelate/PixelateEffect.cs b/WpfExtended/Effects/Pixelate/PixelateEffect.cs new file mode 100644 index 0000000..d8663a8 --- /dev/null +++ b/WpfExtended/Effects/Pixelate/PixelateEffect.cs @@ -0,0 +1,57 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Permissive License. +// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx. +// All other rights reserved. + +using LiteWare.Wpf.ShaderEffects; +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Effects; + +namespace WpfExtended.Effects +{ +#if SILVERLIGHT + using UIPropertyMetadata = System.Windows.PropertyMetadata ; +#endif + public class PixelateEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(PixelateEffect), 0); + public static readonly DependencyProperty HorizontalPixelCountsProperty = DependencyProperty.Register("HorizontalPixelCounts", typeof(double), typeof(PixelateEffect), new UIPropertyMetadata(80.0, PixelShaderConstantCallback(0))); + public static readonly DependencyProperty VerticalPixelCountsProperty = DependencyProperty.Register("VerticalPixelCounts", typeof(double), typeof(PixelateEffect), new UIPropertyMetadata(80.0, PixelShaderConstantCallback(1))); + + private readonly static PixelShader pixelShader = new PixelShader(); + + static PixelateEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("Pixelate/Pixelate.ps"); + } + + public PixelateEffect() + { + this.PixelShader = pixelShader; + + // Update each DependencyProperty that's registered with a shader register. This + // is needed to ensure the shader gets sent the proper default value. + UpdateShaderValue(InputProperty); + UpdateShaderValue(HorizontalPixelCountsProperty); + UpdateShaderValue(VerticalPixelCountsProperty); + } + + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + public double HorizontalPixelCounts + { + get { return (double)GetValue(HorizontalPixelCountsProperty); } + set { SetValue(HorizontalPixelCountsProperty, value); } + } + public double VerticalPixelCounts + { + get { return (double)GetValue(VerticalPixelCountsProperty); } + set { SetValue(VerticalPixelCountsProperty, value); } + } + } +} diff --git a/WpfExtended/Effects/Ripple/Ripple.fx b/WpfExtended/Effects/Ripple/Ripple.fx new file mode 100644 index 0000000..2e51784 --- /dev/null +++ b/WpfExtended/Effects/Ripple/Ripple.fx @@ -0,0 +1,52 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- RippleEffect +// +//-------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------------- +// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.) +//----------------------------------------------------------------------------------------- + +float2 center : register(C0); +float amplitude : register(C1); +float frequency: register(C2); +float phase: register(C3); + +//-------------------------------------------------------------------------------------- +// Sampler Inputs (Brushes, including ImplicitInput) +//-------------------------------------------------------------------------------------- + +sampler2D implicitInputSampler : register(S0); + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + + float2 dir = uv - center; + + float2 toPixel = uv - center; // vector from center to pixel + float distance = length(toPixel); + float2 direction = toPixel/distance; + float angle = atan2(direction.y, direction.x); + float2 wave; + sincos(frequency * distance + phase, wave.x, wave.y); + + //float falloff = saturate(1-distance); + float falloff = 1 - distance; + falloff *= falloff; + + distance += amplitude * wave.x * falloff; + sincos(angle, direction.y, direction.x); + float2 uv2 = center + distance * direction; + + float lighting = saturate(wave.y * falloff) * 0.2 + 0.8; + + float4 color = tex2D( implicitInputSampler, uv2 ); + color.rgb *= lighting; + + return color; +} diff --git a/WpfExtended/Effects/Ripple/Ripple.ps b/WpfExtended/Effects/Ripple/Ripple.ps new file mode 100644 index 0000000000000000000000000000000000000000..185e6bc17b971355454bcfcf8c228c6dc2513515 GIT binary patch literal 1328 zcma)6ziSg=7=G_^xm;5m1{(2z8Aw8JQ(rl4>(Ch^r8Cn`=CFa@a1P}T_v;IgL^sYC0E6sMlS7j{n z9XU1;r@dM02GZ`X&8^MItwz1m>b5p|#fx_?6_+d3O0l|GTMs(LrPfxvfdIwXnJcp> zXLwsA>qtQ{>)K9qPy zu*8Ax~Rb` z#a?}NO7G0@ChZaIiMpVB;Qf$rN@A6VARfx*{>;2ad3Zl?In-pF|IdT({Y0KDdN+CW z+|$`{Hql^o4^Rqp&WgJhd`vF}8{OBF+Kzftj`8tOtC#K$zaQXmRx#eOTGVqd7~P8% TYq2B;8*7Onn1N^PNh0zW{E_z- literal 0 HcmV?d00001 diff --git a/WpfExtended/Effects/Ripple/RippleEffect.cs b/WpfExtended/Effects/Ripple/RippleEffect.cs new file mode 100644 index 0000000..89aa115 --- /dev/null +++ b/WpfExtended/Effects/Ripple/RippleEffect.cs @@ -0,0 +1,68 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Permissive License. +// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx. +// All other rights reserved. + +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Effects; + +namespace WpfExtended.Effects +{ +#if SILVERLIGHT + using UIPropertyMetadata = System.Windows.PropertyMetadata ; +#endif + public class RippleEffect : ShaderEffect + { + public static readonly DependencyProperty CenterProperty = DependencyProperty.Register("Center", typeof(Point), typeof(RippleEffect), new UIPropertyMetadata(new Point(0.5, 0.5), PixelShaderConstantCallback(0))); + public static readonly DependencyProperty AmplitudeProperty = DependencyProperty.Register("Amplitude", typeof(double), typeof(RippleEffect), new UIPropertyMetadata(0.1, PixelShaderConstantCallback(1))); + public static readonly DependencyProperty FrequencyProperty = DependencyProperty.Register("Frequency", typeof(double), typeof(RippleEffect), new UIPropertyMetadata(50.0, PixelShaderConstantCallback(2))); + public static readonly DependencyProperty PhaseProperty = DependencyProperty.Register("Phase", typeof(double), typeof(RippleEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(3))); + public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(RippleEffect), 0); + + private static readonly PixelShader pixelShader; + + static RippleEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("Ripple/Ripple.ps"); + } + + public RippleEffect() + { + this.PixelShader = pixelShader; + + UpdateShaderValue(CenterProperty); + UpdateShaderValue(AmplitudeProperty); + UpdateShaderValue(PhaseProperty); + UpdateShaderValue(FrequencyProperty); + UpdateShaderValue(InputProperty); + } + + public Point Center + { + get { return (Point)GetValue(CenterProperty); } + set { SetValue(CenterProperty, value); } + } + public double Amplitude + { + get { return (double)GetValue(AmplitudeProperty); } + set { SetValue(AmplitudeProperty, value); } + } + public double Frequency + { + get { return (double)GetValue(FrequencyProperty); } + set { SetValue(FrequencyProperty, value); } + } + public double Phase + { + get { return (double)GetValue(PhaseProperty); } + set { SetValue(PhaseProperty, value); } + } + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + } +} diff --git a/WpfExtended/Effects/Sharpen/Sharpen.fx b/WpfExtended/Effects/Sharpen/Sharpen.fx new file mode 100644 index 0000000..2916bf9 --- /dev/null +++ b/WpfExtended/Effects/Sharpen/Sharpen.fx @@ -0,0 +1,33 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- SharpenEffect +// +//-------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------------- +// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.) +//----------------------------------------------------------------------------------------- + +float Amount : register(C0); +float Width : register(C1); + +//-------------------------------------------------------------------------------------- +// Sampler Inputs (Brushes, including ImplicitInput) +//-------------------------------------------------------------------------------------- + +sampler2D implicitInputSampler : register(S0); + + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + float4 color = tex2D(implicitInputSampler, uv); + color.rgb += tex2D(implicitInputSampler, uv - Width) * Amount; + color.rgb -= tex2D(implicitInputSampler, uv + Width) * Amount; + return color; +} + + diff --git a/WpfExtended/Effects/Sharpen/Sharpen.ps b/WpfExtended/Effects/Sharpen/Sharpen.ps new file mode 100644 index 0000000000000000000000000000000000000000..32a9f4a034f6581ebd22c33eac63873518498a93 GIT binary patch literal 376 zcmY*UJ5Iwu5PiF`AO(^yfW(&2pagLNCk;rU!AQ`BC<)3+I9@p$>OBAj2cSqq=_ZHr zIWTW*M8Zh3Gw;3mEp%Of*Vh<6B!g1`Uv!Y`FbGBhd@?-IHC^$2W)yRDO-AA9k9#90 zy;AqiD3)aTdg)P$BGsy;@n~m$0h_s3JGK6H>DE4-5X}pe5l;Tqy4Cn<+{2xn7WpcF z@#g&g!rY9~kx3Vm*}O2rJad+yWQ@yraQtkGF$H uk3|pYRvW~ponBH4pfM}YOY{*Oe#X2oY{iW@IFr3D+qt@Fdpr0U%5&Ka5*dXQ^^oj8 zyVGraZEVo7Y{pSHI#2vh-#+_?)mqiBT?A*X*guHc9f`dD=EnLaf}aq%g32jpe$#pf zTLn|9Fzy0>E{}Gf%SVrF=f(IeaIx@o6MVS6%d;=rm;L@0<8#3CEV~Eofn#8=tlDua z^e`NsugHVH!97(XN^u_;zW_%ooCmYU#yYV+gE`_{;A)D&4DKtO6LsU0jI94 zuRYtiC4+NZt6Lj_4DfG^^YU+zaV>alUO{!#n5D~8wM^ULo4Vkv!3Q@Ce?sm8wG@+n zkPkI#@ZR%qOk1O;kUZs>+#mPD{iDZp$;9NI*}q_H_}$dz;+$b7Bj6)tG3M0`hv>K3 TH@V8JEAooe%-OTL)Ooo$(xNoB0kKdI8UxZx2ytx}(j;!Sf*`oXO9c;t z|G;|F4U}H|anRDE-aHCD2(tf!cyWF2`*w{UO_=OAZ)V=iyl*3Bp8v`l(zv~}d|X7n z!33C%2Yp!*`HDvmX5wqelsqDi&oh__Gw@qtFW_4R_6kpa-osdFh%28IBGT!v_xx+2 ze}BvGcOS~wKoxn6BHs1;ksnI1IqU`9AX@1Ux1weT9za`W6kC})8U|sf*Nj5HzaDMK zm=myD86S??7u&OPBj|>M(coTGJA3O~?fPnSwbtC|-1Wm+W3V|4z+9V~y)Y-^n<9=S z)r6z8chf7E)^tC+Cyp! zc(w<7d0OSoz&{pGBVdS!a|+927cnRj8#qs?n5l5aHIL2QZRXw)NG!^aZAlYb^2AZS zJk$%U71Jjl^Jy%={i(Pmt;AAw6O1($c>c~K2EV{Ko94DrU-lz6ab2hTA%=KM)p1V7 z%RTk%+*@J?GdSou*^jf9`<5K8JZK#1H$NoQpdWLp&h|V~*0@R%h&yXkXWve>Bj(i?|EysG37# zB`3LD?BQacGipB_uSk}7F!J*L1bvHpQL}Ka|KY_ySk3w`FEQbJR=jH#dSt+|WLfQ3 R|(jU+PF){Q9bYil^%EF3y&%I8NIMTJxea?HnE>uzcDTe62Kj>@$7*zNnbNQ1y z4uDT&H-b?|1)KOToOZ{fNGjwj_QNocsWtm)Se2}aU-XT!rZU<0*1Ec3HR>K=gTC0d zVGh~DweC4tl`-kjD|Ma8BIuumqZG@fL}jWngu`GIjq&nx9L*O=fLGDD8%?5wanVU_ zYp?z3)W?T#JPXn^=mxViNLX%Zb+W0omEzbRhKo7EX*>xBVR|%+7ir(;jcE=ZQ2%d+ zcz*iqbO&$4K@!cQQR;0UKk?r5`aQ3I<`09!>qgT!WTv;f^K=)>cR;OyR%Scu{jxQL zyX0SQdwcrZ@0)n<;)TQ>%X0#nyI+_77r3pgW1gx-o?pYwGm5I*$J}ekFFyhfr_>eX za?Tq#$!bO;4CefQCszut#4^X^H?=~ct7u;WZGE5l3Ju2Fxe(Dy+vZr`=GeJp259=+J2!RgT)D23i3XfgVlMK`z5%$J Jc`scQz+a++hZq0= literal 0 HcmV?d00001 diff --git a/WpfExtended/Effects/ToneMapping/ToneMappingEffect.cs b/WpfExtended/Effects/ToneMapping/ToneMappingEffect.cs new file mode 100644 index 0000000..69c8452 --- /dev/null +++ b/WpfExtended/Effects/ToneMapping/ToneMappingEffect.cs @@ -0,0 +1,92 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Permissive License. +// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx. +// All other rights reserved. + +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Effects; + +namespace WpfExtended.Effects +{ +#if SILVERLIGHT + using UIPropertyMetadata = System.Windows.PropertyMetadata ; +#endif + public class ToneMappingEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(ToneMappingEffect), 0); + public static readonly DependencyProperty ExposureProperty = DependencyProperty.Register("Exposure", typeof(double), typeof(ToneMappingEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(0))); + public static readonly DependencyProperty DefogProperty = DependencyProperty.Register("Defog", typeof(double), typeof(ToneMappingEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(1))); + public static readonly DependencyProperty GammaProperty = DependencyProperty.Register("Gamma", typeof(double), typeof(ToneMappingEffect), new UIPropertyMetadata(0.454545, PixelShaderConstantCallback(2))); + public static readonly DependencyProperty FogColorProperty = DependencyProperty.Register("FogColor", typeof(Color), typeof(ToneMappingEffect), new UIPropertyMetadata(Colors.White, PixelShaderConstantCallback(3))); + public static readonly DependencyProperty VignetteRadiusProperty = DependencyProperty.Register("VignetteRadius", typeof(double), typeof(ToneMappingEffect), new UIPropertyMetadata(0.35, PixelShaderConstantCallback(4))); + public static readonly DependencyProperty VignetteCenterProperty = DependencyProperty.Register("VignetteCenter", typeof(Point), typeof(ToneMappingEffect), new UIPropertyMetadata( new Point(0.5, 0.5), PixelShaderConstantCallback(5))); + public static readonly DependencyProperty BlueShiftProperty = DependencyProperty.Register("BlueShift", typeof(double), typeof(ToneMappingEffect), new UIPropertyMetadata(1.0, PixelShaderConstantCallback(6))); + + private readonly static PixelShader pixelShader; + + static ToneMappingEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("ToneMapping/ToneMapping.ps"); + } + + public ToneMappingEffect() + { + this.PixelShader = pixelShader; + + // Update each DependencyProperty that's registered with a shader register. This + // is needed to ensure the shader gets sent the proper default value. + UpdateShaderValue(InputProperty); + UpdateShaderValue(ExposureProperty); + UpdateShaderValue(DefogProperty); + UpdateShaderValue(GammaProperty); + UpdateShaderValue(FogColorProperty); + UpdateShaderValue(VignetteRadiusProperty); + UpdateShaderValue(VignetteCenterProperty); + UpdateShaderValue(BlueShiftProperty); + } + + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + + public double Exposure + { + get { return (double)GetValue(ExposureProperty); } + set { SetValue(ExposureProperty, value); } + } + public double Defog + { + get { return (double)GetValue(DefogProperty); } + set { SetValue(DefogProperty, value); } + } + public double Gamma + { + get { return (double)GetValue(GammaProperty); } + set { SetValue(GammaProperty, value); } + } + public Color FogColor + { + get { return (Color)GetValue(FogColorProperty); } + set { SetValue(FogColorProperty, value); } + } + public double VignetteRadius + { + get { return (double)GetValue(VignetteRadiusProperty); } + set { SetValue(VignetteRadiusProperty, value); } + } + public Point VignetteCenter + { + get { return (Point)GetValue(VignetteCenterProperty); } + set { SetValue(VignetteCenterProperty, value); } + } + public double BlueShift + { + get { return (double)GetValue(BlueShiftProperty); } + set { SetValue(BlueShiftProperty, value); } + } + } +} diff --git a/WpfExtended/Effects/ToonShader/ToonShader.fx b/WpfExtended/Effects/ToonShader/ToonShader.fx new file mode 100644 index 0000000..5f6a969 --- /dev/null +++ b/WpfExtended/Effects/ToonShader/ToonShader.fx @@ -0,0 +1,27 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- ToonEffect +// +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +// Sampler Inputs (Brushes, including ImplicitInput) +//-------------------------------------------------------------------------------------- + +sampler2D implicitInputSampler : register(S0); + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + float4 color = tex2D( implicitInputSampler, uv ); + + color *= 3; + color = floor(color); + color /= 3; + + return color; + +} diff --git a/WpfExtended/Effects/ToonShader/ToonShader.ps b/WpfExtended/Effects/ToonShader/ToonShader.ps new file mode 100644 index 0000000000000000000000000000000000000000..2cad8e2e322a1bf6d350c9f5386ed02d1c1d2bd9 GIT binary patch literal 288 zcmY*TI|{-;6r4l_3n7KA;DU`d5ooEnz z%kbXJzBdePV_v3)!MxY60PqP=v)EFO9HAiA_S?RTiCjm)IoQRbK5K~K*c%IPzuIggF$j*K (Brush)GetValue(InputProperty); + set => SetValue(InputProperty, value); + } + public Point BlurCenter + { + get => (Point)GetValue(BlurCenterProperty); + set => SetValue(BlurCenterProperty, value); + } + public double BlurMagnitude + { + get => (double)GetValue(BlurMagnitudeProperty); + set => SetValue(BlurMagnitudeProperty, value); + } + + public ZoomBlurEffect() + { + PixelShader = PixelShaderUtility.LoadPixelShader("ZoomBlur/ZoomBlurEffect.ps"); + + UpdateShaderValue(InputProperty); + UpdateShaderValue(BlurCenterProperty); + UpdateShaderValue(BlurMagnitudeProperty); + } + } +} \ No newline at end of file diff --git a/WpfExtended/Effects/ZoomBlur/ZoomBlurEffect.fx b/WpfExtended/Effects/ZoomBlur/ZoomBlurEffect.fx new file mode 100644 index 0000000..8efe192 --- /dev/null +++ b/WpfExtended/Effects/ZoomBlur/ZoomBlurEffect.fx @@ -0,0 +1,27 @@ +// Sampler Registers // + +sampler2D implicitInputSampler : register(S0); + +// Constants Registers // + +float2 blurCenter : register(C0); +float blurMagnitude : register(C1); + +// Pixel Shader // + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + const float STRENGTH = 0.02; + + uv -= blurCenter; + + float4 c = 0; + for (int i = 0; i < 15; i++) + { + float scale = 1.0 + (blurMagnitude * STRENGTH) * (i / 14.0); + c += tex2D(implicitInputSampler, uv * scale + blurCenter); + } + c /= 15; + + return c; +} \ No newline at end of file diff --git a/WpfExtended/Effects/ZoomBlur/ZoomBlurEffect.ps b/WpfExtended/Effects/ZoomBlur/ZoomBlurEffect.ps new file mode 100644 index 0000000000000000000000000000000000000000..c2871f09690b56a81a2691f4bb270b7348b0ff94 GIT binary patch literal 1476 zcmbtUJ#Q016r4Nz&Sxu%|3D-xrGX|&DDjafb^}sU5EF?mGO>X}iETNTev1@AqM)Fl zJPV1!N8vtnh=P_Tf51{Cegwz7`(jD41z3LGo7vg7@7~TDc9Q%`d~~1gcGduVWq@3T zgJA3eUpPEt*bIxm1CH_u88#UUE-q3Ac+XMRitcmHJwG|0c88;II7Mu6R^}{iZomI> z6olu4A>vq8OU7b8IGvmX$3ggbG&v7@eIm&c$5pKSrJI}`-9OsIesDY;pN(IHt-A;J zT95X6d#&E9{$Mz5b;qZZfQwsOn;Tn*p8$@HX0*2c!3We%*V{^jJkQL^NhNr)YWh4I_z-+P3h$V-ZBzw z5nEWQ0@E|f)-b)IDjKFoR8_e!C#REk>4RQsRdZfkz zOFcT4dUP!H=veB}vDBkusYl0Bk6`f@konXFA~!!Lliys-OP$GYE|OAb@*Cedvh#gS zezUo6p<^3)#((Zjhs6J$D|k-yP3n{49I~GM+qo3^BnR&R?|zowW?$0(3NOP+0{jLd C%Q_bT literal 0 HcmV?d00001 diff --git a/WpfExtended/License.txt b/WpfExtended/License.txt new file mode 100644 index 0000000..17ad228 --- /dev/null +++ b/WpfExtended/License.txt @@ -0,0 +1,8 @@ +The MIT License (MIT) +Copyright © 2021 Alexandru Macocian + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/WpfExtended/ShaderCompiler.target b/WpfExtended/ShaderCompiler.target new file mode 100644 index 0000000..42315a8 --- /dev/null +++ b/WpfExtended/ShaderCompiler.target @@ -0,0 +1,19 @@ + + + + $(ProjectDir) + $(SolutionDir)tools\fxc.exe + /O0 /T ps_2_0 /nologo /Fo + + + + + + <_ShaderFiles Include="$(ShaderDir)**\*.fx" /> + + + + + + + \ No newline at end of file diff --git a/WpfExtended/WpfExtended.csproj b/WpfExtended/WpfExtended.csproj new file mode 100644 index 0000000..427897d --- /dev/null +++ b/WpfExtended/WpfExtended.csproj @@ -0,0 +1,20 @@ + + + + net5.0-windows + true + true + true + License.txt + 0.1 + Extension library for Windows Presentation Platform. + + + + + True + + + + + diff --git a/tools/fxc.exe b/tools/fxc.exe new file mode 100644 index 0000000000000000000000000000000000000000..792ed265867ee9f980f7b95f24e87e4262d87a8d GIT binary patch literal 153032 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 Cal)+t literal 0 HcmV?d00001