commit 98e9d6d50f446833862ce0786a8a7ccbcd8a3c8c Author: Alexandru Macocian Date: Thu Apr 1 11:53:42 2021 +0200 Add project files. 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 0000000..718c413 Binary files /dev/null and b/WpfExtended/Effects/BandedSwirl/BandedSwirl.ps differ diff --git a/WpfExtended/Effects/BandedSwirl/BandedSwirlEffect.cs b/WpfExtended/Effects/BandedSwirl/BandedSwirlEffect.cs new file mode 100644 index 0000000..ddf97fa --- /dev/null +++ b/WpfExtended/Effects/BandedSwirl/BandedSwirlEffect.cs @@ -0,0 +1,62 @@ +// (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 BandedSwirlEffect : ShaderEffect + { + public static readonly DependencyProperty CenterProperty = DependencyProperty.Register("Center", typeof(Point), typeof(BandedSwirlEffect), new UIPropertyMetadata(new Point(0.5, 0.5), PixelShaderConstantCallback(0))); + public static readonly DependencyProperty SwirlStrengthProperty = DependencyProperty.Register("SwirlStrength", typeof(double), typeof(BandedSwirlEffect), new UIPropertyMetadata(0.5, PixelShaderConstantCallback(1))); + public static readonly DependencyProperty DistanceThresholdProperty = DependencyProperty.Register("DistanceThreshold", typeof(double), typeof(BandedSwirlEffect), new UIPropertyMetadata(0.2, PixelShaderConstantCallback(2))); + public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(BandedSwirlEffect), 0); + + private readonly static PixelShader pixelShader; + + static BandedSwirlEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("BandedSwirl/BandedSwirl.ps"); + } + + public BandedSwirlEffect() + { + this.PixelShader = pixelShader; + + UpdateShaderValue(CenterProperty); + UpdateShaderValue(SwirlStrengthProperty); + UpdateShaderValue(DistanceThresholdProperty); + UpdateShaderValue(InputProperty); + } + + public Point Center + { + get { return (Point)GetValue(CenterProperty); } + set { SetValue(CenterProperty, value); } + } + public double SwirlStrength + { + get { return (double)GetValue(SwirlStrengthProperty); } + set { SetValue(SwirlStrengthProperty, value); } + } + public double DistanceThreshold + { + get { return (double)GetValue(DistanceThresholdProperty); } + set { SetValue(DistanceThresholdProperty, 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/Bloom/Bloom.fx b/WpfExtended/Effects/Bloom/Bloom.fx new file mode 100644 index 0000000..b02dd6a --- /dev/null +++ b/WpfExtended/Effects/Bloom/Bloom.fx @@ -0,0 +1,51 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- BloomEffect +// +//-------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------------- +// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.) +//----------------------------------------------------------------------------------------- + +float BloomIntensity : register(C0); +float BaseIntensity : register(C1); +float BloomSaturation : 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 BloomThreshold = 0.25f; + + float4 base = tex2D(implicitInputSampler, uv); + float4 bloom = saturate((base - BloomThreshold) / (1 - BloomThreshold)); + + // Adjust color saturation and intensity. + bloom = AdjustSaturation(bloom, BloomSaturation) * BloomIntensity; + 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(bloom)); + + // Combine the two images. + return base + bloom; +} + + diff --git a/WpfExtended/Effects/Bloom/Bloom.ps b/WpfExtended/Effects/Bloom/Bloom.ps new file mode 100644 index 0000000..c8846e5 Binary files /dev/null and b/WpfExtended/Effects/Bloom/Bloom.ps differ diff --git a/WpfExtended/Effects/Bloom/BloomEffect.cs b/WpfExtended/Effects/Bloom/BloomEffect.cs new file mode 100644 index 0000000..db657fb --- /dev/null +++ b/WpfExtended/Effects/Bloom/BloomEffect.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 BloomEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = + ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(BloomEffect), 0); + public static readonly DependencyProperty BloomIntensityProperty = + DependencyProperty.Register("BloomIntensity", typeof(double), typeof(BloomEffect), new UIPropertyMetadata(1.0, PixelShaderConstantCallback(0))); + public static readonly DependencyProperty BaseIntensityProperty = + DependencyProperty.Register("BaseIntensity", typeof(double), typeof(BloomEffect), new UIPropertyMetadata(1.0, PixelShaderConstantCallback(1))); + public static readonly DependencyProperty BloomSaturationProperty = + DependencyProperty.Register("BloomSaturation", typeof(double), typeof(BloomEffect), new UIPropertyMetadata(1.0, PixelShaderConstantCallback(2))); + public static readonly DependencyProperty BaseSaturationProperty = + DependencyProperty.Register("BaseSaturation", typeof(double), typeof(BloomEffect), new UIPropertyMetadata(1.0, PixelShaderConstantCallback(3))); + + private readonly static PixelShader pixelShader = new PixelShader(); + + static BloomEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("Bloom/Bloom.ps"); + } + + public BloomEffect() + { + 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(BloomIntensityProperty); + UpdateShaderValue(BaseIntensityProperty); + UpdateShaderValue(BloomSaturationProperty); + UpdateShaderValue(BaseSaturationProperty); + } + + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + public double BloomIntensity + { + get { return (double)GetValue(BloomIntensityProperty); } + set { SetValue(BloomIntensityProperty, value); } + } + public double BaseIntensity + { + get { return (double)GetValue(BaseIntensityProperty); } + set { SetValue(BaseIntensityProperty, value); } + } + public double BloomSaturation + { + get { return (double)GetValue(BloomSaturationProperty); } + set { SetValue(BloomSaturationProperty, value); } + } + public double BaseSaturation + { + get { return (double)GetValue(BaseSaturationProperty); } + set { SetValue(BaseSaturationProperty, value); } + } + } +} diff --git a/WpfExtended/Effects/BrightExtract/BrightExtract.fx b/WpfExtended/Effects/BrightExtract/BrightExtract.fx new file mode 100644 index 0000000..383ad2e --- /dev/null +++ b/WpfExtended/Effects/BrightExtract/BrightExtract.fx @@ -0,0 +1,33 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- BrightExtractEffect +// +//-------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------------- +// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.) +//----------------------------------------------------------------------------------------- + +float Threshold : register(C0); + +//-------------------------------------------------------------------------------------- +// Sampler Inputs (Brushes, including ImplicitInput) +//-------------------------------------------------------------------------------------- + +sampler2D implicitInputSampler : register(S0); + + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + // Look up the original image color. + float4 c = tex2D(implicitInputSampler, uv); + + // Adjust it to keep only values brighter than the specified threshold. + return saturate((c - Threshold) / (1 - Threshold)); +} + + diff --git a/WpfExtended/Effects/BrightExtract/BrightExtract.ps b/WpfExtended/Effects/BrightExtract/BrightExtract.ps new file mode 100644 index 0000000..41a06db Binary files /dev/null and b/WpfExtended/Effects/BrightExtract/BrightExtract.ps differ 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 0000000..dc92707 Binary files /dev/null and b/WpfExtended/Effects/ColorKeyAlpha/ColorKeyAlpha.ps differ diff --git a/WpfExtended/Effects/ColorKeyAlpha/ColorKeyAlphaEffect.cs b/WpfExtended/Effects/ColorKeyAlpha/ColorKeyAlphaEffect.cs new file mode 100644 index 0000000..71762b6 --- /dev/null +++ b/WpfExtended/Effects/ColorKeyAlpha/ColorKeyAlphaEffect.cs @@ -0,0 +1,38 @@ +// (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 +{ + public class ColorKeyAlphaEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(ColorKeyAlphaEffect), 0); + + private readonly static PixelShader pixelShader; + + static ColorKeyAlphaEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("ColorKeyAlpha/ColorKeyAlpha.ps"); + } + + public ColorKeyAlphaEffect() + { + this.PixelShader = pixelShader; + + UpdateShaderValue(InputProperty); + } + + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + } +} diff --git a/WpfExtended/Effects/ColorTone/ColorTone.fx b/WpfExtended/Effects/ColorTone/ColorTone.fx new file mode 100644 index 0000000..c167413 --- /dev/null +++ b/WpfExtended/Effects/ColorTone/ColorTone.fx @@ -0,0 +1,39 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- ColorToneEffect +// +//-------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------------- +// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.) +//----------------------------------------------------------------------------------------- + +float Desaturation : register(C0); +float Toned : register(C1); +float4 LightColor : register(C2); +float4 DarkColor : register(C3); + +//-------------------------------------------------------------------------------------- +// Sampler Inputs (Brushes, including ImplicitInput) +//-------------------------------------------------------------------------------------- + +sampler2D implicitInputSampler : register(S0); + + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + float4 scnColor = LightColor * tex2D(implicitInputSampler, uv); + float gray = dot(float3(0.3, 0.59, 0.11), scnColor.rgb); + + float3 muted = lerp(scnColor.rgb, gray.xxx, Desaturation); + float3 middle = lerp(DarkColor, LightColor, gray); + + scnColor.rgb = lerp(muted, middle, Toned); + return scnColor; +} + + diff --git a/WpfExtended/Effects/ColorTone/ColorTone.ps b/WpfExtended/Effects/ColorTone/ColorTone.ps new file mode 100644 index 0000000..0113ee2 Binary files /dev/null and b/WpfExtended/Effects/ColorTone/ColorTone.ps differ 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 0000000..7f8ffc4 Binary files /dev/null and b/WpfExtended/Effects/ContrastAdjust/ContrastAdjust.ps differ 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 0000000..f135258 Binary files /dev/null and b/WpfExtended/Effects/DirectionalBlur/DirectionalBlur.ps differ diff --git a/WpfExtended/Effects/DirectionalBlur/DirectionalBlurEffect.cs b/WpfExtended/Effects/DirectionalBlur/DirectionalBlurEffect.cs new file mode 100644 index 0000000..dec56a3 --- /dev/null +++ b/WpfExtended/Effects/DirectionalBlur/DirectionalBlurEffect.cs @@ -0,0 +1,54 @@ +// (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 DirectionalBlurEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(DirectionalBlurEffect), 0); + public static readonly DependencyProperty AngleProperty = DependencyProperty.Register("Angle", typeof(double), typeof(DirectionalBlurEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(0))); + public static readonly DependencyProperty BlurAmountProperty = DependencyProperty.Register("BlurAmount", typeof(double), typeof(DirectionalBlurEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(1))); + + private readonly static PixelShader pixelShader; + + static DirectionalBlurEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("DirectionalBlur/DirectionalBlur.ps"); + } + + public DirectionalBlurEffect() + { + this.PixelShader = pixelShader; + UpdateShaderValue(InputProperty); + UpdateShaderValue(AngleProperty); + UpdateShaderValue(BlurAmountProperty); + } + + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + public double Angle + { + get { return (double)GetValue(AngleProperty); } + set { SetValue(AngleProperty, ((value % 360) + 360) % 360); } + } + public double BlurAmount + { + get { return (double)GetValue(BlurAmountProperty); } + set { SetValue(BlurAmountProperty, value); } + } + } +} diff --git a/WpfExtended/Effects/Embossed/Embossed.fx b/WpfExtended/Effects/Embossed/Embossed.fx new file mode 100644 index 0000000..7366aa1 --- /dev/null +++ b/WpfExtended/Effects/Embossed/Embossed.fx @@ -0,0 +1,36 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- EmbossedEffect +// +//-------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------------- +// 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 outC = {0.5, 0.5, 0.5, 1.0}; + + outC -= tex2D(implicitInputSampler, uv - Width) * Amount; + outC += tex2D(implicitInputSampler, uv + Width) * Amount; + outC.rgb = (outC.r + outC.g + outC.b) / 3.0f; + + return outC; +} + + diff --git a/WpfExtended/Effects/Embossed/Embossed.ps b/WpfExtended/Effects/Embossed/Embossed.ps new file mode 100644 index 0000000..115486b Binary files /dev/null and b/WpfExtended/Effects/Embossed/Embossed.ps differ 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 0000000..06bc3df Binary files /dev/null and b/WpfExtended/Effects/Gloom/Gloom.ps differ 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 0000000..117f1d1 Binary files /dev/null and b/WpfExtended/Effects/GrowablePoissonDisk/GrowablePoissonDisk.ps differ 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 0000000..8b02f7a Binary files /dev/null and b/WpfExtended/Effects/InvertColor/InvertColor.ps differ diff --git a/WpfExtended/Effects/InvertColor/InvertColorEffect.cs b/WpfExtended/Effects/InvertColor/InvertColorEffect.cs new file mode 100644 index 0000000..13050d8 --- /dev/null +++ b/WpfExtended/Effects/InvertColor/InvertColorEffect.cs @@ -0,0 +1,38 @@ +// (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 +{ + public class InvertColorEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(InvertColorEffect), 0); + + private readonly static PixelShader pixelShader; + + static InvertColorEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("InvertColor/InvertColor.ps"); + } + + public InvertColorEffect() + { + this.PixelShader = pixelShader; + + UpdateShaderValue(InputProperty); + } + + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + } +} diff --git a/WpfExtended/Effects/LightStreak/LightStreak.fx b/WpfExtended/Effects/LightStreak/LightStreak.fx new file mode 100644 index 0000000..de2224b --- /dev/null +++ b/WpfExtended/Effects/LightStreak/LightStreak.fx @@ -0,0 +1,50 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- LightStreakEffect +// +//-------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------------- +// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.) +//----------------------------------------------------------------------------------------- + +float BrightThreshold : register(C0); +float Scale : register(C1); +float Attenuation : Attenuation : register(C2); + +//-------------------------------------------------------------------------------------- +// Sampler Inputs (Brushes, including ImplicitInput) +//-------------------------------------------------------------------------------------- + +sampler2D implicitInputSampler : register(S0); + + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + float2 Direction = {1.0f, 1.0f}; + float2 PixelSize = {0.0009766f, 0.0013021f}; + const static int numSamples = 2; + int Iteration = 1.0; + + float4 pixelColor = tex2D(implicitInputSampler, uv); + float4 bright = saturate((pixelColor - BrightThreshold) / (1 - BrightThreshold)); + + pixelColor += bright; + + float weightIter = pow(numSamples, Iteration); + + for(int sample=0; sample 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 0000000..3a8a767 Binary files /dev/null and b/WpfExtended/Effects/Magnify/Magnify.ps differ diff --git a/WpfExtended/Effects/Magnify/MagnifyEffect.cs b/WpfExtended/Effects/Magnify/MagnifyEffect.cs new file mode 100644 index 0000000..9150bd3 --- /dev/null +++ b/WpfExtended/Effects/Magnify/MagnifyEffect.cs @@ -0,0 +1,163 @@ +// (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 ; + using Vector = System.Windows.Point ; +#endif + public class MagnifyEffect : ShaderEffect + { + public static readonly DependencyProperty RadiiProperty = DependencyProperty.Register("Radii", typeof(Size), typeof(MagnifyEffect), new UIPropertyMetadata(new Size(0.2, 0.2), PixelShaderConstantCallback(0))); + public static readonly DependencyProperty CenterProperty = DependencyProperty.Register("Center", typeof(Point), typeof(MagnifyEffect), new UIPropertyMetadata(new Point(0.25, 0.25), PixelShaderConstantCallback(1))); + public static readonly DependencyProperty ShrinkFactorProperty = DependencyProperty.Register("ShrinkFactor", typeof(double), typeof(MagnifyEffect), new UIPropertyMetadata(0.5, PixelShaderConstantCallback(2))); + public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(MagnifyEffect), 0); + + private readonly static PixelShader pixelShader; + private readonly MagnifyGeneralTransform generalTransform; + + static MagnifyEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("Magnify/Magnify.ps"); + } + + public MagnifyEffect() + { + this.PixelShader = pixelShader; + + UpdateShaderValue(RadiiProperty); + UpdateShaderValue(CenterProperty); + UpdateShaderValue(ShrinkFactorProperty); + UpdateShaderValue(InputProperty); + + this.generalTransform = new MagnifyGeneralTransform(this); + } + + public Size Radii + { + get { return (Size)GetValue(RadiiProperty); } + set { SetValue(RadiiProperty, value); } + } + public Point Center + { + get { return (Point)GetValue(CenterProperty); } + set { SetValue(CenterProperty, value); } + } + public double ShrinkFactor + { + get { return (double)GetValue(ShrinkFactorProperty); } + set { SetValue(ShrinkFactorProperty, value); } + } + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + + protected override GeneralTransform EffectMapping + { + get + { + return this.generalTransform; + } + } + + private class MagnifyGeneralTransform : GeneralTransform + { + private readonly MagnifyEffect effect; + private bool thisIsInverse; + private MagnifyGeneralTransform inverseTransform; + public MagnifyGeneralTransform(MagnifyEffect fx) + { + this.effect = fx; + } + public override GeneralTransform Inverse + { + get + { + // Cache this since it can get called often + if (this.inverseTransform == null) + { +#if !SILVERLIGHT + this.inverseTransform = (MagnifyGeneralTransform)this.Clone(); +#else + this.inverseTransform = new MagnifyGeneralTransform( this.effect) ; +#endif + this.inverseTransform.thisIsInverse = !this.thisIsInverse; + } + + return this.inverseTransform; + } + } + public override Rect TransformBounds(Rect rect) + { + Rect result; + bool ok1 = this.TryTransform( new Point ( rect.Left, rect.Top ) , out Point tl); + bool ok2 = this.TryTransform( new Point ( rect.Right, rect.Bottom ), out Point br); + if (ok1 && ok2) + { + result = new Rect(tl, br); + } + else + { + result = Rect.Empty; + } + + return result; + } + public override bool TryTransform(Point targetPoint, out Point result) + { + // In this particular case, the inverse transform is the same as the forward + // transform. + if (!this.PointIsInEllipse(targetPoint, this.effect.Center, this.effect.Radii)) + { + // If outside the ellipse, just the identity. + result = targetPoint; + } + else + { + // If inside the ellipse, calculate that magnification/minification + Point center = this.effect.Center; + Point ray = new Point(targetPoint.X - center.X, targetPoint.Y - center.Y); + + // Inverse maps a point from after the effect was applied to the point that it came from before the effect. + // Non-inverse maps where a point before the effect is applied goes after the effect is applied. + // The operation the shader itself performs should match up with the "inverse" operation here. + double scaleFactor = this.thisIsInverse ? this.effect.ShrinkFactor : 1.0 / this.effect.ShrinkFactor; + + result = new Point(center.X + scaleFactor * ray.X, center.Y + scaleFactor * ray.Y); + } + + return true; + } + +#if !SILVERLIGHT + protected override Freezable CreateInstanceCore() + { + return new MagnifyGeneralTransform(this.effect) { thisIsInverse = this.thisIsInverse }; + } +#endif + private bool PointIsInEllipse(Point pt, Point center, Size radii) + { + Point ray = new Point ( pt.X - center.X , pt.Y - center.Y) ; + double rayPctX = ray.X / radii.Width; + double rayPctY = ray.Y / radii.Height; + + // Normally would take sqrt() for length, but since we're comparing + // to 1.0, it doesn't matter. + double pctLength = rayPctX * rayPctX + rayPctY * rayPctY; + + return pctLength <= 1.0; + } + } + } +} diff --git a/WpfExtended/Effects/MonoChrome/Monochrome.fx b/WpfExtended/Effects/MonoChrome/Monochrome.fx new file mode 100644 index 0000000..e854055 --- /dev/null +++ b/WpfExtended/Effects/MonoChrome/Monochrome.fx @@ -0,0 +1,33 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- MonoChromeEffect +// +//-------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------------- +// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.) +//----------------------------------------------------------------------------------------- + +float4 filterColor : register(C0); + +//-------------------------------------------------------------------------------------- +// Sampler Inputs (Brushes, including ImplicitInput) +//-------------------------------------------------------------------------------------- + +sampler2D implicitInputSampler : register(S0); + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + float2 texuv = uv; + float4 srcColor = tex2D(implicitInputSampler, texuv); + float4 luminance = srcColor.r*0.30 + srcColor.g*0.59 + srcColor.b*0.11; + luminance.a = 1.0; + + return luminance * filterColor; +} + + diff --git a/WpfExtended/Effects/MonoChrome/Monochrome.ps b/WpfExtended/Effects/MonoChrome/Monochrome.ps new file mode 100644 index 0000000..ef8936c Binary files /dev/null and b/WpfExtended/Effects/MonoChrome/Monochrome.ps differ 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 0000000..2f92eff Binary files /dev/null and b/WpfExtended/Effects/MotionBlur/MotionBlurEffect.ps differ 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 0000000..027e032 Binary files /dev/null and b/WpfExtended/Effects/Negative/NegativeEffect.ps differ diff --git a/WpfExtended/Effects/Pinch/Pinch.fx b/WpfExtended/Effects/Pinch/Pinch.fx new file mode 100644 index 0000000..cbcd1e2 --- /dev/null +++ b/WpfExtended/Effects/Pinch/Pinch.fx @@ -0,0 +1,35 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- PinchEffect +// +//-------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------------- +// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.) +//----------------------------------------------------------------------------------------- + +float CenterX : register(C0); +float CenterY : register(C1); +float Radius : register(C2); +float Amount : register(C3); + +//-------------------------------------------------------------------------------------- +// Sampler Inputs (Brushes, including ImplicitInput) +//-------------------------------------------------------------------------------------- + +sampler2D implicitInputSampler : register(S0); + + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + float2 center = { CenterX, CenterY }; + float2 displace = center - uv; + float range = saturate(1 - (length(displace) / (abs(-sin(Radius * 8) * Radius) + 0.00000001F))); + return tex2D(implicitInputSampler, uv + displace * range * Amount); +} + + diff --git a/WpfExtended/Effects/Pinch/Pinch.ps b/WpfExtended/Effects/Pinch/Pinch.ps new file mode 100644 index 0000000..dc99482 Binary files /dev/null and b/WpfExtended/Effects/Pinch/Pinch.ps differ 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 0000000..5a5202c Binary files /dev/null and b/WpfExtended/Effects/Pixelate/Pixelate.ps differ 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 0000000..185e6bc Binary files /dev/null and b/WpfExtended/Effects/Ripple/Ripple.ps differ 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 0000000..32a9f4a Binary files /dev/null and b/WpfExtended/Effects/Sharpen/Sharpen.ps differ diff --git a/WpfExtended/Effects/Sharpen/SharpenEffect.cs b/WpfExtended/Effects/Sharpen/SharpenEffect.cs new file mode 100644 index 0000000..031d883 --- /dev/null +++ b/WpfExtended/Effects/Sharpen/SharpenEffect.cs @@ -0,0 +1,56 @@ +// (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 SharpenEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(SharpenEffect), 0); + public static readonly DependencyProperty AmountProperty = DependencyProperty.Register("Amount", typeof(double), typeof(SharpenEffect), new UIPropertyMetadata(15.0, PixelShaderConstantCallback(0))); + public static readonly DependencyProperty WidthProperty = DependencyProperty.Register("Width", typeof(double), typeof(SharpenEffect), new UIPropertyMetadata(0.0001, PixelShaderConstantCallback(1))); + + private readonly static PixelShader pixelShader = new PixelShader(); + + static SharpenEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("Sharpen/Sharpen.ps"); + } + + public SharpenEffect() + { + 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/SmoothMagnify/SmoothMagnify.fx b/WpfExtended/Effects/SmoothMagnify/SmoothMagnify.fx new file mode 100644 index 0000000..d366980 --- /dev/null +++ b/WpfExtended/Effects/SmoothMagnify/SmoothMagnify.fx @@ -0,0 +1,60 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- SmoothMagnifyEffect +// +//-------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------------- +// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.) +//----------------------------------------------------------------------------------------- + +float2 center : register(C0); +float inner_radius: register(C2); +float magnification : register(c3); +float outer_radius : register(c4); + +//-------------------------------------------------------------------------------------- +// Sampler Inputs (Brushes, including ImplicitInput) +//-------------------------------------------------------------------------------------- + +sampler2D implicitInputSampler : register(S0); + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + + + float2 center_to_pixel = uv - center; // vector from center to pixel + + float distance = length(center_to_pixel); + + float4 color; + + float2 sample_point; + + if(distance < outer_radius) { + + if( distance < inner_radius ) { + sample_point = center + (center_to_pixel / magnification); + } + else { + float radius_diff = outer_radius - inner_radius; + float ratio = (distance - inner_radius ) / radius_diff; // 0 == inner radius, 1 == outer_radius + ratio = ratio * 3.14159; // -pi/2 .. pi/2 + float adjusted_ratio = cos( ratio ); // -1 .. 1 + adjusted_ratio = adjusted_ratio + 1; // 0 .. 2 + adjusted_ratio = adjusted_ratio / 2; // 0 .. 1 + + sample_point = ( (center + (center_to_pixel / magnification) ) * ( adjusted_ratio)) + ( uv * ( 1 - adjusted_ratio) ); + } + } + else { + sample_point = uv; + } + + return tex2D( implicitInputSampler, sample_point ); + +} diff --git a/WpfExtended/Effects/SmoothMagnify/SmoothMagnify.ps b/WpfExtended/Effects/SmoothMagnify/SmoothMagnify.ps new file mode 100644 index 0000000..0138f2e Binary files /dev/null and b/WpfExtended/Effects/SmoothMagnify/SmoothMagnify.ps differ diff --git a/WpfExtended/Effects/SmoothMagnify/SmoothMagnifyEffect.cs b/WpfExtended/Effects/SmoothMagnify/SmoothMagnifyEffect.cs new file mode 100644 index 0000000..e2bbc02 --- /dev/null +++ b/WpfExtended/Effects/SmoothMagnify/SmoothMagnifyEffect.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 SmoothMagnifyEffect : ShaderEffect + { + public static readonly DependencyProperty CenterProperty = DependencyProperty.Register("Center", typeof(Point), typeof(SmoothMagnifyEffect), new UIPropertyMetadata(new Point(0.5, 0.5), PixelShaderConstantCallback(0))); + public static readonly DependencyProperty InnerRadiusProperty = DependencyProperty.Register("InnerRadius", typeof(double), typeof(SmoothMagnifyEffect), new UIPropertyMetadata(.2, PixelShaderConstantCallback(2))); + public static readonly DependencyProperty MagnificationProperty = DependencyProperty.Register("Magnification", typeof(double), typeof(SmoothMagnifyEffect), new UIPropertyMetadata(2.0, PixelShaderConstantCallback(3))); + public static readonly DependencyProperty OuterRadiusProperty = DependencyProperty.Register("OuterRadius", typeof(double), typeof(SmoothMagnifyEffect), new UIPropertyMetadata(.27, PixelShaderConstantCallback(4))); + public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(SmoothMagnifyEffect), 0); + + private readonly static PixelShader pixelShader; + + static SmoothMagnifyEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("SmoothMagnify/SmoothMagnify.ps"); + } + + public SmoothMagnifyEffect() + { + this.PixelShader = pixelShader; + + UpdateShaderValue(CenterProperty); + UpdateShaderValue(InnerRadiusProperty); + UpdateShaderValue(OuterRadiusProperty); + UpdateShaderValue(MagnificationProperty); + UpdateShaderValue(InputProperty); + } + + public Point Center + { + get { return (Point)GetValue(CenterProperty); } + set { SetValue(CenterProperty, value); } + } + public double InnerRadius + { + get { return (double)GetValue(InnerRadiusProperty); } + set { SetValue(InnerRadiusProperty, value); } + } + public double Magnification + { + get { return (double)GetValue(MagnificationProperty); } + set { SetValue(MagnificationProperty, value); } + } + public double OuterRadius + { + get { return (double)GetValue(OuterRadiusProperty); } + set { SetValue(OuterRadiusProperty, value); } + } + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + } +} diff --git a/WpfExtended/Effects/Swirl/Swirl.fx b/WpfExtended/Effects/Swirl/Swirl.fx new file mode 100644 index 0000000..b681325 --- /dev/null +++ b/WpfExtended/Effects/Swirl/Swirl.fx @@ -0,0 +1,40 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- SwirlEffect +// +//-------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------------- +// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.) +//----------------------------------------------------------------------------------------- + +float2 center : register(C0); +float spiralStrength : register(C1); +float2 angleFrequency : 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); + float angle = atan2(dir.y, dir.x); + + float newAng = angle + spiralStrength * l; + float xAmt = cos(angleFrequency.x * newAng) * l; + float yAmt = sin(angleFrequency.y * newAng) * l; + + float2 newCoord = center + float2(xAmt, yAmt); + + return tex2D( implicitInputSampler, newCoord ); +} + + diff --git a/WpfExtended/Effects/Swirl/Swirl.ps b/WpfExtended/Effects/Swirl/Swirl.ps new file mode 100644 index 0000000..b93f682 Binary files /dev/null and b/WpfExtended/Effects/Swirl/Swirl.ps differ diff --git a/WpfExtended/Effects/Swirl/SwirlEffect.cs b/WpfExtended/Effects/Swirl/SwirlEffect.cs new file mode 100644 index 0000000..2d08327 --- /dev/null +++ b/WpfExtended/Effects/Swirl/SwirlEffect.cs @@ -0,0 +1,150 @@ +// (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; +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Effects; + +namespace WpfExtended.Effects +{ +#if SILVERLIGHT + using UIPropertyMetadata = System.Windows.PropertyMetadata ; + using Vector = System.Windows.Point ; +#endif + public class SwirlEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(SwirlEffect), 0); + public static readonly DependencyProperty CenterProperty = DependencyProperty.Register("Center", typeof(Point), typeof(SwirlEffect), new UIPropertyMetadata(new Point(0.5, 0.5), PixelShaderConstantCallback(0))); + public static readonly DependencyProperty SwirlStrengthProperty = DependencyProperty.Register("SwirlStrength", typeof(double), typeof(SwirlEffect), new UIPropertyMetadata(0.5, PixelShaderConstantCallback(1))); + public static readonly DependencyProperty AngleFrequencyProperty = DependencyProperty.Register("AngleFrequency", typeof(Vector), typeof(SwirlEffect), new UIPropertyMetadata(new Vector(1, 1), PixelShaderConstantCallback(2))); + + private readonly static PixelShader pixelShader; + private readonly SwirlGeneralTransform generalTransform; + + static SwirlEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("SwirlEffect/SwirlEffect.ps"); + } + + public SwirlEffect() + { + this.PixelShader = pixelShader; + + UpdateShaderValue(CenterProperty); + UpdateShaderValue(SwirlStrengthProperty); + UpdateShaderValue(AngleFrequencyProperty); + UpdateShaderValue(InputProperty); + + this.generalTransform = new SwirlGeneralTransform(this); + } + + public Point Center + { + get { return (Point)GetValue(CenterProperty); } + set { SetValue(CenterProperty, value); } + } + public double SwirlStrength + { + get { return (double)GetValue(SwirlStrengthProperty); } + set { SetValue(SwirlStrengthProperty, value); } + } + public Vector AngleFrequency + { + get { return (Vector)GetValue(AngleFrequencyProperty); } + set { SetValue(AngleFrequencyProperty, value); } + } + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + protected override GeneralTransform EffectMapping + { + get + { + return this.generalTransform; + } + } + private class SwirlGeneralTransform : GeneralTransform + { + private readonly SwirlEffect theEffect; + private bool thisIsInverse; + private SwirlGeneralTransform inverseTransform; + public SwirlGeneralTransform(SwirlEffect eff) + { + this.theEffect = eff; + } + public override GeneralTransform Inverse + { + get + { + // Cache this since it can get called often + if (this.inverseTransform == null) + { +#if !SILVERLIGHT + this.inverseTransform = (SwirlGeneralTransform)this.Clone(); +#else + this.inverseTransform = new SwirlGeneralTransform (this.theEffect); +#endif + this.inverseTransform.thisIsInverse = !this.thisIsInverse; + } + + return this.inverseTransform; + } + } + public override Rect TransformBounds(Rect rect) + { + if (this.TryTransform(new Point(rect.Left, rect.Top), out Point tl) && + this.TryTransform(new Point(rect.Right, rect.Top), out Point tr) && + this.TryTransform(new Point(rect.Left, rect.Bottom), out Point bl) && + this.TryTransform(new Point(rect.Right, rect.Bottom), out Point br)) + { + double maxX = Math.Max(tl.X, Math.Max(tr.X, Math.Max(bl.X, br.X))); + double minX = Math.Min(tl.X, Math.Min(tr.X, Math.Min(bl.X, br.X))); + + double maxY = Math.Max(tl.Y, Math.Max(tr.Y, Math.Max(bl.Y, br.Y))); + double minY = Math.Min(tl.Y, Math.Min(tr.Y, Math.Min(bl.Y, br.Y))); + + return new Rect(minX, minY, maxX - minX, maxY - minY); + } + else + { + return Rect.Empty; + } + } + public override bool TryTransform(Point targetPoint, out Point result) + { + // Exactly follows what the HLSL shader itself does. + Point dir = new Point(targetPoint.X - this.theEffect.Center.X, targetPoint.Y - this.theEffect.Center.Y); + double l = Math.Sqrt(dir.X * dir.X + dir.Y * dir.Y); + dir.X /= l; + dir.Y /= l; + + + double angle = Math.Atan2(dir.Y, dir.X); + + double inverseFactor = this.thisIsInverse ? 1 : -1; + double newAngle = angle + inverseFactor * this.theEffect.SwirlStrength * l; + + Point angleFrequency = new Point(this.theEffect.AngleFrequency.X, this.theEffect.AngleFrequency.Y); + double xamt = Math.Cos(angleFrequency.X * newAngle) * l; + double yamt = Math.Sin(angleFrequency.Y * newAngle) * l; + + result = new Point ( this.theEffect.Center.X + xamt, + this.theEffect.Center.Y + yamt); + + return true; + } +#if !SILVERLIGHT + protected override Freezable CreateInstanceCore() + { + return new SwirlGeneralTransform(this.theEffect) { thisIsInverse = this.thisIsInverse }; + } +#endif + } + } +} diff --git a/WpfExtended/Effects/ToneMapping/ToneMapping.fx b/WpfExtended/Effects/ToneMapping/ToneMapping.fx new file mode 100644 index 0000000..34b7c9c --- /dev/null +++ b/WpfExtended/Effects/ToneMapping/ToneMapping.fx @@ -0,0 +1,47 @@ +//-------------------------------------------------------------------------------------- +// +// WPF ShaderEffect HLSL -- ToneMappingEffect +// +//-------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------------- +// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.) +//----------------------------------------------------------------------------------------- + +float Exposure : register(C0); +float Defog : register(C1); +float Gamma : register(C2); +float4 FogColor : register(C3); +float VignetteRadius : register(C4); +float2 VignetteCenter : register(C5); +float BlueShift : register(C6); + +//-------------------------------------------------------------------------------------- +// Sampler Inputs (Brushes, including ImplicitInput) +//-------------------------------------------------------------------------------------- + +sampler2D implicitInputSampler : register(S0); + + +//-------------------------------------------------------------------------------------- +// Pixel Shader +//-------------------------------------------------------------------------------------- + +float4 main(float2 uv : TEXCOORD) : COLOR +{ + float4 c = tex2D(implicitInputSampler, uv); + c.rgb = max(0, c.rgb - Defog * FogColor.rgb); + c.rgb *= pow(2.0f, Exposure); + c.rgb = pow(c.rgb, Gamma); + + float2 tc = uv - VignetteCenter; + float v = 1.0f - dot(tc, tc); + c.rgb += pow(v, 4) * VignetteRadius; + + float3 d = c.rgb * float3(1.05f, 0.97f, 1.27f); + c.rgb = lerp(c.rgb, d, BlueShift); + + return c; +} + + diff --git a/WpfExtended/Effects/ToneMapping/ToneMapping.ps b/WpfExtended/Effects/ToneMapping/ToneMapping.ps new file mode 100644 index 0000000..49910aa Binary files /dev/null and b/WpfExtended/Effects/ToneMapping/ToneMapping.ps differ 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 0000000..2cad8e2 Binary files /dev/null and b/WpfExtended/Effects/ToonShader/ToonShader.ps differ diff --git a/WpfExtended/Effects/ToonShader/ToonShaderEffect.cs b/WpfExtended/Effects/ToonShader/ToonShaderEffect.cs new file mode 100644 index 0000000..ceb9ec7 --- /dev/null +++ b/WpfExtended/Effects/ToonShader/ToonShaderEffect.cs @@ -0,0 +1,44 @@ +// (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 +{ + public class ToonShaderEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = + ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(ToonShaderEffect), 0); + + private static readonly PixelShader pixelShader; + + static ToonShaderEffect() + { + pixelShader = PixelShaderUtility.LoadPixelShader("ToonShader/ToonShader.ps"); + + // Just saying hardware only for now since our drop of sw doesn't have sin/cos in + // it, and thus we can't validate against that. +#if !SILVERLIGHT + // TODO: + pixelShader.ShaderRenderMode = ShaderRenderMode.HardwareOnly; +#endif + } + + public ToonShaderEffect() + { + this.PixelShader = pixelShader; + UpdateShaderValue(InputProperty); + } + + [System.ComponentModel.BrowsableAttribute(false)] + public Brush Input + { + get { return (Brush)GetValue(InputProperty); } + set { SetValue(InputProperty, value); } + } + } +} diff --git a/WpfExtended/Effects/ZoomBlur/ZoomBlurEffect.cs b/WpfExtended/Effects/ZoomBlur/ZoomBlurEffect.cs new file mode 100644 index 0000000..0e00b22 --- /dev/null +++ b/WpfExtended/Effects/ZoomBlur/ZoomBlurEffect.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 ZoomBlurEffect : ShaderEffect + { + public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty(nameof(Input), typeof(ZoomBlurEffect), 0); + public static readonly DependencyProperty BlurCenterProperty = + DependencyProperty.Register(nameof(BlurCenter), typeof(Point), typeof(ZoomBlurEffect), new UIPropertyMetadata(new Point(0.5D, 0.5D), PixelShaderConstantCallback(0))); + public static readonly DependencyProperty BlurMagnitudeProperty = + DependencyProperty.Register(nameof(BlurMagnitude), typeof(double), typeof(ZoomBlurEffect), new UIPropertyMetadata(5D, PixelShaderConstantCallback(1))); + + public Brush Input + { + get => (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 0000000..c2871f0 Binary files /dev/null and b/WpfExtended/Effects/ZoomBlur/ZoomBlurEffect.ps differ 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 0000000..792ed26 Binary files /dev/null and b/tools/fxc.exe differ