├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── Tools
├── pscompiler.deps.json
├── pscompiler.dll
├── pscompiler.runtimeconfig.dev.json
└── pscompiler.runtimeconfig.json
├── WPF-Pixel-Shader-Library.sln
├── WPFTestApplication
├── App.xaml
├── App.xaml.cs
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── Resources
│ └── testimage.jpg
└── WPFTestApplication.csproj
├── capture.png
├── pscompiler
├── Program.cs
└── pscompiler.csproj
└── wpfpslib
├── Effects.cs
├── ShaderEffectBase.cs
├── ps-compiled
├── BlackHole.ps
├── BlurBehind.ps
├── CubicChromaticAbberation.ps
├── CubicLensDistortion.ps
├── DiagonalPixelation.ps
├── GlassTiles.ps
├── HexagonalPixelation.ps
├── Invert.ps
├── LinearChromaticAbberation.ps
├── NormalMap.ps
├── Pixelation.ps
├── Ripple.ps
├── RoundedGlassTiles.ps
├── SpasticChromaticAbberation.ps
└── TelescopicBlur.ps
├── ps-hlsl
├── BlackHole.fx
├── BlurBehind.fx
├── CubicChromaticAbberation.fx
├── CubicLensDistortion.fx
├── DiagonalPixelation.fx
├── GlassTiles.fx
├── HexagonalPixelation.fx
├── Invert.fx
├── LinearChromaticAbberation.fx
├── NormalMap.fx
├── Pixelation.fx
├── Ripple.fx
├── RoundedGlassTiles.fx
├── SpasticChromaticAbberation.fx
└── TelescopicBlur.fx
├── wpfpslib.csproj
└── wpfpslib.xml
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | publish.bat
2 |
3 | ## Ignore Visual Studio temporary files, build results, and
4 | ## files generated by popular Visual Studio add-ons.
5 |
6 | # User-specific files
7 | *.suo
8 | *.user
9 | *.userosscache
10 | *.sln.docstates
11 |
12 | # User-specific files (MonoDevelop/Xamarin Studio)
13 | *.userprefs
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | [Rr]eleases/
20 | x64/
21 | x86/
22 | bld/
23 | [Bb]in/
24 | [Oo]bj/
25 | [Ll]og/
26 |
27 | # Visual Studio 2015 cache/options directory
28 | .vs/
29 | # Uncomment if you have tasks that create the project's static files in wwwroot
30 | #wwwroot/
31 |
32 | # MSTest test Results
33 | [Tt]est[Rr]esult*/
34 | [Bb]uild[Ll]og.*
35 |
36 | # NUNIT
37 | *.VisualState.xml
38 | TestResult.xml
39 |
40 | # Build Results of an ATL Project
41 | [Dd]ebugPS/
42 | [Rr]eleasePS/
43 | dlldata.c
44 |
45 | # DNX
46 | project.lock.json
47 | artifacts/
48 |
49 | *_i.c
50 | *_p.c
51 | *_i.h
52 | *.ilk
53 | *.meta
54 | *.obj
55 | *.pch
56 | *.pdb
57 | *.pgc
58 | *.pgd
59 | *.rsp
60 | *.sbr
61 | *.tlb
62 | *.tli
63 | *.tlh
64 | *.tmp
65 | *.tmp_proj
66 | *.log
67 | *.vspscc
68 | *.vssscc
69 | .builds
70 | *.pidb
71 | *.svclog
72 | *.scc
73 |
74 | # Chutzpah Test files
75 | _Chutzpah*
76 |
77 | # Visual C++ cache files
78 | ipch/
79 | *.aps
80 | *.ncb
81 | *.opendb
82 | *.opensdf
83 | *.sdf
84 | *.cachefile
85 | *.VC.db
86 | *.VC.VC.opendb
87 |
88 | # Visual Studio profiler
89 | *.psess
90 | *.vsp
91 | *.vspx
92 | *.sap
93 |
94 | # TFS 2012 Local Workspace
95 | $tf/
96 |
97 | # Guidance Automation Toolkit
98 | *.gpState
99 |
100 | # ReSharper is a .NET coding add-in
101 | _ReSharper*/
102 | *.[Rr]e[Ss]harper
103 | *.DotSettings.user
104 |
105 | # JustCode is a .NET coding add-in
106 | .JustCode
107 |
108 | # TeamCity is a build add-in
109 | _TeamCity*
110 |
111 | # DotCover is a Code Coverage Tool
112 | *.dotCover
113 |
114 | # NCrunch
115 | _NCrunch_*
116 | .*crunch*.local.xml
117 | nCrunchTemp_*
118 |
119 | # MightyMoose
120 | *.mm.*
121 | AutoTest.Net/
122 |
123 | # Web workbench (sass)
124 | .sass-cache/
125 |
126 | # Installshield output folder
127 | [Ee]xpress/
128 |
129 | # DocProject is a documentation generator add-in
130 | DocProject/buildhelp/
131 | DocProject/Help/*.HxT
132 | DocProject/Help/*.HxC
133 | DocProject/Help/*.hhc
134 | DocProject/Help/*.hhk
135 | DocProject/Help/*.hhp
136 | DocProject/Help/Html2
137 | DocProject/Help/html
138 |
139 | # Click-Once directory
140 | publish/
141 |
142 | # Publish Web Output
143 | *.[Pp]ublish.xml
144 | *.azurePubxml
145 | # TODO: Comment the next line if you want to checkin your web deploy settings
146 | # but database connection strings (with potential passwords) will be unencrypted
147 | *.pubxml
148 | *.publishproj
149 |
150 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
151 | # checkin your Azure Web App publish settings, but sensitive information contained
152 | # in these scripts will be unencrypted
153 | PublishScripts/
154 |
155 | # NuGet Packages
156 | *.nupkg
157 | # The packages folder can be ignored because of Package Restore
158 | **/packages/*
159 | # except build/, which is used as an MSBuild target.
160 | !**/packages/build/
161 | # Uncomment if necessary however generally it will be regenerated when needed
162 | #!**/packages/repositories.config
163 | # NuGet v3's project.json files produces more ignoreable files
164 | *.nuget.props
165 | *.nuget.targets
166 |
167 | # Microsoft Azure Build Output
168 | csx/
169 | *.build.csdef
170 |
171 | # Microsoft Azure Emulator
172 | ecf/
173 | rcf/
174 |
175 | # Windows Store app package directories and files
176 | AppPackages/
177 | BundleArtifacts/
178 | Package.StoreAssociation.xml
179 | _pkginfo.txt
180 |
181 | # Visual Studio cache files
182 | # files ending in .cache can be ignored
183 | *.[Cc]ache
184 | # but keep track of directories ending in .cache
185 | !*.[Cc]ache/
186 |
187 | # Others
188 | ClientBin/
189 | ~$*
190 | *~
191 | *.dbmdl
192 | *.dbproj.schemaview
193 | *.pfx
194 | *.publishsettings
195 | node_modules/
196 | orleans.codegen.cs
197 |
198 | # Since there are multiple workflows, uncomment next line to ignore bower_components
199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
200 | #bower_components/
201 |
202 | # RIA/Silverlight projects
203 | Generated_Code/
204 |
205 | # Backup & report files from converting an old project file
206 | # to a newer Visual Studio version. Backup files are not needed,
207 | # because we have git ;-)
208 | _UpgradeReport_Files/
209 | Backup*/
210 | UpgradeLog*.XML
211 | UpgradeLog*.htm
212 |
213 | # SQL Server files
214 | *.mdf
215 | *.ldf
216 |
217 | # Business Intelligence projects
218 | *.rdl.data
219 | *.bim.layout
220 | *.bim_*.settings
221 |
222 | # Microsoft Fakes
223 | FakesAssemblies/
224 |
225 | # GhostDoc plugin setting file
226 | *.GhostDoc.xml
227 |
228 | # Node.js Tools for Visual Studio
229 | .ntvs_analysis.dat
230 |
231 | # Visual Studio 6 build log
232 | *.plg
233 |
234 | # Visual Studio 6 workspace options file
235 | *.opt
236 |
237 | # Visual Studio LightSwitch build output
238 | **/*.HTMLClient/GeneratedArtifacts
239 | **/*.DesktopClient/GeneratedArtifacts
240 | **/*.DesktopClient/ModelManifest.xml
241 | **/*.Server/GeneratedArtifacts
242 | **/*.Server/ModelManifest.xml
243 | _Pvt_Extensions
244 |
245 | # Paket dependency manager
246 | .paket/paket.exe
247 | paket-files/
248 |
249 | # FAKE - F# Make
250 | .fake/
251 |
252 | # JetBrains Rider
253 | .idea/
254 | *.sln.iml
255 |
256 | # =========================
257 | # Operating System Files
258 | # =========================
259 |
260 | # OSX
261 | # =========================
262 |
263 | .DS_Store
264 | .AppleDouble
265 | .LSOverride
266 |
267 | # Thumbnails
268 | ._*
269 |
270 | # Files that might appear in the root of a volume
271 | .DocumentRevisions-V100
272 | .fseventsd
273 | .Spotlight-V100
274 | .TemporaryItems
275 | .Trashes
276 | .VolumeIcon.icns
277 |
278 | # Directories potentially created on remote AFP share
279 | .AppleDB
280 | .AppleDesktop
281 | Network Trash Folder
282 | Temporary Items
283 | .apdisk
284 |
285 | # Windows
286 | # =========================
287 |
288 | # Windows image file caches
289 | Thumbs.db
290 | ehthumbs.db
291 |
292 | # Folder config file
293 | Desktop.ini
294 |
295 | # Recycle Bin used on file shares
296 | $RECYCLE.BIN/
297 |
298 | # Windows Installer files
299 | *.cab
300 | *.msi
301 | *.msm
302 | *.msp
303 |
304 | # Windows shortcuts
305 | *.lnk
306 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WPFPixelShaderLibrary
2 | ## A Pixel Shader library to be used in WPF's XAML.
3 | 
4 | | [NuGet Package](https://www.nuget.org/packages/unknown6656.WPFPixelShaderLibrary/)
5 |
6 | Requires .NET Framework v.4.6 (or higher) or .NET Core 3.0 (or higher).
7 |
8 | Have a look at https://github.com/Unknown6656-Megacorp/Unknown6656.CVGLPixelShader for a rough Python-equivalent of this repo.
9 |
10 | #### Usage
11 | Just add `xmlns:fx="https://unknown6656.com/wpfpslib"` to your XAML namespace definitions to use the effects:
12 | ```xml
13 |
20 |
21 |
27 |
28 |
29 | ```
30 | Result:
31 |
32 | 
33 |
34 |
35 | # The complete documentation will be available when I will have more free time!
36 |
--------------------------------------------------------------------------------
/Tools/pscompiler.deps.json:
--------------------------------------------------------------------------------
1 | {
2 | "runtimeTarget": {
3 | "name": ".NETCoreApp,Version=v2.0",
4 | "signature": ""
5 | },
6 | "compilationOptions": {},
7 | "targets": {
8 | ".NETCoreApp,Version=v2.0": {
9 | "pscompiler/1.0.0": {
10 | "runtime": {
11 | "pscompiler.dll": {}
12 | }
13 | }
14 | }
15 | },
16 | "libraries": {
17 | "pscompiler/1.0.0": {
18 | "type": "project",
19 | "serviceable": false,
20 | "sha512": ""
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/Tools/pscompiler.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/Tools/pscompiler.dll
--------------------------------------------------------------------------------
/Tools/pscompiler.runtimeconfig.dev.json:
--------------------------------------------------------------------------------
1 | {
2 | "runtimeOptions": {
3 | "additionalProbingPaths": [
4 | "C:\\Users\\unknown6656\\.dotnet\\store\\|arch|\\|tfm|",
5 | "C:\\Users\\unknown6656\\.nuget\\packages"
6 | ]
7 | }
8 | }
--------------------------------------------------------------------------------
/Tools/pscompiler.runtimeconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "runtimeOptions": {
3 | "tfm": "netcoreapp2.0",
4 | "framework": {
5 | "name": "Microsoft.NETCore.App",
6 | "version": "2.0.0"
7 | }
8 | }
9 | }
--------------------------------------------------------------------------------
/WPF-Pixel-Shader-Library.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26730.15
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wpfpslib", "wpfpslib\wpfpslib.csproj", "{298D6F05-69AE-4807-A951-FAE518D0D791}"
7 | ProjectSection(ProjectDependencies) = postProject
8 | {EB453DBA-B607-4177-9E30-E0B0B760630C} = {EB453DBA-B607-4177-9E30-E0B0B760630C}
9 | EndProjectSection
10 | EndProject
11 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "pscompiler", "pscompiler\pscompiler.csproj", "{EB453DBA-B607-4177-9E30-E0B0B760630C}"
12 | EndProject
13 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Testing", "Testing", "{50829CDD-8206-4093-AEB8-53FCED8B1D2C}"
14 | EndProject
15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WPFTestApplication", "WPFTestApplication\WPFTestApplication.csproj", "{5B342B14-41FD-43D8-8FA8-D1EAEFE585AD}"
16 | EndProject
17 | Global
18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
19 | Debug|Any CPU = Debug|Any CPU
20 | Release|Any CPU = Release|Any CPU
21 | EndGlobalSection
22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
23 | {298D6F05-69AE-4807-A951-FAE518D0D791}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
24 | {298D6F05-69AE-4807-A951-FAE518D0D791}.Debug|Any CPU.Build.0 = Debug|Any CPU
25 | {298D6F05-69AE-4807-A951-FAE518D0D791}.Release|Any CPU.ActiveCfg = Release|Any CPU
26 | {298D6F05-69AE-4807-A951-FAE518D0D791}.Release|Any CPU.Build.0 = Release|Any CPU
27 | {EB453DBA-B607-4177-9E30-E0B0B760630C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
28 | {EB453DBA-B607-4177-9E30-E0B0B760630C}.Debug|Any CPU.Build.0 = Debug|Any CPU
29 | {EB453DBA-B607-4177-9E30-E0B0B760630C}.Release|Any CPU.ActiveCfg = Release|Any CPU
30 | {EB453DBA-B607-4177-9E30-E0B0B760630C}.Release|Any CPU.Build.0 = Release|Any CPU
31 | {5B342B14-41FD-43D8-8FA8-D1EAEFE585AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
32 | {5B342B14-41FD-43D8-8FA8-D1EAEFE585AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
33 | {5B342B14-41FD-43D8-8FA8-D1EAEFE585AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
34 | {5B342B14-41FD-43D8-8FA8-D1EAEFE585AD}.Release|Any CPU.Build.0 = Release|Any CPU
35 | EndGlobalSection
36 | GlobalSection(SolutionProperties) = preSolution
37 | HideSolutionNode = FALSE
38 | EndGlobalSection
39 | GlobalSection(NestedProjects) = preSolution
40 | {5B342B14-41FD-43D8-8FA8-D1EAEFE585AD} = {50829CDD-8206-4093-AEB8-53FCED8B1D2C}
41 | EndGlobalSection
42 | GlobalSection(ExtensibilityGlobals) = postSolution
43 | SolutionGuid = {8EF7C287-CCB9-4F96-BD3A-331F5B87D1F0}
44 | EndGlobalSection
45 | EndGlobal
46 |
--------------------------------------------------------------------------------
/WPFTestApplication/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/WPFTestApplication/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Data;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 |
9 | using wpfpslib;
10 |
11 | namespace WPFTestApplication
12 | {
13 | public partial class App
14 | : Application
15 | {
16 | protected override void OnStartup(StartupEventArgs e)
17 | {
18 | MessageBox.Show($"Available pixel shaders:\n{string.Join("\n", from fx in PixelShaderEffectBase.AvailableEffects select $" > {fx}")}");
19 |
20 | base.OnStartup(e);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/WPFTestApplication/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
40 |
41 |
42 |
43 |
134 |
135 |
--------------------------------------------------------------------------------
/WPFTestApplication/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows;
3 | using wpfpslib;
4 |
5 | namespace WPFTestApplication
6 | {
7 | public partial class MainWindow
8 | : Window
9 | {
10 | public MainWindow() => InitializeComponent();
11 |
12 | private void Window_Loaded(object sender, RoutedEventArgs e)
13 | {
14 | PresentationSource presentationSource = PresentationSource.FromVisual(this);
15 |
16 | presentationSource.ContentRendered += MainWindow_ContentRendered;
17 | }
18 |
19 | private void MainWindow_ContentRendered(object sender, EventArgs e)
20 | {
21 | (sender as PresentationSource).ContentRendered -= MainWindow_ContentRendered;
22 | (grid_bbh.Effect as BlurBehindEffect).FrameworkElement = grid_bbh;
23 | (gb1.Effect as NormalMapEffect).Range = 1 / gb1.ActualWidth;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/WPFTestApplication/Resources/testimage.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/WPFTestApplication/Resources/testimage.jpg
--------------------------------------------------------------------------------
/WPFTestApplication/WPFTestApplication.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Exe
4 | netcoreapp3.1
5 | WPFTestApplication
6 | false
7 | true
8 | enable
9 | latest
10 | True
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/capture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/capture.png
--------------------------------------------------------------------------------
/pscompiler/Program.cs:
--------------------------------------------------------------------------------
1 | using System.Text.RegularExpressions;
2 | using System.Diagnostics;
3 | using System.Linq;
4 | using System.IO;
5 | using System;
6 |
7 | namespace pscompiler
8 | {
9 | using SpecialFolder = Environment.SpecialFolder;
10 |
11 |
12 | public static class Program
13 | {
14 | public static int Main(string[] argv)
15 | {
16 | Console.WriteLine("Copyright (c) Unknown6656, 2017. All rights reserved.");
17 |
18 | if (!argv.Any())
19 | {
20 | Console.WriteLine(@"Usage:
21 | pscompiler
22 |
23 | Compiles any *.fx file in `src-dir` and writes the generated *.ps file into the directory `dst-dir`.");
24 |
25 | return 0;
26 | }
27 |
28 | string archstr = IntPtr.Size == 8 ? "x64" : "x86";
29 |
30 | FileInfo fxc = (from f in new[]
31 | {
32 | SpecialFolder.Programs,
33 | SpecialFolder.ProgramFiles,
34 | SpecialFolder.ProgramFilesX86,
35 | SpecialFolder.CommonPrograms,
36 | SpecialFolder.CommonProgramFiles,
37 | SpecialFolder.CommonProgramFilesX86,
38 | }
39 | let path = Environment.GetFolderPath(f)
40 | let dir = new DirectoryInfo($@"{path}\Windows Kits")
41 | where dir.Exists
42 | from file in dir.GetFiles("fxc.exe", SearchOption.AllDirectories)
43 | where file?.Directory?.Name != null
44 | let arch = file.Directory.Name
45 | let verstr = file.Directory.FullName.match(@"([0-9]+\.[0-9]+[\.0-9]*)", out Match m) ? m.ToString() : "0.0.0.0"
46 | orderby new Version(verstr) descending
47 | orderby arch.ToLower().Contains(archstr) ? 1 : -1 descending
48 | select file).FirstOrDefault();
49 |
50 | foreach ((Func func, string message) in new(Func, string)[]
51 | {
52 | (() => fxc is null, "The fxc compiler could not be found on this machine. Please install the latest Windows SDK version."),
53 | (() => argv.Length < 1, "A source directory must be given."),
54 | (() => argv.Length < 2, "A target directory must be given."),
55 | (() => !Directory.Exists(argv[0]), "The source directory must exist."),
56 | (() => !Directory.Exists(argv[0]), "The target directory must exist."),
57 | })
58 | if (func())
59 | {
60 | Console.Error.WriteLine(message);
61 |
62 | return -1;
63 | }
64 |
65 | DirectoryInfo dst = new DirectoryInfo(argv[1]);
66 | int ret = 0;
67 |
68 | foreach (FileInfo fx in new DirectoryInfo(argv[0]).GetFiles("*.fx"))
69 | {
70 | string ps = $@"{dst.FullName}\{fx.Name.Replace(fx.Extension, "")}.ps";
71 | ProcessStartInfo psi = new ProcessStartInfo
72 | {
73 | FileName = fxc.FullName,
74 | Arguments = $"/T ps_3_0 /E main /Fo \"{ps}\" \"{fx.FullName}\"",
75 | CreateNoWindow = true,
76 | UseShellExecute = false,
77 | RedirectStandardError = true,
78 | RedirectStandardOutput = true,
79 | };
80 | bool failed;
81 |
82 | using (Process p = new Process())
83 | {
84 | p.StartInfo = psi;
85 | p.Start();
86 |
87 | string cout = p.StandardOutput.ReadToEnd();
88 | string cerr = p.StandardError.ReadToEnd();
89 |
90 | p.WaitForExit();
91 | failed = p.ExitCode != 0;
92 |
93 | if (failed)
94 | {
95 | Console.Out.WriteLine(cout);
96 | Console.Error.WriteLine(cerr);
97 |
98 | if (ret == 0)
99 | ret = p.ExitCode;
100 | }
101 | }
102 |
103 | Console.WriteLine($"[{(failed ? "ERR." : " OK ")}] {fx.FullName} --> {ps}");
104 | }
105 |
106 | return ret;
107 | }
108 |
109 | private static bool match(this string str, string pat, out Match m, RegexOptions opt = RegexOptions.Compiled | RegexOptions.IgnoreCase) =>
110 | (m = Regex.Match(str, pat, opt)).Success;
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/pscompiler/pscompiler.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Exe
4 | netcoreapp2.0
5 | false
6 | true
7 | enable
8 | preview
9 | True
10 | pscompiler.Program
11 | ../tools
12 |
13 |
14 |
--------------------------------------------------------------------------------
/wpfpslib/Effects.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Markup;
2 | using System.Windows.Media;
3 | using System.Windows;
4 | using System.Reflection;
5 | using System;
6 |
7 | [assembly: XmlnsDefinition("https://unknown6656.com/wpfpslib", nameof(wpfpslib))]
8 |
9 | namespace wpfpslib
10 | {
11 | ///
12 | /// Represents an effect, which renderes any input into its corresponding normal map
13 | ///
14 | ///
15 | public sealed class NormalMapEffect
16 | : PixelShaderEffectBase
17 | {
18 | ///
19 | /// Identifies the property
20 | ///
21 | public static readonly DependencyProperty RangeProperty = Register(nameof(Range), typeof(double), typeof(NormalMapEffect), 0d, 0);
22 | ///
23 | /// Identifies the property
24 | ///
25 | public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty(nameof(Input), typeof(NormalMapEffect), 0);
26 |
27 |
28 | ///
29 | /// The normal map edge detection range.
30 | ///
31 | /// Should be set to a value between [0..1]
32 | ///
33 | /// Should be set to `4 / Min(Width, Height)` for best results
34 | ///
35 | public double Range
36 | {
37 | get => (double)GetValue(RangeProperty);
38 | set => SetValue(RangeProperty, value);
39 | }
40 |
41 | ///
42 | /// The imagery input data
43 | ///
44 | public Brush Input
45 | {
46 | get => (Brush)GetValue(InputProperty);
47 | set => SetValue(InputProperty, value);
48 | }
49 |
50 |
51 | ///
52 | /// Creates a new instance
53 | ///
54 | ///
55 | public NormalMapEffect()
56 | : base(typeof(NormalMapEffect))
57 | {
58 | }
59 |
60 | ///
61 | /// Updates all pixel shader properties
62 | ///
63 | ///
64 | protected internal override void UpdateShader()
65 | {
66 | UpdateShaderValue(InputProperty);
67 | UpdateShaderValue(RangeProperty);
68 | }
69 | }
70 |
71 | public sealed class GlassTilesEffect
72 | : PixelShaderEffectBase
73 | {
74 | ///
75 | /// Identifies the property
76 | ///
77 | public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty(nameof(Input), typeof(GlassTilesEffect), 0);
78 | ///
79 | /// Identifies the property
80 | ///
81 | public static readonly DependencyProperty TilesProperty = Register(nameof(Tiles), typeof(double), typeof(GlassTilesEffect), 5d, 0);
82 | ///
83 | /// Identifies the property
84 | ///
85 | public static readonly DependencyProperty BevelWidthProperty = Register(nameof(BevelWidth), typeof(double), typeof(GlassTilesEffect), 1d, 1);
86 | ///
87 | /// Identifies the property
88 | ///
89 | public static readonly DependencyProperty OffsetProperty = Register(nameof(Offset), typeof(double), typeof(GlassTilesEffect), 1d, 3);
90 | ///
91 | /// Identifies the property
92 | ///
93 | public static readonly DependencyProperty BackgroundColorProperty = Register(nameof(BackgroundColor), typeof(Color), typeof(GlassTilesEffect), Color.FromArgb(255, 0, 0, 0), 2);
94 |
95 |
96 | public double Tiles
97 | {
98 | get => (double)GetValue(TilesProperty);
99 | set => SetValue(TilesProperty, value);
100 | }
101 |
102 | public double BevelWidth
103 | {
104 | get => (double)GetValue(BevelWidthProperty);
105 | set => SetValue(BevelWidthProperty, value);
106 | }
107 |
108 | public double Offset
109 | {
110 | get => (double)GetValue(OffsetProperty);
111 | set => SetValue(OffsetProperty, value);
112 | }
113 |
114 | public Color BackgroundColor
115 | {
116 | get => (Color)GetValue(BackgroundColorProperty);
117 | set => SetValue(BackgroundColorProperty, value);
118 | }
119 |
120 | ///
121 | /// The imagery input data
122 | ///
123 | public Brush Input
124 | {
125 | get => GetValue(InputProperty) as Brush;
126 | set => SetValue(InputProperty, value);
127 | }
128 |
129 |
130 | ///
131 | /// Creates a new instance
132 | ///
133 | ///
134 | public GlassTilesEffect()
135 | : base(typeof(NormalMapEffect))
136 | {
137 | }
138 |
139 | ///
140 | /// Updates all pixel shader properties
141 | ///
142 | ///
143 | protected internal override void UpdateShader()
144 | {
145 | UpdateShaderValue(InputProperty);
146 | UpdateShaderValue(TilesProperty);
147 | UpdateShaderValue(BevelWidthProperty);
148 | UpdateShaderValue(OffsetProperty);
149 | UpdateShaderValue(BackgroundColorProperty);
150 | }
151 | }
152 |
153 | public sealed class CubicLensDistortionEffect
154 | : PixelShaderEffectBase
155 | {
156 | ///
157 | /// Identifies the property
158 | ///
159 | public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty(nameof(Input), typeof(CubicLensDistortionEffect), 0);
160 | ///
161 | /// Identifies the property
162 | ///
163 | public static readonly DependencyProperty DistortionCoefficientProperty = DependencyProperty.Register(nameof(DistortionCoefficient), typeof(double), typeof(CubicLensDistortionEffect), new UIPropertyMetadata(-.15, PixelShaderConstantCallback(0)));
164 | ///
165 | /// Identifies the property
166 | ///
167 | public static readonly DependencyProperty CubicDistortionProperty = DependencyProperty.Register(nameof(CubicDistortion), typeof(double), typeof(CubicLensDistortionEffect), new UIPropertyMetadata(.5, PixelShaderConstantCallback(1)));
168 | ///
169 | /// Identifies the property
170 | ///
171 | public static readonly DependencyProperty ZoomProperty = DependencyProperty.Register(nameof(Zoom), typeof(double), typeof(CubicLensDistortionEffect), new UIPropertyMetadata(1d, PixelShaderConstantCallback(2)));
172 |
173 |
174 | ///
175 | /// The imagery input data
176 | ///
177 | public Brush Input
178 | {
179 | get => GetValue(InputProperty) as Brush;
180 | set => SetValue(InputProperty, value);
181 | }
182 |
183 | public double DistortionCoefficient
184 | {
185 | get => (double)GetValue(DistortionCoefficientProperty);
186 | set => SetValue(DistortionCoefficientProperty, value);
187 | }
188 |
189 | public double CubicDistortion
190 | {
191 | get => (double)GetValue(CubicDistortionProperty);
192 | set => SetValue(CubicDistortionProperty, value);
193 | }
194 |
195 | public double Zoom
196 | {
197 | get => (double)GetValue(ZoomProperty);
198 | set => SetValue(ZoomProperty, value);
199 | }
200 |
201 |
202 | ///
203 | /// Creates a new instance
204 | ///
205 | ///
206 | public CubicLensDistortionEffect()
207 | : base(typeof(CubicLensDistortionEffect))
208 | {
209 | }
210 |
211 | ///
212 | /// Updates all pixel shader properties
213 | ///
214 | ///
215 | protected internal override void UpdateShader()
216 | {
217 | UpdateShaderValue(InputProperty);
218 | UpdateShaderValue(DistortionCoefficientProperty);
219 | UpdateShaderValue(CubicDistortionProperty);
220 | }
221 | }
222 |
223 | ///
224 | /// Represents a cubic chromatic abberation effect (also known as cubic RGB-split)
225 | ///
226 | ///
227 | public sealed class CubicChromaticAbberationEffect
228 | : PixelShaderEffectBase
229 | {
230 | ///
231 | /// Identifies the property
232 | ///
233 | public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty(nameof(Input), typeof(CubicChromaticAbberationEffect), 0);
234 | ///
235 | /// Identifies the property
236 | ///
237 | public static readonly DependencyProperty AmountProperty = DependencyProperty.Register(nameof(Amount), typeof(double), typeof(CubicChromaticAbberationEffect), new UIPropertyMetadata(0d, PixelShaderConstantCallback(0)));
238 |
239 |
240 | ///
241 | /// The imagery input data
242 | ///
243 | public Brush Input
244 | {
245 | get => GetValue(InputProperty) as Brush;
246 | set => SetValue(InputProperty, value);
247 | }
248 |
249 | ///
250 | /// Abberation amount.
251 | ///
252 | /// Should be set to a value between [0..∞)
253 | ///
254 | public double Amount
255 | {
256 | get => (double)GetValue(AmountProperty);
257 | set => SetValue(AmountProperty, value);
258 | }
259 |
260 |
261 | ///
262 | /// Creates a new instance
263 | ///
264 | ///
265 | public CubicChromaticAbberationEffect()
266 | : base(typeof(CubicChromaticAbberationEffect))
267 | {
268 | }
269 |
270 | ///
271 | /// Updates all pixel shader properties
272 | ///
273 | ///
274 | protected internal override void UpdateShader()
275 | {
276 | UpdateShaderValue(InputProperty);
277 | UpdateShaderValue(AmountProperty);
278 | }
279 | }
280 |
281 | ///
282 | /// Represents a linear chromatic abberation effect (also known as linear RGB-split)
283 | ///
284 | ///
285 | public sealed class LinearChromaticAbberationEffect
286 | : PixelShaderEffectBase
287 | {
288 | ///
289 | /// Identifies the property
290 | ///
291 | public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty(nameof(Input), typeof(LinearChromaticAbberationEffect), 0);
292 | ///
293 | /// Identifies the property
294 | ///
295 | public static readonly DependencyProperty AmountProperty = DependencyProperty.Register(nameof(Amount), typeof(double), typeof(LinearChromaticAbberationEffect), new UIPropertyMetadata(0d, PixelShaderConstantCallback(0)));
296 | ///
297 | /// Identifies the property
298 | ///
299 | public static readonly DependencyProperty AngleProperty = DependencyProperty.Register(nameof(Angle), typeof(double), typeof(LinearChromaticAbberationEffect), new UIPropertyMetadata(0d, PixelShaderConstantCallback(1)));
300 |
301 |
302 | ///
303 | /// The imagery input data
304 | ///
305 | public Brush Input
306 | {
307 | get => GetValue(InputProperty) as Brush;
308 | set => SetValue(InputProperty, value);
309 | }
310 |
311 | ///
312 | /// Abberation amount.
313 | ///
314 | /// Should be set to a value between [0..1]
315 | ///
316 | public double Amount
317 | {
318 | get => (double)GetValue(AmountProperty);
319 | set => SetValue(AmountProperty, value);
320 | }
321 |
322 | ///
323 | /// Abberation angle.
324 | ///
325 | /// Should be set to a value between [0..1] which will be translated to a mathematical angle between [0..2π]
326 | ///
327 | public double Angle
328 | {
329 | get => (double)GetValue(AngleProperty);
330 | set => SetValue(AngleProperty, value);
331 | }
332 |
333 |
334 | ///
335 | /// Creates a new instance
336 | ///
337 | ///
338 | public LinearChromaticAbberationEffect()
339 | : base(typeof(LinearChromaticAbberationEffect))
340 | {
341 | }
342 |
343 | ///
344 | /// Updates all pixel shader properties
345 | ///
346 | protected internal override void UpdateShader()
347 | {
348 | UpdateShaderValue(InputProperty);
349 | UpdateShaderValue(AmountProperty);
350 | UpdateShaderValue(AngleProperty);
351 | }
352 | }
353 |
354 | public sealed class RoundedGlassTilesEffect
355 | : PixelShaderEffectBase
356 | {
357 | ///
358 | /// Identifies the property
359 | ///
360 | public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty(nameof(Input), typeof(RoundedGlassTilesEffect), 0);
361 | ///
362 | /// Identifies the property
363 | ///
364 | public static readonly DependencyProperty DensityProperty = DependencyProperty.Register(nameof(Density), typeof(double), typeof(RoundedGlassTilesEffect), new UIPropertyMetadata(0.04d, PixelShaderConstantCallback(0)));
365 |
366 |
367 | ///
368 | /// The imagery input data
369 | ///
370 | public Brush Input
371 | {
372 | get => GetValue(InputProperty) as Brush;
373 | set => SetValue(InputProperty, value);
374 | }
375 |
376 | public double Density
377 | {
378 | get => (double)GetValue(DensityProperty);
379 | set => SetValue(DensityProperty, value);
380 | }
381 |
382 |
383 | ///
384 | /// Creates a new instance
385 | ///
386 | ///
387 | public RoundedGlassTilesEffect()
388 | : base(typeof(RoundedGlassTilesEffect))
389 | {
390 | }
391 |
392 | ///
393 | /// Updates all pixel shader properties
394 | ///
395 | ///
396 | protected internal override void UpdateShader()
397 | {
398 | UpdateShaderValue(InputProperty);
399 | UpdateShaderValue(DensityProperty);
400 | }
401 | }
402 |
403 | ///
404 | /// Represents an hexagonal pixelation effect
405 | ///
406 | ///
407 | public sealed class HexagonalPixelationEffect
408 | : PixelShaderEffectBase
409 | {
410 | ///
411 | /// Identifies the property
412 | ///
413 | public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty(nameof(Input), typeof(HexagonalPixelationEffect), 0);
414 | ///
415 | /// Identifies the property
416 | ///
417 | public static readonly DependencyProperty AmountProperty = DependencyProperty.Register(nameof(Amount), typeof(double), typeof(HexagonalPixelationEffect), new UIPropertyMetadata(0d, PixelShaderConstantCallback(0)));
418 |
419 |
420 | ///
421 | /// The imagery input data
422 | ///
423 | public Brush Input
424 | {
425 | get => GetValue(InputProperty) as Brush;
426 | set => SetValue(InputProperty, value);
427 | }
428 |
429 | ///
430 | /// The pixelation amount
431 | ///
432 | /// The value should be between (0..1]
433 | ///
434 | public double Amount
435 | {
436 | get => (double)GetValue(AmountProperty);
437 | set => SetValue(AmountProperty, value);
438 | }
439 |
440 |
441 | ///
442 | /// Creates a new instance
443 | ///
444 | ///
445 | public HexagonalPixelationEffect()
446 | : base(typeof(HexagonalPixelationEffect))
447 | {
448 | }
449 |
450 | ///
451 | /// Updates all pixel shader properties
452 | ///
453 | ///
454 | protected internal override void UpdateShader()
455 | {
456 | UpdateShaderValue(InputProperty);
457 | UpdateShaderValue(AmountProperty);
458 | }
459 | }
460 |
461 | ///
462 | /// Represents a rippling effect
463 | ///
464 | ///
465 | public class RippleEffect
466 | : PixelShaderEffectBase
467 | {
468 | ///
469 | /// Identifies the property
470 | ///
471 | public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty(nameof(Input), typeof(RippleEffect), 0);
472 | ///
473 | /// Identifies the property
474 | ///
475 | public static readonly DependencyProperty CenterProperty = DependencyProperty.Register(nameof(Center), typeof(Point), typeof(RippleEffect), new UIPropertyMetadata(new Point(.5, .5), PixelShaderConstantCallback(0)));
476 | ///
477 | /// Identifies the property
478 | ///
479 | public static readonly DependencyProperty AmplitudeProperty = DependencyProperty.Register(nameof(Amplitude), typeof(double), typeof(RippleEffect), new UIPropertyMetadata(.1, PixelShaderConstantCallback(1)));
480 | ///
481 | /// Identifies the property
482 | ///
483 | public static readonly DependencyProperty FrequencyProperty = DependencyProperty.Register(nameof(Frequency), typeof(double), typeof(RippleEffect), new UIPropertyMetadata(70d, PixelShaderConstantCallback(2)));
484 | ///
485 | /// Identifies the property
486 | ///
487 | public static readonly DependencyProperty PhaseProperty = DependencyProperty.Register(nameof(Phase), typeof(double), typeof(RippleEffect), new UIPropertyMetadata(.0, PixelShaderConstantCallback(3)));
488 | ///
489 | /// Identifies the property
490 | ///
491 | public static readonly DependencyProperty AspectRatioProperty = DependencyProperty.Register(nameof(AspectRatio), typeof(double), typeof(RippleEffect), new UIPropertyMetadata(1.5, PixelShaderConstantCallback(4)));
492 |
493 |
494 | ///
495 | /// The imagery input data
496 | ///
497 | public Brush Input
498 | {
499 | get => GetValue(InputProperty) as Brush;
500 | set => SetValue(InputProperty, value);
501 | }
502 |
503 | ///
504 | /// The ripple effect's center point.
505 | ///
506 | /// Should be set to a value between [(0,0)..(1,1)]
507 | ///
508 | public Point Center
509 | {
510 | get => (Point)GetValue(CenterProperty);
511 | set => SetValue(CenterProperty, value);
512 | }
513 |
514 | ///
515 | /// The rippling effect's wave amplitude.
516 | ///
517 | /// Should be set to a value between [0..1]
518 | ///
519 | public double Amplitude
520 | {
521 | get => (double)GetValue(AmplitudeProperty);
522 | set => SetValue(AmplitudeProperty, value);
523 | }
524 |
525 | ///
526 | /// The rippling effect's wave frequency.
527 | ///
528 | /// Should be set to a value between [0..300]
529 | ///
530 | public double Frequency
531 | {
532 | get => (double)GetValue(FrequencyProperty);
533 | set => SetValue(FrequencyProperty, value);
534 | }
535 |
536 | ///
537 | /// The rippling effect's phase.
538 | ///
539 | /// Should be set to a value between [-π..+π]
540 | ///
541 | public double Phase
542 | {
543 | get => (double)GetValue(PhaseProperty);
544 | set => SetValue(PhaseProperty, value);
545 | }
546 |
547 | ///
548 | /// The rippling effect's aspect ratio.
549 | ///
550 | /// Should be set to `Width / Height`
551 | ///
552 | public double AspectRatio
553 | {
554 | get => (double)GetValue(AspectRatioProperty);
555 | set => SetValue(AspectRatioProperty, value);
556 | }
557 |
558 |
559 | ///
560 | /// Creates a new instance
561 | ///
562 | ///
563 | public RippleEffect()
564 | : base(typeof(RippleEffect))
565 | {
566 | }
567 |
568 | ///
569 | /// Updates all pixel shader properties
570 | ///
571 | ///
572 | protected internal override void UpdateShader()
573 | {
574 | UpdateShaderValue(InputProperty);
575 | UpdateShaderValue(CenterProperty);
576 | UpdateShaderValue(AmplitudeProperty);
577 | UpdateShaderValue(FrequencyProperty);
578 | UpdateShaderValue(PhaseProperty);
579 | UpdateShaderValue(AspectRatioProperty);
580 | }
581 | }
582 |
583 | ///
584 | /// Represents a pixelation effect
585 | ///
586 | ///
587 | public class PixelationEffect
588 | : PixelShaderEffectBase
589 | {
590 | ///
591 | /// Identifies the property
592 | ///
593 | public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty(nameof(Input), typeof(PixelationEffect), 0);
594 | ///
595 | /// Identifies the property
596 | ///
597 | public static readonly DependencyProperty CountProperty = DependencyProperty.Register(nameof(Count), typeof(Point), typeof(PixelationEffect), new UIPropertyMetadata(new Point(0, 0), PixelShaderConstantCallback(0)));
598 |
599 |
600 | ///
601 | /// The imagery input data
602 | ///
603 | public Brush Input
604 | {
605 | get => GetValue(InputProperty) as Brush;
606 | set => SetValue(InputProperty, value);
607 | }
608 |
609 | ///
610 | /// The horizontal and vertical pixel count
611 | ///
612 | public Point Count
613 | {
614 | get => (Point)GetValue(CountProperty);
615 | set => SetValue(CountProperty, value);
616 | }
617 |
618 |
619 | ///
620 | /// Creates a new instance
621 | ///
622 | ///
623 | public PixelationEffect()
624 | : base(typeof(PixelationEffect))
625 | {
626 | }
627 |
628 | ///
629 | /// Updates all pixel shader properties
630 | ///
631 | ///
632 | protected internal override void UpdateShader()
633 | {
634 | UpdateShaderValue(InputProperty);
635 | UpdateShaderValue(CountProperty);
636 | }
637 | }
638 |
639 | ///
640 | /// Represents an offset/diagonalized pixelation effect
641 | ///
642 | ///
643 | public class DiagonalPixelationEffect
644 | : PixelShaderEffectBase
645 | {
646 | ///
647 | /// Identifies the property
648 | ///
649 | public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty(nameof(Input), typeof(DiagonalPixelationEffect), 0);
650 | ///
651 | /// Identifies the property
652 | ///
653 | public static readonly DependencyProperty CountProperty = DependencyProperty.Register(nameof(Count), typeof(Point), typeof(DiagonalPixelationEffect), new UIPropertyMetadata(new Point(0, 0), PixelShaderConstantCallback(0)));
654 |
655 |
656 | ///
657 | /// The imagery input data
658 | ///
659 | public Brush Input
660 | {
661 | get => GetValue(InputProperty) as Brush;
662 | set => SetValue(InputProperty, value);
663 | }
664 |
665 | ///
666 | /// The horizontal and vertical pixel count
667 | ///
668 | public Point Count
669 | {
670 | get => (Point)GetValue(CountProperty);
671 | set => SetValue(CountProperty, value);
672 | }
673 |
674 |
675 | ///
676 | /// Creates a new instance
677 | ///
678 | ///
679 | public DiagonalPixelationEffect()
680 | : base(typeof(DiagonalPixelationEffect))
681 | {
682 | }
683 |
684 | ///
685 | /// Updates all pixel shader properties
686 | ///
687 | ///
688 | protected internal override void UpdateShader()
689 | {
690 | UpdateShaderValue(InputProperty);
691 | UpdateShaderValue(CountProperty);
692 | }
693 | }
694 |
695 | ///
696 | /// Represents an effect creating a gravitational lensing around a black hole
697 | ///
698 | ///
699 | public sealed class BlackHoleEffect
700 | : PixelShaderEffectBase
701 | {
702 | ///
703 | /// Identifies the property
704 | ///
705 | public static readonly DependencyProperty PositionProperty = Register(nameof(Position), typeof(Point), typeof(BlackHoleEffect), new Point(.5, .5), 0);
706 | ///
707 | /// Identifies the property
708 | ///
709 | public static readonly DependencyProperty AspectratioProperty = Register(nameof(Aspectratio), typeof(double), typeof(BlackHoleEffect), default(double), 1);
710 | ///
711 | /// Identifies the property
712 | ///
713 | public static readonly DependencyProperty RadiusProperty = Register(nameof(Radius), typeof(double), typeof(BlackHoleEffect), default(double), 2);
714 | ///
715 | /// Identifies the property
716 | ///
717 | public static readonly DependencyProperty DistProperty = Register(nameof(Dist), typeof(double), typeof(BlackHoleEffect), default(double), 3);
718 | ///
719 | /// Identifies the property
720 | ///
721 | public static readonly DependencyProperty SizeProperty = Register(nameof(Size), typeof(double), typeof(BlackHoleEffect), default(double), 4);
722 | ///
723 | /// Identifies the property
724 | ///
725 | public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty(nameof(Input), typeof(BlackHoleEffect), 0);
726 |
727 |
728 | ///
729 | /// The black hole's center position
730 | ///
731 | /// Should be set to a value between [(0,0)..(1,1)]
732 | ///
733 | public Point Position
734 | {
735 | get => (Point)GetValue(PositionProperty);
736 | set => SetValue(PositionProperty, value);
737 | }
738 |
739 | ///
740 | /// The aspect ratio.
741 | ///
742 | /// Should be set to the value 'Width / Height'
743 | ///
744 | public double Aspectratio
745 | {
746 | get => (double)GetValue(AspectratioProperty);
747 | set => SetValue(AspectratioProperty, value);
748 | }
749 |
750 | ///
751 | /// The graviational lensing effect radius.
752 | ///
753 | /// Should be set to a value between [0..1]
754 | ///
755 | public double Radius
756 | {
757 | get => (double)GetValue(RadiusProperty);
758 | set => SetValue(RadiusProperty, value);
759 | }
760 |
761 | ///
762 | /// The black hole's distance to the 'camera'.
763 | ///
764 | /// Should be set to a value of (0..1]
765 | ///
766 | public double Dist
767 | {
768 | get => (double)GetValue(DistProperty);
769 | set => SetValue(DistProperty, value);
770 | }
771 |
772 | ///
773 | /// The black hole's size compared to its graviational lensing radius.
774 | ///
775 | /// Should be set to a value between [(0,0)...(1,1)]
776 | ///
777 | public double Size
778 | {
779 | get => (double)GetValue(SizeProperty);
780 | set => SetValue(SizeProperty, value);
781 | }
782 |
783 | ///
784 | /// The imagery input data
785 | ///
786 | public Brush Input
787 | {
788 | get => (Brush)GetValue(InputProperty);
789 | set => SetValue(InputProperty, value);
790 | }
791 |
792 |
793 | ///
794 | /// Creates a new instance
795 | ///
796 | ///
797 | public BlackHoleEffect()
798 | : base(typeof(BlackHoleEffect))
799 | {
800 | }
801 |
802 | ///
803 | /// Updates all pixel shader properties
804 | ///
805 | ///
806 | protected internal override void UpdateShader()
807 | {
808 | UpdateShaderValue(PositionProperty);
809 | UpdateShaderValue(AspectratioProperty);
810 | UpdateShaderValue(RadiusProperty);
811 | UpdateShaderValue(DistProperty);
812 | UpdateShaderValue(SizeProperty);
813 | UpdateShaderValue(InputProperty);
814 | }
815 | }
816 |
817 | ///
818 | /// Represents a color inversion effect
819 | ///
820 | ///
821 | public sealed class InvertEffect
822 | : PixelShaderEffectBase
823 | {
824 | ///
825 | /// Identifies the property
826 | ///
827 | public static readonly DependencyProperty AmountProperty = Register(nameof(Amount), typeof(double), typeof(InvertEffect), 1d, 0);
828 | ///
829 | /// Identifies the property
830 | ///
831 | public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty(nameof(Input), typeof(InvertEffect), 0);
832 |
833 |
834 | ///
835 | /// The inversion amount.
836 | ///
837 | /// Should be set to a value between [0..1]
838 | ///
839 | public double Amount
840 | {
841 | get => (double)GetValue(AmountProperty);
842 | set => SetValue(AmountProperty, value);
843 | }
844 |
845 | ///
846 | /// The imagery input data
847 | ///
848 | public Brush Input
849 | {
850 | get => (Brush)GetValue(InputProperty);
851 | set => SetValue(InputProperty, value);
852 | }
853 |
854 |
855 | ///
856 | /// Creates a new instance
857 | ///
858 | ///
859 | public InvertEffect()
860 | : base(typeof(InvertEffect))
861 | {
862 | }
863 |
864 | ///
865 | /// Updates all pixel shader properties
866 | ///
867 | ///
868 | protected internal override void UpdateShader()
869 | {
870 | UpdateShaderValue(AmountProperty);
871 | UpdateShaderValue(InputProperty);
872 | }
873 | }
874 |
875 | ///
876 | /// Represents a telescopic blurring effect
877 | ///
878 | ///
879 | public sealed class TelescopicBlurEffect
880 | : PixelShaderEffectBase
881 | {
882 | ///
883 | /// Identifies the property
884 | ///
885 | public static readonly DependencyProperty CenterProperty = Register(nameof(Center), typeof(Point), typeof(TelescopicBlurEffect), new Point(.5, .5), 0);
886 | ///
887 | /// Identifies the property
888 | ///
889 | public static readonly DependencyProperty AmountProperty = Register(nameof(Amount), typeof(double), typeof(TelescopicBlurEffect), default(double), 1);
890 | ///
891 | /// Identifies the property
892 | ///
893 | public static readonly DependencyProperty RadiusProperty = Register(nameof(Radius), typeof(double), typeof(TelescopicBlurEffect), default(double), 2);
894 | ///
895 | /// Identifies the property
896 | ///
897 | public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty(nameof(Input), typeof(TelescopicBlurEffect), 0);
898 |
899 |
900 | ///
901 | /// The blur's center point
902 | ///
903 | /// Should be set to a value between [(0,0)..(1,1)]
904 | ///
905 | public Point Center
906 | {
907 | get => (Point)GetValue(CenterProperty);
908 | set => SetValue(CenterProperty, value);
909 | }
910 |
911 | ///
912 | /// The telescopic blur amount.
913 | ///
914 | /// Should be set to a value between [0..1]
915 | ///
916 | public double Amount
917 | {
918 | get => (double)GetValue(AmountProperty);
919 | set => SetValue(AmountProperty, value);
920 | }
921 |
922 | ///
923 | /// The blur's inner falloff radius.
924 | ///
925 | /// Should be set to a value between [0..1]
926 | ///
927 | public double Radius
928 | {
929 | get => (double)GetValue(RadiusProperty);
930 | set => SetValue(RadiusProperty, value);
931 | }
932 |
933 | ///
934 | /// The imagery input data
935 | ///
936 | public Brush Input
937 | {
938 | get => (Brush)GetValue(InputProperty);
939 | set => SetValue(InputProperty, value);
940 | }
941 |
942 |
943 | ///
944 | /// Creates a new instance
945 | ///
946 | ///
947 | public TelescopicBlurEffect()
948 | : base(typeof(TelescopicBlurEffect))
949 | {
950 | }
951 |
952 | ///
953 | /// Updates all pixel shader properties
954 | ///
955 | ///
956 | protected internal override void UpdateShader()
957 | {
958 | UpdateShaderValue(CenterProperty);
959 | UpdateShaderValue(AmountProperty);
960 | UpdateShaderValue(RadiusProperty);
961 | UpdateShaderValue(InputProperty);
962 | }
963 | }
964 |
965 | ///
966 | /// Represents a spastic horizontal twitching effect
967 | ///
968 | ///
969 | public sealed class SpasticChromaticAbberationEffect
970 | : PixelShaderEffectBase
971 | {
972 | ///
973 | /// Identifies the property
974 | ///
975 | public static readonly DependencyProperty PhaseProperty = Register(nameof(Phase), typeof(double), typeof(SpasticChromaticAbberationEffect), default(double), 0);
976 | ///
977 | /// Identifies the property
978 | ///
979 | public static readonly DependencyProperty AmountProperty = Register(nameof(Amount), typeof(double), typeof(SpasticChromaticAbberationEffect), default(double), 1);
980 | ///
981 | /// Identifies the property
982 | ///
983 | public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty(nameof(Input), typeof(SpasticChromaticAbberationEffect), 0);
984 |
985 |
986 | ///
987 | /// The twitching phase shift.
988 | ///
989 | /// Should be set to a value between [0..1] which will be mapped to a value between [0..2π]
990 | ///
991 | public double Phase
992 | {
993 | get => (double)GetValue(PhaseProperty);
994 | set => SetValue(PhaseProperty, value);
995 | }
996 |
997 | ///
998 | /// The twitching amount.
999 | ///
1000 | /// Should be set to a value between [0..1]
1001 | ///
1002 | public double Amount
1003 | {
1004 | get => (double)GetValue(AmountProperty);
1005 | set => SetValue(AmountProperty, value);
1006 | }
1007 |
1008 | ///
1009 | /// The imagery input data
1010 | ///
1011 | public Brush Input
1012 | {
1013 | get => (Brush)GetValue(InputProperty);
1014 | set => SetValue(InputProperty, value);
1015 | }
1016 |
1017 |
1018 | ///
1019 | /// Creates a new instance
1020 | ///
1021 | ///
1022 | public SpasticChromaticAbberationEffect()
1023 | : base(typeof(SpasticChromaticAbberationEffect))
1024 | {
1025 | }
1026 |
1027 | ///
1028 | /// Updates all pixel shader properties
1029 | ///
1030 | ///
1031 | protected internal override void UpdateShader()
1032 | {
1033 | UpdateShaderValue(PhaseProperty);
1034 | UpdateShaderValue(AmountProperty);
1035 | UpdateShaderValue(InputProperty);
1036 | }
1037 | }
1038 |
1039 | public sealed class BlurBehindEffect
1040 | : PixelShaderEffectBase
1041 | {
1042 | ///
1043 | /// Identifies the property
1044 | ///
1045 | public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty(nameof(Input), typeof(BlurBehindEffect), 0);
1046 |
1047 | public static readonly DependencyProperty UpLeftCornerProperty = Register(nameof(UpLeftCorner), typeof(Point), typeof(BlurBehindEffect), default(Point), 0);
1048 |
1049 | public static readonly DependencyProperty LowRightCornerProperty = Register(nameof(LowRightCorner), typeof(Point), typeof(BlurBehindEffect), default(Point), 1);
1050 |
1051 | public static readonly DependencyProperty SpacingProperty = Register(nameof(Spacing), typeof(Size), typeof(BlurBehindEffect), default(Size), 2);
1052 |
1053 | ///
1054 | /// Identifies the property
1055 | ///
1056 | public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register(nameof(Radius), typeof(double), typeof(BlurBehindEffect), new PropertyMetadata(0d));
1057 |
1058 | public static readonly DependencyProperty FrameworkElementProperty = DependencyProperty.Register(nameof(FrameworkElement), typeof(FrameworkElement), typeof(BlurBehindEffect), new PropertyMetadata(null, OnFrameworkElementPropertyChanged));
1059 |
1060 | private static readonly PropertyInfo? _inheritance_ctx = typeof(BlurBehindEffect).GetProperty("InheritanceContext", BindingFlags.Instance | BindingFlags.NonPublic);
1061 |
1062 |
1063 | ///
1064 | /// The imagery input data
1065 | ///
1066 | public Brush Input
1067 | {
1068 | get => (Brush)GetValue(InputProperty);
1069 | set => SetValue(InputProperty, value);
1070 | }
1071 |
1072 | ///
1073 | /// The blur radius.
1074 | ///
1075 | public double Radius
1076 | {
1077 | get => (double)GetValue(RadiusProperty);
1078 | set
1079 | {
1080 | SetValue(RadiusProperty, value);
1081 | FrameworkElement = FrameworkElement; // trigger update
1082 | }
1083 | }
1084 |
1085 | public Size Spacing
1086 | {
1087 | get => (Size)GetValue(SpacingProperty);
1088 | set => SetValue(SpacingProperty, value);
1089 | }
1090 |
1091 | public Point UpLeftCorner
1092 | {
1093 | get => (Point)GetValue(UpLeftCornerProperty);
1094 | set => SetValue(UpLeftCornerProperty, value);
1095 | }
1096 |
1097 | public Point LowRightCorner
1098 | {
1099 | get => (Point)GetValue(LowRightCornerProperty);
1100 | set => SetValue(LowRightCornerProperty, value);
1101 | }
1102 |
1103 | public FrameworkElement? FrameworkElement
1104 | {
1105 | get => GetValue(FrameworkElementProperty) as FrameworkElement;
1106 | set => SetValue(FrameworkElementProperty, value);
1107 | }
1108 |
1109 | public FrameworkElement? GetInheritanceContext => _inheritance_ctx?.GetValue(this, null) as FrameworkElement;
1110 |
1111 |
1112 | ///
1113 | /// Creates a new instance.
1114 | ///
1115 | ///
1116 | public BlurBehindEffect()
1117 | : base(typeof(BlurBehindEffect))
1118 | {
1119 | }
1120 |
1121 | ///
1122 | /// Updates all pixel shader properties
1123 | ///
1124 | ///
1125 | protected internal override void UpdateShader()
1126 | {
1127 | UpdateShaderValue(RadiusProperty);
1128 | UpdateShaderValue(UpLeftCornerProperty);
1129 | UpdateShaderValue(LowRightCornerProperty);
1130 | UpdateShaderValue(InputProperty);
1131 | UpdateShaderValue(SpacingProperty);
1132 | }
1133 |
1134 | private void UpdateEffect(object? sender, EventArgs args)
1135 | {
1136 | if (GetInheritanceContext is FrameworkElement under && FrameworkElement is FrameworkElement over)
1137 | {
1138 | Point u_origin = under.PointToScreen(new Point(0, 0));
1139 | Point o_origin = over.PointToScreen(new Point(0, 0));
1140 | Rect u_rect = new Rect(u_origin.X, u_origin.Y, under.ActualWidth, under.ActualHeight);
1141 | Rect o_rect = new Rect(o_origin.X, o_origin.Y, over.ActualWidth, over.ActualHeight);
1142 | Rect intersect = Rect.Intersect(o_rect, u_rect);
1143 |
1144 | if (intersect.IsEmpty)
1145 | {
1146 | UpLeftCorner = new Point(0, 0);
1147 | LowRightCorner = new Point(0, 0);
1148 | }
1149 | else
1150 | {
1151 | Point i_origin = under.PointFromScreen(new Point(intersect.X, intersect.Y));
1152 |
1153 | UpLeftCorner = new Point(i_origin.X / under.ActualWidth, i_origin.Y / under.ActualHeight);
1154 | LowRightCorner = new Point(UpLeftCorner.X + (intersect.Width / under.ActualWidth), UpLeftCorner.Y + (intersect.Height / under.ActualHeight));
1155 | }
1156 |
1157 | UpdateShader();
1158 | }
1159 | }
1160 |
1161 | private void SizeChanged(object sender, SizeChangedEventArgs e) => Spacing = new Size(Radius / e.NewSize.Width, Radius / e.NewSize.Height);
1162 |
1163 | private static void OnFrameworkElementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
1164 | {
1165 | BlurBehindEffect fx = (BlurBehindEffect)d;
1166 |
1167 | if (args.OldValue is FrameworkElement old)
1168 | {
1169 | old.LayoutUpdated -= fx.UpdateEffect;
1170 | old.SizeChanged -= fx.SizeChanged;
1171 | }
1172 |
1173 | if (args.NewValue is FrameworkElement @new)
1174 | {
1175 | @new.LayoutUpdated += fx.UpdateEffect;
1176 | @new.SizeChanged += fx.SizeChanged;
1177 | }
1178 | }
1179 | }
1180 | }
1181 |
--------------------------------------------------------------------------------
/wpfpslib/ShaderEffectBase.cs:
--------------------------------------------------------------------------------
1 | using System.Text.RegularExpressions;
2 | using System.Windows.Media.Effects;
3 | using System.Diagnostics;
4 | using System.Collections;
5 | using System.Reflection;
6 | using System.Resources;
7 | using System.Windows;
8 | using System.Linq;
9 | using System.IO;
10 | using System;
11 |
12 |
13 | namespace wpfpslib
14 | {
15 | ///
16 | /// Represents the base class for all pixel shader effects. Cannot be inherited from external classes.
17 | ///
18 | ///
19 | public abstract class PixelShaderEffectBase
20 | : ShaderEffect
21 | {
22 | private static readonly string asmname = typeof(PixelShaderEffectBase).Assembly.ToString().Split(',')[0];
23 |
24 |
25 | ///
26 | /// A list of all available pixel shader effects' names
27 | ///
28 | public static string[] AvailableEffects { get; }
29 |
30 |
31 | ///
32 | /// Static constructor
33 | ///
34 | ///
35 | static PixelShaderEffectBase()
36 | {
37 | Assembly asm = typeof(PixelShaderEffectBase).Assembly;
38 | string resname = asm.GetManifestResourceNames().FirstOrDefault(s => s.Contains("g.resources")) ?? $"{asm.GetName().Name}.g.resources";
39 | Match m = null;
40 |
41 | using (Stream str = asm.GetManifestResourceStream(resname))
42 | using (ResourceReader rd = new ResourceReader(str))
43 | AvailableEffects = (from e in rd.Cast()
44 | let name = e.Key as string
45 | where name.Match(@"(.*(\\|\/))?(?.+)\.ps", out m)
46 | let res = m?.Groups["name"]?.ToString()
47 | where res != null
48 | select res).ToArray();
49 | }
50 |
51 | ///
52 | /// Creates a new pixel shader with the caller's name used as pixel shader input file
53 | ///
54 | ///
55 | internal PixelShaderEffectBase()
56 | : this(TrimEnd(new StackTrace().GetFrame(1).GetMethod().DeclaringType?.Name, "Effect"))
57 | {
58 | }
59 |
60 | ///
61 | /// Creates a new pixel shader with the given name used as pixel shader input file (without file extension or directory)
62 | ///
63 | /// Compiled pixel shader file name
64 | ///
65 | internal PixelShaderEffectBase(string name)
66 | : this(new PixelShader
67 | {
68 | UriSource = GetUri(name)
69 | })
70 | {
71 | }
72 |
73 | ///
74 | /// Creates a new pixel shader with the given C# class type
75 | ///
76 | /// Pixel shader effect type
77 | ///
78 | internal PixelShaderEffectBase(Type type)
79 | : this(TrimEnd(type.Name, "Effect"))
80 | {
81 | }
82 |
83 | ///
84 | /// Creates a new pixel shader effect based on the given shader
85 | ///
86 | /// Pixel shader
87 | ///
88 | internal PixelShaderEffectBase(PixelShader shader)
89 | {
90 | PixelShader = shader;
91 |
92 | UpdateShader();
93 | }
94 |
95 | ///
96 | /// Updates all pixel shader properties
97 | ///
98 | protected internal abstract void UpdateShader();
99 |
100 | ///
101 | /// Tries to get the pixel shader associated with the given name and returns whether the fetch was successfull
102 | ///
103 | /// Pixel shader name
104 | /// The pixel shader (null if not found)
105 | /// Result, whether the fetching operation was successfull
106 | public static bool TryGetShaderByName(string? name, out PixelShaderEffectBase? shader)
107 | {
108 | shader = null;
109 | name = name?.ToLower();
110 |
111 | if (AvailableEffects.Contains(name))
112 | shader = (from t in typeof(PixelShaderEffectBase).Assembly.GetExportedTypes()
113 | where typeof(PixelShaderEffectBase).IsAssignableFrom(t)
114 | where t.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)
115 | select Activator.CreateInstance(t) as PixelShaderEffectBase).FirstOrDefault();
116 |
117 | return shader != null;
118 | }
119 |
120 | private static Uri GetUri(string name) => new Uri($"pack://application:,,,/{asmname};component/ps-compiled/{name}.ps");
121 |
122 | private static string? TrimEnd(string? input, string? suffix, StringComparison cmp = StringComparison.InvariantCulture) =>
123 | suffix is string s && (input?.EndsWith(s, cmp) ?? false) ? input.Remove(input.Length - s.Length) : input;
124 |
125 | ///
126 | /// Registers a new Dependency Property bound to a given .NET Property and a HLSL Pixel Shader register
127 | ///
128 | /// .NET Property name
129 | /// .NET Property type
130 | /// .NET Parent type
131 | /// Default value
132 | /// HLSL register
133 | /// >Generated Depenendy Property
134 | protected static DependencyProperty Register(string name, Type type, Type parent, dynamic @default, int slot) =>
135 | DependencyProperty.Register(name, type, parent, new UIPropertyMetadata(@default, PixelShaderConstantCallback(slot)));
136 | }
137 |
138 | internal static class Extensions
139 | {
140 | internal static bool Match(this string str, string pat, out Match m, RegexOptions opt = RegexOptions.Compiled | RegexOptions.IgnoreCase) => (m = Regex.Match(str, pat, opt)).Success;
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/wpfpslib/ps-compiled/BlackHole.ps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/wpfpslib/ps-compiled/BlackHole.ps
--------------------------------------------------------------------------------
/wpfpslib/ps-compiled/BlurBehind.ps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/wpfpslib/ps-compiled/BlurBehind.ps
--------------------------------------------------------------------------------
/wpfpslib/ps-compiled/CubicChromaticAbberation.ps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/wpfpslib/ps-compiled/CubicChromaticAbberation.ps
--------------------------------------------------------------------------------
/wpfpslib/ps-compiled/CubicLensDistortion.ps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/wpfpslib/ps-compiled/CubicLensDistortion.ps
--------------------------------------------------------------------------------
/wpfpslib/ps-compiled/DiagonalPixelation.ps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/wpfpslib/ps-compiled/DiagonalPixelation.ps
--------------------------------------------------------------------------------
/wpfpslib/ps-compiled/GlassTiles.ps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/wpfpslib/ps-compiled/GlassTiles.ps
--------------------------------------------------------------------------------
/wpfpslib/ps-compiled/HexagonalPixelation.ps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/wpfpslib/ps-compiled/HexagonalPixelation.ps
--------------------------------------------------------------------------------
/wpfpslib/ps-compiled/Invert.ps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/wpfpslib/ps-compiled/Invert.ps
--------------------------------------------------------------------------------
/wpfpslib/ps-compiled/LinearChromaticAbberation.ps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/wpfpslib/ps-compiled/LinearChromaticAbberation.ps
--------------------------------------------------------------------------------
/wpfpslib/ps-compiled/NormalMap.ps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/wpfpslib/ps-compiled/NormalMap.ps
--------------------------------------------------------------------------------
/wpfpslib/ps-compiled/Pixelation.ps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/wpfpslib/ps-compiled/Pixelation.ps
--------------------------------------------------------------------------------
/wpfpslib/ps-compiled/Ripple.ps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/wpfpslib/ps-compiled/Ripple.ps
--------------------------------------------------------------------------------
/wpfpslib/ps-compiled/RoundedGlassTiles.ps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/wpfpslib/ps-compiled/RoundedGlassTiles.ps
--------------------------------------------------------------------------------
/wpfpslib/ps-compiled/SpasticChromaticAbberation.ps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/wpfpslib/ps-compiled/SpasticChromaticAbberation.ps
--------------------------------------------------------------------------------
/wpfpslib/ps-compiled/TelescopicBlur.ps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/wpfpslib/ps-compiled/TelescopicBlur.ps
--------------------------------------------------------------------------------
/wpfpslib/ps-hlsl/BlackHole.fx:
--------------------------------------------------------------------------------
1 | sampler2D input : register(s0);
2 | float2 position : register(C0);
3 | float aspectratio : register(C1);
4 | float radius : register(C2);
5 | float dist : register(C3);
6 | float size : register(C4);
7 |
8 |
9 | float4 main(float2 uv : TEXCOORD) : COLOR
10 | {
11 | float irad = saturate(radius / 100);
12 | float2 offs = uv - position;
13 | float2 ratio = { clamp(aspectratio, 0.001, 1000), 1 };
14 | float rad = length(offs / ratio);
15 |
16 | if (rad < irad * 6 * saturate(size))
17 | return float4(0, 0, 0, 1);
18 | else
19 | {
20 | float defm = 2 * irad / pow(rad * pow(dist, 0.5), 1.7);
21 |
22 | offs *= 1 - defm;
23 | offs += position;
24 |
25 | return tex2D(input, offs);
26 | }
27 | }
--------------------------------------------------------------------------------
/wpfpslib/ps-hlsl/BlurBehind.fx:
--------------------------------------------------------------------------------
1 | sampler2D input : register(s0);
2 | float2 upperLeftCorner : register(C0);
3 | float2 lowerRightCorner : register(C1);
4 | float2 spacing : register(C2);
5 |
6 |
7 |
8 |
9 | const float PI = 3.14159265358979323846;
10 | const float EPSILON = 0.0001;
11 | const float SIGMA = 2;
12 |
13 | float gauss(float n)
14 | {
15 | return (float)((1.0 / sqrt(2 * PI * SIGMA)) * exp(-(n * n) / (2 * SIGMA * SIGMA)));
16 | }
17 |
18 | float4 gaussianblur(float2 coord : TEXCOORD0) : COLOR
19 | {
20 | const int COUNT = 2;
21 | float total = 0;
22 |
23 | float kernel[] = {
24 | 0.023528, 0.033969, 0.038393, 0.033969, 0.023528,
25 | 0.033969, 0.049045, 0.055432, 0.049045, 0.033969,
26 | 0.038393, 0.055432, 0.062651, 0.055432, 0.038393,
27 | 0.033969, 0.049045, 0.055432, 0.049045, 0.033969,
28 | 0.023528, 0.033969, 0.038393, 0.033969, 0.023528
29 | };
30 | total = 1;
31 |
32 | /*
33 | float kernel[COUNT * 2 + 1];
34 | for (int i = -COUNT; i <= COUNT; ++i)
35 | {
36 | float w = gauss((float)i / COUNT);
37 |
38 | kernel[COUNT + i] = w;
39 | total += w;
40 | }
41 | */
42 |
43 | float4 color = 0;
44 |
45 | for (int y = -COUNT; y <= COUNT; ++y)
46 | for (int x = -COUNT; x <= COUNT; ++x)
47 | {
48 | float2 offs = { spacing.x * x, spacing.y * y };
49 |
50 | color += kernel[COUNT + x] * kernel[COUNT + y] * tex2D(input, coord + offs);
51 | }
52 |
53 | total *= total;
54 | color /= total;
55 |
56 | return color;
57 | }
58 |
59 | float4 main(float2 uv : TEXCOORD) : COLOR
60 | {
61 | if (uv.x < upperLeftCorner.x || uv.y < upperLeftCorner.y || uv.x > lowerRightCorner.x || uv.y > lowerRightCorner.y)
62 | return tex2D(input, uv);
63 | else
64 | return gaussianblur(uv);
65 | }
66 |
--------------------------------------------------------------------------------
/wpfpslib/ps-hlsl/CubicChromaticAbberation.fx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/wpfpslib/ps-hlsl/CubicChromaticAbberation.fx
--------------------------------------------------------------------------------
/wpfpslib/ps-hlsl/CubicLensDistortion.fx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unknown6656/WPFPixelShaderLibrary/b9ba1df8fa6213512d7d4d46b1932e841c4865aa/wpfpslib/ps-hlsl/CubicLensDistortion.fx
--------------------------------------------------------------------------------
/wpfpslib/ps-hlsl/DiagonalPixelation.fx:
--------------------------------------------------------------------------------
1 | sampler2D input : register(s0);
2 | float2 count : register(C0);
3 |
4 |
5 | float4 main(float2 uv : TEXCOORD) : COLOR
6 | {
7 | float2 sz = 1.0 / count;
8 | float2 offs = uv;
9 |
10 | if (floor(offs.y / sz.y) % 2 >= 1)
11 | offs.x += sz / 2.0;
12 |
13 | float2 pos = floor(offs / sz);
14 | float2 cnt = pos * sz + sz / 2;
15 |
16 | cnt = clamp(cnt, 0, 1);
17 |
18 | return tex2D(input, cnt);
19 | }
20 |
--------------------------------------------------------------------------------
/wpfpslib/ps-hlsl/GlassTiles.fx:
--------------------------------------------------------------------------------
1 | // contributed by Fakhruddin Faizal
2 | // http://hdprogramming.blogspot.com/
3 | // modifications by Walt Ritscher and Unknown6656
4 |
5 | sampler2D inputSampler : register(s0);
6 | float Tiles : register(C0);
7 | float BevelWidth : register(C1);
8 | float Offset : register(C3);
9 | float4 GroutColor : register(C2);
10 |
11 |
12 | float4 main(float2 uv : TEXCOORD) : COLOR
13 | {
14 | float2 newUV1;
15 |
16 | newUV1.xy = uv.xy + tan((Tiles * 2.5) * uv.xy + Offset) * (BevelWidth / 100);
17 |
18 | float4 c1 = tex2D(inputSampler, newUV1);
19 |
20 | if ((newUV1.x < 0) ||
21 | (newUV1.x > 1) ||
22 | (newUV1.y < 0) ||
23 | (newUV1.y > 1))
24 | c1 = GroutColor;
25 |
26 | c1.a = 1;
27 |
28 | return c1;
29 | }
--------------------------------------------------------------------------------
/wpfpslib/ps-hlsl/HexagonalPixelation.fx:
--------------------------------------------------------------------------------
1 | sampler2D input : register(S0);
2 | float amount : register(C0);
3 |
4 | #define H (clamp(amount, 0.0001, 1) / 2)
5 | #define S ((3.0 /2.0) * H / sqrt(3.0))
6 |
7 |
8 | float2 GetHexCoord(int2 hex)
9 | {
10 | int i = hex.x;
11 | int j = hex.y;
12 | float2 coord;
13 |
14 | coord.x = i * S;
15 | coord.y = j * H + (i % 2) * H / 2.0;
16 |
17 | return coord;
18 | }
19 |
20 | int2 GetHexIndex(float2 coord)
21 | {
22 | int2 hex;
23 | int it = int(floor(coord.x / S));
24 |
25 | float yts = coord.y - float(it % 2) * H / 2.0;
26 | int jt = int(floor((1.0 / H) * yts));
27 |
28 | float xt = coord.x - it * S;
29 | float yt = yts - jt * H;
30 |
31 | int deltaj = (yt > H / 2.0) ? 1 : 0;
32 |
33 | float fcond = S * (2.0 / 3.0) * abs(0.5 - yt / H);
34 |
35 | if (xt > fcond)
36 | {
37 | hex.x = it;
38 | hex.y = jt;
39 | }
40 | else
41 | {
42 | hex.x = it - 1;
43 | hex.y = jt - (hex.x % 2) + deltaj;
44 | }
45 |
46 | return hex;
47 | }
48 |
49 | float4 main(float2 uv : TEXCOORD0) : COLOR
50 | {
51 | int2 hex = GetHexIndex(uv);
52 | float2 coord = GetHexCoord(hex);
53 | float4 clr = tex2D(input, coord);
54 |
55 | return clr;
56 | }
--------------------------------------------------------------------------------
/wpfpslib/ps-hlsl/Invert.fx:
--------------------------------------------------------------------------------
1 | sampler2D input : register(S0);
2 | float amount : register(C0);
3 |
4 |
5 | float4 main(float2 uv : TEXCOORD) : COLOR
6 | {
7 | float f = saturate(amount);
8 | float4 color = tex2D(input, uv);
9 |
10 | return float4(color.a - color.rgb, color.a) * f + color * (1 - f);
11 | }
12 |
--------------------------------------------------------------------------------
/wpfpslib/ps-hlsl/LinearChromaticAbberation.fx:
--------------------------------------------------------------------------------
1 | sampler2D input : register(s0);
2 | float amount : register(C0);
3 | float angle : register(C1);
4 |
5 | static const float PI = 3.14159265f;
6 |
7 |
8 | float4 main(float2 uv : TEXCOORD0) : COLOR
9 | {
10 | float a = clamp(amount, 0, 1) / 8;
11 | float f = clamp(angle, 0, 1) * PI * 2;
12 | float x1 = sin(-f) * a + (uv.x - 0.5) + 0.5;
13 | float y1 = cos(-f) * a + (uv.y - 0.5) + 0.5;
14 | float x2 = sin(PI - f) * a + (uv.x - 0.5) + 0.5;
15 | float y2 = cos(PI - f) * a + (uv.y - 0.5) + 0.5;
16 |
17 | float4 clr = tex2D(input, uv);
18 | float4 clrd1 = tex2D(input, float2(x1, y1));
19 | float4 clrd2 = tex2D(input, float2(x2, y2));
20 |
21 | return float4(clrd1.r, clr.g, clrd2.b, 1);
22 | }
23 |
--------------------------------------------------------------------------------
/wpfpslib/ps-hlsl/NormalMap.fx:
--------------------------------------------------------------------------------
1 | sampler2D input : register(S0);
2 | float Range : register(C0);
3 |
4 |
5 | float abs(float f)
6 | {
7 | return f < 0 ? -f : f;
8 | }
9 |
10 | float constr(float f)
11 | {
12 | return f < 0 ? 0 : f > 1 ? 1 : f;
13 | }
14 |
15 | float4 main(float2 uv : TEXCOORD) : COLOR
16 | {
17 | float4 clr = tex2D(input, uv);
18 | float3x3 hmat =
19 | {
20 | -1, 0, 1,
21 | -2, 0, 2,
22 | -1, 0, 1,
23 | };
24 | float3x3 vmat =
25 | {
26 | 1, 2, 1,
27 | 0, 0, 0,
28 | -1, -2, -1,
29 | };
30 | float sx = 128, sy = 128;
31 | float r = clamp(Range, 0.000001, 1);
32 | int fx, fy;
33 |
34 | for (fy = -1; fy <= 1; ++fy)
35 | for (fx = -1; fx <= 1; ++fx)
36 | {
37 | float2 nuv = { uv[0] + fy * r * 0.125f, uv[1] + fx * r * 0.125f };
38 | float4 nclr = tex2D(input, nuv);
39 | float gray = (nclr.r + nclr.g + nclr.g) * 255 / 3;
40 |
41 | sx += hmat[fy + 1][fx + 1] * gray;
42 | sy += vmat[fy + 1][fx + 1] * gray;
43 | }
44 |
45 | float sz = (abs(sx - 128) + abs(sy - 128)) / 4.0f;
46 |
47 | return float4(
48 | constr(sx / 255),
49 | constr(sy / 255),
50 | (sz > 64 ? 191 : sz < 0 ? 255 : 255 - sz) / 255,
51 | 1
52 | );
53 | }
54 |
--------------------------------------------------------------------------------
/wpfpslib/ps-hlsl/Pixelation.fx:
--------------------------------------------------------------------------------
1 | sampler2D input : register(s0);
2 | float2 count : register(C0);
3 |
4 |
5 | float4 main(float2 uv : TEXCOORD) : COLOR
6 | {
7 | float2 sz = 1.0 / count;
8 | float2 offs = uv;
9 |
10 | if ((floor(offs.y / sz.y) % 2 >= 1) && false)
11 | offs.x += sz / 2.0;
12 |
13 | float2 pos = floor(offs / sz);
14 | float2 cnt = pos * sz + sz / 2;
15 |
16 | cnt = clamp(cnt, 0, 1);
17 |
18 | return tex2D(input, cnt);
19 | }
20 |
--------------------------------------------------------------------------------
/wpfpslib/ps-hlsl/Ripple.fx:
--------------------------------------------------------------------------------
1 | sampler2D inputSampler : register(S0);
2 | float2 Center : register(C0); // [0,0 - 1,1]
3 | float Amplitude : register(C1); // [0 - 1]
4 | float Frequency : register(C2); // [0 - 300]
5 | float Phase : register(C3); // [±π]
6 | float AspectRatio : register(C4); // W * H^-1
7 |
8 |
9 | float4 main(float2 uv : TEXCOORD) : COLOR
10 | {
11 | float2 dir = uv - Center;
12 |
13 | dir.y /= AspectRatio;
14 |
15 | float dist = length(dir);
16 |
17 | dir /= dist;
18 | dir.y *= AspectRatio;
19 |
20 | float falloff = saturate(1 - dist);
21 | float2 wave = {
22 | sin(Frequency * dist + Phase),
23 | cos(Frequency * dist + Phase),
24 | };
25 |
26 | falloff *= falloff;
27 | dist += Amplitude * wave.x * falloff;
28 |
29 | float4 color = tex2D(inputSampler, Center + dist * dir);
30 |
31 | float light = 1 - Amplitude * 0.2 * (1 - saturate(wave.y * falloff));
32 |
33 | color.rgb *= light;
34 |
35 | return color;
36 | }
--------------------------------------------------------------------------------
/wpfpslib/ps-hlsl/RoundedGlassTiles.fx:
--------------------------------------------------------------------------------
1 | sampler2D input : register(s0);
2 | /// 0.04
3 | float density : register(c0);
4 |
5 |
6 | static const float PI = 3.14159265f;
7 |
8 |
9 | float2 f(float2 uv, float d)
10 | {
11 | //return uv + 0.01 * sin(2 * PI * uv / d);
12 | return uv + tan((PI / 2 + PI * uv) / d) / 100;
13 | }
14 |
15 | float4 main(float2 uv : TEXCOORD) : COLOR
16 | {
17 | float d = clamp(density, 0, 1);
18 | float2 coord = uv + d - 2 * f(uv % d, d);
19 |
20 | coord %= 1;
21 |
22 | float4 clr = tex2D(input, coord);
23 |
24 | if (clr.a < 1)
25 | {
26 | clr.rgb -= clamp(clr.a / 2, 0, 1) + 0.5f;
27 | clr.a = 1;
28 | }
29 |
30 | return clr;
31 | }
--------------------------------------------------------------------------------
/wpfpslib/ps-hlsl/SpasticChromaticAbberation.fx:
--------------------------------------------------------------------------------
1 | sampler2D input : register(S0);
2 | float phase : register(C0);
3 | float amount : register(C1);
4 |
5 | static const float PI = 3.14159265f;
6 |
7 |
8 | float4 main(float2 uv : TEXCOORD) : COLOR
9 | {
10 | float phi = (abs(phase + uv.y) % 1.0) * 20 * PI;
11 | float f1 = sin(phi) + 0.2 * cos(16 * phi) * sin(2 * phi) + 0.5 * cos(4 * phi);
12 | float am = saturate(amount);
13 | float fam = am > 0.7 ? 0.7 - am : am;
14 | bool inv1 = uv.y % ((1.1 - fam) / 20) < 0.01;
15 | bool inv2 = uv.y % 0.05 < 0.025;
16 | bool inv3 = (uv.y + f1) % 0.09 < 0.002;
17 |
18 | if (inv1)
19 | f1 = -(1 + f1);
20 |
21 | f1 /= 15;
22 |
23 | uv.x = uv.x * (1 - am / 10) + uv.x * f1 * am;
24 |
25 | if (inv1)
26 | uv.x = saturate(uv.x - am * f1);
27 |
28 | float4 color;
29 |
30 | if (inv2)
31 | {
32 | float4 clr = tex2D(input, uv);
33 | float4 clrd1 = tex2D(input, float2(tan(uv.x - 0.5) + 0.5125, uv.y));
34 | float4 clrd2 = tex2D(input, float2(tan(uv.x - 0.5) + 0.4875, uv.y));
35 |
36 | color = float4(clrd1.r, clr.g, clrd2.b, 1);
37 | }
38 |
39 | if (inv3)
40 | color = tex2D(input, float2((uv.x * uv.x + uv.y + f1) % 1, uv.y));
41 |
42 | float r2 = (uv.x - 0.5) * (uv.x - 0.5) + (uv.y - 0.5) * (uv.y - 0.5);
43 | float f = 1 + r2 * (0.03 * sqrt(r2));
44 | float x = f * (uv.x - 0.5) + 0.5;
45 | float y = f * (uv.y - 0.5) + 0.5;
46 |
47 | float4 clr = tex2D(input, uv);
48 | float4 clrd = tex2D(input, float2(x, y));
49 |
50 | if (!inv2)
51 | color = float4(clrd.r, clr.g, clr.b, 1);
52 |
53 | float3 scnColor = normalize(float4(0xc8, 0xf4, 0xf4, 0xff)) * (color.rgb / color.a);
54 | float gray = dot(float3(0.3, 0.59, 0.11), scnColor);
55 |
56 | float3 muted = lerp(scnColor, gray.xxx, 0.15);
57 | float3 middle = lerp(float4(0, 0, 0, 1), normalize(float4(0xc8, 0xf4, 0xf4, 0xff)), gray);
58 |
59 | scnColor = lerp(muted * 2, middle, 0.4);
60 |
61 | return float4(scnColor * color.a, color.a) * am / 2 + clr * (1 - am / 2);
62 | }
--------------------------------------------------------------------------------
/wpfpslib/ps-hlsl/TelescopicBlur.fx:
--------------------------------------------------------------------------------
1 | // from Affirma Consulting Blog
2 | // http://affirmaconsulting.wordpress.com/2010/12/30/tool-for-developing-hlsl-pixel-shaders-for-wpf-and-silverlight/
3 |
4 | sampler2D input : register(s0);
5 | float2 center : register(C0);
6 | float amount : register(C1);
7 | float radius : register(C2);
8 |
9 | #define ITERATIONS 48
10 |
11 | float4 main(float2 uv : TEXCOORD) : COLOR
12 | {
13 | uv -= center;
14 |
15 | float edge = saturate(radius) * 4 + .5;
16 | float dist = pow(pow(uv.x, edge) + pow(uv.y, edge),2);
17 | float a = saturate(amount) * 3;
18 | float4 c = 0;
19 |
20 | [unroll(ITERATIONS)] for(int i = 0; i < ITERATIONS; ++i)
21 | {
22 | float scale = 1.0 - ((dist * a * i * 17.0) / (30.0 * ITERATIONS));
23 | float2 coord = uv * scale;
24 |
25 | c += tex2D(input, coord + center);
26 | }
27 |
28 | return c / ITERATIONS;
29 | }
30 |
--------------------------------------------------------------------------------
/wpfpslib/wpfpslib.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Library
4 | wpfpslib.xml
5 | netcoreapp3.0;net46
6 | WPFTestApplication
7 | true
8 | enable
9 | latest
10 | True
11 |
12 | Always
13 | unknown6656.WPFPixelShaderLibrary
14 | unknown6656
15 | unknown6656
16 | WPF Pixel Shader Library
17 | A Pixel Shader library to be used in WPF's XAML.
18 | Just add `xmlns:fx="https://unknown6656.com/wpfpslib"` to your XAML namespace definitions to use the effects.
19 | Copyright © unknown6656, 2017 - 2020
20 | https://github.com/Unknown6656/WPFPixelShaderLibrary
21 | unknown6656-logo-1024.png
22 | https://github.com/Unknown6656/WPFPixelShaderLibrary
23 | Git
24 | unknown6656;pixel;shader;effect;library;wpf;xaml;windows;blur;distortion;ps;dgsl;hlsl;fx;pscompiler;fxc
25 | LICENSE
26 | true
27 | 1.0.2
28 | 1.0.2.0
29 |
30 |
31 |
32 |
33 |
34 | True
35 |
36 |
37 |
38 | True
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/wpfpslib/wpfpslib.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | wpfpslib
5 |
6 |
7 |
8 |
9 | Represents an effect, which renderes any input into its corresponding normal map
10 |
11 |
12 |
13 |
14 |
15 | Identifies the property
16 |
17 |
18 |
19 |
20 | Identifies the property
21 |
22 |
23 |
24 |
25 | The normal map edge detection range.
26 |
27 | Should be set to a value between [0..1]
28 |
29 | Should be set to `4 / Min(Width, Height)` for best results
30 |
31 |
32 |
33 |
34 | The imagery input data
35 |
36 |
37 |
38 |
39 | Creates a new instance
40 |
41 |
42 |
43 |
44 |
45 | Updates all pixel shader properties
46 |
47 |
48 |
49 |
50 |
51 | Identifies the property
52 |
53 |
54 |
55 |
56 | Identifies the property
57 |
58 |
59 |
60 |
61 | Identifies the property
62 |
63 |
64 |
65 |
66 | Identifies the property
67 |
68 |
69 |
70 |
71 | Identifies the property
72 |
73 |
74 |
75 |
76 | The imagery input data
77 |
78 |
79 |
80 |
81 | Creates a new instance
82 |
83 |
84 |
85 |
86 |
87 | Updates all pixel shader properties
88 |
89 |
90 |
91 |
92 |
93 | Identifies the property
94 |
95 |
96 |
97 |
98 | Identifies the property
99 |
100 |
101 |
102 |
103 | Identifies the property
104 |
105 |
106 |
107 |
108 | Identifies the property
109 |
110 |
111 |
112 |
113 | The imagery input data
114 |
115 |
116 |
117 |
118 | Creates a new instance
119 |
120 |
121 |
122 |
123 |
124 | Updates all pixel shader properties
125 |
126 |
127 |
128 |
129 |
130 | Represents a cubic chromatic abberation effect (also known as cubic RGB-split)
131 |
132 |
133 |
134 |
135 |
136 | Identifies the property
137 |
138 |
139 |
140 |
141 | Identifies the property
142 |
143 |
144 |
145 |
146 | The imagery input data
147 |
148 |
149 |
150 |
151 | Abberation amount.
152 |
153 | Should be set to a value between [0..∞)
154 |
155 |
156 |
157 |
158 | Creates a new instance
159 |
160 |
161 |
162 |
163 |
164 | Updates all pixel shader properties
165 |
166 |
167 |
168 |
169 |
170 | Represents a linear chromatic abberation effect (also known as linear RGB-split)
171 |
172 |
173 |
174 |
175 |
176 | Identifies the property
177 |
178 |
179 |
180 |
181 | Identifies the property
182 |
183 |
184 |
185 |
186 | Identifies the property
187 |
188 |
189 |
190 |
191 | The imagery input data
192 |
193 |
194 |
195 |
196 | Abberation amount.
197 |
198 | Should be set to a value between [0..1]
199 |
200 |
201 |
202 |
203 | Abberation angle.
204 |
205 | Should be set to a value between [0..1] which will be translated to a mathematical angle between [0..2π]
206 |
207 |
208 |
209 |
210 | Creates a new instance
211 |
212 |
213 |
214 |
215 |
216 | Updates all pixel shader properties
217 |
218 |
219 |
220 |
221 | Identifies the property
222 |
223 |
224 |
225 |
226 | Identifies the property
227 |
228 |
229 |
230 |
231 | The imagery input data
232 |
233 |
234 |
235 |
236 | Creates a new instance
237 |
238 |
239 |
240 |
241 |
242 | Updates all pixel shader properties
243 |
244 |
245 |
246 |
247 |
248 | Represents an hexagonal pixelation effect
249 |
250 |
251 |
252 |
253 |
254 | Identifies the property
255 |
256 |
257 |
258 |
259 | Identifies the property
260 |
261 |
262 |
263 |
264 | The imagery input data
265 |
266 |
267 |
268 |
269 | The pixelation amount
270 |
271 | The value should be between (0..1]
272 |
273 |
274 |
275 |
276 | Creates a new instance
277 |
278 |
279 |
280 |
281 |
282 | Updates all pixel shader properties
283 |
284 |
285 |
286 |
287 |
288 | Represents a rippling effect
289 |
290 |
291 |
292 |
293 |
294 | Identifies the property
295 |
296 |
297 |
298 |
299 | Identifies the property
300 |
301 |
302 |
303 |
304 | Identifies the property
305 |
306 |
307 |
308 |
309 | Identifies the property
310 |
311 |
312 |
313 |
314 | Identifies the property
315 |
316 |
317 |
318 |
319 | Identifies the property
320 |
321 |
322 |
323 |
324 | The imagery input data
325 |
326 |
327 |
328 |
329 | The ripple effect's center point.
330 |
331 | Should be set to a value between [(0,0)..(1,1)]
332 |
333 |
334 |
335 |
336 | The rippling effect's wave amplitude.
337 |
338 | Should be set to a value between [0..1]
339 |
340 |
341 |
342 |
343 | The rippling effect's wave frequency.
344 |
345 | Should be set to a value between [0..300]
346 |
347 |
348 |
349 |
350 | The rippling effect's phase.
351 |
352 | Should be set to a value between [-π..+π]
353 |
354 |
355 |
356 |
357 | The rippling effect's aspect ratio.
358 |
359 | Should be set to `Width / Height`
360 |
361 |
362 |
363 |
364 | Creates a new instance
365 |
366 |
367 |
368 |
369 |
370 | Updates all pixel shader properties
371 |
372 |
373 |
374 |
375 |
376 | Represents a pixelation effect
377 |
378 |
379 |
380 |
381 |
382 | Identifies the property
383 |
384 |
385 |
386 |
387 | Identifies the property
388 |
389 |
390 |
391 |
392 | The imagery input data
393 |
394 |
395 |
396 |
397 | The horizontal and vertical pixel count
398 |
399 |
400 |
401 |
402 | Creates a new instance
403 |
404 |
405 |
406 |
407 |
408 | Updates all pixel shader properties
409 |
410 |
411 |
412 |
413 |
414 | Represents an offset/diagonalized pixelation effect
415 |
416 |
417 |
418 |
419 |
420 | Identifies the property
421 |
422 |
423 |
424 |
425 | Identifies the property
426 |
427 |
428 |
429 |
430 | The imagery input data
431 |
432 |
433 |
434 |
435 | The horizontal and vertical pixel count
436 |
437 |
438 |
439 |
440 | Creates a new instance
441 |
442 |
443 |
444 |
445 |
446 | Updates all pixel shader properties
447 |
448 |
449 |
450 |
451 |
452 | Represents an effect creating a gravitational lensing around a black hole
453 |
454 |
455 |
456 |
457 |
458 | Identifies the property
459 |
460 |
461 |
462 |
463 | Identifies the property
464 |
465 |
466 |
467 |
468 | Identifies the property
469 |
470 |
471 |
472 |
473 | Identifies the property
474 |
475 |
476 |
477 |
478 | Identifies the property
479 |
480 |
481 |
482 |
483 | Identifies the property
484 |
485 |
486 |
487 |
488 | The black hole's center position
489 |
490 | Should be set to a value between [(0,0)..(1,1)]
491 |
492 |
493 |
494 |
495 | The aspect ratio.
496 |
497 | Should be set to the value 'Width / Height'
498 |
499 |
500 |
501 |
502 | The graviational lensing effect radius.
503 |
504 | Should be set to a value between [0..1]
505 |
506 |
507 |
508 |
509 | The black hole's distance to the 'camera'.
510 |
511 | Should be set to a value of (0..1]
512 |
513 |
514 |
515 |
516 | The black hole's size compared to its graviational lensing radius.
517 |
518 | Should be set to a value between [(0,0)...(1,1)]
519 |
520 |
521 |
522 |
523 | The imagery input data
524 |
525 |
526 |
527 |
528 | Creates a new instance
529 |
530 |
531 |
532 |
533 |
534 | Updates all pixel shader properties
535 |
536 |
537 |
538 |
539 |
540 | Represents a color inversion effect
541 |
542 |
543 |
544 |
545 |
546 | Identifies the property
547 |
548 |
549 |
550 |
551 | Identifies the property
552 |
553 |
554 |
555 |
556 | The inversion amount.
557 |
558 | Should be set to a value between [0..1]
559 |
560 |
561 |
562 |
563 | The imagery input data
564 |
565 |
566 |
567 |
568 | Creates a new instance
569 |
570 |
571 |
572 |
573 |
574 | Updates all pixel shader properties
575 |
576 |
577 |
578 |
579 |
580 | Represents a telescopic blurring effect
581 |
582 |
583 |
584 |
585 |
586 | Identifies the property
587 |
588 |
589 |
590 |
591 | Identifies the property
592 |
593 |
594 |
595 |
596 | Identifies the property
597 |
598 |
599 |
600 |
601 | Identifies the property
602 |
603 |
604 |
605 |
606 | The blur's center point
607 |
608 | Should be set to a value between [(0,0)..(1,1)]
609 |
610 |
611 |
612 |
613 | The telescopic blur amount.
614 |
615 | Should be set to a value between [0..1]
616 |
617 |
618 |
619 |
620 | The blur's inner falloff radius.
621 |
622 | Should be set to a value between [0..1]
623 |
624 |
625 |
626 |
627 | The imagery input data
628 |
629 |
630 |
631 |
632 | Creates a new instance
633 |
634 |
635 |
636 |
637 |
638 | Updates all pixel shader properties
639 |
640 |
641 |
642 |
643 |
644 | Represents a spastic horizontal twitching effect
645 |
646 |
647 |
648 |
649 |
650 | Identifies the property
651 |
652 |
653 |
654 |
655 | Identifies the property
656 |
657 |
658 |
659 |
660 | Identifies the property
661 |
662 |
663 |
664 |
665 | The twitching phase shift.
666 |
667 | Should be set to a value between [0..1] which will be mapped to a value between [0..2π]
668 |
669 |
670 |
671 |
672 | The twitching amount.
673 |
674 | Should be set to a value between [0..1]
675 |
676 |
677 |
678 |
679 | The imagery input data
680 |
681 |
682 |
683 |
684 | Creates a new instance
685 |
686 |
687 |
688 |
689 |
690 | Updates all pixel shader properties
691 |
692 |
693 |
694 |
695 |
696 | Identifies the property
697 |
698 |
699 |
700 |
701 | Identifies the property
702 |
703 |
704 |
705 |
706 | The imagery input data
707 |
708 |
709 |
710 |
711 | The blur radius.
712 |
713 |
714 |
715 |
716 | Creates a new instance.
717 |
718 |
719 |
720 |
721 |
722 | Updates all pixel shader properties
723 |
724 |
725 |
726 |
727 |
728 | Represents the base class for all pixel shader effects. Cannot be inherited from external classes.
729 |
730 |
731 |
732 |
733 |
734 | A list of all available pixel shader effects' names
735 |
736 |
737 |
738 |
739 | Static constructor
740 |
741 |
742 |
743 |
744 |
745 | Creates a new pixel shader with the caller's name used as pixel shader input file
746 |
747 |
748 |
749 |
750 |
751 | Creates a new pixel shader with the given name used as pixel shader input file (without file extension or directory)
752 |
753 | Compiled pixel shader file name
754 |
755 |
756 |
757 |
758 | Creates a new pixel shader with the given C# class type
759 |
760 | Pixel shader effect type
761 |
762 |
763 |
764 |
765 | Creates a new pixel shader effect based on the given shader
766 |
767 | Pixel shader
768 |
769 |
770 |
771 |
772 | Updates all pixel shader properties
773 |
774 |
775 |
776 |
777 | Tries to get the pixel shader associated with the given name and returns whether the fetch was successfull
778 |
779 | Pixel shader name
780 | The pixel shader (null if not found)
781 | Result, whether the fetching operation was successfull
782 |
783 |
784 |
785 | Registers a new Dependency Property bound to a given .NET Property and a HLSL Pixel Shader register
786 |
787 | .NET Property name
788 | .NET Property type
789 | .NET Parent type
790 | Default value
791 | HLSL register
792 | >Generated Depenendy Property
793 |
794 |
795 |
796 |
--------------------------------------------------------------------------------