Update Files
BIN
leenkx/Assets/blue_noise64.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
leenkx/Assets/brdf.png
Normal file
After Width: | Height: | Size: 20 KiB |
1
leenkx/Assets/clouds_base.raw
Normal file
1
leenkx/Assets/clouds_detail.raw
Normal file
BIN
leenkx/Assets/clouds_map.png
Normal file
After Width: | Height: | Size: 953 KiB |
BIN
leenkx/Assets/font_default.ttf
Normal file
BIN
leenkx/Assets/font_default_full.ttf
Normal file
202
leenkx/Assets/font_license_roboto.txt
Normal file
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
BIN
leenkx/Assets/font_mono.ttf
Normal file
BIN
leenkx/Assets/font_mono_full.ttf
Normal file
BIN
leenkx/Assets/hosek/hosek_radiance.hdr
Normal file
7
leenkx/Assets/hosek/hosek_radiance_0.hdr
Normal file
7
leenkx/Assets/hosek/hosek_radiance_1.hdr
Normal file
7
leenkx/Assets/hosek/hosek_radiance_2.hdr
Normal file
@ -0,0 +1,7 @@
|
||||
#?RADIANCE
|
||||
# Output from cmft.
|
||||
FORMAT=32-bit_rle_rgbe
|
||||
EXPOSURE=1
|
||||
|
||||
-Y 16 +X 32
|
||||
?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>?h<><68>Cl<43><6C>Cl<43><6C>Bl<42><6C>Bk<42><6B>Aj<41><6A>Aj<41><6A>Aj<41><6A>Aj<41><6A>Ai<41><69>@i<><69>?h<><68>>g<><67>>f<><66>>g<><67>?g<><67>?g<><67>?g<><67>?g<><67>>g<><67>>f<><66>>g<><67>?h<><68>@i<><69>@i<><69>Aj<41><6A>Aj<41><6A>Aj<41><6A>Aj<41><6A>Bk<42><6B>Bl<42><6C>Cl<43><6C>Cl<43><6C>JuĀJuÀJtÀItÀItHr<48><72>Gq<47><71>Fp<46><70>Eo<45><6F>Dn<44><6E>Dm<44><6D>Dm<44><6D>Dm<44><6D>Cl<43><6C>Bk<42><6B>Bk<42><6B>Bk<42><6B>Bk<42><6B>Cl<43><6C>Cm<43><6D>Dm<44><6D>Dm<44><6D>Dn<44><6E>Eo<45><6F>Fp<46><70>Fq<46><71>Hr<48><72>ItItÀItÀJuÀJuĀU<C480>πT<CF80>T<CE80>πS<CF80>S̀R~ˀP|ɀO{ǀNzƀMxĀMxĀLwÀLvLvKu<4B><75>Ku<4B><75>Ku<4B><75>Ku<4B><75>Kv<4B><76>LvLwÀMxĀMxĀNyŀOzǀP|ɀR~ˀS̀S<CD80>T<CE80>πT<CF80>U<CE80>πj<CF80><6A><EFBFBD>j<EFBFBD><6A><EFBFBD>i<EFBFBD><69><EFBFBD>`<60>ـ_<D980>^<5E>րe<D680>ـd<D980>c<D880>׀b<D780>րY<D680>πX<CF80>X<CE80>̀W<CD80>̀`<60>Ҁ`<60>Ҁ`<60>Ҁ`<60>ҀW<D280>̀X<CC80>̀X<CD80>̀Y<CD80>b<CE80>րc<D680>׀d<D780>d<D880>ـ^<5E>ր_<D680>`<60>ـi<D980><69><EFBFBD>j<EFBFBD><6A><EFBFBD>j<EFBFBD><6A><EFBFBD>t<EFBFBD><74><EFBFBD>t<EFBFBD><74><EFBFBD>s<EFBFBD><73><EFBFBD>r<EFBFBD><72><EFBFBD>p<EFBFBD><70><EFBFBD>p<EFBFBD><70><EFBFBD>o<EFBFBD>߀o<DF80>ހn<DE80>݀m<DD80>݀l<DD80>܀k<DC80>ۀk<DB80>ڀk<DA80>ـk<D980>ـk<D980>ـk<D980>ـk<D980>ـk<D980>ـk<D980>ڀk<DA80>ۀl<DB80>ۀm<DB80>܀n<DC80>݀n<DD80>ހo<DE80>߀p<DF80><70><EFBFBD>p<EFBFBD><70><EFBFBD>r<EFBFBD><72><EFBFBD>s<EFBFBD><73><EFBFBD>t<EFBFBD><74><EFBFBD>t<EFBFBD><74><EFBFBD>|<7C><><EFBFBD>|<7C><><EFBFBD>|<7C><><EFBFBD>{<7B><><EFBFBD>y<EFBFBD><79><EFBFBD>x<EFBFBD><78><EFBFBD>x<EFBFBD><78><EFBFBD>w<EFBFBD><77><EFBFBD>v<EFBFBD><76><EFBFBD>v<EFBFBD><76><EFBFBD>u<EFBFBD>߀u<DF80>߀t<DF80>ހt<DE80>ހt<DE80>ހt<DE80>݀t<DD80>݀t<DD80>݀t<DD80>ހt<DE80>ހu<DE80>߀u<DF80>߀v<DF80><76><EFBFBD>v<EFBFBD><76><EFBFBD>w<EFBFBD><77><EFBFBD>w<EFBFBD><77><EFBFBD>x<EFBFBD><78><EFBFBD>y<EFBFBD><79><EFBFBD>{<7B><><EFBFBD>{<7B><><EFBFBD>|<7C><><EFBFBD>|<7C>瀂<EFBFBD>倁<EFBFBD>倁<EFBFBD>倁<EFBFBD>倀<EFBFBD><E58080><EFBFBD><EFBFBD><7F><EFBFBD>~<7E><><EFBFBD>}<7D><><EFBFBD>}<7D><><EFBFBD>|<7C><><EFBFBD>|<7C><><EFBFBD>|<7C><><EFBFBD>{<7B><><EFBFBD>{<7B>߀{<7B>߀{<7B>߀{<7B>߀{<7B>߀{<7B>߀{<7B><><EFBFBD>|<7C><><EFBFBD>|<7C><><EFBFBD>|<7C><><EFBFBD>|<7C><><EFBFBD>}<7D><><EFBFBD>~<7E><><EFBFBD>~<7E> <EFBFBD>、<EFBFBD>倁<EFBFBD>倁<EFBFBD>倂<EFBFBD>倅<EFBFBD>င<EFBFBD>င<EFBFBD><E18084><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߀<EFBFBD><DF80>߀<EFBFBD><DF80>߀<EFBFBD><DF80>߀<EFBFBD><DF80>߀<EFBFBD><DF80>߀<EFBFBD><DF80>߀<DF80>ހ<DE80>ހ<DE80>ހ<DE80>ހ<DE80>ހ<DE80>ހ<EFBFBD><DE80>߀<EFBFBD><DF80>߀<EFBFBD><DF80>߀<EFBFBD><DF80>߀<EFBFBD><DF80>߀<EFBFBD><DF80>߀<EFBFBD><DF80>߀<EFBFBD><DF80><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>စ<EFBFBD>܀<EFBFBD><DC80>ۀ<EFBFBD><DB80>ۀ<EFBFBD><DB80>ۀ<EFBFBD><DB80>ۀ<EFBFBD><DB80>܀<EFBFBD><DC80>܀<EFBFBD><DC80>܀<EFBFBD><DC80>܀<EFBFBD><DC80>܀<EFBFBD><DC80>݀<EFBFBD><DD80>݀<EFBFBD><DD80>݀<EFBFBD><DD80>݀<EFBFBD><DD80>݀<EFBFBD><DD80>݀<EFBFBD><DD80>݀<EFBFBD><DD80>݀<EFBFBD><DD80>݀<EFBFBD><DD80>݀<EFBFBD><DD80>݀<EFBFBD><DD80>݀<EFBFBD><DD80>݀<EFBFBD><DD80>݀<EFBFBD><DD80>܀<EFBFBD><DC80>܀<EFBFBD><DC80>܀<EFBFBD><DC80>ۀ<EFBFBD><DB80>ۀ<EFBFBD><DB80>ۀ<EFBFBD><DB80>ۀ<EFBFBD><DB80>܀<EFBFBD><DC80>׀<EFBFBD><D780>׀<EFBFBD><D780>׀<EFBFBD><D780>׀<EFBFBD><D780><EFBFBD><D880>ـ<EFBFBD><D980>ڀ<EFBFBD><DA80>ڀ<EFBFBD><DA80>ۀ<EFBFBD><DB80>ۀ<EFBFBD><DB80>ۀ<EFBFBD><DB80>ۀ<DB80>܀<DC80>܀<DC80>݀<DD80>݀<DD80>݀<DD80>݀<DD80>݀<DD80>܀<EFBFBD><DC80>܀<EFBFBD><DC80>ۀ<EFBFBD><DB80>ۀ<EFBFBD><DB80>ۀ<EFBFBD><DB80>ڀ<EFBFBD><DA80>ڀ<EFBFBD><DA80>ـ<EFBFBD><D980><EFBFBD><D880>׀<EFBFBD><D780>׀<EFBFBD><D780>׀<EFBFBD><D780>׀<EFBFBD><D780>ր<EFBFBD><D680>ր<EFBFBD><D680>ր~<7E>׀}<7D>}<7D><D880>ـ~<7E>ڀ~<7E>ۀ~<7E>ۀz<DB80>݀z<DD80>ހz<DE80>ހz<DE80>߀|<7C>ހ|<7C>ހ|<7C>ހ|<7C>ހz<DE80>߀z<DF80>ހz<DE80>ހz<DE80>݀}<7D>܀~<7E>ۀ~<7E>ڀ<DA80>ـ}<7D>ـ}<7D>~<7E>׀<EFBFBD><D780>ր<EFBFBD><D680>ր<EFBFBD><D680>րz<D680>ۀz<DB80>ۀz<DB80>ۀy<DB80>ۀy<DB80>܀x<DC80>݀x<DD80>ހx<DE80>߀w<DF80><77><EFBFBD>w<EFBFBD><77><EFBFBD>v<EFBFBD><76><EFBFBD>v<EFBFBD><76><EFBFBD>v<EFBFBD><76><EFBFBD>v<EFBFBD><76><EFBFBD>u<EFBFBD><75><EFBFBD>u<EFBFBD><75><EFBFBD>u<EFBFBD><75><EFBFBD>u<EFBFBD><75><EFBFBD>v<EFBFBD><76><EFBFBD>v<EFBFBD><76><EFBFBD>v<EFBFBD><76><EFBFBD>v<EFBFBD><76><EFBFBD>w<EFBFBD><77><EFBFBD>w<EFBFBD><77><EFBFBD>x<EFBFBD>߀x<DF80>ހx<DE80>݀y<DD80>܀y<DC80>ۀz<DB80>ۀz<DB80>ۀz<DB80>ۀv<DB80><76><EFBFBD>v<EFBFBD><76><EFBFBD>v<EFBFBD><76><EFBFBD>v<EFBFBD><76><EFBFBD>u<EFBFBD><75><EFBFBD>u<EFBFBD><75><EFBFBD>u<EFBFBD><75><EFBFBD>t<EFBFBD><74><EFBFBD>t<EFBFBD><74><EFBFBD>t<EFBFBD><74><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>r<EFBFBD><72><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>r<EFBFBD><72><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>t<EFBFBD><74><EFBFBD>t<EFBFBD><74><EFBFBD>t<EFBFBD><74><EFBFBD>u<EFBFBD><75><EFBFBD>u<EFBFBD><75><EFBFBD>u<EFBFBD><75><EFBFBD>v<EFBFBD><76><EFBFBD>v<EFBFBD><76><EFBFBD>v<EFBFBD><76><EFBFBD>v<EFBFBD><76><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>q<EFBFBD><71><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>q<EFBFBD><71><EFBFBD>q<EFBFBD><71><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>s<EFBFBD><73><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>r<EFBFBD><72><EFBFBD>
|
BIN
leenkx/Assets/hosek/hosek_radiance_3.hdr
Normal file
BIN
leenkx/Assets/hosek/hosek_radiance_4.hdr
Normal file
7
leenkx/Assets/hosek/hosek_radiance_5.hdr
Normal file
@ -0,0 +1,7 @@
|
||||
#?RADIANCE
|
||||
# Written by stb_image_write.h
|
||||
FORMAT=32-bit_rle_rgbe
|
||||
EXPOSURE= 1.0000000000000
|
||||
|
||||
-Y 2 +X 4
|
||||
^<5E>Z<CE80>ɀZ<C980>ɀ^<5E>y<CE80>ހv<DE80><76><EFBFBD>v<EFBFBD><76><EFBFBD>y<EFBFBD>ހ
|
7
leenkx/Assets/hosek/hosek_radiance_6.hdr
Normal file
@ -0,0 +1,7 @@
|
||||
#?RADIANCE
|
||||
# Written by stb_image_write.h
|
||||
FORMAT=32-bit_rle_rgbe
|
||||
EXPOSURE= 1.0000000000000
|
||||
|
||||
-Y 1 +X 2
|
||||
i<EFBFBD>Հi<EFBFBD>Հ
|
7
leenkx/Assets/hosek/hosek_radiance_7.hdr
Normal file
@ -0,0 +1,7 @@
|
||||
#?RADIANCE
|
||||
# Written by stb_image_write.h
|
||||
FORMAT=32-bit_rle_rgbe
|
||||
EXPOSURE= 1.0000000000000
|
||||
|
||||
-Y 1 +X 1
|
||||
i<EFBFBD>Հ
|
80
leenkx/Assets/ies/JellyFish.ies
Normal file
@ -0,0 +1,80 @@
|
||||
IESNA:LM-63-1995
|
||||
[TEST]BALLABS TEST NO. 12788.0
|
||||
[MANUFAC] INFINITY LIGHTING INC - CARTHAGE, MISSOURI
|
||||
[LUMINAIRE] 1/100W ICETRON INDUCTION 20x15"DIRECT AREALIGHT LUMINAIRE
|
||||
[LUMINAIRE] MIRO4 SPEC ALUM TYPE II OPTICS & CLEAR FLAT GLASS LENS
|
||||
[LUMINAIRE] BLACK PANEL STREET SIDE SYLVANIA # QT 1x150 ICE/UNV-T
|
||||
[LUMCAT] ICEAL2-150S-TYPE2/CG1-277
|
||||
[LAMPCAT] ICE100/QT150 2PIN
|
||||
TILT=NONE
|
||||
1 11000. 1.000000 25 21 1 1 .938 1.266 .000
|
||||
1.0000 1.0000 140.0000
|
||||
.0 5.0 10.0 15.0 20.0 25.0 30.0 35.0 40.0 45.0
|
||||
50.0 55.0 60.0 62.5 65.0 67.5 70.0 72.5 75.0 77.5
|
||||
80.0 82.5 85.0 87.5 90.0
|
||||
.0 5.0 15.0 25.0 35.0 45.0 55.0 65.0 75.0 85.0
|
||||
90.0 95.0 105.0 115.0 125.0 135.0 145.0 155.0 165.0 175.0
|
||||
180.0
|
||||
1789. 1841. 1911. 1979. 2023. 2025. 1994. 1867. 1718. 1551.
|
||||
1374. 1208. 990. 808. 637. 469. 347. 202. 89. 18.
|
||||
9. 7. 7. 6. 0.
|
||||
1789. 1831. 1908. 1969. 2013. 2018. 1983. 1865. 1701. 1548.
|
||||
1353. 1193. 981. 842. 661. 503. 352. 172. 68. 19.
|
||||
8. 6. 6. 5. 0.
|
||||
1789. 1828. 1891. 1939. 1958. 1939. 1908. 1808. 1668. 1559.
|
||||
1428. 1300. 1222. 1161. 999. 778. 580. 318. 129. 39.
|
||||
10. 7. 7. 4. 0.
|
||||
1789. 1818. 1865. 1891. 1942. 1959. 1927. 1843. 1761. 1714.
|
||||
1673. 1599. 1445. 1325. 1165. 948. 668. 400. 186. 75.
|
||||
30. 9. 7. 2. 0.
|
||||
1789. 1811. 1821. 1891. 1941. 1974. 1980. 1943. 1993. 2082.
|
||||
1963. 1808. 1621. 1601. 1424. 1166. 829. 487. 279. 152.
|
||||
65. 15. 8. 2. 0.
|
||||
1789. 1794. 1804. 1893. 1935. 1995. 2020. 2145. 2342. 2221.
|
||||
2063. 2135. 2157. 1694. 948. 340. 101. 8. 0. 185.
|
||||
94. 32. 9. 0. 0.
|
||||
1789. 1775. 1803. 1868. 1931. 1992. 2076. 2357. 2333. 2285.
|
||||
2254. 2608. 2375. 2010. 1722. 1448. 981. 661. 376. 244.
|
||||
122. 38. 8. 0. 0.
|
||||
1789. 1763. 1798. 1839. 1918. 1961. 2151. 2291. 2310. 2263.
|
||||
2575. 2700. 2380. 2075. 1792. 1483. 1102. 702. 430. 298.
|
||||
192. 67. 11. 2. 0.
|
||||
1789. 1746. 1801. 1827. 1871. 1923. 2176. 2119. 2124. 2062.
|
||||
2553. 2596. 2201. 1907. 1678. 1368. 1015. 673. 440. 303.
|
||||
178. 63. 10. 1. 0.
|
||||
1789. 1738. 1788. 1808. 1830. 1895. 2081. 2024. 1953. 1883.
|
||||
2313. 2285. 1854. 1661. 1400. 1139. 833. 577. 404. 267.
|
||||
157. 54. 12. 1. 0.
|
||||
1789. 1735. 1783. 1797. 1812. 1868. 2046. 1983. 1911. 1805.
|
||||
2191. 2151. 1759. 1513. 1288. 1033. 802. 568. 386. 243.
|
||||
134. 56. 10. 3. 0.
|
||||
1789. 1734. 1778. 1786. 1797. 1838. 2016. 1951. 1871. 1766.
|
||||
2128. 2078. 1681. 1474. 1248. 1009. 739. 523. 349. 228.
|
||||
144. 52. 13. 2. 0.
|
||||
1789. 1733. 1774. 1773. 1771. 1777. 1959. 1895. 1811. 1647.
|
||||
2034. 1957. 1595. 1293. 1118. 925. 717. 481. 319. 208.
|
||||
125. 51. 7. 1. 0.
|
||||
1789. 1738. 1763. 1755. 1744. 1704. 1880. 1794. 1752. 1541.
|
||||
1772. 1720. 1427. 1191. 1003. 795. 588. 427. 274. 166.
|
||||
98. 39. 8. 3. 0.
|
||||
1789. 1734. 1744. 1732. 1708. 1647. 1674. 1703. 1620. 1413.
|
||||
1325. 1423. 1205. 983. 808. 642. 464. 312. 192. 107.
|
||||
57. 18. 8. 3. 0.
|
||||
1789. 1735. 1714. 1725. 1673. 1590. 1481. 1511. 1373. 1230.
|
||||
982. 993. 902. 771. 626. 456. 300. 187. 112. 60.
|
||||
31. 14. 8. 4. 0.
|
||||
1789. 1736. 1681. 1700. 1617. 1511. 1381. 1252. 1210. 1043.
|
||||
875. 657. 554. 487. 398. 294. 195. 122. 70. 40.
|
||||
19. 11. 8. 3. 0.
|
||||
1789. 1737. 1666. 1641. 1577. 1471. 1333. 1172. 1015. 890.
|
||||
728. 574. 409. 326. 243. 181. 114. 72. 40. 24.
|
||||
14. 9. 7. 4. 0.
|
||||
1789. 1740. 1679. 1601. 1493. 1388. 1268. 1114. 956. 769.
|
||||
624. 481. 347. 267. 201. 141. 85. 41. 25. 16.
|
||||
10. 7. 6. 3. 0.
|
||||
1789. 1737. 1693. 1616. 1479. 1340. 1187. 1041. 896. 724.
|
||||
572. 431. 303. 233. 167. 117. 62. 29. 18. 12.
|
||||
9. 6. 6. 4. 1.
|
||||
1789. 1742. 1698. 1623. 1491. 1354. 1196. 1040. 894. 722.
|
||||
565. 421. 302. 227. 159. 108. 57. 20. 14. 10.
|
||||
8. 6. 6. 5. 0.
|
173
leenkx/Assets/ies/load_ies.py
Normal file
@ -0,0 +1,173 @@
|
||||
# Using IES profiles from http://www.derekjenson.com/3d-blog/ies-light-profiles
|
||||
# IES parser based on:
|
||||
# https://github.com/tobspr/RenderPipeline
|
||||
# Copyright (c) 2014-2016 tobspr <tobias.springer1@gmail.com>
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import re
|
||||
import os
|
||||
import math
|
||||
import bpy
|
||||
import random
|
||||
|
||||
def load(filepath):
|
||||
global _vertical_angles
|
||||
global _horizontal_angles
|
||||
global _candela_values
|
||||
KEYWORD_REGEX = re.compile(r"\[([A-Za-z0-8_-]+)\](.*)")
|
||||
|
||||
PROFILES = [
|
||||
"IESNA:LM-63-1986",
|
||||
"IESNA:LM-63-1991",
|
||||
"IESNA91",
|
||||
"IESNA:LM-63-1995",
|
||||
"IESNA:LM-63-2002",
|
||||
"ERCO Leuchten GmbH BY: ERCO/LUM650/8701",
|
||||
"ERCO Leuchten GmbH"
|
||||
]
|
||||
|
||||
with open(filepath, "r") as handle:
|
||||
lines = handle.readlines()
|
||||
|
||||
lines = [i.strip() for i in lines]
|
||||
|
||||
# Parse version header
|
||||
first_line = lines.pop(0)
|
||||
if first_line not in PROFILES:
|
||||
raise "Unsupported Profile: " + first_line
|
||||
|
||||
# Extracts the keywords
|
||||
keywords = {}
|
||||
while lines:
|
||||
line = lines.pop(0)
|
||||
if not line.startswith("["):
|
||||
if line != "TILT=NONE":
|
||||
continue
|
||||
lines.insert(0, line)
|
||||
break
|
||||
else:
|
||||
match = KEYWORD_REGEX.match(line)
|
||||
if match:
|
||||
key, val = match.group(1, 2)
|
||||
keywords[key.strip()] = val.strip()
|
||||
else:
|
||||
raise "Invalid keyword line: " + line
|
||||
|
||||
# Next line should be TILT=NONE according to the spec
|
||||
if lines.pop(0) != "TILT=NONE":
|
||||
raise "Expected TILT=NONE line, but none found!"
|
||||
|
||||
# From now on, lines do not matter anymore, instead everything is space seperated
|
||||
new_parts = (' '.join(lines)).replace(",", " ").split()
|
||||
|
||||
def read_int():
|
||||
return int(new_parts.pop(0))
|
||||
|
||||
def read_float():
|
||||
return float(new_parts.pop(0))
|
||||
|
||||
# Amount of Lamps
|
||||
if read_int() != 1:
|
||||
raise "Only 1 Lamp supported!"
|
||||
|
||||
# Extract various properties
|
||||
lumen_per_lamp = read_float()
|
||||
candela_multiplier = read_float()
|
||||
num_vertical_angles = read_int()
|
||||
num_horizontal_angles = read_int()
|
||||
|
||||
if num_vertical_angles < 1 or num_horizontal_angles < 1:
|
||||
raise "Invalid of vertical/horizontal angles!"
|
||||
|
||||
photometric_type = read_int()
|
||||
unit_type = read_int()
|
||||
|
||||
# Check for a correct unit type, should be 1 for meters and 2 for feet
|
||||
if unit_type not in [1, 2]:
|
||||
raise "Invalid unit type"
|
||||
|
||||
width = read_float()
|
||||
length = read_float()
|
||||
height = read_float()
|
||||
ballast_factor = read_float()
|
||||
future_use = read_float()
|
||||
input_watts = read_float()
|
||||
|
||||
_vertical_angles = [read_float() for i in range(num_vertical_angles)]
|
||||
_horizontal_angles = [read_float() for i in range(num_horizontal_angles)]
|
||||
|
||||
_candela_values = []
|
||||
candela_scale = 0.0
|
||||
|
||||
for i in range(num_horizontal_angles):
|
||||
vertical_data = [read_float() for i in range(num_vertical_angles)]
|
||||
candela_scale = max(candela_scale, max(vertical_data))
|
||||
_candela_values += vertical_data
|
||||
|
||||
# Rescale values, divide by maximum
|
||||
_candela_values = [i / candela_scale for i in _candela_values]
|
||||
generate_texture()
|
||||
|
||||
def generate_texture():
|
||||
tex = bpy.data.images.new("iestexture", width=128, height=128, float_buffer=True) # R16
|
||||
resolution_vertical = 128
|
||||
resolution_horizontal = 128
|
||||
|
||||
for vert in range(resolution_vertical):
|
||||
for horiz in range(resolution_horizontal):
|
||||
vert_angle = vert / (resolution_vertical - 1.0)
|
||||
vert_angle = math.cos(vert_angle * math.pi) * 90.0 + 90.0
|
||||
horiz_angle = horiz / (resolution_horizontal - 1.0) * 360.0
|
||||
candela = get_candela_value(vert_angle, horiz_angle)
|
||||
x = vert
|
||||
y = horiz
|
||||
i = x + y * resolution_horizontal
|
||||
tex.pixels[i * 4] = candela
|
||||
tex.pixels[i * 4 + 1] = candela
|
||||
tex.pixels[i * 4 + 2] = candela
|
||||
tex.pixels[i * 4 + 3] = 1.0
|
||||
|
||||
def get_candela_value(vertical_angle, horizontal_angle):
|
||||
# Assume a dataset without horizontal angles
|
||||
return get_vertical_candela_value(0, vertical_angle)
|
||||
|
||||
def get_vertical_candela_value(horizontal_angle_idx, vertical_angle):
|
||||
if vertical_angle < 0.0:
|
||||
return 0.0
|
||||
|
||||
if vertical_angle > _vertical_angles[len(_vertical_angles) - 1]:
|
||||
return 0.0
|
||||
|
||||
for vertical_index in range(1, len(_vertical_angles)):
|
||||
curr_angle = _vertical_angles[vertical_index]
|
||||
if curr_angle > vertical_angle:
|
||||
prev_angle = _vertical_angles[vertical_index - 1]
|
||||
prev_value = get_candela_value_from_index(vertical_index - 1, horizontal_angle_idx)
|
||||
curr_value = get_candela_value_from_index(vertical_index, horizontal_angle_idx)
|
||||
lerp = (vertical_angle - prev_angle) / (curr_angle - prev_angle)
|
||||
assert lerp >= 0.0 and lerp <= 1.0
|
||||
return curr_value * lerp + prev_value * (1.0 - lerp)
|
||||
return 0.0
|
||||
|
||||
def get_candela_value_from_index(vertical_angle_idx, horizontal_angle_idx):
|
||||
index = vertical_angle_idx + horizontal_angle_idx * len(_vertical_angles)
|
||||
return _candela_values[index]
|
||||
|
||||
filepath = "/Users/onek8/Desktop/ies/JellyFish.ies"
|
||||
load(filepath)
|
BIN
leenkx/Assets/noise256.png
Normal file
After Width: | Height: | Size: 66 KiB |
BIN
leenkx/Assets/noise64.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
leenkx/Assets/noise8.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
leenkx/Assets/smaa_area.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
leenkx/Assets/smaa_search.png
Normal file
After Width: | Height: | Size: 313 B |
BIN
leenkx/Assets/water_base.png
Normal file
After Width: | Height: | Size: 410 KiB |
BIN
leenkx/Assets/water_detail.png
Normal file
After Width: | Height: | Size: 461 KiB |
BIN
leenkx/Assets/water_foam.png
Normal file
After Width: | Height: | Size: 61 KiB |
17
leenkx/Shaders/blend_pass/blend_pass.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "blend_pass",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"blend_source": "blend_one",
|
||||
"blend_destination": "blend_one",
|
||||
"blend_operation": "add",
|
||||
"links": [],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "../include/pass_copy.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
62
leenkx/Shaders/bloom_pass/bloom_pass.json
Normal file
@ -0,0 +1,62 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "downsample_pass",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "screenSizeInv",
|
||||
"link": "_screenSizeInv"
|
||||
},
|
||||
{
|
||||
"name": "currentMipLevel",
|
||||
"link": "_downsampleCurrentMip"
|
||||
},
|
||||
{
|
||||
"name": "BloomThresholdData",
|
||||
"link": "_BloomThresholdData",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "downsample_pass.frag.glsl"
|
||||
},
|
||||
{
|
||||
"name": "upsample_pass",
|
||||
"blend_source": "blend_one",
|
||||
"blend_destination": "blend_one",
|
||||
"blend_operation": "add",
|
||||
"alpha_blend_source": "blend_zero",
|
||||
"alpha_blend_destination": "blend_one",
|
||||
"alpha_blend_operation": "add",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "screenSizeInv",
|
||||
"link": "_screenSizeInv"
|
||||
},
|
||||
{
|
||||
"name": "currentMipLevel",
|
||||
"link": "_upsampleCurrentMip"
|
||||
},
|
||||
{
|
||||
"name": "sampleScale",
|
||||
"link": "_bloomSampleScale"
|
||||
},
|
||||
{
|
||||
"name": "PPComp11",
|
||||
"link": "_PPComp11",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "upsample_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
79
leenkx/Shaders/bloom_pass/downsample_pass.frag.glsl
Normal file
@ -0,0 +1,79 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc" // bloomKnee, bloomThreshold
|
||||
#include "std/resample.glsl"
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 screenSizeInv;
|
||||
uniform int currentMipLevel;
|
||||
|
||||
#ifdef _CPostprocess
|
||||
uniform vec4 BloomThresholdData; // Only filled with data if currentMipLevel == 0
|
||||
#endif
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
const float epsilon = 6.2e-5; // see https://github.com/keijiro/KinoBloom/issues/15
|
||||
|
||||
#ifdef _BloomAntiFlicker
|
||||
const bool antiFlicker = true;
|
||||
#else
|
||||
const bool antiFlicker = false;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
if (antiFlicker && currentMipLevel == 0) {
|
||||
#ifdef _BloomQualityHigh
|
||||
fragColor.rgb = downsample_13_tap_anti_flicker(tex, texCoord, screenSizeInv);
|
||||
#else
|
||||
#ifdef _BloomQualityMedium
|
||||
fragColor.rgb = downsample_dual_filter_anti_flicker(tex, texCoord, screenSizeInv);
|
||||
#else // _BloomQualityLow
|
||||
fragColor.rgb = downsample_box_filter_anti_flicker(tex, texCoord, screenSizeInv);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
#ifdef _BloomQualityHigh
|
||||
fragColor.rgb = downsample_13_tap(tex, texCoord, screenSizeInv);
|
||||
#else
|
||||
#ifdef _BloomQualityMedium
|
||||
fragColor.rgb = downsample_dual_filter(tex, texCoord, screenSizeInv);
|
||||
#else // _BloomQualityLow
|
||||
fragColor.rgb = downsample_box_filter(tex, texCoord, screenSizeInv);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
if (currentMipLevel == 0) {
|
||||
// https://catlikecoding.com/unity/tutorials/advanced-rendering/bloom/#3.2
|
||||
// https://catlikecoding.com/unity/tutorials/advanced-rendering/bloom/#3.4
|
||||
|
||||
float brightness = max(fragColor.r, max(fragColor.g, fragColor.b));
|
||||
|
||||
#ifdef _CPostprocess
|
||||
// Only apply precalculation optimization if _CPostprocess, otherwise
|
||||
// the compiler is able to do the same optimization for the constant
|
||||
// values from compiled.inc without the need to pass a uniform
|
||||
float softeningCurve = brightness - BloomThresholdData.y;
|
||||
softeningCurve = clamp(softeningCurve, 0.0, BloomThresholdData.z); // "connect" to hard knee curve
|
||||
softeningCurve = softeningCurve * softeningCurve * BloomThresholdData.w;
|
||||
|
||||
float contributionFactor = max(softeningCurve, brightness - BloomThresholdData.x);
|
||||
#else
|
||||
float softeningCurve = brightness - bloomThreshold + bloomKnee;
|
||||
softeningCurve = clamp(softeningCurve, 0.0, 2.0 * bloomKnee);
|
||||
softeningCurve = softeningCurve * softeningCurve / (4 * bloomKnee + epsilon);
|
||||
|
||||
float contributionFactor = max(softeningCurve, brightness - bloomThreshold);
|
||||
#endif
|
||||
|
||||
contributionFactor /= max(epsilon, brightness);
|
||||
|
||||
fragColor.rgb *= contributionFactor;
|
||||
}
|
||||
|
||||
fragColor.a = 1.0;
|
||||
}
|
39
leenkx/Shaders/bloom_pass/upsample_pass.frag.glsl
Normal file
@ -0,0 +1,39 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc" // bloomStrength
|
||||
#include "std/resample.glsl"
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 screenSizeInv;
|
||||
uniform int currentMipLevel;
|
||||
uniform float sampleScale;
|
||||
|
||||
#ifdef _CPostprocess
|
||||
uniform vec3 PPComp11;
|
||||
#endif
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
#ifdef _BloomQualityHigh
|
||||
fragColor.rgb = upsample_tent_filter_3x3(tex, texCoord, screenSizeInv, sampleScale);
|
||||
#else
|
||||
#ifdef _BloomQualityMedium
|
||||
fragColor.rgb = upsample_dual_filter(tex, texCoord, screenSizeInv, sampleScale);
|
||||
#else // _BloomQualityLow
|
||||
fragColor.rgb = upsample_4tap_bilinear(tex, texCoord, screenSizeInv, sampleScale);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (currentMipLevel == 0) {
|
||||
#ifdef _CPostprocess
|
||||
fragColor.rgb *= PPComp11.x;
|
||||
#else
|
||||
fragColor.rgb *= bloomStrength;
|
||||
#endif
|
||||
}
|
||||
|
||||
fragColor.a = 1.0;
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
// Exclusive to SSR for now
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
#include "std/gbuffer.glsl"
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D gbuffer0; // Roughness
|
||||
|
||||
uniform vec2 dirInv;
|
||||
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
float roughness = textureLod(gbuffer0, texCoord, 0.0).b;
|
||||
// if (roughness == 0.0) { // Always blur for now, non blured output can produce noise
|
||||
// fragColor.rgb = textureLod(tex, texCoord).rgb;
|
||||
// return;
|
||||
// }
|
||||
if (roughness >= 0.8) { // No reflections
|
||||
fragColor.rgb = textureLod(tex, texCoord, 0.0).rgb;
|
||||
return;
|
||||
}
|
||||
|
||||
fragColor.rgb = textureLod(tex, texCoord + dirInv * 2.5, 0.0).rgb;
|
||||
fragColor.rgb += textureLod(tex, texCoord + dirInv * 1.5, 0.0).rgb;
|
||||
fragColor.rgb += textureLod(tex, texCoord, 0.0).rgb;
|
||||
fragColor.rgb += textureLod(tex, texCoord - dirInv * 1.5, 0.0).rgb;
|
||||
fragColor.rgb += textureLod(tex, texCoord - dirInv * 2.5, 0.0).rgb;
|
||||
fragColor.rgb /= vec3(5.0);
|
||||
}
|
84
leenkx/Shaders/blur_adaptive_pass/blur_adaptive_pass.json
Normal file
@ -0,0 +1,84 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "blur_adaptive_pass_x",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "dirInv",
|
||||
"link": "_vec2xInv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_adaptive_pass.frag.glsl"
|
||||
},
|
||||
{
|
||||
"name": "blur_adaptive_pass_y",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "dirInv",
|
||||
"link": "_vec2yInv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_adaptive_pass.frag.glsl"
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"name": "blur_adaptive_pass_x2",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "dirInv",
|
||||
"link": "_vec2x2Inv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_adaptive_pass.frag.glsl"
|
||||
},
|
||||
{
|
||||
"name": "blur_adaptive_pass_y3",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "dirInv",
|
||||
"link": "_vec2y3Inv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_adaptive_pass.frag.glsl"
|
||||
},
|
||||
{
|
||||
"name": "blur_adaptive_pass_y3_blend",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"blend_source": "blend_one",
|
||||
"blend_destination": "blend_one",
|
||||
"blend_operation": "add",
|
||||
"links": [
|
||||
{
|
||||
"name": "dirInv",
|
||||
"link": "_vec2y3Inv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_adaptive_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
// Exclusive to volumetric light for now
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 dir;
|
||||
uniform vec2 screenSize;
|
||||
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
const float weight[10] = float[] (0.132572, 0.125472, 0.106373, 0.08078, 0.05495, 0.033482, 0.018275, 0.008934, 0.003912, 0.001535);
|
||||
|
||||
float normpdf(float x, float sigma) {
|
||||
return 0.39894 * exp(-0.5 * x * x / (sigma * sigma)) / sigma;
|
||||
}
|
||||
|
||||
float normpdf3(vec3 v, float sigma) {
|
||||
return 0.39894 * exp(-0.5 * dot(v, v) / (sigma * sigma)) / sigma;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 step = (dir / screenSize.xy);
|
||||
vec3 colf = textureLod(tex, texCoord, 0.0).rgb * weight[0];
|
||||
|
||||
float col;
|
||||
float res = 0.0;
|
||||
float sumfactor = 0.0;
|
||||
float factor;
|
||||
float f = 1.0 / normpdf(0.0, 1.0);
|
||||
|
||||
for (int i = 1; i < 10; i++) {
|
||||
float fw = f * weight[i];
|
||||
vec2 s = step * (float(i) + 0.5);
|
||||
|
||||
col = textureLod(tex, texCoord + s, 0.0).r;
|
||||
factor = normpdf3(col - colf, 1.0) * fw;
|
||||
sumfactor += factor;
|
||||
res += factor * col;
|
||||
|
||||
col = textureLod(tex, texCoord - s, 0.0).r;
|
||||
factor = normpdf3(col - colf, 1.0) * fw;
|
||||
sumfactor += factor;
|
||||
res += factor * col;
|
||||
}
|
||||
|
||||
res /= sumfactor;
|
||||
fragColor = vec4(volumAirColor * res, 1.0);
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "blur_bilat_blend_pass_y",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"blend_source": "blend_one",
|
||||
"blend_destination": "blend_one",
|
||||
"blend_operation": "add",
|
||||
"alpha_blend_source": "blend_one",
|
||||
"alpha_blend_destination": "blend_one",
|
||||
"alpha_blend_operation": "add",
|
||||
"links": [
|
||||
{
|
||||
"name": "dir",
|
||||
"link": "_vec2y"
|
||||
},
|
||||
{
|
||||
"name": "screenSize",
|
||||
"link": "_screenSize"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_bilat_blend_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
49
leenkx/Shaders/blur_bilat_pass/blur_bilat_pass.frag.glsl
Normal file
@ -0,0 +1,49 @@
|
||||
// Exclusive to volumetric light for now
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 dir;
|
||||
uniform vec2 screenSize;
|
||||
|
||||
in vec2 texCoord;
|
||||
out float fragColor;
|
||||
|
||||
const float weight[10] = float[] (0.132572, 0.125472, 0.106373, 0.08078, 0.05495, 0.033482, 0.018275, 0.008934, 0.003912, 0.001535);
|
||||
|
||||
float normpdf(float x, float sigma) {
|
||||
return 0.39894 * exp(-0.5 * x * x / (sigma * sigma)) / sigma;
|
||||
}
|
||||
|
||||
float normpdf3(vec3 v, float sigma) {
|
||||
return 0.39894 * exp(-0.5 * dot(v, v) / (sigma * sigma)) / sigma;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 step = (dir / screenSize.xy);
|
||||
vec3 colf = textureLod(tex, texCoord, 0.0).rgb * weight[0];
|
||||
|
||||
float col;
|
||||
float sumfactor = 0.0;
|
||||
float factor;
|
||||
float f = 1.0 / normpdf(0.0, 1.0);
|
||||
fragColor = 0.0;
|
||||
|
||||
for (int i = 1; i < 10; i++) {
|
||||
float fw = f * weight[i];
|
||||
vec2 s = step * (float(i) + 0.5);
|
||||
|
||||
col = textureLod(tex, texCoord + s, 0.0).r;
|
||||
factor = normpdf3(col - colf, 1.0) * fw;
|
||||
sumfactor += factor;
|
||||
fragColor += factor * col;
|
||||
|
||||
col = textureLod(tex, texCoord - s, 0.0).r;
|
||||
factor = normpdf3(col - colf, 1.0) * fw;
|
||||
sumfactor += factor;
|
||||
fragColor += factor * col;
|
||||
}
|
||||
|
||||
fragColor /= sumfactor;
|
||||
}
|
67
leenkx/Shaders/blur_bilat_pass/blur_bilat_pass.json
Normal file
@ -0,0 +1,67 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "blur_bilat_pass_x",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "dir",
|
||||
"link": "_vec2x"
|
||||
},
|
||||
{
|
||||
"name": "screenSize",
|
||||
"link": "_screenSize"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_bilat_pass.frag.glsl"
|
||||
},
|
||||
{
|
||||
"name": "blur_bilat_pass_y",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "dir",
|
||||
"link": "_vec2y"
|
||||
},
|
||||
{
|
||||
"name": "screenSize",
|
||||
"link": "_screenSize"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_bilat_pass.frag.glsl"
|
||||
},
|
||||
{
|
||||
"name": "blur_bilat_pass_y_blend",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"blend_source": "blend_one",
|
||||
"blend_destination": "blend_one",
|
||||
"blend_operation": "add",
|
||||
"alpha_blend_source": "blend_one",
|
||||
"alpha_blend_destination": "blend_one",
|
||||
"alpha_blend_operation": "add",
|
||||
"links": [
|
||||
{
|
||||
"name": "dir",
|
||||
"link": "_vec2y"
|
||||
},
|
||||
{
|
||||
"name": "screenSize",
|
||||
"link": "_screenSize"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_bilat_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
44
leenkx/Shaders/blur_edge_pass/blur_edge_pass.frag.glsl
Normal file
@ -0,0 +1,44 @@
|
||||
// Exclusive to SSAO for now
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
#include "std/gbuffer.glsl"
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D gbuffer0;
|
||||
|
||||
uniform vec2 dirInv; // texStep
|
||||
|
||||
in vec2 texCoord;
|
||||
out float fragColor;
|
||||
|
||||
// const float blurWeights[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
|
||||
const float blurWeights[10] = float[] (0.132572, 0.125472, 0.106373, 0.08078, 0.05495, 0.033482, 0.018275, 0.008934, 0.003912, 0.001535);
|
||||
const float discardThreshold = 0.95;
|
||||
|
||||
void main() {
|
||||
vec3 nor = getNor(textureLod(gbuffer0, texCoord, 0.0).rg);
|
||||
|
||||
fragColor = textureLod(tex, texCoord, 0.0).r * blurWeights[0];
|
||||
float weight = blurWeights[0];
|
||||
|
||||
for (int i = 1; i < 8; ++i) {
|
||||
float posadd = i;// + 0.5;
|
||||
|
||||
vec3 nor2 = getNor(textureLod(gbuffer0, texCoord + i * dirInv, 0.0).rg);
|
||||
float influenceFactor = step(discardThreshold, dot(nor2, nor));
|
||||
float col = textureLod(tex, texCoord + posadd * dirInv, 0.0).r;
|
||||
float w = blurWeights[i] * influenceFactor;
|
||||
fragColor += col * w;
|
||||
weight += w;
|
||||
|
||||
nor2 = getNor(textureLod(gbuffer0, texCoord - i * dirInv, 0.0).rg);
|
||||
influenceFactor = step(discardThreshold, dot(nor2, nor));
|
||||
col = textureLod(tex, texCoord - posadd * dirInv, 0.0).r;
|
||||
w = blurWeights[i] * influenceFactor;
|
||||
fragColor += col * w;
|
||||
weight += w;
|
||||
}
|
||||
|
||||
fragColor = fragColor / weight;
|
||||
}
|
74
leenkx/Shaders/blur_edge_pass/blur_edge_pass.json
Normal file
@ -0,0 +1,74 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "blur_edge_pass_x",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "dirInv",
|
||||
"link": "_vec2xInv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_edge_pass.frag.glsl"
|
||||
},
|
||||
{
|
||||
"name": "blur_edge_pass_y",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "dirInv",
|
||||
"link": "_vec2yInv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_edge_pass.frag.glsl"
|
||||
},
|
||||
{
|
||||
"name": "blur_edge_pass_y_blend",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"blend_source": "destination_color",
|
||||
"blend_destination": "blend_zero",
|
||||
"blend_operation": "add",
|
||||
"links": [
|
||||
{
|
||||
"name": "dirInv",
|
||||
"link": "_vec2yInv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_edge_pass.frag.glsl"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "blur_edge_pass_y_blend_add",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"blend_source": "blend_one",
|
||||
"blend_destination": "blend_one",
|
||||
"blend_operation": "add",
|
||||
"alpha_blend_source": "blend_one",
|
||||
"alpha_blend_destination": "blend_one",
|
||||
"alpha_blend_operation": "add",
|
||||
"links": [
|
||||
{
|
||||
"name": "dirInv",
|
||||
"link": "_vec2yInv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_edge_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
23
leenkx/Shaders/blur_pass/blur_pass.frag.glsl
Normal file
@ -0,0 +1,23 @@
|
||||
#version 450
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform vec2 dirInv;
|
||||
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor.rgb = textureLod(tex, texCoord + dirInv * 5.5, 0.0).rgb;
|
||||
fragColor.rgb += textureLod(tex, texCoord + dirInv * 4.5, 0.0).rgb;
|
||||
fragColor.rgb += textureLod(tex, texCoord + dirInv * 3.5, 0.0).rgb;
|
||||
fragColor.rgb += textureLod(tex, texCoord + dirInv * 2.5, 0.0).rgb;
|
||||
fragColor.rgb += textureLod(tex, texCoord + dirInv * 1.5, 0.0).rgb;
|
||||
fragColor.rgb += textureLod(tex, texCoord, 0.0).rgb;
|
||||
fragColor.rgb += textureLod(tex, texCoord - dirInv * 1.5, 0.0).rgb;
|
||||
fragColor.rgb += textureLod(tex, texCoord - dirInv * 2.5, 0.0).rgb;
|
||||
fragColor.rgb += textureLod(tex, texCoord - dirInv * 3.5, 0.0).rgb;
|
||||
fragColor.rgb += textureLod(tex, texCoord - dirInv * 4.5, 0.0).rgb;
|
||||
fragColor.rgb += textureLod(tex, texCoord - dirInv * 5.5, 0.0).rgb;
|
||||
fragColor.rgb /= vec3(11.0);
|
||||
}
|
66
leenkx/Shaders/blur_pass/blur_pass.json
Normal file
@ -0,0 +1,66 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "blur_pass_x",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "dirInv",
|
||||
"link": "_vec2xInv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_pass.frag.glsl"
|
||||
},
|
||||
{
|
||||
"name": "blur_pass_y",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "dirInv",
|
||||
"link": "_vec2yInv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_pass.frag.glsl"
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"name": "blur_pass_x2",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "dirInv",
|
||||
"link": "_vec2x2Inv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_pass.frag.glsl"
|
||||
},
|
||||
{
|
||||
"name": "blur_pass_y2",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "dirInv",
|
||||
"link": "_vec2y2Inv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blur_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
#ifdef _CPostprocess
|
||||
uniform vec3 PPComp13;
|
||||
#endif
|
||||
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
vec2 barrelDistortion(vec2 coord, float amt) {
|
||||
vec2 cc = coord - 0.5;
|
||||
float dist = dot(cc, cc);
|
||||
return coord + cc * dist * amt;
|
||||
}
|
||||
float sat(float value)
|
||||
{
|
||||
return clamp(value, 0.0, 1.0);
|
||||
}
|
||||
float linterp(float t) {
|
||||
return sat(1.0 - abs(2.0 * t - 1.0) );
|
||||
}
|
||||
float remap(float t, float a, float b ) {
|
||||
return sat((t - a) / (b - a));
|
||||
}
|
||||
vec4 spectrum_offset(float t) {
|
||||
vec4 ret;
|
||||
float low = step(t,0.5);
|
||||
float high = 1.0 - low;
|
||||
float minMap = 1.0;
|
||||
float maxMap = 6.0;
|
||||
float w = linterp( remap(t, minMap/maxMap, 5.0/maxMap ) );
|
||||
ret = vec4(low, 1.0, high, 1.) * vec4(1.0-w, w, 1.0-w, 1.0);
|
||||
|
||||
return pow(ret, vec4(1.0/2.2) );
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
#ifdef _CPostprocess
|
||||
float max_distort = PPComp13.x;
|
||||
int num_iter = int(PPComp13.y);
|
||||
#else
|
||||
float max_distort = compoChromaticStrength;
|
||||
int num_iter = compoChromaticSamples;
|
||||
#endif
|
||||
|
||||
// Spectral
|
||||
if (compoChromaticType == 1) {
|
||||
float reci_num_iter_f = 1.0 / float(num_iter);
|
||||
|
||||
vec2 resolution = vec2(1,1);
|
||||
vec2 uv = (texCoord.xy/resolution.xy);
|
||||
vec4 sumcol = vec4(0.0);
|
||||
vec4 sumw = vec4(0.0);
|
||||
for (int i=0; i < num_iter; ++i)
|
||||
{
|
||||
float t = float(i) * reci_num_iter_f;
|
||||
vec4 w = spectrum_offset(t);
|
||||
sumw += w;
|
||||
sumcol += w * texture(tex, barrelDistortion(uv, 0.6 * max_distort * t));
|
||||
}
|
||||
|
||||
fragColor = sumcol / sumw;
|
||||
}
|
||||
|
||||
// Simple
|
||||
else {
|
||||
vec3 col = vec3(0.0);
|
||||
col.x = texture(tex, texCoord + ((vec2(0.0, 1.0) * max_distort) / vec2(1000.0))).x;
|
||||
col.y = texture(tex, texCoord + ((vec2(-0.85, -0.5) * max_distort) / vec2(1000.0))).y;
|
||||
col.z = texture(tex, texCoord + ((vec2(0.85, -0.5) * max_distort) / vec2(1000.0))).z;
|
||||
fragColor = vec4(col.x, col.y, col.z, fragColor.w);
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "chromatic_aberration_pass",
|
||||
"depth_write": false,
|
||||
"color_write_alpha": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "PPComp13",
|
||||
"link": "_PPComp13",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "chromatic_aberration_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#version 450
|
||||
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
gl_FragDepth = 1.0;
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "clear_color_depth_pass",
|
||||
"depth_write": true,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "clear_color_depth_pass.frag.glsl",
|
||||
"color_attachments": ["_HDR"]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
#version 450
|
||||
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
15
leenkx/Shaders/clear_color_pass/clear_color_pass.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "clear_color_pass",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "clear_color_pass.frag.glsl",
|
||||
"color_attachments": ["_HDR"]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
#version 450
|
||||
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
gl_FragDepth = 1.0;
|
||||
}
|
19
leenkx/Shaders/clear_depth_pass/clear_depth_pass.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "clear_depth_pass",
|
||||
"depth_write": true,
|
||||
"color_write_red": false,
|
||||
"color_write_green": false,
|
||||
"color_write_blue": false,
|
||||
"color_write_alpha": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "clear_depth_pass.frag.glsl",
|
||||
"color_attachments": ["_HDR"]
|
||||
}
|
||||
]
|
||||
}
|
617
leenkx/Shaders/compositor_pass/compositor_pass.frag.glsl
Normal file
@ -0,0 +1,617 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
#include "std/tonemap.glsl"
|
||||
#include "std/math.glsl"
|
||||
#ifdef _CDOF
|
||||
#include "std/dof.glsl"
|
||||
#endif
|
||||
#ifdef _CPostprocess
|
||||
#include "std/colorgrading.glsl"
|
||||
#endif
|
||||
|
||||
uniform sampler2D tex;
|
||||
#ifdef _CDepth
|
||||
uniform sampler2D gbufferD;
|
||||
#endif
|
||||
|
||||
#ifdef _CLensTex
|
||||
uniform sampler2D lensTexture;
|
||||
#endif
|
||||
|
||||
#ifdef _CLUT
|
||||
uniform sampler2D lutTexture;
|
||||
#endif
|
||||
|
||||
#ifdef _AutoExposure
|
||||
uniform sampler2D histogram;
|
||||
#endif
|
||||
|
||||
#ifdef _CPostprocess
|
||||
uniform vec3 globalWeight;
|
||||
uniform vec3 globalTint;
|
||||
uniform vec3 globalSaturation;
|
||||
uniform vec3 globalContrast;
|
||||
uniform vec3 globalGamma;
|
||||
uniform vec3 globalGain;
|
||||
uniform vec3 globalOffset;
|
||||
|
||||
uniform vec3 shadowSaturation;
|
||||
uniform vec3 shadowContrast;
|
||||
uniform vec3 shadowGamma;
|
||||
uniform vec3 shadowGain;
|
||||
uniform vec3 shadowOffset;
|
||||
|
||||
uniform vec3 midtoneSaturation;
|
||||
uniform vec3 midtoneContrast;
|
||||
uniform vec3 midtoneGamma;
|
||||
uniform vec3 midtoneGain;
|
||||
uniform vec3 midtoneOffset;
|
||||
|
||||
uniform vec3 highlightSaturation;
|
||||
uniform vec3 highlightContrast;
|
||||
uniform vec3 highlightGamma;
|
||||
uniform vec3 highlightGain;
|
||||
uniform vec3 highlightOffset;
|
||||
|
||||
uniform vec3 PPComp1;
|
||||
uniform vec3 PPComp2;
|
||||
uniform vec3 PPComp3;
|
||||
uniform vec3 PPComp4;
|
||||
uniform vec3 PPComp5;
|
||||
uniform vec3 PPComp6;
|
||||
uniform vec3 PPComp7;
|
||||
uniform vec3 PPComp8;
|
||||
uniform vec3 PPComp14;
|
||||
uniform vec4 PPComp15;
|
||||
#endif
|
||||
|
||||
// #ifdef _CPos
|
||||
// uniform vec3 eye;
|
||||
// uniform vec3 eyeLook;
|
||||
// #endif
|
||||
|
||||
#ifdef _CGlare
|
||||
uniform vec3 light;
|
||||
uniform mat4 VP;
|
||||
uniform vec3 eye;
|
||||
uniform vec3 eyeLook;
|
||||
uniform float aspectRatio;
|
||||
#endif
|
||||
|
||||
#ifdef _CTexStep
|
||||
uniform vec2 texStep;
|
||||
#endif
|
||||
|
||||
#ifdef _CDistort
|
||||
uniform float time;
|
||||
#else
|
||||
#ifdef _CGrain
|
||||
uniform float time;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _DynRes
|
||||
uniform float dynamicScale;
|
||||
#endif
|
||||
|
||||
#ifdef _CCameraProj
|
||||
uniform vec2 cameraProj;
|
||||
#endif
|
||||
|
||||
in vec2 texCoord;
|
||||
// #ifdef _CPos
|
||||
// in vec3 viewRay;
|
||||
// #endif
|
||||
out vec4 fragColor;
|
||||
|
||||
#ifdef _CFog
|
||||
// const vec3 compoFogColor = vec3(0.5, 0.6, 0.7);
|
||||
// const float compoFogAmountA = 1.0; // b = 0.01
|
||||
// const float compoFogAmountB = 1.0; // c = 0.1
|
||||
// vec3 applyFog(vec3 rgb, // original color of the pixel
|
||||
// float distance, // camera to point distance
|
||||
// vec3 rayOri, // camera position
|
||||
// vec3 rayDir) { // camera to point vector
|
||||
// float fogAmount = compoFogAmountB * exp(-rayOri.y * compoFogAmountA) * (1.0 - exp(-distance * rayDir.y * compoFogAmountA)) / rayDir.y;
|
||||
// return mix(rgb, compoFogColor, fogAmount);
|
||||
// }
|
||||
vec3 applyFog(vec3 rgb, float distance) {
|
||||
// float fogAmount = 1.0 - exp(-distance * compoFogAmountA);
|
||||
float fogAmount = 1.0 - exp(-distance * (compoFogAmountA / 100));
|
||||
return mix(rgb, compoFogColor, fogAmount);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _CPostprocess
|
||||
float ComputeEV100(const float aperture2, const float shutterTime, const float ISO) {
|
||||
return log2(aperture2 / shutterTime * 100.0 / ISO);
|
||||
}
|
||||
float ConvertEV100ToExposure(float EV100) {
|
||||
return 1/0.8 * exp2(-EV100);
|
||||
}
|
||||
float ComputeEV(float avgLuminance) {
|
||||
const float sqAperture = PPComp1[0].x * PPComp1.x;
|
||||
const float shutterTime = 1.0 / PPComp1.y;
|
||||
const float ISO = PPComp1.z;
|
||||
const float EC = PPComp2.x;
|
||||
|
||||
float EV100 = ComputeEV100(sqAperture, shutterTime, ISO);
|
||||
|
||||
return ConvertEV100ToExposure(EV100 - EC) * PI;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec4 LUTlookup(in vec4 textureColor, in sampler2D lookupTable) {
|
||||
|
||||
//Clamp to prevent weird results
|
||||
textureColor = clamp(textureColor, 0.0, 1.0);
|
||||
|
||||
mediump float blueColor = textureColor.b * 63.0;
|
||||
mediump vec2 quad1;
|
||||
|
||||
quad1.y = floor(floor(blueColor) / 8.0);
|
||||
quad1.x = floor(blueColor) - (quad1.y * 8.0);
|
||||
|
||||
mediump vec2 quad2;
|
||||
quad2.y = floor(ceil(blueColor) / 8.0);
|
||||
quad2.x = ceil(blueColor) - (quad2.y * 8.0);
|
||||
|
||||
highp vec2 texelPosition1;
|
||||
texelPosition1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);
|
||||
texelPosition1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);
|
||||
|
||||
highp vec2 texelPosition2;
|
||||
texelPosition2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);
|
||||
texelPosition2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);
|
||||
|
||||
lowp vec4 newColor1 = textureLod(lookupTable, texelPosition1, 0.0);
|
||||
lowp vec4 newColor2 = textureLod(lookupTable, texelPosition2, 0.0);
|
||||
|
||||
lowp vec4 colorGradedResult = mix(newColor1, newColor2, fract(blueColor));
|
||||
|
||||
return colorGradedResult;
|
||||
|
||||
}
|
||||
|
||||
#ifdef _CVignette
|
||||
float vignette() {
|
||||
#ifdef _CPostprocess
|
||||
float strengthVignette = PPComp14.z;
|
||||
#else
|
||||
float strengthVignette = compoVignetteStrength;
|
||||
#endif
|
||||
return (1.0 - strengthVignette) + strengthVignette * pow(16.0 * texCoord.x * texCoord.y * (1.0 - texCoord.x) * (1.0 - texCoord.y), 0.2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _CGlare
|
||||
// Based on lense flare implementation by musk
|
||||
// https://www.shadertoy.com/view/4sX3Rs
|
||||
vec3 lensflare(vec2 uv, vec2 pos) {
|
||||
vec2 uvd = uv * (length(uv));
|
||||
float f2 = max(1.0/(1.0+32.0*pow(length(uvd+0.8*pos),2.0)),0.0)*0.25;
|
||||
float f22 = max(1.0/(1.0+32.0*pow(length(uvd+0.85*pos),2.0)),0.0)*0.23;
|
||||
float f23 = max(1.0/(1.0+32.0*pow(length(uvd+0.9*pos),2.0)),0.0)*0.21;
|
||||
|
||||
vec2 uvx = mix(uv, uvd, -0.5);
|
||||
float f4 = max(0.01-pow(length(uvx+0.4*pos),2.4),0.0)*6.0;
|
||||
float f42 = max(0.01-pow(length(uvx+0.45*pos),2.4),0.0)*5.0;
|
||||
float f43 = max(0.01-pow(length(uvx+0.5*pos),2.4),0.0)*3.0;
|
||||
|
||||
uvx = mix(uv, uvd, -0.4);
|
||||
float f5 = max(0.01-pow(length(uvx+0.2*pos),5.5),0.0)*2.0;
|
||||
float f52 = max(0.01-pow(length(uvx+0.4*pos),5.5),0.0)*2.0;
|
||||
float f53 = max(0.01-pow(length(uvx+0.6*pos),5.5),0.0)*2.0;
|
||||
|
||||
uvx = mix(uv, uvd, -0.5);
|
||||
float f6 = max(0.01-pow(length(uvx-0.3*pos),1.6),0.0)*6.0;
|
||||
float f62 = max(0.01-pow(length(uvx-0.325*pos),1.6),0.0)*3.0;
|
||||
float f63 = max(0.01-pow(length(uvx-0.35*pos),1.6),0.0)*5.0;
|
||||
|
||||
vec3 c = vec3(0.0);
|
||||
c.r += f2 + f4 + f5 + f6;
|
||||
c.g += f22 + f42 + f52 + f62;
|
||||
c.b += f23 + f43 + f53 + f63;
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
vec2 texCo = texCoord;
|
||||
#ifdef _DynRes
|
||||
texCo *= dynamicScale;
|
||||
#endif
|
||||
|
||||
#ifdef _CLetterbox
|
||||
#ifdef _CPostprocess
|
||||
vec3 uColor = vec3(PPComp15.x, PPComp15.y, PPComp15.z);
|
||||
float uSize = PPComp15.w;
|
||||
#else
|
||||
vec3 uColor = compoLetterboxColor;
|
||||
float uSize = compoLetterboxSize;
|
||||
#endif
|
||||
if (texCo.y < uSize || texCo.y > (1.0 - uSize)) {
|
||||
fragColor.rgb = uColor;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _CFishEye
|
||||
#ifdef _CPostprocess
|
||||
const float fishEyeStrength = -(PPComp2.y);
|
||||
#else
|
||||
const float fishEyeStrength = -0.01;
|
||||
#endif
|
||||
const vec2 m = vec2(0.5, 0.5);
|
||||
vec2 d = texCo - m;
|
||||
float r = sqrt(dot(d, d));
|
||||
float power = (2.0 * PI / (2.0 * sqrt(dot(m, m)))) * fishEyeStrength;
|
||||
float bind;
|
||||
if (power > 0.0) { bind = sqrt(dot(m, m)); }
|
||||
else { bind = m.x; }
|
||||
if (power > 0.0) {
|
||||
texCo = m + normalize(d) * tan(r * power) * bind / tan(bind * power);
|
||||
}
|
||||
else {
|
||||
texCo = m + normalize(d) * atan(r * -power * 10.0) * bind / atan(-power * bind * 10.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _CDistort
|
||||
#ifdef _CPostprocess
|
||||
float strengthDistort = PPComp14.x;
|
||||
#else
|
||||
float strengthDistort = compoDistortStrength;
|
||||
#endif
|
||||
float uX = time * strengthDistort;
|
||||
texCo.y = texCo.y + (sin(texCo.x*4.0+uX*2.0)*0.01);
|
||||
texCo.x = texCo.x + (cos(texCo.y*4.0+uX*2.0)*0.01);
|
||||
#endif
|
||||
|
||||
#ifdef _CDepth
|
||||
float depth = textureLod(gbufferD, texCo, 0.0).r * 2.0 - 1.0;
|
||||
#endif
|
||||
|
||||
#ifdef _CFXAA
|
||||
const float FXAA_REDUCE_MIN = 1.0 / 128.0;
|
||||
const float FXAA_REDUCE_MUL = 1.0 / 8.0;
|
||||
const float FXAA_SPAN_MAX = 8.0;
|
||||
|
||||
vec2 tcrgbNW = (texCo + vec2(-1.0, -1.0) * texStep);
|
||||
vec2 tcrgbNE = (texCo + vec2(1.0, -1.0) * texStep);
|
||||
vec2 tcrgbSW = (texCo + vec2(-1.0, 1.0) * texStep);
|
||||
vec2 tcrgbSE = (texCo + vec2(1.0, 1.0) * texStep);
|
||||
vec2 tcrgbM = vec2(texCo);
|
||||
|
||||
vec3 rgbNW = textureLod(tex, tcrgbNW, 0.0).rgb;
|
||||
vec3 rgbNE = textureLod(tex, tcrgbNE, 0.0).rgb;
|
||||
vec3 rgbSW = textureLod(tex, tcrgbSW, 0.0).rgb;
|
||||
vec3 rgbSE = textureLod(tex, tcrgbSE, 0.0).rgb;
|
||||
vec3 rgbM = textureLod(tex, tcrgbM, 0.0).rgb;
|
||||
vec3 luma = vec3(0.299, 0.587, 0.114);
|
||||
float lumaNW = dot(rgbNW, luma);
|
||||
float lumaNE = dot(rgbNE, luma);
|
||||
float lumaSW = dot(rgbSW, luma);
|
||||
float lumaSE = dot(rgbSE, luma);
|
||||
float lumaM = dot(rgbM, luma);
|
||||
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
|
||||
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
|
||||
|
||||
vec2 dir;
|
||||
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
|
||||
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
|
||||
|
||||
float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *
|
||||
(0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
|
||||
|
||||
float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
|
||||
dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
|
||||
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
|
||||
dir * rcpDirMin)) * texStep;
|
||||
|
||||
vec3 rgbA = 0.5 * (
|
||||
textureLod(tex, texCo + dir * (1.0 / 3.0 - 0.5), 0.0).rgb +
|
||||
textureLod(tex, texCo + dir * (2.0 / 3.0 - 0.5), 0.0).rgb);
|
||||
vec3 rgbB = rgbA * 0.5 + 0.25 * (
|
||||
textureLod(tex, texCo + dir * -0.5, 0.0).rgb +
|
||||
textureLod(tex, texCo + dir * 0.5, 0.0).rgb);
|
||||
|
||||
float lumaB = dot(rgbB, luma);
|
||||
if ((lumaB < lumaMin) || (lumaB > lumaMax)) fragColor = vec4(rgbA, 1.0);
|
||||
else fragColor = vec4(rgbB, 1.0);
|
||||
|
||||
#else
|
||||
|
||||
#ifdef _CDOF
|
||||
#ifdef _CPostprocess
|
||||
|
||||
bool compoAutoFocus = false;
|
||||
float compoDistance = PPComp3.x;
|
||||
float compoLength = PPComp3.y;
|
||||
float compoStop = PPComp3.z;
|
||||
|
||||
if (PPComp2.z == 1){
|
||||
compoAutoFocus = true;
|
||||
} else {
|
||||
compoAutoFocus = false;
|
||||
}
|
||||
|
||||
fragColor.rgb = dof(texCo, depth, tex, gbufferD, texStep, cameraProj, compoAutoFocus, compoDistance, compoLength, compoStop);
|
||||
#else
|
||||
fragColor.rgb = dof(texCo, depth, tex, gbufferD, texStep, cameraProj, true, compoDOFDistance, compoDOFLength, compoDOFFstop);
|
||||
#endif
|
||||
#else
|
||||
fragColor = textureLod(tex, texCo, 0.0);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _CSharpen
|
||||
#ifdef _CPostprocess
|
||||
float strengthSharpen = PPComp14.y;
|
||||
#else
|
||||
float strengthSharpen = compoSharpenStrength;
|
||||
#endif
|
||||
vec3 col1 = textureLod(tex, texCo + vec2(-texStep.x, -texStep.y) * 1.5, 0.0).rgb;
|
||||
vec3 col2 = textureLod(tex, texCo + vec2(texStep.x, -texStep.y) * 1.5, 0.0).rgb;
|
||||
vec3 col3 = textureLod(tex, texCo + vec2(-texStep.x, texStep.y) * 1.5, 0.0).rgb;
|
||||
vec3 col4 = textureLod(tex, texCo + vec2(texStep.x, texStep.y) * 1.5, 0.0).rgb;
|
||||
vec3 colavg = (col1 + col2 + col3 + col4) * 0.25;
|
||||
fragColor.rgb += (fragColor.rgb - colavg) * strengthSharpen;
|
||||
#endif
|
||||
|
||||
#ifdef _CFog
|
||||
// if (depth < 1.0) {
|
||||
// vec3 pos = getPos(depth, cameraProj);
|
||||
// float dist = distance(pos, eye);
|
||||
float dist = linearize(depth, cameraProj);
|
||||
// vec3 eyedir = eyeLook;// normalize(eye + pos);
|
||||
// fragColor.rgb = applyFog(fragColor.rgb, dist, eye, eyedir);
|
||||
fragColor.rgb = applyFog(fragColor.rgb, dist);
|
||||
// }
|
||||
#endif
|
||||
|
||||
#ifdef _CGlare
|
||||
if (dot(light, eyeLook) > 0.0) { // Facing light
|
||||
vec4 lndc = VP * vec4(light, 1.0);
|
||||
lndc.xy /= lndc.w;
|
||||
vec2 lss = lndc.xy * 0.5 + 0.5;
|
||||
float lssdepth = linearize(textureLod(gbufferD, lss, 0.0).r * 2.0 - 1.0, cameraProj);
|
||||
float lightDistance = distance(eye, light);
|
||||
if (lightDistance <= lssdepth) {
|
||||
vec2 lensuv = texCo * 2.0 - 1.0;
|
||||
lensuv.x *= aspectRatio;
|
||||
vec3 lensflarecol = vec3(1.4, 1.2, 1.0) * lensflare(lensuv, lndc.xy);
|
||||
fragColor.rgb += lensflarecol;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _CGrain
|
||||
float x = (texCo.x + 4.0) * (texCo.y + 4.0) * (time * 10.0);
|
||||
#ifdef _CPostprocess
|
||||
fragColor.rgb += vec3(mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01) - 0.005) * PPComp4.y;
|
||||
#else
|
||||
fragColor.rgb += vec3(mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01) - 0.005) * compoGrainStrength;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _CGrainStatic
|
||||
float x = (texCo.x + 4.0) * (texCo.y + 4.0) * 10.0;
|
||||
fragColor.rgb += vec3(mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01) - 0.005) * 0.09;
|
||||
#endif
|
||||
|
||||
#ifdef _CVignette
|
||||
fragColor.rgb *= vignette();
|
||||
#endif
|
||||
|
||||
#ifdef _CExposure
|
||||
fragColor.rgb += fragColor.rgb * compoExposureStrength;
|
||||
#endif
|
||||
|
||||
#ifdef _CPostprocess
|
||||
fragColor.rgb *= ComputeEV(0.0);
|
||||
#endif
|
||||
|
||||
#ifdef _AutoExposure
|
||||
float expo = 2.0 - clamp(length(textureLod(histogram, vec2(0.5, 0.5), 0).rgb), 0.0, 1.0);
|
||||
fragColor.rgb *= pow(expo, autoExposureStrength * 2.0);
|
||||
#endif
|
||||
|
||||
// Clamp color to get rid of INF values that don't work for the tone mapping below
|
||||
// The max value is kind of arbitrary (16 bit float max * 0.5), but it should be large enough
|
||||
fragColor.rgb = min(fragColor.rgb, 65504 * 0.5);
|
||||
|
||||
#ifdef _CPostprocess
|
||||
|
||||
#ifdef _CToneCustom
|
||||
fragColor.rgb = clamp((fragColor.rgb * (PPComp4.z * fragColor.rgb + PPComp5.x)) / (fragColor.rgb * (PPComp5.y * fragColor.rgb + PPComp5.z) + PPComp6.x), 0.0, 1.0);
|
||||
#else
|
||||
if(PPComp4.x == 0){ //Filmic 1
|
||||
fragColor.rgb = tonemapFilmic(fragColor.rgb); // With gamma
|
||||
} else if (PPComp4.x == 1){ //Filmic 2
|
||||
fragColor.rgb = acesFilm(fragColor.rgb);
|
||||
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));
|
||||
} else if (PPComp4.x == 2){ //Reinhard
|
||||
fragColor.rgb = tonemapReinhard(fragColor.rgb);
|
||||
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));
|
||||
} else if (PPComp4.x == 3){ //Uncharted2
|
||||
fragColor.rgb = tonemapUncharted2(fragColor.rgb);
|
||||
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
|
||||
fragColor.rgb = clamp(fragColor.rgb, 0.0, 1.0);
|
||||
} else if (PPComp4.x == 4){ //None
|
||||
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
|
||||
} else if (PPComp4.x == 5){ //Non-Gamma / Linear
|
||||
fragColor.rgb = fragColor.rgb;
|
||||
} else if (PPComp4.x == 6){ //HDP
|
||||
vec3 x = fragColor.rgb - 0.004;
|
||||
//vec3 x = max(0, fragColor.rgb - 0.004);
|
||||
fragColor.rgb = (x*(6.2*x+.5))/(x*(6.2*x+1.7)+0.06);
|
||||
} else if (PPComp4.x == 7){ //Raw
|
||||
vec4 vh = vec4(fragColor.rgb, 1);
|
||||
vec4 va = (1.425 * vh) + 0.05;
|
||||
vec4 vf = ((vh * va + 0.004) / ((vh * (va + 0.55) + 0.0491))) - 0.0821;
|
||||
fragColor.rgb = vf.rgb / vf.www;
|
||||
} else if (PPComp4.x == 8){ //False Colors for luminance control
|
||||
|
||||
vec4 c = vec4(fragColor.r,fragColor.g,fragColor.b,0); //Linear without gamma
|
||||
|
||||
vec3 luminanceVector = vec3(0.2125, 0.7154, 0.0721); //Relative Luminance Vector
|
||||
float luminance = dot(luminanceVector, c.xyz);
|
||||
|
||||
vec3 maxLumColor = vec3(1,0,0); //High values (> 1.0)
|
||||
//float maxLum = 2.0; Needs to read the highest pixel, but I don't know how to yet
|
||||
//Probably easier with a histogram too, once it's it in place?
|
||||
|
||||
vec3 midLumColor = vec3(0,1,0); //Mid values (< 1.0)
|
||||
float midLum = 1.0;
|
||||
|
||||
vec3 minLumColor = vec3(0,0,1); //Low values (< 1.0)
|
||||
float minLum = 0.0;
|
||||
|
||||
if(luminance < midLum){
|
||||
fragColor.rgb = mix(minLumColor, midLumColor, luminance);
|
||||
} else {
|
||||
fragColor.rgb = mix(midLumColor, maxLumColor, luminance);
|
||||
}
|
||||
|
||||
} else {
|
||||
fragColor.rgb = vec3(0,1,0); //ERROR
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
#ifdef _CToneFilmic
|
||||
fragColor.rgb = tonemapFilmic(fragColor.rgb); // With gamma
|
||||
#endif
|
||||
#ifdef _CToneFilmic2
|
||||
fragColor.rgb = acesFilm(fragColor.rgb);
|
||||
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));
|
||||
#endif
|
||||
#ifdef _CToneReinhard
|
||||
fragColor.rgb = tonemapReinhard(fragColor.rgb);
|
||||
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));
|
||||
#endif
|
||||
#ifdef _CToneUncharted
|
||||
fragColor.rgb = tonemapUncharted2(fragColor.rgb);
|
||||
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
|
||||
fragColor.rgb = clamp(fragColor.rgb, 0.0, 2.2);
|
||||
#endif
|
||||
#ifdef _CToneNone
|
||||
fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
|
||||
#endif
|
||||
#ifdef _CToneCustom
|
||||
fragColor.rgb = clamp((fragColor.rgb * (1 * fragColor.rgb + 1)) / (fragColor.rgb * (1 * fragColor.rgb + 1 ) + 1), 0.0, 1.0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _CBW
|
||||
// fragColor.rgb = vec3(clamp(dot(fragColor.rgb, fragColor.rgb), 0.0, 1.0));
|
||||
fragColor.rgb = vec3((fragColor.r * 0.3 + fragColor.g * 0.59 + fragColor.b * 0.11) / 3.0) * 2.5;
|
||||
#endif
|
||||
|
||||
// #ifdef _CContrast
|
||||
// -0.5 - 0.5
|
||||
// const float compoContrast = 0.2;
|
||||
// fragColor.rgb = ((fragColor.rgb - 0.5) * max(compoContrast + 1.0, 0.0)) + 0.5;
|
||||
// #endif
|
||||
|
||||
// #ifdef _CBrighness
|
||||
// fragColor.rgb += compoBrightness;
|
||||
// #endif
|
||||
|
||||
#ifdef _CPostprocess
|
||||
//Global Values
|
||||
|
||||
float factor = 1;
|
||||
float colorTempK = globalWeight.x;
|
||||
vec3 ColorTempRGB = ColorTemperatureToRGB(colorTempK);
|
||||
|
||||
float originalLuminance = Luminance(fragColor.rgb);
|
||||
vec3 blended = mix(fragColor.rgb, fragColor.rgb * ColorTempRGB, factor);
|
||||
vec3 resultHSL = RGBtoHSL(blended);
|
||||
vec3 luminancePreservedRGB = HSLtoRGB(vec3(resultHSL.x, resultHSL.y, originalLuminance));
|
||||
fragColor = vec4(mix(blended, luminancePreservedRGB, LUMINANCE_PRESERVATION), 1.0);
|
||||
|
||||
mat3 CCSaturation = mat3 ( //Saturation
|
||||
globalSaturation.r * shadowSaturation.r, globalSaturation.g * shadowSaturation.g, globalSaturation.b * shadowSaturation.b, //Shadows + Global
|
||||
globalSaturation.r * midtoneSaturation.r, globalSaturation.g * midtoneSaturation.g, globalSaturation.b * midtoneSaturation.b, //Midtones + Global
|
||||
globalSaturation.r * highlightSaturation.r, globalSaturation.g * highlightSaturation.g, globalSaturation.b * highlightSaturation.b //Highlights + Global
|
||||
);
|
||||
|
||||
mat3 CCContrast = mat3 (
|
||||
globalContrast.r * shadowContrast.r, globalContrast.g * shadowContrast.g, globalContrast.b * shadowContrast.b, //Shadows + Global
|
||||
globalContrast.r * midtoneContrast.r, globalContrast.g * midtoneContrast.g, globalContrast.b * midtoneContrast.b, //Midtones + Global
|
||||
globalContrast.r * highlightContrast.r, globalContrast.g * highlightContrast.g, globalContrast.b * highlightContrast.b //Highlights + Global
|
||||
);
|
||||
|
||||
mat3 CCGamma = mat3 (
|
||||
globalGamma.r * shadowGamma.r, globalGamma.g * shadowGamma.g, globalGamma.b * shadowGamma.b, //Shadows + Global
|
||||
globalGamma.r * midtoneGamma.r, globalGamma.g * midtoneGamma.g, globalGamma.b * midtoneGamma.b, //Midtones + Global
|
||||
globalGamma.r * highlightGamma.r, globalGamma.g * highlightGamma.g, globalGamma.b * highlightGamma.b //Highlights + Global
|
||||
);
|
||||
|
||||
mat3 CCGain = mat3 (
|
||||
globalGain.r * shadowGain.r, globalGain.g * shadowGain.g, globalGain.b * shadowGain.b, //Shadows + Global
|
||||
globalGain.r * midtoneGain.r, globalGain.g * midtoneGain.g, globalGain.b * midtoneGain.b, //Midtones + Global
|
||||
globalGain.r * highlightGain.r, globalGain.g * highlightGain.g, globalGain.b * highlightGain.b //Highlights + Global
|
||||
);
|
||||
|
||||
mat3 CCOffset = mat3 (
|
||||
globalOffset.r * shadowOffset.r, globalOffset.g * shadowOffset.g, globalOffset.b * shadowOffset.b, //Shadows + Global
|
||||
globalOffset.r * midtoneOffset.r, globalOffset.g * midtoneOffset.g, globalOffset.b * midtoneOffset.b, //Midtones + Global
|
||||
globalOffset.r * highlightOffset.r, globalOffset.g * highlightOffset.g, globalOffset.b * highlightOffset.b //Highlights + Global
|
||||
);
|
||||
|
||||
vec2 ToneWeights = vec2(globalWeight.y, globalWeight.z);
|
||||
|
||||
fragColor.rgb = FinalizeColorCorrection(
|
||||
fragColor.rgb,
|
||||
CCSaturation,
|
||||
CCContrast,
|
||||
CCGamma,
|
||||
CCGain,
|
||||
CCOffset,
|
||||
ToneWeights
|
||||
);
|
||||
|
||||
//Tint
|
||||
fragColor.rgb *= vec3(globalTint.r,globalTint.g,globalTint.b);
|
||||
#endif
|
||||
|
||||
#ifdef _CLensTex
|
||||
#ifdef _CLensTexMasking
|
||||
vec4 scratches = texture(lensTexture, texCo);
|
||||
vec3 scratchBlend = fragColor.rgb + scratches.rgb;
|
||||
|
||||
#ifdef _CPostprocess
|
||||
float centerMaxClip = PPComp6.y;
|
||||
float centerMinClip = PPComp6.z;
|
||||
float luminanceMax = PPComp7.x;
|
||||
float luminanceMin = PPComp7.y;
|
||||
float brightnessExp = PPComp7.z;
|
||||
#else
|
||||
float centerMaxClip = compoCenterMaxClip;
|
||||
float centerMinClip = compoCenterMinClip;
|
||||
float luminanceMax = compoLuminanceMax;
|
||||
float luminanceMin = compoLuminanceMin;
|
||||
float brightnessExp = compoBrightnessExponent;
|
||||
#endif
|
||||
|
||||
float center = smoothstep(centerMaxClip, centerMinClip, length(texCo - 0.5));
|
||||
float luminance = dot(fragColor.rgb, vec3(0.299, 0.587, 0.114));
|
||||
float brightnessMap = smoothstep(luminanceMax, luminanceMin, luminance * center);
|
||||
fragColor.rgb = clamp(mix(fragColor.rgb, scratchBlend, brightnessMap * brightnessExp), 0, 1);
|
||||
#else
|
||||
fragColor.rgb += textureLod(lensTexture, texCo, 0.0).rgb;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//3D LUT Implementation from GPUGems 2 by Nvidia
|
||||
//https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter24.html
|
||||
|
||||
#ifdef _CLUT
|
||||
fragColor = LUTlookup(fragColor, lutTexture);
|
||||
#endif
|
||||
}
|
245
leenkx/Shaders/compositor_pass/compositor_pass.json
Normal file
@ -0,0 +1,245 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "compositor_pass",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "eye",
|
||||
"link": "_cameraPosition",
|
||||
"ifdef": ["_CGlare"]
|
||||
},
|
||||
{
|
||||
"name": "eye",
|
||||
"link": "_cameraPosition",
|
||||
"ifdef": ["_Disabled_CPos"]
|
||||
},
|
||||
{
|
||||
"name": "eyeLook",
|
||||
"link": "_cameraLook",
|
||||
"ifdef": ["_CGlare"]
|
||||
},
|
||||
{
|
||||
"name": "eyeLook",
|
||||
"link": "_cameraLook",
|
||||
"ifdef": ["_Disabled_CPos"]
|
||||
},
|
||||
{
|
||||
"name": "invVP",
|
||||
"link": "_inverseViewProjectionMatrix",
|
||||
"ifdef": ["_Disabled_CPos"]
|
||||
},
|
||||
{
|
||||
"name": "light",
|
||||
"link": "_lightPosition",
|
||||
"ifdef": ["_CGlare"]
|
||||
},
|
||||
{
|
||||
"name": "VP",
|
||||
"link": "_viewProjectionMatrix",
|
||||
"ifdef": ["_CGlare"]
|
||||
},
|
||||
{
|
||||
"name": "time",
|
||||
"link": "_time",
|
||||
"ifdef": ["_CDistort", "_CGrain"]
|
||||
},
|
||||
{
|
||||
"name": "texStep",
|
||||
"link": "_screenSizeInv",
|
||||
"ifdef": ["_CTexStep"]
|
||||
},
|
||||
{
|
||||
"name": "dynamicScale",
|
||||
"link": "_dynamicScale",
|
||||
"ifdef": ["_DynRes"]
|
||||
},
|
||||
{
|
||||
"name": "aspectRatio",
|
||||
"link": "_aspectRatioF",
|
||||
"ifdef": ["_CGlare"]
|
||||
},
|
||||
{
|
||||
"name": "lensTexture",
|
||||
"link": "$lenstexture.jpg",
|
||||
"ifdef": ["_CLensTex"]
|
||||
},
|
||||
{
|
||||
"name": "cameraProj",
|
||||
"link": "_cameraPlaneProj",
|
||||
"ifdef": ["_CCameraProj"]
|
||||
},
|
||||
{
|
||||
"name": "lutTexture",
|
||||
"link": "$luttexture.jpg",
|
||||
"ifdef": ["_CLUT"]
|
||||
},
|
||||
{
|
||||
"name": "globalWeight",
|
||||
"link": "_globalWeight",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "globalTint",
|
||||
"link": "_globalTint",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "globalSaturation",
|
||||
"link": "_globalSaturation",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "globalContrast",
|
||||
"link": "_globalContrast",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "globalGamma",
|
||||
"link": "_globalGamma",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "globalGain",
|
||||
"link": "_globalGain",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "globalOffset",
|
||||
"link": "_globalOffset",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "shadowSaturation",
|
||||
"link": "_shadowSaturation",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "shadowContrast",
|
||||
"link": "_shadowContrast",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "shadowGamma",
|
||||
"link": "_shadowGamma",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "shadowGain",
|
||||
"link": "_shadowGain",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "shadowOffset",
|
||||
"link": "_shadowOffset",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "midtoneSaturation",
|
||||
"link": "_midtoneSaturation",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "midtoneContrast",
|
||||
"link": "_midtoneContrast",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "midtoneGamma",
|
||||
"link": "_midtoneGamma",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "midtoneGain",
|
||||
"link": "_midtoneGain",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "midtoneOffset",
|
||||
"link": "_midtoneOffset",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "highlightSaturation",
|
||||
"link": "_highlightSaturation",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "highlightContrast",
|
||||
"link": "_highlightContrast",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "highlightGamma",
|
||||
"link": "_highlightGamma",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "highlightGain",
|
||||
"link": "_highlightGain",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "highlightOffset",
|
||||
"link": "_highlightOffset",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "PPComp1",
|
||||
"link": "_PPComp1",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "PPComp2",
|
||||
"link": "_PPComp2",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "PPComp3",
|
||||
"link": "_PPComp3",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "PPComp4",
|
||||
"link": "_PPComp4",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "PPComp5",
|
||||
"link": "_PPComp5",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "PPComp6",
|
||||
"link": "_PPComp6",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "PPComp7",
|
||||
"link": "_PPComp7",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "PPComp8",
|
||||
"link": "_PPComp8",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "PPComp14",
|
||||
"link": "_PPComp14",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
},
|
||||
{
|
||||
"name": "PPComp15",
|
||||
"link": "_PPComp15",
|
||||
"ifdef": ["_CPostprocess"]
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "compositor_pass.vert.glsl",
|
||||
"fragment_shader": "compositor_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
34
leenkx/Shaders/compositor_pass/compositor_pass.vert.glsl
Normal file
@ -0,0 +1,34 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
|
||||
// #ifdef _CPos
|
||||
// uniform mat4 invVP;
|
||||
// uniform vec3 eye;
|
||||
// #endif
|
||||
|
||||
in vec2 pos;
|
||||
|
||||
out vec2 texCoord;
|
||||
// #ifdef _CPos
|
||||
// out vec3 viewRay;
|
||||
// #endif
|
||||
|
||||
void main() {
|
||||
// Scale vertex attribute to [0-1] range
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
texCoord = pos.xy * madd + madd;
|
||||
#ifdef _InvY
|
||||
texCoord.y = 1.0 - texCoord.y;
|
||||
#endif
|
||||
|
||||
gl_Position = vec4(pos.xy, 0.0, 1.0);
|
||||
|
||||
// #ifdef _CPos
|
||||
// NDC (at the back of cube)
|
||||
// vec4 v = vec4(pos.xy, 1.0, 1.0);
|
||||
// v = vec4(invVP * v);
|
||||
// v.xyz /= v.w;
|
||||
// viewRay = v.xyz - eye;
|
||||
// #endif
|
||||
}
|
12
leenkx/Shaders/copy_mrt2_pass/copy_mrt2_pass.frag.glsl
Normal file
@ -0,0 +1,12 @@
|
||||
#version 450
|
||||
|
||||
uniform sampler2D tex0;
|
||||
uniform sampler2D tex1;
|
||||
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor[2];
|
||||
|
||||
void main() {
|
||||
fragColor[0] = textureLod(tex0, texCoord, 0.0);
|
||||
fragColor[1] = textureLod(tex1, texCoord, 0.0);
|
||||
}
|
14
leenkx/Shaders/copy_mrt2_pass/copy_mrt2_pass.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "copy_mrt2_pass",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "copy_mrt2_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
14
leenkx/Shaders/copy_mrt3_pass/copy_mrt3_pass.frag.glsl
Normal file
@ -0,0 +1,14 @@
|
||||
#version 450
|
||||
|
||||
uniform sampler2D tex0;
|
||||
uniform sampler2D tex1;
|
||||
uniform sampler2D tex2;
|
||||
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor[3];
|
||||
|
||||
void main() {
|
||||
fragColor[0] = textureLod(tex0, texCoord, 0.0);
|
||||
fragColor[1] = textureLod(tex1, texCoord, 0.0);
|
||||
fragColor[2] = textureLod(tex2, texCoord, 0.0);
|
||||
}
|
14
leenkx/Shaders/copy_mrt3_pass/copy_mrt3_pass.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "copy_mrt3_pass",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "copy_mrt3_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
14
leenkx/Shaders/copy_pass/copy_pass.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "copy_pass",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "../include/pass_copy.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
#version 450
|
||||
|
||||
#include "../compiled.inc"
|
||||
|
||||
// Include functions for gbuffer operations (packFloat2() etc.)
|
||||
#include "../std/gbuffer.glsl"
|
||||
|
||||
// World-space normal from the vertex shader stage
|
||||
in vec3 wnormal;
|
||||
|
||||
/*
|
||||
The G-Buffer output. Deferred rendering uses the following render target layout:
|
||||
|
||||
| Index | Needs #define || R | G | B | A |
|
||||
+===================+=================++==============+==============+=================+====================+
|
||||
| GBUF_IDX_0 | || normal (XY) | roughness | metallic/matID |
|
||||
+-------------------+-----------------++--------------+--------------+-----------------+--------------------+
|
||||
| GBUF_IDX_1 | || base color (RGB) | occlusion/specular |
|
||||
+-------------------+-----------------++--------------+--------------+-----------------+--------------------+
|
||||
| GBUF_IDX_2 | _gbuffer2 || velocity (XY) | ignore radiance | unused |
|
||||
+-------------------+-----------------++--------------+--------------+-----------------+--------------------+
|
||||
| GBUF_IDX_EMISSION | _EmissionShaded || emission color (RGB) | unused |
|
||||
+-------------------+-----------------++--------------+--------------+-----------------+--------------------+
|
||||
|
||||
The indices as well as the GBUF_SIZE define are defined in "compiled.inc".
|
||||
*/
|
||||
out vec4 fragColor[GBUF_SIZE];
|
||||
|
||||
void main() {
|
||||
// Pack normals into 2 components to fit into the gbuffer
|
||||
vec3 n = normalize(wnormal);
|
||||
n /= (abs(n.x) + abs(n.y) + abs(n.z));
|
||||
n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);
|
||||
|
||||
// Define PBR material values
|
||||
vec3 basecol = vec3(1.0);
|
||||
float roughness = 0.0;
|
||||
float metallic = 0.0;
|
||||
float occlusion = 1.0;
|
||||
float specular = 1.0;
|
||||
uint materialId = 0;
|
||||
vec3 emissionCol = vec3(0.0);
|
||||
float ior = 1.450;
|
||||
float opacity = 1.0;
|
||||
|
||||
// Store in gbuffer (see layout table above)
|
||||
fragColor[GBUF_IDX_0] = vec4(n.xy, roughness, packFloatInt16(metallic, materialId));
|
||||
fragColor[GBUF_IDX_1] = vec4(basecol.rgb, packFloat2(occlusion, specular));
|
||||
|
||||
#ifdef _EmissionShaded
|
||||
fragColor[GBUF_IDX_EMISSION] = vec4(emissionCol, 0.0);
|
||||
#endif
|
||||
|
||||
#ifdef _SSRefraction
|
||||
fragColor[GBUF_IDX_REFRACTION] = vec4(ior, opacity, 0.0, 0.0);
|
||||
#endif
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
#version 450
|
||||
|
||||
// World to view projection matrix to correctly position the vertex on screen
|
||||
uniform mat4 WVP;
|
||||
// Matrix to transform normals from local into world space
|
||||
uniform mat3 N;
|
||||
|
||||
// Position and normal vectors of the current vertex in local space
|
||||
// Leenkx packs the vertex data to preserve memory, so nor.z values are
|
||||
// saved in pos.w
|
||||
in vec4 pos; // pos.xyz, nor.w
|
||||
in vec2 nor; // nor.xy
|
||||
|
||||
// Normal vector in world space
|
||||
out vec3 wnormal;
|
||||
|
||||
void main() {
|
||||
wnormal = normalize(N * vec3(nor.xy, pos.w));
|
||||
gl_Position = WVP * vec4(pos.xyz, 1.0);
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#version 450
|
||||
|
||||
// Color of each fragment on the screen
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
// Shadeless white color
|
||||
fragColor = vec4(1.0);
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
#version 450
|
||||
|
||||
// World to view projection matrix to correctly position the vertex on screen
|
||||
uniform mat4 WVP;
|
||||
|
||||
// Position vector of the current vertex in local space
|
||||
in vec3 pos;
|
||||
|
||||
void main() {
|
||||
gl_Position = WVP * vec4(pos, 1.0);
|
||||
}
|
8
leenkx/Shaders/debug_draw/line.frag.glsl
Normal file
@ -0,0 +1,8 @@
|
||||
#version 450
|
||||
|
||||
in vec3 color;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor = vec4(color, 1.0);
|
||||
}
|
12
leenkx/Shaders/debug_draw/line.vert.glsl
Normal file
@ -0,0 +1,12 @@
|
||||
#version 450
|
||||
|
||||
in vec3 pos;
|
||||
in vec3 col;
|
||||
|
||||
uniform mat4 ViewProjection;
|
||||
out vec3 color;
|
||||
|
||||
void main() {
|
||||
color = col;
|
||||
gl_Position = ViewProjection * vec4(pos, 1.0);
|
||||
}
|
15
leenkx/Shaders/debug_draw/line_deferred.frag.glsl
Normal file
@ -0,0 +1,15 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
|
||||
in vec3 color;
|
||||
out vec4 fragColor[GBUF_SIZE];
|
||||
|
||||
void main() {
|
||||
fragColor[GBUF_IDX_0] = vec4(1.0, 1.0, 0.0, 1.0);
|
||||
fragColor[GBUF_IDX_1] = vec4(color, 1.0);
|
||||
|
||||
#ifdef _EmissionShaded
|
||||
fragColor[GBUF_IDX_EMISSION] = vec4(0.0);
|
||||
#endif
|
||||
}
|
527
leenkx/Shaders/deferred_light/deferred_light.frag.glsl
Normal file
@ -0,0 +1,527 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
#include "std/gbuffer.glsl"
|
||||
#ifdef _Clusters
|
||||
#include "std/clusters.glsl"
|
||||
#endif
|
||||
#ifdef _Irr
|
||||
#include "std/shirr.glsl"
|
||||
#endif
|
||||
#ifdef _SSS
|
||||
#include "std/sss.glsl"
|
||||
#endif
|
||||
#ifdef _SSRS
|
||||
#include "std/ssrs.glsl"
|
||||
#endif
|
||||
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform sampler2D gbuffer1;
|
||||
|
||||
#ifdef _gbuffer2
|
||||
uniform sampler2D gbuffer2;
|
||||
#endif
|
||||
#ifdef _EmissionShaded
|
||||
uniform sampler2D gbufferEmission;
|
||||
#endif
|
||||
|
||||
#ifdef _VoxelGI
|
||||
uniform sampler2D voxels_diffuse;
|
||||
uniform sampler2D voxels_specular;
|
||||
#endif
|
||||
#ifdef _VoxelAOvar
|
||||
uniform sampler2D voxels_ao;
|
||||
#endif
|
||||
#ifdef _VoxelShadow
|
||||
uniform sampler3D voxels;
|
||||
uniform sampler3D voxelsSDF;
|
||||
uniform float clipmaps[10 * voxelgiClipmapCount];
|
||||
#endif
|
||||
|
||||
uniform float envmapStrength;
|
||||
#ifdef _Irr
|
||||
uniform vec4 shirr[7];
|
||||
#endif
|
||||
#ifdef _Brdf
|
||||
uniform sampler2D senvmapBrdf;
|
||||
#endif
|
||||
#ifdef _Rad
|
||||
uniform sampler2D senvmapRadiance;
|
||||
uniform int envmapNumMipmaps;
|
||||
#endif
|
||||
#ifdef _EnvCol
|
||||
uniform vec3 backgroundCol;
|
||||
#endif
|
||||
|
||||
#ifdef _SSAO
|
||||
uniform sampler2D ssaotex;
|
||||
#endif
|
||||
|
||||
#ifdef _SSS
|
||||
uniform vec2 lightPlane;
|
||||
#endif
|
||||
|
||||
#ifdef _SSRS
|
||||
//!uniform mat4 VP;
|
||||
uniform mat4 invVP;
|
||||
#endif
|
||||
|
||||
#ifdef _LightIES
|
||||
//!uniform sampler2D texIES;
|
||||
#endif
|
||||
|
||||
#ifdef _SMSizeUniform
|
||||
//!uniform vec2 smSizeUniform;
|
||||
#endif
|
||||
|
||||
#ifdef _LTC
|
||||
//!uniform vec3 lightArea0;
|
||||
//!uniform vec3 lightArea1;
|
||||
//!uniform vec3 lightArea2;
|
||||
//!uniform vec3 lightArea3;
|
||||
//!uniform sampler2D sltcMat;
|
||||
//!uniform sampler2D sltcMag;
|
||||
#ifdef _ShadowMap
|
||||
#ifdef _SinglePoint
|
||||
//!uniform sampler2DShadow shadowMapSpot[1];
|
||||
//!uniform sampler2D shadowMapSpotTransparent[1];
|
||||
//!uniform mat4 LWVPSpot[1];
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
//!uniform sampler2DShadow shadowMapSpot[4];
|
||||
//!uniform sampler2D shadowMapSpotTransparent[4];
|
||||
//!uniform mat4 LWVPSpotArray[4];
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
uniform vec2 cameraProj;
|
||||
uniform vec3 eye;
|
||||
uniform vec3 eyeLook;
|
||||
|
||||
#ifdef _Clusters
|
||||
uniform vec4 lightsArray[maxLights * 3];
|
||||
#ifdef _Spot
|
||||
uniform vec4 lightsArraySpot[maxLights * 2];
|
||||
#endif
|
||||
uniform sampler2D clustersData;
|
||||
uniform vec2 cameraPlane;
|
||||
#endif
|
||||
|
||||
#ifdef _ShadowMap
|
||||
#ifdef _SinglePoint
|
||||
#ifdef _Spot
|
||||
//!uniform sampler2DShadow shadowMapSpot[1];
|
||||
//!uniform sampler2D shadowMapSpotTransparent[1];
|
||||
//!uniform mat4 LWVPSpot[1];
|
||||
#else
|
||||
//!uniform samplerCubeShadow shadowMapPoint[1];
|
||||
//!uniform samplerCube shadowMapPointTransparent[1];
|
||||
//!uniform vec2 lightProj;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifdef _SingleAtlas
|
||||
uniform sampler2DShadow shadowMapAtlas;
|
||||
uniform sampler2D shadowMapAtlasTransparent;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
//!uniform sampler2DShadow shadowMapAtlasPoint;
|
||||
//!uniform sampler2D shadowMapAtlasPointTransparent;
|
||||
#endif
|
||||
//!uniform vec4 pointLightDataArray[4];
|
||||
#else
|
||||
//!uniform samplerCubeShadow shadowMapPoint[4];
|
||||
//!uniform samplerCube shadowMapPointTransparent[4];
|
||||
#endif
|
||||
//!uniform vec2 lightProj;
|
||||
#ifdef _Spot
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
//!uniform sampler2DShadow shadowMapAtlasSpot;
|
||||
//!uniform sampler2D shadowMapAtlasSpotTransparent;
|
||||
#endif
|
||||
#else
|
||||
//!uniform sampler2DShadow shadowMapSpot[4];
|
||||
//!uniform sampler2D shadowMapSpotTransparent[4];
|
||||
#endif
|
||||
//!uniform mat4 LWVPSpotArray[maxLightsCluster];
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _Sun
|
||||
uniform vec3 sunDir;
|
||||
uniform vec3 sunCol;
|
||||
#ifdef _ShadowMap
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
uniform sampler2DShadow shadowMapAtlasSun;
|
||||
uniform sampler2D shadowMapAtlasSunTransparent;
|
||||
#endif
|
||||
#else
|
||||
uniform sampler2DShadow shadowMap;
|
||||
uniform sampler2D shadowMapTransparent;
|
||||
#endif
|
||||
uniform float shadowsBias;
|
||||
#ifdef _CSM
|
||||
//!uniform vec4 casData[shadowmapCascades * 4 + 4];
|
||||
#else
|
||||
uniform mat4 LWVP;
|
||||
#endif
|
||||
#endif // _ShadowMap
|
||||
#endif
|
||||
|
||||
#ifdef _SinglePoint // Fast path for single light
|
||||
uniform vec3 pointPos;
|
||||
uniform vec3 pointCol;
|
||||
#ifdef _ShadowMap
|
||||
uniform float pointBias;
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
uniform vec3 spotDir;
|
||||
uniform vec3 spotRight;
|
||||
uniform vec4 spotData;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _LightClouds
|
||||
uniform sampler2D texClouds;
|
||||
uniform float time;
|
||||
#endif
|
||||
|
||||
#include "std/light.glsl"
|
||||
|
||||
in vec2 texCoord;
|
||||
in vec3 viewRay;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
vec4 g0 = textureLod(gbuffer0, texCoord, 0.0); // Normal.xy, roughness, metallic/matid
|
||||
|
||||
vec3 n;
|
||||
n.z = 1.0 - abs(g0.x) - abs(g0.y);
|
||||
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
|
||||
n = normalize(n);
|
||||
|
||||
float roughness = g0.b;
|
||||
float metallic;
|
||||
uint matid;
|
||||
unpackFloatInt16(g0.a, metallic, matid);
|
||||
|
||||
vec4 g1 = textureLod(gbuffer1, texCoord, 0.0); // Basecolor.rgb, spec/occ
|
||||
vec2 occspec = unpackFloat2(g1.a);
|
||||
vec3 albedo = surfaceAlbedo(g1.rgb, metallic); // g1.rgb - basecolor
|
||||
vec3 f0 = surfaceF0(g1.rgb, metallic);
|
||||
|
||||
float depth = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
|
||||
vec3 p = getPos(eye, eyeLook, normalize(viewRay), depth, cameraProj);
|
||||
vec3 v = normalize(eye - p);
|
||||
float dotNV = max(dot(n, v), 0.0);
|
||||
|
||||
#ifdef _gbuffer2
|
||||
vec4 g2 = textureLod(gbuffer2, texCoord, 0.0);
|
||||
#endif
|
||||
|
||||
#ifdef _MicroShadowing
|
||||
occspec.x = mix(1.0, occspec.x, dotNV); // AO Fresnel
|
||||
#endif
|
||||
|
||||
#ifdef _Brdf
|
||||
vec2 envBRDF = texelFetch(senvmapBrdf, ivec2(vec2(dotNV, 1.0 - roughness) * 256.0), 0).xy;
|
||||
#endif
|
||||
|
||||
// Envmap
|
||||
#ifdef _Irr
|
||||
|
||||
vec3 envl = shIrradiance(n, shirr);
|
||||
|
||||
#ifdef _gbuffer2
|
||||
if (g2.b < 0.5) {
|
||||
envl = envl;
|
||||
} else {
|
||||
envl = vec3(0.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _EnvTex
|
||||
envl /= PI;
|
||||
#endif
|
||||
#else
|
||||
vec3 envl = vec3(0.0);
|
||||
#endif
|
||||
|
||||
#ifdef _Rad
|
||||
vec3 reflectionWorld = reflect(-v, n);
|
||||
float lod = getMipFromRoughness(roughness, envmapNumMipmaps);
|
||||
vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;
|
||||
#endif
|
||||
|
||||
#ifdef _EnvLDR
|
||||
envl.rgb = pow(envl.rgb, vec3(2.2));
|
||||
#ifdef _Rad
|
||||
prefilteredColor = pow(prefilteredColor, vec3(2.2));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
envl.rgb *= albedo;
|
||||
|
||||
#ifdef _Brdf
|
||||
envl.rgb *= 1.0 - (f0 * envBRDF.x + envBRDF.y); //LV: We should take refracted light into account
|
||||
#endif
|
||||
|
||||
#ifdef _Rad // Indirect specular
|
||||
envl.rgb += prefilteredColor * (f0 * envBRDF.x + envBRDF.y); //LV: Removed "1.5 * occspec.y". Specular should be weighted only by FV LUT
|
||||
#else
|
||||
#ifdef _EnvCol
|
||||
envl.rgb += backgroundCol * (f0 * envBRDF.x + envBRDF.y); //LV: Eh, what's the point of weighting it only by F0?
|
||||
#endif
|
||||
#endif
|
||||
|
||||
envl.rgb *= envmapStrength * occspec.x;
|
||||
|
||||
#ifdef _VoxelGI
|
||||
vec4 indirect_diffuse = textureLod(voxels_diffuse, texCoord, 0.0);
|
||||
fragColor.rgb = (indirect_diffuse.rgb * albedo + envl.rgb * (1.0 - indirect_diffuse.a)) * voxelgiDiff;
|
||||
if(roughness < 1.0 && occspec.y > 0.0)
|
||||
fragColor.rgb += textureLod(voxels_specular, texCoord, 0.0).rgb * occspec.y * voxelgiRefl;
|
||||
#endif
|
||||
|
||||
#ifdef _VoxelAOvar
|
||||
envl.rgb *= textureLod(voxels_ao, texCoord, 0.0).r;
|
||||
#endif
|
||||
|
||||
#ifndef _VoxelGI
|
||||
fragColor.rgb = envl;
|
||||
#endif
|
||||
// Show voxels
|
||||
// vec3 origin = vec3(texCoord * 2.0 - 1.0, 0.99);
|
||||
// vec3 direction = vec3(0.0, 0.0, -1.0);
|
||||
// vec4 color = vec4(0.0f);
|
||||
// for(uint step = 0; step < 400 && color.a < 0.99f; ++step) {
|
||||
// vec3 point = origin + 0.005 * step * direction;
|
||||
// color += (1.0f - color.a) * textureLod(voxels, point * 0.5 + 0.5, 0);
|
||||
// }
|
||||
// fragColor.rgb += color.rgb;
|
||||
|
||||
// Show SSAO
|
||||
// fragColor.rgb = texture(ssaotex, texCoord).rrr;
|
||||
|
||||
#ifdef _SSAO
|
||||
// #ifdef _RTGI
|
||||
// fragColor.rgb *= textureLod(ssaotex, texCoord, 0.0).rgb;
|
||||
// #else
|
||||
fragColor.rgb *= textureLod(ssaotex, texCoord, 0.0).r;
|
||||
// #endif
|
||||
#endif
|
||||
|
||||
#ifdef _EmissionShadeless
|
||||
if (matid == 1) { // pure emissive material, color stored in basecol
|
||||
fragColor.rgb += g1.rgb;
|
||||
fragColor.a = 1.0; // Mark as opaque
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef _EmissionShaded
|
||||
#ifdef _EmissionShadeless
|
||||
else {
|
||||
#endif
|
||||
vec3 emission = textureLod(gbufferEmission, texCoord, 0.0).rgb;
|
||||
fragColor.rgb += emission;
|
||||
#ifdef _EmissionShadeless
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _Sun
|
||||
vec3 sh = normalize(v + sunDir);
|
||||
float sdotNH = max(0.0, dot(n, sh));
|
||||
float sdotVH = max(0.0, dot(v, sh));
|
||||
float sdotNL = max(0.0, dot(n, sunDir));
|
||||
vec3 svisibility = vec3(1.0);
|
||||
vec3 sdirect = lambertDiffuseBRDF(albedo, sdotNL) +
|
||||
specularBRDF(f0, roughness, sdotNL, sdotNH, dotNV, sdotVH) * occspec.y;
|
||||
|
||||
#ifdef _ShadowMap
|
||||
#ifdef _CSM
|
||||
svisibility = shadowTestCascade(
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSun, shadowMapAtlasSunTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
#else
|
||||
shadowMap, shadowMapTransparent
|
||||
#endif
|
||||
, eye, p + n * shadowsBias * 10, shadowsBias, false
|
||||
);
|
||||
#else
|
||||
vec4 lPos = LWVP * vec4(p + n * shadowsBias * 100, 1.0);
|
||||
if (lPos.w > 0.0) {
|
||||
svisibility = shadowTest(
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSun, shadowMapAtlasSunTransparent
|
||||
#else
|
||||
shadowMapAtlas, shadowMapAtlasTransparent
|
||||
#endif
|
||||
#else
|
||||
shadowMap, shadowMapTransparent
|
||||
#endif
|
||||
, lPos.xyz / lPos.w, shadowsBias, false
|
||||
);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _VoxelShadow
|
||||
svisibility *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, sunDir, clipmaps, gl_FragCoord.xy).r) * voxelgiShad;
|
||||
#endif
|
||||
|
||||
#ifdef _SSRS
|
||||
// vec2 coords = getProjectedCoord(hitCoord);
|
||||
// vec2 deltaCoords = abs(vec2(0.5, 0.5) - coords.xy);
|
||||
// float screenEdgeFactor = clamp(1.0 - (deltaCoords.x + deltaCoords.y), 0.0, 1.0);
|
||||
svisibility *= traceShadowSS(sunDir, p, gbufferD, invVP, eye);
|
||||
#endif
|
||||
|
||||
#ifdef _LightClouds
|
||||
svisibility *= textureLod(texClouds, vec2(p.xy / 100.0 + time / 80.0), 0.0).r * dot(n, vec3(0,0,1));
|
||||
#endif
|
||||
|
||||
#ifdef _MicroShadowing
|
||||
// See https://advances.realtimerendering.com/other/2016/naughty_dog/NaughtyDog_TechArt_Final.pdf
|
||||
svisibility *= clamp(sdotNL + 2.0 * occspec.x * occspec.x - 1.0, 0.0, 1.0);
|
||||
#endif
|
||||
|
||||
fragColor.rgb += sdirect * sunCol * svisibility;
|
||||
|
||||
// #ifdef _Hair // Aniso
|
||||
// if (matid == 2) {
|
||||
// const float shinyParallel = roughness;
|
||||
// const float shinyPerpendicular = 0.1;
|
||||
// const vec3 v = vec3(0.99146, 0.11664, 0.05832);
|
||||
// vec3 T = abs(dot(n, v)) > 0.99999 ? cross(n, vec3(0.0, 1.0, 0.0)) : cross(n, v);
|
||||
// fragColor.rgb = orenNayarDiffuseBRDF(albedo, roughness, dotNV, dotNL, dotVH) + wardSpecular(n, h, dotNL, dotNV, dotNH, T, shinyParallel, shinyPerpendicular) * spec;
|
||||
// }
|
||||
// #endif
|
||||
|
||||
#ifdef _SSS
|
||||
if (matid == 2) {
|
||||
#ifdef _CSM
|
||||
int casi, casindex;
|
||||
mat4 LWVP = getCascadeMat(distance(eye, p), casi, casindex);
|
||||
#endif
|
||||
fragColor.rgb += fragColor.rgb * SSSSTransmittance(
|
||||
LWVP, p, n, sunDir, lightPlane.y,
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSun
|
||||
#else
|
||||
shadowMapAtlas
|
||||
#endif
|
||||
#else
|
||||
shadowMap
|
||||
#endif
|
||||
);//TODO implement transparent shadowmaps into the SSSSTransmittance()
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _Sun
|
||||
|
||||
#ifdef _SinglePoint
|
||||
|
||||
fragColor.rgb += sampleLight(
|
||||
p, n, v, dotNV, pointPos, pointCol, albedo, roughness, occspec.y, f0
|
||||
#ifdef _ShadowMap
|
||||
, 0, pointBias, true, false
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
, true, spotData.x, spotData.y, spotDir, spotData.zw, spotRight
|
||||
#endif
|
||||
#ifdef _VoxelShadow
|
||||
, voxels, voxelsSDF, clipmaps
|
||||
#endif
|
||||
#ifdef _MicroShadowing
|
||||
, occspec.x
|
||||
#endif
|
||||
#ifdef _SSRS
|
||||
, gbufferD, invVP, eye
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef _Spot
|
||||
#ifdef _SSS
|
||||
if (matid == 2) fragColor.rgb += fragColor.rgb * SSSSTransmittance(LWVPSpot[0], p, n, normalize(pointPos - p), lightPlane.y, shadowMapSpot[0]);//TODO implement transparent shadowmaps into the SSSSTransmittance()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _Clusters
|
||||
float viewz = linearize(depth * 0.5 + 0.5, cameraProj);
|
||||
int clusterI = getClusterI(texCoord, viewz, cameraPlane);
|
||||
int numLights = int(texelFetch(clustersData, ivec2(clusterI, 0), 0).r * 255);
|
||||
|
||||
#ifdef HLSL
|
||||
viewz += textureLod(clustersData, vec2(0.0), 0.0).r * 1e-9; // TODO: krafix bug, needs to generate sampler
|
||||
#endif
|
||||
|
||||
#ifdef _Spot
|
||||
int numSpots = int(texelFetch(clustersData, ivec2(clusterI, 1 + maxLightsCluster), 0).r * 255);
|
||||
int numPoints = numLights - numSpots;
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < min(numLights, maxLightsCluster); i++) {
|
||||
int li = int(texelFetch(clustersData, ivec2(clusterI, i + 1), 0).r * 255);
|
||||
fragColor.rgb += sampleLight(
|
||||
p,
|
||||
n,
|
||||
v,
|
||||
dotNV,
|
||||
lightsArray[li * 3].xyz, // lp
|
||||
lightsArray[li * 3 + 1].xyz, // lightCol
|
||||
albedo,
|
||||
roughness,
|
||||
occspec.y,
|
||||
f0
|
||||
#ifdef _ShadowMap
|
||||
// light index, shadow bias, cast_shadows
|
||||
, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0, false
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
, lightsArray[li * 3 + 2].y != 0.0
|
||||
, lightsArray[li * 3 + 2].y // spot size (cutoff)
|
||||
, lightsArraySpot[li * 2].w // spot blend (exponent)
|
||||
, lightsArraySpot[li * 2].xyz // spotDir
|
||||
, vec2(lightsArray[li * 3].w, lightsArray[li * 3 + 1].w) // scale
|
||||
, lightsArraySpot[li * 2 + 1].xyz // right
|
||||
#endif
|
||||
#ifdef _VoxelShadow
|
||||
, voxels, voxelsSDF, clipmaps
|
||||
#endif
|
||||
#ifdef _MicroShadowing
|
||||
, occspec.x
|
||||
#endif
|
||||
#ifdef _SSRS
|
||||
, gbufferD, invVP, eye
|
||||
#endif
|
||||
);
|
||||
}
|
||||
#endif // _Clusters
|
||||
|
||||
/*
|
||||
#ifdef _VoxelRefract
|
||||
if(opac < 1.0) {
|
||||
vec3 refraction = traceRefraction(p, n, voxels, v, ior, roughness, eye) * voxelgiRefr;
|
||||
fragColor.rgb = mix(refraction, fragColor.rgb, opac);
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
fragColor.a = 1.0; // Mark as opaque
|
||||
}
|
246
leenkx/Shaders/deferred_light/deferred_light.json
Normal file
@ -0,0 +1,246 @@
|
||||
{
|
||||
"variants": ["_VoxelAOvar"],
|
||||
"contexts": [
|
||||
{
|
||||
"name": "deferred_light",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "eye",
|
||||
"link": "_cameraPosition"
|
||||
},
|
||||
{
|
||||
"name": "voxelBlend",
|
||||
"link": "_voxelBlend",
|
||||
"ifdef": ["_VoxelTemporal"]
|
||||
},
|
||||
{
|
||||
"name": "eyeLook",
|
||||
"link": "_cameraLook"
|
||||
},
|
||||
{
|
||||
"name": "clipmaps",
|
||||
"link": "_clipmaps",
|
||||
"ifdef": ["_VoxelShadow"]
|
||||
},
|
||||
{
|
||||
"name": "invVP",
|
||||
"link": "_inverseViewProjectionMatrix"
|
||||
},
|
||||
{
|
||||
"name": "shirr",
|
||||
"link": "_envmapIrradiance",
|
||||
"ifdef": ["_Irr"]
|
||||
},
|
||||
{
|
||||
"name": "senvmapRadiance",
|
||||
"link": "_envmapRadiance",
|
||||
"ifdef": ["_Rad"]
|
||||
},
|
||||
{
|
||||
"name": "envmapNumMipmaps",
|
||||
"link": "_envmapNumMipmaps",
|
||||
"ifdef": ["_Rad"]
|
||||
},
|
||||
{
|
||||
"name": "senvmapBrdf",
|
||||
"link": "$brdf.png",
|
||||
"ifdef": ["_Brdf"]
|
||||
},
|
||||
{
|
||||
"name": "cameraProj",
|
||||
"link": "_cameraPlaneProj"
|
||||
},
|
||||
{
|
||||
"name": "envmapStrength",
|
||||
"link": "_envmapStrength"
|
||||
},
|
||||
{
|
||||
"name": "backgroundCol",
|
||||
"link": "_backgroundCol",
|
||||
"ifdef": ["_EnvCol"]
|
||||
},
|
||||
{
|
||||
"name": "lightsArray",
|
||||
"link": "_lightsArray",
|
||||
"ifdef": ["_Clusters"]
|
||||
},
|
||||
{
|
||||
"name": "lightsArraySpot",
|
||||
"link": "_lightsArraySpot",
|
||||
"ifdef": ["_Clusters", "_Spot"]
|
||||
},
|
||||
{
|
||||
"name": "clustersData",
|
||||
"link": "_clustersData",
|
||||
"ifdef": ["_Clusters"]
|
||||
},
|
||||
{
|
||||
"name": "cameraPlane",
|
||||
"link": "_cameraPlane",
|
||||
"ifdef": ["_Clusters"]
|
||||
},
|
||||
{
|
||||
"name": "sunDir",
|
||||
"link": "_sunDirection",
|
||||
"ifdef": ["_Sun"]
|
||||
},
|
||||
{
|
||||
"name": "sunCol",
|
||||
"link": "_sunColor",
|
||||
"ifdef": ["_Sun"]
|
||||
},
|
||||
{
|
||||
"name": "shadowsBias",
|
||||
"link": "_sunShadowsBias",
|
||||
"ifdef": ["_Sun", "_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"name": "LWVP",
|
||||
"link": "_biasLightWorldViewProjectionMatrixSun",
|
||||
"ifndef": ["_CSM"],
|
||||
"ifdef": ["_Sun", "_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"name": "casData",
|
||||
"link": "_cascadeData",
|
||||
"ifdef": ["_Sun", "_ShadowMap", "_CSM"]
|
||||
},
|
||||
{
|
||||
"name": "lightPlane",
|
||||
"link": "_lightPlane",
|
||||
"ifdef": ["_SSS"]
|
||||
},
|
||||
{
|
||||
"name": "VP",
|
||||
"link": "_viewProjectionMatrix",
|
||||
"ifdef": ["_SSRS"]
|
||||
},
|
||||
{
|
||||
"name": "texClouds",
|
||||
"link": "$cloudstexture.png",
|
||||
"ifdef": ["_LightClouds"]
|
||||
},
|
||||
{
|
||||
"name": "time",
|
||||
"link": "_time",
|
||||
"ifdef": ["_LightClouds"]
|
||||
},
|
||||
{
|
||||
"name": "texIES",
|
||||
"link": "$iestexture.png",
|
||||
"ifdef": ["_LightIES"]
|
||||
},
|
||||
{
|
||||
"name": "lightArea0",
|
||||
"link": "_lightArea0",
|
||||
"ifdef": ["_LTC"]
|
||||
},
|
||||
{
|
||||
"name": "lightArea1",
|
||||
"link": "_lightArea1",
|
||||
"ifdef": ["_LTC"]
|
||||
},
|
||||
{
|
||||
"name": "lightArea2",
|
||||
"link": "_lightArea2",
|
||||
"ifdef": ["_LTC"]
|
||||
},
|
||||
{
|
||||
"name": "lightArea3",
|
||||
"link": "_lightArea3",
|
||||
"ifdef": ["_LTC"]
|
||||
},
|
||||
{
|
||||
"name": "sltcMat",
|
||||
"link": "_ltcMat",
|
||||
"ifdef": ["_LTC"]
|
||||
},
|
||||
{
|
||||
"name": "sltcMag",
|
||||
"link": "_ltcMag",
|
||||
"ifdef": ["_LTC"]
|
||||
},
|
||||
{
|
||||
"name": "smSizeUniform",
|
||||
"link": "_shadowMapSize",
|
||||
"ifdef": ["_SMSizeUniform"]
|
||||
},
|
||||
{
|
||||
"name": "lightProj",
|
||||
"link": "_lightPlaneProj",
|
||||
"ifdef": ["_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"name": "pointPos",
|
||||
"link": "_pointPosition",
|
||||
"ifdef": ["_SinglePoint"]
|
||||
},
|
||||
{
|
||||
"name": "pointCol",
|
||||
"link": "_pointColor",
|
||||
"ifdef": ["_SinglePoint"]
|
||||
},
|
||||
{
|
||||
"name": "pointBias",
|
||||
"link": "_pointShadowsBias",
|
||||
"ifdef": ["_SinglePoint", "_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"name": "spotDir",
|
||||
"link": "_spotDirection",
|
||||
"ifdef": ["_SinglePoint", "_Spot"]
|
||||
},
|
||||
{
|
||||
"name": "spotData",
|
||||
"link": "_spotData",
|
||||
"ifdef": ["_SinglePoint", "_Spot"]
|
||||
},
|
||||
{
|
||||
"name": "spotRight",
|
||||
"link": "_spotRight",
|
||||
"ifdef": ["_SinglePoint", "_Spot"]
|
||||
},
|
||||
{
|
||||
"name": "LWVPSpotArray",
|
||||
"link": "_biasLightWorldViewProjectionMatrixSpotArray",
|
||||
"ifdef": ["_Clusters", "_ShadowMap", "_Spot"]
|
||||
},
|
||||
{
|
||||
"name": "pointLightDataArray",
|
||||
"link": "_pointLightsAtlasArray",
|
||||
"ifdef": ["_Clusters", "_ShadowMap", "_ShadowMapAtlas"]
|
||||
},
|
||||
{
|
||||
"name": "LWVPSpot[0]",
|
||||
"link": "_biasLightWorldViewProjectionMatrixSpot0",
|
||||
"ifndef": ["_ShadowMapAtlas"],
|
||||
"ifdef": ["_LTC", "_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"name": "LWVPSpot[1]",
|
||||
"link": "_biasLightWorldViewProjectionMatrixSpot1",
|
||||
"ifndef": ["_ShadowMapAtlas"],
|
||||
"ifdef": ["_LTC", "_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"name": "LWVPSpot[2]",
|
||||
"link": "_biasLightWorldViewProjectionMatrixSpot2",
|
||||
"ifndef": ["_ShadowMapAtlas"],
|
||||
"ifdef": ["_LTC", "_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"name": "LWVPSpot[3]",
|
||||
"link": "_biasLightWorldViewProjectionMatrixSpot3",
|
||||
"ifndef": ["_ShadowMapAtlas"],
|
||||
"ifdef": ["_LTC", "_ShadowMap"]
|
||||
}
|
||||
],
|
||||
"vertex_shader": "../include/pass_viewray.vert.glsl",
|
||||
"fragment_shader": "deferred_light.frag.glsl",
|
||||
"color_attachments": ["RGBA64"]
|
||||
}
|
||||
]
|
||||
}
|
283
leenkx/Shaders/deferred_light_mobile/deferred_light.frag.glsl
Normal file
@ -0,0 +1,283 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
#include "std/gbuffer.glsl"
|
||||
#include "std/math.glsl"
|
||||
#ifdef _Clusters
|
||||
#include "std/clusters.glsl"
|
||||
#endif
|
||||
#ifdef _Irr
|
||||
#include "std/shirr.glsl"
|
||||
#endif
|
||||
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform sampler2D gbuffer1;
|
||||
|
||||
uniform float envmapStrength;
|
||||
#ifdef _Irr
|
||||
uniform vec4 shirr[7];
|
||||
#endif
|
||||
#ifdef _Brdf
|
||||
uniform sampler2D senvmapBrdf;
|
||||
#endif
|
||||
#ifdef _Rad
|
||||
uniform sampler2D senvmapRadiance;
|
||||
uniform int envmapNumMipmaps;
|
||||
#endif
|
||||
#ifdef _EnvCol
|
||||
uniform vec3 backgroundCol;
|
||||
#endif
|
||||
|
||||
#ifdef _SMSizeUniform
|
||||
//!uniform vec2 smSizeUniform;
|
||||
#endif
|
||||
uniform vec2 cameraProj;
|
||||
uniform vec3 eye;
|
||||
uniform vec3 eyeLook;
|
||||
|
||||
#ifdef _Clusters
|
||||
uniform vec4 lightsArray[maxLights * 3];
|
||||
#ifdef _Spot
|
||||
uniform vec4 lightsArraySpot[maxLights * 2];
|
||||
#endif
|
||||
uniform sampler2D clustersData;
|
||||
uniform vec2 cameraPlane;
|
||||
#endif
|
||||
|
||||
#ifdef _ShadowMap
|
||||
#ifdef _SinglePoint
|
||||
#ifdef _Spot
|
||||
//!uniform sampler2DShadow shadowMapSpot[1];
|
||||
//!uniform mat4 LWVPSpot[1];
|
||||
#else
|
||||
//!uniform samplerCubeShadow shadowMapPoint[1];
|
||||
//!uniform vec2 lightProj;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _Clusters
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifdef _SingleAtlas
|
||||
uniform sampler2DShadow shadowMapAtlas;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
//!uniform sampler2DShadow shadowMapAtlasPoint;
|
||||
#endif
|
||||
//!uniform vec4 pointLightDataArray[4];
|
||||
#else
|
||||
//!uniform samplerCubeShadow shadowMapPoint[4];
|
||||
#endif
|
||||
//!uniform vec2 lightProj;
|
||||
#ifdef _Spot
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
//!uniform sampler2DShadow shadowMapAtlasSpot;
|
||||
#endif
|
||||
#else
|
||||
//!uniform sampler2DShadow shadowMapSpot[4];
|
||||
#endif
|
||||
//!uniform mat4 LWVPSpotArray[4];
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _Sun
|
||||
uniform vec3 sunDir;
|
||||
uniform vec3 sunCol;
|
||||
#ifdef _ShadowMap
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
uniform sampler2DShadow shadowMapAtlasSun;
|
||||
#endif
|
||||
#else
|
||||
uniform sampler2DShadow shadowMap;
|
||||
#endif
|
||||
uniform float shadowsBias;
|
||||
#ifdef _CSM
|
||||
//!uniform vec4 casData[shadowmapCascades * 4 + 4];
|
||||
#else
|
||||
uniform mat4 LWVP;
|
||||
#endif
|
||||
#endif // _ShadowMap
|
||||
#endif
|
||||
|
||||
#ifdef _SinglePoint // Fast path for single light
|
||||
uniform vec3 pointPos;
|
||||
uniform vec3 pointCol;
|
||||
uniform float pointBias;
|
||||
#ifdef _Spot
|
||||
uniform vec3 spotDir;
|
||||
uniform vec3 spotRight;
|
||||
uniform vec4 spotData;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "std/light_mobile.glsl"
|
||||
|
||||
in vec2 texCoord;
|
||||
in vec3 viewRay;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
vec4 g0 = textureLod(gbuffer0, texCoord, 0.0); // Normal.xy, roughness, metallic/matid
|
||||
|
||||
vec3 n;
|
||||
n.z = 1.0 - abs(g0.x) - abs(g0.y);
|
||||
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
|
||||
n = normalize(n);
|
||||
|
||||
float roughness = g0.b;
|
||||
float metallic;
|
||||
uint matid;
|
||||
unpackFloatInt16(g0.a, metallic, matid);
|
||||
|
||||
vec4 g1 = textureLod(gbuffer1, texCoord, 0.0); // Basecolor.rgb, spec/occ
|
||||
vec2 occspec = unpackFloat2(g1.a);
|
||||
vec3 albedo = surfaceAlbedo(g1.rgb, metallic); // g1.rgb - basecolor
|
||||
vec3 f0 = surfaceF0(g1.rgb, metallic);
|
||||
|
||||
float depth = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
|
||||
vec3 p = getPos(eye, eyeLook, normalize(viewRay), depth, cameraProj);
|
||||
vec3 v = normalize(eye - p);
|
||||
float dotNV = max(dot(n, v), 0.0);
|
||||
|
||||
#ifdef _Brdf
|
||||
vec2 envBRDF = texelFetch(senvmapBrdf, ivec2(vec2(dotNV, 1.0 - roughness) * 256.0), 0).xy;
|
||||
#endif
|
||||
|
||||
// Envmap
|
||||
#ifdef _Irr
|
||||
vec3 envl = shIrradiance(n, shirr);
|
||||
#ifdef _EnvTex
|
||||
envl /= PI;
|
||||
#endif
|
||||
#else
|
||||
vec3 envl = vec3(1.0);
|
||||
#endif
|
||||
|
||||
#ifdef _Rad
|
||||
vec3 reflectionWorld = reflect(-v, n);
|
||||
float lod = getMipFromRoughness(roughness, envmapNumMipmaps);
|
||||
vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;
|
||||
#endif
|
||||
|
||||
#ifdef _EnvLDR
|
||||
envl.rgb = pow(envl.rgb, vec3(2.2));
|
||||
#ifdef _Rad
|
||||
prefilteredColor = pow(prefilteredColor, vec3(2.2));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
envl.rgb *= albedo;
|
||||
|
||||
#ifdef _Rad // Indirect specular
|
||||
envl.rgb += prefilteredColor * (f0 * envBRDF.x + envBRDF.y) * 1.5 * occspec.y;
|
||||
#else
|
||||
#ifdef _EnvCol
|
||||
envl.rgb += backgroundCol * surfaceF0(g1.rgb, metallic); // f0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
envl.rgb *= envmapStrength * occspec.x;
|
||||
fragColor.rgb = envl;
|
||||
|
||||
#ifdef _Sun
|
||||
vec3 sh = normalize(v + sunDir);
|
||||
float sdotNH = max(0.0, dot(n, sh));
|
||||
float sdotVH = max(0.0, dot(v, sh));
|
||||
float sdotNL = max(0.0, dot(n, sunDir));
|
||||
float svisibility = 1.0;
|
||||
vec3 sdirect = lambertDiffuseBRDF(albedo, sdotNL) +
|
||||
specularBRDF(f0, roughness, sdotNL, sdotNH, dotNV, sdotVH) * occspec.y;
|
||||
|
||||
#ifdef _ShadowMap
|
||||
#ifdef _CSM
|
||||
svisibility = shadowTestCascade(
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSun
|
||||
#else
|
||||
shadowMapAtlas
|
||||
#endif
|
||||
#else
|
||||
shadowMap
|
||||
#endif
|
||||
, eye, p + n * shadowsBias * 10, shadowsBias
|
||||
);
|
||||
#else
|
||||
vec4 lPos = LWVP * vec4(p + n * shadowsBias * 100, 1.0);
|
||||
if (lPos.w > 0.0) svisibility = shadowTest(
|
||||
#ifdef _ShadowMapAtlas
|
||||
#ifndef _SingleAtlas
|
||||
shadowMapAtlasSun
|
||||
#else
|
||||
shadowMapAtlas
|
||||
#endif
|
||||
#else
|
||||
shadowMap
|
||||
#endif
|
||||
, lPos.xyz / lPos.w, shadowsBias
|
||||
);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
fragColor.rgb += sdirect * svisibility * sunCol;
|
||||
#endif
|
||||
|
||||
#ifdef _SinglePoint
|
||||
fragColor.rgb += sampleLight(
|
||||
p, n, v, dotNV, pointPos, pointCol, albedo, roughness, occspec.y, f0
|
||||
#ifdef _ShadowMap
|
||||
, 0, pointBias, true
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
, true, spotData.x, spotData.y, spotDir, spotData.zw, spotRight // TODO: Test!
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
|
||||
#ifdef _Clusters
|
||||
float viewz = linearize(depth * 0.5 + 0.5, cameraProj);
|
||||
int clusterI = getClusterI(texCoord, viewz, cameraPlane);
|
||||
int numLights = int(texelFetch(clustersData, ivec2(clusterI, 0), 0).r * 255);
|
||||
|
||||
#ifdef HLSL
|
||||
viewz += textureLod(clustersData, vec2(0.0), 0.0).r * 1e-9; // TODO: krafix bug, needs to generate sampler
|
||||
#endif
|
||||
|
||||
#ifdef _Spot
|
||||
int numSpots = int(texelFetch(clustersData, ivec2(clusterI, 1 + maxLightsCluster), 0).r * 255);
|
||||
int numPoints = numLights - numSpots;
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < min(numLights, maxLightsCluster); i++) {
|
||||
int li = int(texelFetch(clustersData, ivec2(clusterI, i + 1), 0).r * 255);
|
||||
fragColor.rgb += sampleLight(
|
||||
p,
|
||||
n,
|
||||
v,
|
||||
dotNV,
|
||||
lightsArray[li * 3].xyz, // lp
|
||||
lightsArray[li * 3 + 1].xyz, // lightCol
|
||||
albedo,
|
||||
roughness,
|
||||
occspec.y,
|
||||
f0
|
||||
#ifdef _ShadowMap
|
||||
// light index, shadow bias, cast_shadows
|
||||
, li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
, lightsArray[li * 3 + 2].y != 0.0
|
||||
, lightsArray[li * 3 + 2].y // spot size (cutoff)
|
||||
, lightsArraySpot[li].w // spot blend (exponent)
|
||||
, lightsArraySpot[li].xyz // spotDir
|
||||
, vec2(lightsArray[li * 3].w, lightsArray[li * 3 + 1].w) // scale
|
||||
, lightsArraySpot[li * 2 + 1].xyz // right
|
||||
#endif
|
||||
);
|
||||
}
|
||||
#endif // _Clusters
|
||||
}
|
190
leenkx/Shaders/deferred_light_mobile/deferred_light_mobile.json
Normal file
@ -0,0 +1,190 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "deferred_light",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "eye",
|
||||
"link": "_cameraPosition"
|
||||
},
|
||||
{
|
||||
"name": "eyeLook",
|
||||
"link": "_cameraLook"
|
||||
},
|
||||
{
|
||||
"name": "invVP",
|
||||
"link": "_inverseViewProjectionMatrix"
|
||||
},
|
||||
{
|
||||
"name": "shirr",
|
||||
"link": "_envmapIrradiance",
|
||||
"ifdef": ["_Irr"]
|
||||
},
|
||||
{
|
||||
"name": "senvmapRadiance",
|
||||
"link": "_envmapRadiance",
|
||||
"ifdef": ["_Rad"]
|
||||
},
|
||||
{
|
||||
"name": "envmapNumMipmaps",
|
||||
"link": "_envmapNumMipmaps",
|
||||
"ifdef": ["_Rad"]
|
||||
},
|
||||
{
|
||||
"name": "senvmapBrdf",
|
||||
"link": "$brdf.png",
|
||||
"ifdef": ["_Brdf"]
|
||||
},
|
||||
{
|
||||
"name": "cameraProj",
|
||||
"link": "_cameraPlaneProj"
|
||||
},
|
||||
{
|
||||
"name": "envmapStrength",
|
||||
"link": "_envmapStrength"
|
||||
},
|
||||
{
|
||||
"name": "backgroundCol",
|
||||
"link": "_backgroundCol",
|
||||
"ifdef": ["_EnvCol"]
|
||||
},
|
||||
{
|
||||
"name": "lightsArray",
|
||||
"link": "_lightsArray",
|
||||
"ifdef": ["_Clusters"]
|
||||
},
|
||||
{
|
||||
"name": "lightsArraySpot",
|
||||
"link": "_lightsArraySpot",
|
||||
"ifdef": ["_Clusters", "_Spot"]
|
||||
},
|
||||
{
|
||||
"name": "clustersData",
|
||||
"link": "_clustersData",
|
||||
"ifdef": ["_Clusters"]
|
||||
},
|
||||
{
|
||||
"name": "cameraPlane",
|
||||
"link": "_cameraPlane",
|
||||
"ifdef": ["_Clusters"]
|
||||
},
|
||||
{
|
||||
"name": "sunDir",
|
||||
"link": "_sunDirection",
|
||||
"ifdef": ["_Sun"]
|
||||
},
|
||||
{
|
||||
"name": "sunCol",
|
||||
"link": "_sunColor",
|
||||
"ifdef": ["_Sun"]
|
||||
},
|
||||
{
|
||||
"name": "shadowsBias",
|
||||
"link": "_sunShadowsBias",
|
||||
"ifdef": ["_Sun", "_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"name": "LWVP",
|
||||
"link": "_biasLightWorldViewProjectionMatrixSun",
|
||||
"ifndef": ["_CSM"],
|
||||
"ifdef": ["_Sun", "_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"name": "casData",
|
||||
"link": "_cascadeData",
|
||||
"ifdef": ["_Sun", "_ShadowMap", "_CSM"]
|
||||
},
|
||||
{
|
||||
"name": "lightPlane",
|
||||
"link": "_lightPlane",
|
||||
"ifdef": ["_SSS"]
|
||||
},
|
||||
{
|
||||
"name": "VP",
|
||||
"link": "_viewProjectionMatrix",
|
||||
"ifdef": ["_SSRS"]
|
||||
},
|
||||
{
|
||||
"name": "smSizeUniform",
|
||||
"link": "_shadowMapSize",
|
||||
"ifdef": ["_SMSizeUniform"]
|
||||
},
|
||||
{
|
||||
"name": "lightProj",
|
||||
"link": "_lightPlaneProj",
|
||||
"ifdef": ["_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"name": "pointPos",
|
||||
"link": "_pointPosition",
|
||||
"ifdef": ["_SinglePoint"]
|
||||
},
|
||||
{
|
||||
"name": "pointCol",
|
||||
"link": "_pointColor",
|
||||
"ifdef": ["_SinglePoint"]
|
||||
},
|
||||
{
|
||||
"name": "pointBias",
|
||||
"link": "_pointShadowsBias",
|
||||
"ifdef": ["_SinglePoint"]
|
||||
},
|
||||
{
|
||||
"name": "spotDir",
|
||||
"link": "_spotDirection",
|
||||
"ifdef": ["_SinglePoint", "_Spot"]
|
||||
},
|
||||
{
|
||||
"name": "spotData",
|
||||
"link": "_spotData",
|
||||
"ifdef": ["_SinglePoint", "_Spot"]
|
||||
},
|
||||
{
|
||||
"name": "spotRight",
|
||||
"link": "_spotRight",
|
||||
"ifdef": ["_SinglePoint", "_Spot"]
|
||||
},
|
||||
{
|
||||
"name": "LWVPSpotArray",
|
||||
"link": "_biasLightWorldViewProjectionMatrixSpotArray",
|
||||
"ifdef": ["_Clusters", "_ShadowMap", "_Spot"]
|
||||
},
|
||||
{
|
||||
"name": "pointLightDataArray",
|
||||
"link": "_pointLightsAtlasArray",
|
||||
"ifdef": ["_Clusters", "_ShadowMap", "_ShadowMapAtlas"]
|
||||
},
|
||||
{
|
||||
"name": "LWVPSpot[0]",
|
||||
"link": "_biasLightWorldViewProjectionMatrixSpot0",
|
||||
"ifndef": ["_ShadowMapAtlas"],
|
||||
"ifdef": ["_LTC", "_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"name": "LWVPSpot[1]",
|
||||
"link": "_biasLightWorldViewProjectionMatrixSpot1",
|
||||
"ifndef": ["_ShadowMapAtlas"],
|
||||
"ifdef": ["_LTC", "_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"name": "LWVPSpot[2]",
|
||||
"link": "_biasLightWorldViewProjectionMatrixSpot2",
|
||||
"ifndef": ["_ShadowMapAtlas"],
|
||||
"ifdef": ["_LTC", "_ShadowMap"]
|
||||
},
|
||||
{
|
||||
"name": "LWVPSpot[3]",
|
||||
"link": "_biasLightWorldViewProjectionMatrixSpot3",
|
||||
"ifndef": ["_ShadowMapAtlas"],
|
||||
"ifdef": ["_LTC", "_ShadowMap"]
|
||||
}
|
||||
],
|
||||
"vertex_shader": "../include/pass_viewray.vert.glsl",
|
||||
"fragment_shader": "deferred_light.frag.glsl",
|
||||
"color_attachments": ["RGBA64"]
|
||||
}
|
||||
]
|
||||
}
|
13
leenkx/Shaders/deferred_light_solid/deferred_light.frag.glsl
Normal file
@ -0,0 +1,13 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
#include "std/gbuffer.glsl"
|
||||
|
||||
uniform sampler2D gbuffer1;
|
||||
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor.rgb = textureLod(gbuffer1, texCoord, 0.0).rgb; // Basecolor.rgb
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "deferred_light",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "deferred_light.frag.glsl",
|
||||
"color_attachments": ["RGBA64"]
|
||||
}
|
||||
]
|
||||
}
|
18
leenkx/Shaders/downsample_depth/downsample_depth.frag.glsl
Normal file
@ -0,0 +1,18 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
|
||||
uniform sampler2D texdepth;
|
||||
uniform vec2 screenSizeInv;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
out float fragColor;
|
||||
|
||||
void main() {
|
||||
float d0 = textureLod(texdepth, texCoord, 0.0).r;
|
||||
float d1 = textureLod(texdepth, texCoord + vec2(screenSizeInv.x, 0.0), 0.0).r;
|
||||
float d2 = textureLod(texdepth, texCoord + vec2(0.0, screenSizeInv.y), 0.0).r;
|
||||
float d3 = textureLod(texdepth, texCoord + vec2(screenSizeInv.x, screenSizeInv.y), 0.0).r;
|
||||
fragColor = max(max(d0, d1), max(d2, d3));
|
||||
}
|
19
leenkx/Shaders/downsample_depth/downsample_depth.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "downsample_depth",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "screenSizeInv",
|
||||
"link": "_screenSizeInv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "downsample_depth.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
58
leenkx/Shaders/fxaa_pass/fxaa_pass.frag.glsl
Normal file
@ -0,0 +1,58 @@
|
||||
#version 450
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 screenSizeInv;
|
||||
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
const float FXAA_REDUCE_MIN = 1.0 / 128.0;
|
||||
const float FXAA_REDUCE_MUL = 1.0 / 8.0;
|
||||
const float FXAA_SPAN_MAX = 8.0;
|
||||
|
||||
vec2 tcrgbNW = (texCoord + vec2(-1.0, -1.0) * screenSizeInv);
|
||||
vec2 tcrgbNE = (texCoord + vec2(1.0, -1.0) * screenSizeInv);
|
||||
vec2 tcrgbSW = (texCoord + vec2(-1.0, 1.0) * screenSizeInv);
|
||||
vec2 tcrgbSE = (texCoord + vec2(1.0, 1.0) * screenSizeInv);
|
||||
vec2 tcrgbM = vec2(texCoord);
|
||||
|
||||
vec3 rgbNW = textureLod(tex, tcrgbNW, 0.0).rgb;
|
||||
vec3 rgbNE = textureLod(tex, tcrgbNE, 0.0).rgb;
|
||||
vec3 rgbSW = textureLod(tex, tcrgbSW, 0.0).rgb;
|
||||
vec3 rgbSE = textureLod(tex, tcrgbSE, 0.0).rgb;
|
||||
vec4 texColor = textureLod(tex, tcrgbM, 0.0);
|
||||
vec3 rgbM = texColor.rgb;
|
||||
vec3 luma = vec3(0.299, 0.587, 0.114);
|
||||
float lumaNW = dot(rgbNW, luma);
|
||||
float lumaNE = dot(rgbNE, luma);
|
||||
float lumaSW = dot(rgbSW, luma);
|
||||
float lumaSE = dot(rgbSE, luma);
|
||||
float lumaM = dot(rgbM, luma);
|
||||
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
|
||||
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
|
||||
|
||||
vec2 dir;
|
||||
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
|
||||
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
|
||||
|
||||
float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *
|
||||
(0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
|
||||
|
||||
float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
|
||||
dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
|
||||
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
|
||||
dir * rcpDirMin)) * screenSizeInv;
|
||||
|
||||
vec3 rgbA = 0.5 * (
|
||||
textureLod(tex, texCoord + dir * (1.0 / 3.0 - 0.5), 0.0).rgb +
|
||||
textureLod(tex, texCoord + dir * (2.0 / 3.0 - 0.5), 0.0).rgb);
|
||||
fragColor.rgb = rgbA * 0.5 + 0.25 * ( // vec3 rgbB
|
||||
textureLod(tex, texCoord + dir * -0.5, 0.0).rgb +
|
||||
textureLod(tex, texCoord + dir * 0.5, 0.0).rgb);
|
||||
|
||||
// float lumaB = dot(rgbB, luma);
|
||||
float lumaB = dot(fragColor.rgb, luma);
|
||||
if ((lumaB < lumaMin) || (lumaB > lumaMax)) fragColor.rgb = rgbA;
|
||||
// else fragColor.rgb = rgbB;
|
||||
}
|
19
leenkx/Shaders/fxaa_pass/fxaa_pass.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "fxaa_pass",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "screenSizeInv",
|
||||
"link": "_screenSizeInv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "fxaa_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
18
leenkx/Shaders/histogram_pass/histogram_pass.frag.glsl
Normal file
@ -0,0 +1,18 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor.a = 0.01 * autoExposureSpeed;
|
||||
fragColor.rgb = textureLod(tex, vec2(0.5, 0.5), 0.0).rgb +
|
||||
textureLod(tex, vec2(0.2, 0.2), 0.0).rgb +
|
||||
textureLod(tex, vec2(0.8, 0.2), 0.0).rgb +
|
||||
textureLod(tex, vec2(0.2, 0.8), 0.0).rgb +
|
||||
textureLod(tex, vec2(0.8, 0.8), 0.0).rgb;
|
||||
fragColor.rgb /= 5.0;
|
||||
}
|
17
leenkx/Shaders/histogram_pass/histogram_pass.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "histogram_pass",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"blend_source": "source_alpha",
|
||||
"blend_destination": "inverse_source_alpha",
|
||||
"blend_operation": "add",
|
||||
"links": [],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "histogram_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
18
leenkx/Shaders/include/pass.vert.glsl
Normal file
@ -0,0 +1,18 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
|
||||
in vec2 pos;
|
||||
|
||||
out vec2 texCoord;
|
||||
|
||||
void main() {
|
||||
// Scale vertex attribute to 0-1 range
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
texCoord = pos.xy * madd + madd;
|
||||
#ifdef _InvY
|
||||
texCoord.y = 1.0 - texCoord.y;
|
||||
#endif
|
||||
|
||||
gl_Position = vec4(pos.xy, 0.0, 1.0);
|
||||
}
|
10
leenkx/Shaders/include/pass_copy.frag.glsl
Normal file
@ -0,0 +1,10 @@
|
||||
#version 450
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor = textureLod(tex, texCoord, 0.0);
|
||||
}
|
31
leenkx/Shaders/include/pass_viewray.vert.glsl
Normal file
@ -0,0 +1,31 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
|
||||
uniform mat4 invVP;
|
||||
uniform vec3 eye;
|
||||
|
||||
in vec2 pos;
|
||||
|
||||
out vec2 texCoord;
|
||||
out vec3 viewRay;
|
||||
|
||||
void main() {
|
||||
// Scale vertex attribute to [0-1] range
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
texCoord = pos.xy * madd + madd;
|
||||
#ifdef _InvY
|
||||
texCoord.y = 1.0 - texCoord.y;
|
||||
#endif
|
||||
|
||||
gl_Position = vec4(pos.xy, 0.0, 1.0);
|
||||
|
||||
// fullscreen triangle: http://de.slideshare.net/DevCentralAMD/vertex-shader-tricks-bill-bilodeau
|
||||
// gl_Position = vec4((gl_VertexID % 2) * 4.0 - 1.0, (gl_VertexID / 2) * 4.0 - 1.0, 0.0, 1.0);
|
||||
|
||||
// NDC (at the back of cube)
|
||||
vec4 v = vec4(pos.x, pos.y, 1.0, 1.0);
|
||||
v = vec4(invVP * v);
|
||||
v.xyz /= v.w;
|
||||
viewRay = v.xyz - eye;
|
||||
}
|
26
leenkx/Shaders/include/pass_viewray2.vert.glsl
Normal file
@ -0,0 +1,26 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
|
||||
uniform mat4 invP;
|
||||
|
||||
in vec2 pos;
|
||||
|
||||
out vec2 texCoord;
|
||||
out vec3 viewRay;
|
||||
|
||||
void main() {
|
||||
// Scale vertex attribute to [0-1] range
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
texCoord = pos.xy * madd + madd;
|
||||
#ifdef _InvY
|
||||
texCoord.y = 1.0 - texCoord.y;
|
||||
#endif
|
||||
|
||||
gl_Position = vec4(pos.xy, 0.0, 1.0);
|
||||
|
||||
// NDC (at the back of cube)
|
||||
vec4 v = vec4(pos.x, pos.y, 1.0, 1.0);
|
||||
v = vec4(invP * v);
|
||||
viewRay = vec3(v.xy / v.z, 1.0);
|
||||
}
|
12
leenkx/Shaders/include/pass_volume.vert.glsl
Normal file
@ -0,0 +1,12 @@
|
||||
#version 450
|
||||
|
||||
uniform mat4 VWVP;
|
||||
|
||||
in vec3 pos;
|
||||
|
||||
out vec4 wvpposition;
|
||||
|
||||
void main() {
|
||||
wvpposition = VWVP * vec4(pos, 1.0);
|
||||
gl_Position = wvpposition;
|
||||
}
|
54
leenkx/Shaders/motion_blur_pass/motion_blur_pass.frag.glsl
Normal file
@ -0,0 +1,54 @@
|
||||
// Based on GPU Gems 3
|
||||
// http://http.developer.nvidia.com/GPUGems3/gpugems3_ch27.html
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
#include "std/gbuffer.glsl"
|
||||
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D tex;
|
||||
uniform mat4 prevVP;
|
||||
uniform vec3 eye;
|
||||
uniform vec3 eyeLook;
|
||||
uniform vec2 cameraProj;
|
||||
uniform float frameScale;
|
||||
|
||||
in vec2 texCoord;
|
||||
in vec3 viewRay;
|
||||
out vec4 fragColor;
|
||||
|
||||
vec2 getVelocity(vec2 coord, float depth) {
|
||||
#ifdef _InvY
|
||||
coord.y = 1.0 - coord.y;
|
||||
#endif
|
||||
vec4 currentPos = vec4(coord.xy * 2.0 - 1.0, depth, 1.0);
|
||||
vec4 worldPos = vec4(getPos(eye, eyeLook, normalize(viewRay), depth, cameraProj), 1.0);
|
||||
vec4 previousPos = prevVP * worldPos;
|
||||
previousPos /= previousPos.w;
|
||||
vec2 velocity = (currentPos - previousPos).xy / 40.0;
|
||||
#ifdef _InvY
|
||||
velocity.y = -velocity.y;
|
||||
#endif
|
||||
return velocity;
|
||||
}
|
||||
|
||||
void main() {
|
||||
fragColor.rgb = textureLod(tex, texCoord, 0.0).rgb;
|
||||
|
||||
float depth = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
|
||||
if (depth == 1.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
float blurScale = motionBlurIntensity * frameScale;
|
||||
vec2 velocity = getVelocity(texCoord, depth) * blurScale;
|
||||
|
||||
vec2 offset = texCoord;
|
||||
int processed = 1;
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
offset += velocity;
|
||||
fragColor.rgb += textureLod(tex, offset, 0.0).rgb;
|
||||
processed++;
|
||||
}
|
||||
fragColor.rgb /= processed;
|
||||
}
|
39
leenkx/Shaders/motion_blur_pass/motion_blur_pass.json
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "motion_blur_pass",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "prevVP",
|
||||
"link": "_prevViewProjectionMatrix"
|
||||
},
|
||||
{
|
||||
"name": "invVP",
|
||||
"link": "_inverseViewProjectionMatrix"
|
||||
},
|
||||
{
|
||||
"name": "eye",
|
||||
"link": "_cameraPosition"
|
||||
},
|
||||
{
|
||||
"name": "eyeLook",
|
||||
"link": "_cameraLook"
|
||||
},
|
||||
{
|
||||
"name": "cameraProj",
|
||||
"link": "_cameraPlaneProj"
|
||||
},
|
||||
{
|
||||
"name": "frameScale",
|
||||
"link": "_frameScale"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass_viewray.vert.glsl",
|
||||
"fragment_shader": "motion_blur_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
// Per-Object Motion Blur
|
||||
// http://john-chapman-graphics.blogspot.com/2013/01/per-object-motion-blur.html
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
|
||||
uniform sampler2D sveloc;
|
||||
uniform sampler2D tex;
|
||||
// uniform vec2 texStep;
|
||||
uniform float frameScale;
|
||||
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
vec2 velocity = textureLod(sveloc, texCoord, 0.0).rg * motionBlurIntensity * frameScale;
|
||||
|
||||
#ifdef _InvY
|
||||
velocity.y = -velocity.y;
|
||||
#endif
|
||||
|
||||
fragColor.rgb = textureLod(tex, texCoord, 0.0).rgb;
|
||||
|
||||
// float speed = length(velocity / texStep);
|
||||
// const int MAX_SAMPLES = 8;
|
||||
// int samples = clamp(int(speed), 1, MAX_SAMPLES);
|
||||
const int samples = 8;
|
||||
for (int i = 0; i < samples; ++i) {
|
||||
vec2 offset = velocity * (float(i) / float(samples - 1) - 0.5);
|
||||
fragColor.rgb += textureLod(tex, texCoord + offset, 0.0).rgb;
|
||||
}
|
||||
fragColor.rgb /= float(samples + 1);
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "motion_blur_veloc_pass",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "frameScale",
|
||||
"link": "_frameScale"
|
||||
},
|
||||
{
|
||||
"name": "texStep",
|
||||
"link": "_screenSizeInv",
|
||||
"ifdef": ["_Disabled"]
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "motion_blur_veloc_pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
54
leenkx/Shaders/probe_cubemap/probe_cubemap.frag.glsl
Normal file
@ -0,0 +1,54 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
#include "std/gbuffer.glsl"
|
||||
|
||||
uniform samplerCube probeTex;
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform sampler2D gbuffer1;
|
||||
uniform mat4 invVP;
|
||||
uniform vec3 probep;
|
||||
uniform vec3 eye;
|
||||
|
||||
in vec4 wvpposition;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
vec2 texCoord = wvpposition.xy / wvpposition.w;
|
||||
texCoord = texCoord * 0.5 + 0.5;
|
||||
#ifdef _InvY
|
||||
texCoord.y = 1.0 - texCoord.y;
|
||||
#endif
|
||||
|
||||
vec4 g0 = textureLod(gbuffer0, texCoord, 0.0); // Normal.xy, roughness, metallic/matid
|
||||
|
||||
float roughness = g0.b;
|
||||
if (roughness > 0.95) {
|
||||
fragColor.rgb = vec3(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
float spec = fract(textureLod(gbuffer1, texCoord, 0.0).a);
|
||||
if (spec == 0.0) {
|
||||
fragColor.rgb = vec3(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
float depth = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
|
||||
vec3 wp = getPos2(invVP, depth, texCoord);
|
||||
|
||||
vec2 enc = g0.rg;
|
||||
vec3 n;
|
||||
n.z = 1.0 - abs(enc.x) - abs(enc.y);
|
||||
n.xy = n.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
|
||||
n = normalize(n);
|
||||
|
||||
vec3 v = wp - eye;
|
||||
vec3 r = reflect(v, n);
|
||||
#ifdef _InvY
|
||||
r.y = -r.y;
|
||||
#endif
|
||||
float intensity = clamp((1.0 - roughness) * dot(wp - probep, n), 0.0, 1.0);
|
||||
fragColor.rgb = texture(probeTex, r).rgb * intensity;
|
||||
}
|
36
leenkx/Shaders/probe_cubemap/probe_cubemap.json
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "probe_cubemap",
|
||||
"depth_write": false,
|
||||
"compare_mode": "less",
|
||||
"cull_mode": "clockwise",
|
||||
"blend_source": "blend_one",
|
||||
"blend_destination": "blend_one",
|
||||
"blend_operation": "add",
|
||||
"alpha_blend_source": "blend_one",
|
||||
"alpha_blend_destination": "blend_one",
|
||||
"alpha_blend_operation": "add",
|
||||
"links": [
|
||||
{
|
||||
"name": "VWVP",
|
||||
"link": "_worldViewProjectionMatrix"
|
||||
},
|
||||
{
|
||||
"name": "invVP",
|
||||
"link": "_inverseViewProjectionMatrix"
|
||||
},
|
||||
{
|
||||
"name": "probep",
|
||||
"link": "_probePosition"
|
||||
},
|
||||
{
|
||||
"name": "eye",
|
||||
"link": "_cameraPosition"
|
||||
}
|
||||
],
|
||||
"vertex_shader": "../include/pass_volume.vert.glsl",
|
||||
"fragment_shader": "probe_cubemap.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
54
leenkx/Shaders/probe_planar/probe_planar.frag.glsl
Normal file
@ -0,0 +1,54 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
#include "std/gbuffer.glsl"
|
||||
|
||||
uniform sampler2D probeTex;
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform sampler2D gbuffer1;
|
||||
uniform mat4 probeVP;
|
||||
uniform mat4 invVP;
|
||||
uniform vec3 proben;
|
||||
|
||||
in vec4 wvpposition;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
vec2 texCoord = wvpposition.xy / wvpposition.w;
|
||||
texCoord = texCoord * 0.5 + 0.5;
|
||||
#ifdef _InvY
|
||||
texCoord.y = 1.0 - texCoord.y;
|
||||
#endif
|
||||
|
||||
vec4 g0 = textureLod(gbuffer0, texCoord, 0.0); // Normal.xy, roughness, metallic/matid
|
||||
|
||||
float roughness = g0.b;
|
||||
if (roughness > 0.95) {
|
||||
fragColor.rgb = vec3(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
float spec = fract(textureLod(gbuffer1, texCoord, 0.0).a);
|
||||
if (spec == 0.0) {
|
||||
fragColor.rgb = vec3(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
float depth = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
|
||||
vec3 wp = getPos2(invVP, depth, texCoord);
|
||||
vec4 pp = probeVP * vec4(wp.xyz, 1.0);
|
||||
vec2 tc = (pp.xy / pp.w) * 0.5 + 0.5;
|
||||
#ifdef _InvY
|
||||
tc.y = 1.0 - tc.y;
|
||||
#endif
|
||||
|
||||
vec2 enc = g0.rg;
|
||||
vec3 n;
|
||||
n.z = 1.0 - abs(enc.x) - abs(enc.y);
|
||||
n.xy = n.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
|
||||
n = normalize(n);
|
||||
|
||||
float intensity = clamp((1.0 - roughness) * dot(n, proben), 0.0, 1.0);
|
||||
fragColor.rgb = texture(probeTex, tc).rgb * intensity;
|
||||
}
|
36
leenkx/Shaders/probe_planar/probe_planar.json
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "probe_planar",
|
||||
"depth_write": false,
|
||||
"compare_mode": "less",
|
||||
"cull_mode": "clockwise",
|
||||
"blend_source": "blend_one",
|
||||
"blend_destination": "blend_one",
|
||||
"blend_operation": "add",
|
||||
"alpha_blend_source": "blend_one",
|
||||
"alpha_blend_destination": "blend_one",
|
||||
"alpha_blend_operation": "add",
|
||||
"links": [
|
||||
{
|
||||
"name": "VWVP",
|
||||
"link": "_worldViewProjectionMatrix"
|
||||
},
|
||||
{
|
||||
"name": "invVP",
|
||||
"link": "_inverseViewProjectionMatrix"
|
||||
},
|
||||
{
|
||||
"name": "probeVP",
|
||||
"link": "_probeViewProjectionMatrix"
|
||||
},
|
||||
{
|
||||
"name": "proben",
|
||||
"link": "_probeNormal"
|
||||
}
|
||||
],
|
||||
"vertex_shader": "../include/pass_volume.vert.glsl",
|
||||
"fragment_shader": "probe_planar.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
457
leenkx/Shaders/smaa_blend_weight/smaa_blend_weight.frag.glsl
Normal file
@ -0,0 +1,457 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
#define SMAA_MAX_SEARCH_STEPS_DIAG 8
|
||||
#define SMAA_AREATEX_MAX_DISTANCE 16
|
||||
#define SMAA_AREATEX_MAX_DISTANCE_DIAG 20
|
||||
#define SMAA_AREATEX_PIXEL_SIZE (1.0 / vec2(160.0, 560.0))
|
||||
#define SMAA_AREATEX_SUBTEX_SIZE (1.0 / 7.0)
|
||||
#define SMAA_SEARCHTEX_SIZE vec2(66.0, 33.0)
|
||||
#define SMAA_SEARCHTEX_PACKED_SIZE vec2(64.0, 16.0)
|
||||
#define SMAA_CORNER_ROUNDING 25
|
||||
#define SMAA_CORNER_ROUNDING_NORM (float(SMAA_CORNER_ROUNDING) / 100.0)
|
||||
#define SMAA_AREATEX_SELECT(sample) sample.rg
|
||||
#define SMAA_SEARCHTEX_SELECT(sample) sample.r
|
||||
#define mad(a, b, c) (a * b + c)
|
||||
#define saturate(a) clamp(a, 0.0, 1.0)
|
||||
#define round(a) floor(a + 0.5)
|
||||
|
||||
uniform sampler2D edgesTex;
|
||||
uniform sampler2D areaTex;
|
||||
uniform sampler2D searchTex;
|
||||
|
||||
uniform vec2 screenSize;
|
||||
uniform vec2 screenSizeInv;
|
||||
|
||||
in vec2 texCoord;
|
||||
in vec2 pixcoord;
|
||||
in vec4 offset0;
|
||||
in vec4 offset1;
|
||||
in vec4 offset2;
|
||||
out vec4 fragColor;
|
||||
|
||||
// Blending Weight Calculation Pixel Shader (Second Pass)
|
||||
vec2 cdw_end;
|
||||
|
||||
vec4 textureLodA(sampler2D tex, vec2 coord, float lod) {
|
||||
#ifdef _InvY
|
||||
coord.y = 1.0 - coord.y;
|
||||
#endif
|
||||
return textureLod(tex, coord, lod);
|
||||
}
|
||||
|
||||
#define SMAASampleLevelZeroOffset(tex, coord, offset) textureLodA(tex, coord + offset * screenSizeInv.xy, 0.0)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Diagonal Search Functions
|
||||
|
||||
// #if !defined(SMAA_DISABLE_DIAG_DETECTION)
|
||||
/**
|
||||
* Allows to decode two binary values from a bilinear-filtered access.
|
||||
*/
|
||||
vec2 SMAADecodeDiagBilinearAccess(vec2 e) {
|
||||
// Bilinear access for fetching 'e' have a 0.25 offset, and we are
|
||||
// interested in the R and G edges:
|
||||
//
|
||||
// +---G---+-------+
|
||||
// | x o R x |
|
||||
// +-------+-------+
|
||||
//
|
||||
// Then, if one of these edge is enabled:
|
||||
// Red: (0.75 * X + 0.25 * 1) => 0.25 or 1.0
|
||||
// Green: (0.75 * 1 + 0.25 * X) => 0.75 or 1.0
|
||||
//
|
||||
// This function will unpack the values (mad + mul + round):
|
||||
// wolframalpha.com: round(x * abs(5 * x - 5 * 0.75)) plot 0 to 1
|
||||
e.r = e.r * abs(5.0 * e.r - 5.0 * 0.75);
|
||||
return round(e);
|
||||
}
|
||||
|
||||
vec4 SMAADecodeDiagBilinearAccess(vec4 e) {
|
||||
e.rb = e.rb * abs(5.0 * e.rb - 5.0 * 0.75);
|
||||
return round(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* These functions allows to perform diagonal pattern searches.
|
||||
*/
|
||||
vec2 SMAASearchDiag1(vec2 texcoord, vec2 dir/*, out vec2 e*/) {
|
||||
vec4 coord = vec4(texcoord, -1.0, 1.0);
|
||||
vec3 t = vec3(screenSizeInv.xy, 1.0);
|
||||
float cw = coord.w; // TODO: krafix hlsl bug
|
||||
while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) && cw > 0.9) {
|
||||
coord.xyz = mad(t, vec3(dir, 1.0), coord.xyz);
|
||||
cdw_end /*e*/ = textureLodA(edgesTex, coord.xy, 0.0).rg;
|
||||
cw = dot(cdw_end /*e*/, vec2(0.5, 0.5));
|
||||
}
|
||||
coord.w = cw;
|
||||
return coord.zw;
|
||||
}
|
||||
|
||||
vec2 SMAASearchDiag2(vec2 texcoord, vec2 dir) {
|
||||
vec4 coord = vec4(texcoord, -1.0, 1.0);
|
||||
coord.x += 0.25 * screenSizeInv.x; // See @SearchDiag2Optimization
|
||||
vec3 t = vec3(screenSizeInv.xy, 1.0);
|
||||
float cw = coord.w; // TODO: krafix hlsl bug
|
||||
while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) && cw > 0.9) {
|
||||
coord.xyz = mad(t, vec3(dir, 1.0), coord.xyz);
|
||||
// @SearchDiag2Optimization
|
||||
// Fetch both edges at once using bilinear filtering:
|
||||
cdw_end /*e*/ = textureLodA(edgesTex, coord.xy, 0.0).rg;
|
||||
cdw_end /*e*/ = SMAADecodeDiagBilinearAccess(cdw_end /*e*/);
|
||||
cw = dot(cdw_end /*e*/, vec2(0.5, 0.5));
|
||||
}
|
||||
coord.w = cw;
|
||||
return coord.zw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to SMAAArea, this calculates the area corresponding to a certain
|
||||
* diagonal distance and crossing edges 'e'.
|
||||
*/
|
||||
vec2 SMAAAreaDiag(vec2 dist, vec2 e, float offset) {
|
||||
vec2 texcoord = mad(vec2(SMAA_AREATEX_MAX_DISTANCE_DIAG, SMAA_AREATEX_MAX_DISTANCE_DIAG), e, dist);
|
||||
|
||||
// We do a scale and bias for mapping to texel space:
|
||||
texcoord = mad(SMAA_AREATEX_PIXEL_SIZE, texcoord, 0.5 * SMAA_AREATEX_PIXEL_SIZE);
|
||||
|
||||
// Diagonal areas are on the second half of the texture:
|
||||
texcoord.x += 0.5;
|
||||
|
||||
// Move to proper place, according to the subpixel offset:
|
||||
texcoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset;
|
||||
|
||||
// Do it!
|
||||
return SMAA_AREATEX_SELECT(textureLod(areaTex, texcoord, 0.0));
|
||||
}
|
||||
|
||||
/**
|
||||
* This searches for diagonal patterns and returns the corresponding weights.
|
||||
*/
|
||||
vec2 SMAACalculateDiagWeights(vec2 texcoord, vec2 e, vec4 subsampleIndices) {
|
||||
vec2 weights = vec2(0.0, 0.0);
|
||||
|
||||
// Search for the line ends:
|
||||
vec4 d;
|
||||
if (e.r > 0.0) {
|
||||
d.xz = SMAASearchDiag1(texcoord, vec2(-1.0, 1.0)/*, cdw_end*/);
|
||||
float dadd = cdw_end.y > 0.9 ? 1.0 : 0.0;
|
||||
d.x += dadd;
|
||||
}
|
||||
else {
|
||||
d.xz = vec2(0.0, 0.0);
|
||||
}
|
||||
d.yw = SMAASearchDiag1(texcoord, vec2(1.0, -1.0)/*, cdw_end*/);
|
||||
|
||||
//SMAA_BRANCH
|
||||
if (d.x + d.y > 2.0) { // d.x + d.y + 1 > 3
|
||||
// Fetch the crossing edges:
|
||||
vec4 coords = mad(vec4(-d.x + 0.25, d.x, d.y, -d.y - 0.25), screenSizeInv.xyxy, texcoord.xyxy);
|
||||
vec4 c;
|
||||
|
||||
c.xy = SMAASampleLevelZeroOffset(edgesTex, coords.xy, ivec2(-1, 0)).rg;
|
||||
c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, ivec2( 1, 0)).rg;
|
||||
c.yxwz = SMAADecodeDiagBilinearAccess(c.xyzw);
|
||||
|
||||
// Merge crossing edges at each side into a single value:
|
||||
vec2 cc = mad(vec2(2.0, 2.0), c.xz, c.yw);
|
||||
|
||||
// Remove the crossing edge if we didn't found the end of the line:
|
||||
// SMAAMovc(bvec2(step(0.9, d.zw)), cc, vec2(0.0, 0.0));
|
||||
float a1condx = step(0.9, d.z);
|
||||
float a1condy = step(0.9, d.w);
|
||||
if (a1condx == 1.0) cc.x = 0.0;
|
||||
if (a1condy == 1.0) cc.y = 0.0;
|
||||
|
||||
// Fetch the areas for this line:
|
||||
weights += SMAAAreaDiag(d.xy, cc, subsampleIndices.z);
|
||||
}
|
||||
|
||||
// Search for the line ends:
|
||||
d.xz = SMAASearchDiag2(texcoord, vec2(-1.0, -1.0)/*, cdw_end*/);
|
||||
if (SMAASampleLevelZeroOffset(edgesTex, texcoord, ivec2(1, 0)).r > 0.0) {
|
||||
d.yw = SMAASearchDiag2(texcoord, vec2(1.0, 1.0)/*, cdw_end*/);
|
||||
float dadd = cdw_end.y > 0.9 ? 1.0 : 0.0;
|
||||
d.y += dadd;
|
||||
}
|
||||
else {
|
||||
d.yw = vec2(0.0, 0.0);
|
||||
}
|
||||
|
||||
// SMAA_BRANCH
|
||||
if (d.x + d.y > 2.0) { // d.x + d.y + 1 > 3
|
||||
// Fetch the crossing edges:
|
||||
vec4 coords = mad(vec4(-d.x, -d.x, d.y, d.y), screenSizeInv.xyxy, texcoord.xyxy);
|
||||
vec4 c;
|
||||
c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy, ivec2(-1, 0)).g;
|
||||
c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy, ivec2( 0, -1)).r;
|
||||
c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, ivec2( 1, 0)).gr;
|
||||
vec2 cc = mad(vec2(2.0, 2.0), c.xz, c.yw);
|
||||
|
||||
// Remove the crossing edge if we didn't found the end of the line:
|
||||
// SMAAMovc(bvec2(step(0.9, d.zw)), cc, vec2(0.0, 0.0));
|
||||
float a1condx = step(0.9, d.z);
|
||||
float a1condy = step(0.9, d.w);
|
||||
if (a1condx == 1.0) cc.x = 0.0;
|
||||
if (a1condy == 1.0) cc.y = 0.0;
|
||||
|
||||
// Fetch the areas for this line:
|
||||
weights += SMAAAreaDiag(d.xy, cc, subsampleIndices.w).gr;
|
||||
}
|
||||
|
||||
return weights;
|
||||
}
|
||||
// #endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Horizontal/Vertical Search Functions
|
||||
|
||||
/**
|
||||
* This allows to determine how much length should we add in the last step
|
||||
* of the searches. It takes the bilinearly interpolated edge (see
|
||||
* @PSEUDO_GATHER4), and adds 0, 1 or 2, depending on which edges and
|
||||
* crossing edges are active.
|
||||
*/
|
||||
float SMAASearchLength(vec2 e, float offset) {
|
||||
// The texture is flipped vertically, with left and right cases taking half
|
||||
// of the space horizontally:
|
||||
vec2 scale = SMAA_SEARCHTEX_SIZE * vec2(0.5, -1.0);
|
||||
vec2 bias = SMAA_SEARCHTEX_SIZE * vec2(offset, 1.0);
|
||||
|
||||
// Scale and bias to access texel centers:
|
||||
scale += vec2(-1.0, 1.0);
|
||||
bias += vec2( 0.5, -0.5);
|
||||
|
||||
// Convert from pixel coordinates to texcoords:
|
||||
// (We use SMAA_SEARCHTEX_PACKED_SIZE because the texture is cropped)
|
||||
scale *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE;
|
||||
bias *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE;
|
||||
|
||||
vec2 coord = mad(scale, e, bias);
|
||||
|
||||
// Lookup the search texture:
|
||||
return SMAA_SEARCHTEX_SELECT(textureLod(searchTex, coord, 0.0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Horizontal/vertical search functions for the 2nd pass.
|
||||
*/
|
||||
float SMAASearchXLeft(vec2 texcoord, float end) {
|
||||
/**
|
||||
* @PSEUDO_GATHER4
|
||||
* This texcoord has been offset by (-0.25, -0.125) in the vertex shader to
|
||||
* sample between edge, thus fetching four edges in a row.
|
||||
* Sampling with different offsets in each direction allows to disambiguate
|
||||
* which edges are active from the four fetched ones.
|
||||
*/
|
||||
vec2 e = vec2(0.0, 1.0);
|
||||
while (texcoord.x > end &&
|
||||
e.g > 0.8281 && // Is there some edge not activated?
|
||||
e.r == 0.0) { // Or is there a crossing edge that breaks the line?
|
||||
e = textureLodA(edgesTex, texcoord, 0.0).rg;
|
||||
texcoord = mad(-vec2(2.0, 0.0), screenSizeInv.xy, texcoord);
|
||||
}
|
||||
|
||||
float offset = mad(-(255.0 / 127.0), SMAASearchLength(e, 0.0), 3.25);
|
||||
return mad(screenSizeInv.x, offset, texcoord.x);
|
||||
}
|
||||
|
||||
float SMAASearchXRight(vec2 texcoord, float end) {
|
||||
vec2 e = vec2(0.0, 1.0);
|
||||
while (texcoord.x < end &&
|
||||
e.g > 0.8281 && // Is there some edge not activated?
|
||||
e.r == 0.0) { // Or is there a crossing edge that breaks the line?
|
||||
e = textureLodA(edgesTex, texcoord, 0.0).rg;
|
||||
texcoord = mad(vec2(2.0, 0.0), screenSizeInv.xy, texcoord);
|
||||
}
|
||||
|
||||
float offset = mad(-(255.0 / 127.0), SMAASearchLength(e, 0.5), 3.25);
|
||||
return mad(-screenSizeInv.x, offset, texcoord.x);
|
||||
}
|
||||
|
||||
float SMAASearchYUp(vec2 texcoord, float end) {
|
||||
vec2 e = vec2(1.0, 0.0);
|
||||
while (texcoord.y > end &&
|
||||
e.r > 0.8281 && // Is there some edge not activated?
|
||||
e.g == 0.0) { // Or is there a crossing edge that breaks the line?
|
||||
e = textureLodA(edgesTex, texcoord, 0.0).rg;
|
||||
texcoord = mad(-vec2(0.0, 2.0), screenSizeInv.xy, texcoord);
|
||||
}
|
||||
float offset = mad(-(255.0 / 127.0), SMAASearchLength(e.gr, 0.0), 3.25);
|
||||
return mad(screenSizeInv.y, offset, texcoord.y);
|
||||
}
|
||||
|
||||
float SMAASearchYDown(vec2 texcoord, float end) {
|
||||
vec2 e = vec2(1.0, 0.0);
|
||||
while (texcoord.y < end &&
|
||||
e.r > 0.8281 && // Is there some edge not activated?
|
||||
e.g == 0.0) { // Or is there a crossing edge that breaks the line?
|
||||
e = textureLodA(edgesTex, texcoord, 0.0).rg;
|
||||
texcoord = mad(vec2(0.0, 2.0), screenSizeInv.xy, texcoord);
|
||||
}
|
||||
float offset = mad(-(255.0 / 127.0), SMAASearchLength(/*searchTex,*/ e.gr, 0.5), 3.25);
|
||||
return mad(-screenSizeInv.y, offset, texcoord.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ok, we have the distance and both crossing edges. So, what are the areas
|
||||
* at each side of current edge?
|
||||
*/
|
||||
vec2 SMAAArea(vec2 dist, float e1, float e2, float offset) {
|
||||
// Rounding prevents precision errors of bilinear filtering:
|
||||
vec2 texcoord = mad(vec2(SMAA_AREATEX_MAX_DISTANCE, SMAA_AREATEX_MAX_DISTANCE), round(4.0 * vec2(e1, e2)), dist);
|
||||
|
||||
// We do a scale and bias for mapping to texel space:
|
||||
texcoord = mad(SMAA_AREATEX_PIXEL_SIZE, texcoord, 0.5 * SMAA_AREATEX_PIXEL_SIZE);
|
||||
|
||||
// Move to proper place, according to the subpixel offset:
|
||||
texcoord.y = mad(SMAA_AREATEX_SUBTEX_SIZE, offset, texcoord.y);
|
||||
|
||||
// Do it!
|
||||
return SMAA_AREATEX_SELECT(textureLod(areaTex, texcoord, 0.0));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Corner Detection Functions
|
||||
|
||||
vec2 SMAADetectHorizontalCornerPattern(vec2 weights, vec4 texcoord, vec2 d) {
|
||||
// #if !defined(SMAA_DISABLE_CORNER_DETECTION)
|
||||
vec2 leftRight = step(d.xy, d.yx);
|
||||
vec2 rounding = (1.0 - SMAA_CORNER_ROUNDING_NORM) * leftRight;
|
||||
|
||||
rounding /= leftRight.x + leftRight.y; // Reduce blending for pixels in the center of a line.
|
||||
|
||||
vec2 factor = vec2(1.0, 1.0);
|
||||
factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, ivec2(0, 1)).r;
|
||||
factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, ivec2(1, 1)).r;
|
||||
factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, ivec2(0, -2)).r;
|
||||
factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, ivec2(1, -2)).r;
|
||||
|
||||
weights *= saturate(factor);
|
||||
return weights; //
|
||||
// #endif
|
||||
}
|
||||
|
||||
vec2 SMAADetectVerticalCornerPattern(vec2 weights, vec4 texcoord, vec2 d) {
|
||||
//#if !defined(SMAA_DISABLE_CORNER_DETECTION)
|
||||
vec2 leftRight = step(d.xy, d.yx);
|
||||
vec2 rounding = (1.0 - SMAA_CORNER_ROUNDING_NORM) * leftRight;
|
||||
|
||||
rounding /= leftRight.x + leftRight.y;
|
||||
|
||||
vec2 factor = vec2(1.0, 1.0);
|
||||
factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, ivec2( 1, 0)).g;
|
||||
factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, ivec2( 1, 1)).g;
|
||||
factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, ivec2(-2, 0)).g;
|
||||
factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, ivec2(-2, 1)).g;
|
||||
|
||||
weights *= saturate(factor);
|
||||
return weights; //
|
||||
// #endif
|
||||
}
|
||||
|
||||
|
||||
vec4 SMAABlendingWeightCalculationPS(vec2 texcoord, vec2 pixcoord,
|
||||
vec4 subsampleIndices) { // Just pass zero for SMAA 1x, see @SUBSAMPLE_INDICES.
|
||||
vec4 weights = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
vec2 e = textureLodA(edgesTex, texcoord, 0.0).rg;
|
||||
|
||||
//SMAA_BRANCH
|
||||
if (e.g > 0.0) { // Edge at north
|
||||
//#if !defined(SMAA_DISABLE_DIAG_DETECTION)
|
||||
// Diagonals have both north and west edges, so searching for them in
|
||||
// one of the boundaries is enough.
|
||||
weights.rg = SMAACalculateDiagWeights(texcoord, e, subsampleIndices);
|
||||
|
||||
// We give piority to diagonals, so if we find a diagonal we skip
|
||||
// horizontal/vertical processing.
|
||||
//SMAA_BRANCH
|
||||
if (weights.r == -weights.g) { // weights.r + weights.g == 0.0
|
||||
//#endif
|
||||
|
||||
vec2 d;
|
||||
|
||||
// Find the distance to the left:
|
||||
vec3 coords;
|
||||
coords.x = SMAASearchXLeft(offset0.xy, offset2.x);
|
||||
coords.y = offset1.y; // offset[1].y = texcoord.y - 0.25 * screenSizeInv.y (@CROSSING_OFFSET)
|
||||
d.x = coords.x;
|
||||
|
||||
// Now fetch the left crossing edges, two at a time using bilinear
|
||||
// filtering. Sampling at -0.25 (see @CROSSING_OFFSET) enables to
|
||||
// discern what value each edge has:
|
||||
float e1 = textureLodA(edgesTex, coords.xy, 0.0).r;
|
||||
|
||||
// Find the distance to the right:
|
||||
coords.z = SMAASearchXRight(offset0.zw, offset2.y);
|
||||
d.y = coords.z;
|
||||
|
||||
// We want the distances to be in pixel units (doing this here allow to
|
||||
// better interleave arithmetic and memory accesses):
|
||||
d = abs(round(mad(screenSize.xx, d, -pixcoord.xx)));
|
||||
|
||||
// SMAAArea below needs a sqrt, as the areas texture is compressed
|
||||
// quadratically:
|
||||
vec2 sqrt_d = sqrt(d);
|
||||
|
||||
// Fetch the right crossing edges:
|
||||
float e2 = SMAASampleLevelZeroOffset(edgesTex, coords.zy, ivec2(1, 0)).r;
|
||||
|
||||
// Ok, we know how this pattern looks like, now it is time for getting
|
||||
// the actual area:
|
||||
weights.rg = SMAAArea(sqrt_d, e1, e2, subsampleIndices.y);
|
||||
|
||||
// Fix corners:
|
||||
coords.y = texcoord.y;
|
||||
weights.rg = SMAADetectHorizontalCornerPattern(weights.rg, coords.xyzy, d);
|
||||
|
||||
//#if !defined(SMAA_DISABLE_DIAG_DETECTION)
|
||||
}
|
||||
else {
|
||||
e.r = 0.0; // Skip vertical processing.
|
||||
}
|
||||
//#endif
|
||||
}
|
||||
|
||||
//SMAA_BRANCH
|
||||
if (e.r > 0.0) { // Edge at west
|
||||
vec2 d;
|
||||
|
||||
// Find the distance to the top:
|
||||
vec3 coords;
|
||||
coords.y = SMAASearchYUp(/*edgesTex, searchTex,*/ offset1.xy, offset2.z);
|
||||
coords.x = offset0.x; // offset[1].x = texcoord.x - 0.25 * screenSizeInv.x;
|
||||
d.x = coords.y;
|
||||
|
||||
// Fetch the top crossing edges:
|
||||
float e1 = textureLodA(edgesTex, coords.xy, 0.0).g;
|
||||
|
||||
// Find the distance to the bottom:
|
||||
coords.z = SMAASearchYDown(offset1.zw, offset2.w);
|
||||
d.y = coords.z;
|
||||
|
||||
// We want the distances to be in pixel units:
|
||||
d = abs(round(mad(screenSize.yy, d, -pixcoord.yy)));
|
||||
|
||||
// SMAAArea below needs a sqrt, as the areas texture is compressed
|
||||
// quadratically:
|
||||
vec2 sqrt_d = sqrt(d);
|
||||
|
||||
// Fetch the bottom crossing edges:
|
||||
float e2 = SMAASampleLevelZeroOffset(edgesTex, coords.xz, ivec2(0, 1)).g;
|
||||
|
||||
// Get the area for this direction:
|
||||
weights.ba = SMAAArea(sqrt_d, e1, e2, subsampleIndices.x);
|
||||
|
||||
// Fix corners:
|
||||
coords.x = texcoord.x;
|
||||
weights.ba = SMAADetectVerticalCornerPattern(weights.ba, coords.xyxz, d);
|
||||
}
|
||||
|
||||
return weights;
|
||||
}
|
||||
|
||||
void main() {
|
||||
fragColor = SMAABlendingWeightCalculationPS(texCoord, pixcoord, vec4(0.0));
|
||||
}
|
31
leenkx/Shaders/smaa_blend_weight/smaa_blend_weight.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "smaa_blend_weight",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "areaTex",
|
||||
"link": "$smaa_area.png"
|
||||
},
|
||||
{
|
||||
"name": "searchTex",
|
||||
"link": "$smaa_search.png"
|
||||
},
|
||||
{
|
||||
"name": "screenSize",
|
||||
"link": "_screenSize"
|
||||
},
|
||||
{
|
||||
"name": "screenSizeInv",
|
||||
"link": "_screenSizeInv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "smaa_blend_weight.vert.glsl",
|
||||
"fragment_shader": "smaa_blend_weight.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
36
leenkx/Shaders/smaa_blend_weight/smaa_blend_weight.vert.glsl
Normal file
@ -0,0 +1,36 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
|
||||
in vec2 pos;
|
||||
|
||||
uniform vec2 screenSize;
|
||||
uniform vec2 screenSizeInv;
|
||||
|
||||
out vec2 texCoord;
|
||||
out vec2 pixcoord;
|
||||
out vec4 offset0;
|
||||
out vec4 offset1;
|
||||
out vec4 offset2;
|
||||
|
||||
const int SMAA_MAX_SEARCH_STEPS = 16;
|
||||
|
||||
void main() {
|
||||
// Scale vertex attribute to [0-1] range
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
texCoord = pos.xy * madd + madd;
|
||||
|
||||
// Blend Weight Calculation Vertex Shader
|
||||
pixcoord = texCoord * screenSize;
|
||||
|
||||
// We will use these offsets for the searches later on (see @PSEUDO_GATHER4):
|
||||
offset0 = screenSizeInv.xyxy * vec4(-0.25, -0.125, 1.25, -0.125) + texCoord.xyxy;
|
||||
offset1 = screenSizeInv.xyxy * vec4(-0.125, -0.25, -0.125, 1.25) + texCoord.xyxy;
|
||||
|
||||
// And these for the searches, they indicate the ends of the loops:
|
||||
offset2 = screenSizeInv.xxyy *
|
||||
(vec4(-2.0, 2.0, -2.0, 2.0) * float(SMAA_MAX_SEARCH_STEPS)) +
|
||||
vec4(offset0.xz, offset1.yw);
|
||||
|
||||
gl_Position = vec4(pos.xy, 0.0, 1.0);
|
||||
}
|
207
leenkx/Shaders/smaa_edge_detect/smaa_edge_detect.frag.glsl
Normal file
@ -0,0 +1,207 @@
|
||||
/**
|
||||
* Copyright (C) 2013 Jorge Jimenez (jorge@iryoku.com)
|
||||
* Copyright (C) 2013 Jose I. Echevarria (joseignacioechevarria@gmail.com)
|
||||
* Copyright (C) 2013 Belen Masia (bmasia@unizar.es)
|
||||
* Copyright (C) 2013 Fernando Navarro (fernandn@microsoft.com)
|
||||
* Copyright (C) 2013 Diego Gutierrez (diegog@unizar.es)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to
|
||||
* do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software. As clarification, there
|
||||
* is no requirement that the copyright notice and permission be included in
|
||||
* binary distributions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* _______ ___ ___ ___ ___
|
||||
* / || \/ | / \ / \
|
||||
* | (---- | \ / | / ^ \ / ^ \
|
||||
* \ \ | |\/| | / /_\ \ / /_\ \
|
||||
* ----) | | | | | / _____ \ / _____ \
|
||||
* |_______/ |__| |__| /__/ \__\ /__/ \__\
|
||||
*
|
||||
* E N H A N C E D
|
||||
* S U B P I X E L M O R P H O L O G I C A L A N T I A L I A S I N G
|
||||
*
|
||||
* http://www.iryoku.com/smaa/
|
||||
*/
|
||||
#version 450
|
||||
|
||||
#define SMAA_THRESHOLD 0.1
|
||||
#define SMAA_DEPTH_THRESHOLD (0.1 * SMAA_THRESHOLD) // For depth edge detection, depends on the depth range of the scene
|
||||
#define SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR 2.0
|
||||
|
||||
uniform sampler2D colorTex;
|
||||
|
||||
in vec2 texCoord;
|
||||
in vec4 offset0;
|
||||
in vec4 offset1;
|
||||
in vec4 offset2;
|
||||
out vec4 fragColor;
|
||||
|
||||
// Misc functions
|
||||
// Gathers current pixel, and the top-left neighbors.
|
||||
// vec3 SMAAGatherNeighbours(vec2 texcoord/*, vec4 offset[3], sampler2D tex*/) {
|
||||
// float P = textureLod(tex, texcoord, 0.0).r;
|
||||
// float Pleft = textureLod(tex, offset0.xy, 0.0).r;
|
||||
// float Ptop = textureLod(tex, offset0.zw, 0.0).r;
|
||||
// return vec3(P, Pleft, Ptop);
|
||||
// }
|
||||
|
||||
// Edge Detection Pixel Shaders (First Pass)
|
||||
// Adjusts the threshold by means of predication.
|
||||
// vec2 SMAACalculatePredicatedThreshold(vec2 texcoord, vec4 offset[3], sampler2D predicationTex) {
|
||||
// vec3 neighbours = SMAAGatherNeighbours(texcoord, offset, predicationTex);
|
||||
// vec2 delta = abs(neighbours.xx - neighbours.yz);
|
||||
// vec2 edges = step(SMAA_PREDICATION_THRESHOLD, delta);
|
||||
// return SMAA_PREDICATION_SCALE * SMAA_THRESHOLD * (1.0 - SMAA_PREDICATION_STRENGTH * edges);
|
||||
// }
|
||||
|
||||
// Luma Edge Detection
|
||||
// IMPORTANT NOTICE: luma edge detection requires gamma-corrected colors, and
|
||||
// thus 'colorTex' should be a non-sRGB texture.
|
||||
vec2 SMAALumaEdgeDetectionPS(vec2 texcoord
|
||||
//#if SMAA_PREDICATION
|
||||
//, sampler2D predicationTex
|
||||
//#endif
|
||||
) {
|
||||
// Calculate the threshold:
|
||||
//#if SMAA_PREDICATION
|
||||
//vec2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, SMAATexturePass2D(predicationTex));
|
||||
//#else
|
||||
vec2 threshold = vec2(SMAA_THRESHOLD, SMAA_THRESHOLD);
|
||||
//#endif
|
||||
|
||||
// Calculate lumas:
|
||||
vec3 weights = vec3(0.2126, 0.7152, 0.0722);
|
||||
float L = dot(textureLod(colorTex, texcoord, 0.0).rgb, weights);
|
||||
|
||||
float Lleft = dot(textureLod(colorTex, offset0.xy, 0.0).rgb, weights);
|
||||
float Ltop = dot(textureLod(colorTex, offset0.zw, 0.0).rgb, weights);
|
||||
|
||||
// We do the usual threshold:
|
||||
vec4 delta;
|
||||
delta.xy = abs(L - vec2(Lleft, Ltop));
|
||||
vec2 edges = step(threshold, delta.xy);
|
||||
|
||||
// Then discard if there is no edge:
|
||||
if (dot(edges, vec2(1.0, 1.0)) == 0.0)
|
||||
discard;
|
||||
|
||||
// Calculate right and bottom deltas:
|
||||
float Lright = dot(textureLod(colorTex, offset1.xy, 0.0).rgb, weights);
|
||||
float Lbottom = dot(textureLod(colorTex, offset1.zw, 0.0).rgb, weights);
|
||||
delta.zw = abs(L - vec2(Lright, Lbottom));
|
||||
|
||||
// Calculate the maximum delta in the direct neighborhood:
|
||||
vec2 maxDelta = max(delta.xy, delta.zw);
|
||||
|
||||
// Calculate left-left and top-top deltas:
|
||||
float Lleftleft = dot(textureLod(colorTex, offset2.xy, 0.0).rgb, weights);
|
||||
float Ltoptop = dot(textureLod(colorTex, offset2.zw, 0.0).rgb, weights);
|
||||
delta.zw = abs(vec2(Lleft, Ltop) - vec2(Lleftleft, Ltoptop));
|
||||
|
||||
// Calculate the final maximum delta:
|
||||
maxDelta = max(maxDelta.xy, delta.zw);
|
||||
float finalDelta = max(maxDelta.x, maxDelta.y);
|
||||
|
||||
// Local contrast adaptation:
|
||||
edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
|
||||
|
||||
return edges;
|
||||
}
|
||||
|
||||
// Color Edge Detection
|
||||
// IMPORTANT NOTICE: color edge detection requires gamma-corrected colors, and
|
||||
// thus 'colorTex' should be a non-sRGB texture.
|
||||
vec2 SMAAColorEdgeDetectionPS(vec2 texcoord
|
||||
//#if SMAA_PREDICATION
|
||||
//, sampler2D predicationTex
|
||||
//#endif
|
||||
) {
|
||||
// Calculate the threshold:
|
||||
//#if SMAA_PREDICATION
|
||||
//vec2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, predicationTex);
|
||||
//#else
|
||||
vec2 threshold = vec2(SMAA_THRESHOLD, SMAA_THRESHOLD);
|
||||
//#endif
|
||||
|
||||
// Calculate color deltas:
|
||||
vec4 delta;
|
||||
vec3 C = textureLod(colorTex, texcoord, 0.0).rgb;
|
||||
|
||||
vec3 Cleft = textureLod(colorTex, offset0.xy, 0.0).rgb;
|
||||
vec3 t = abs(C - Cleft);
|
||||
delta.x = max(max(t.r, t.g), t.b);
|
||||
|
||||
vec3 Ctop = textureLod(colorTex, offset0.zw, 0.0).rgb;
|
||||
t = abs(C - Ctop);
|
||||
delta.y = max(max(t.r, t.g), t.b);
|
||||
|
||||
// We do the usual threshold:
|
||||
vec2 edges = step(threshold, delta.xy);
|
||||
|
||||
// Then discard if there is no edge:
|
||||
if (dot(edges, vec2(1.0, 1.0)) == 0.0)
|
||||
discard;
|
||||
|
||||
// Calculate right and bottom deltas:
|
||||
vec3 Cright = textureLod(colorTex, offset1.xy, 0.0).rgb;
|
||||
t = abs(C - Cright);
|
||||
delta.z = max(max(t.r, t.g), t.b);
|
||||
|
||||
vec3 Cbottom = textureLod(colorTex, offset1.zw, 0.0).rgb;
|
||||
t = abs(C - Cbottom);
|
||||
delta.w = max(max(t.r, t.g), t.b);
|
||||
|
||||
// Calculate the maximum delta in the direct neighborhood:
|
||||
vec2 maxDelta = max(delta.xy, delta.zw);
|
||||
|
||||
// Calculate left-left and top-top deltas:
|
||||
vec3 Cleftleft = textureLod(colorTex, offset2.xy, 0.0).rgb;
|
||||
t = abs(C - Cleftleft);
|
||||
delta.z = max(max(t.r, t.g), t.b);
|
||||
|
||||
vec3 Ctoptop = textureLod(colorTex, offset2.zw, 0.0).rgb;
|
||||
t = abs(C - Ctoptop);
|
||||
delta.w = max(max(t.r, t.g), t.b);
|
||||
|
||||
// Calculate the final maximum delta:
|
||||
maxDelta = max(maxDelta.xy, delta.zw);
|
||||
float finalDelta = max(maxDelta.x, maxDelta.y);
|
||||
|
||||
// Local contrast adaptation:
|
||||
edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
|
||||
|
||||
return edges;
|
||||
}
|
||||
|
||||
// Depth Edge Detection
|
||||
// vec2 SMAADepthEdgeDetectionPS(vec2 texcoord, /*vec4 offset[3],*/ sampler2D depthTex) {
|
||||
// vec3 neighbours = SMAAGatherNeighbours(texcoord, /*offset,*/ depthTex);
|
||||
// vec2 delta = abs(neighbours.xx - vec2(neighbours.y, neighbours.z));
|
||||
// vec2 edges = step(SMAA_DEPTH_THRESHOLD, delta);
|
||||
|
||||
// if (dot(edges, vec2(1.0, 1.0)) == 0.0)
|
||||
// discard;
|
||||
|
||||
// return edges;
|
||||
// }
|
||||
|
||||
void main() {
|
||||
fragColor.rg = SMAAColorEdgeDetectionPS(texCoord);
|
||||
}
|
19
leenkx/Shaders/smaa_edge_detect/smaa_edge_detect.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "smaa_edge_detect",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "screenSizeInv",
|
||||
"link": "_screenSizeInv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "smaa_edge_detect.vert.glsl",
|
||||
"fragment_shader": "smaa_edge_detect.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
33
leenkx/Shaders/smaa_edge_detect/smaa_edge_detect.vert.glsl
Normal file
@ -0,0 +1,33 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
|
||||
in vec2 pos;
|
||||
|
||||
uniform vec2 screenSizeInv;
|
||||
|
||||
out vec2 texCoord;
|
||||
out vec4 offset0;
|
||||
out vec4 offset1;
|
||||
out vec4 offset2;
|
||||
|
||||
#ifdef _InvY
|
||||
#define V_DIR(v) -(v)
|
||||
#else
|
||||
#define V_DIR(v) v
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
// Scale vertex attribute to [0-1] range
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
texCoord = pos.xy * madd + madd;
|
||||
#ifdef _InvY
|
||||
texCoord.y = 1.0 - texCoord.y;
|
||||
#endif
|
||||
|
||||
offset0 = screenSizeInv.xyxy * vec4(-1.0, 0.0, 0.0, V_DIR(-1.0)) + texCoord.xyxy;
|
||||
offset1 = screenSizeInv.xyxy * vec4( 1.0, 0.0, 0.0, V_DIR(1.0)) + texCoord.xyxy;
|
||||
offset2 = screenSizeInv.xyxy * vec4(-2.0, 0.0, 0.0, V_DIR(-2.0)) + texCoord.xyxy;
|
||||
|
||||
gl_Position = vec4(pos.xy, 0.0, 1.0);
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
|
||||
uniform sampler2D colorTex;
|
||||
uniform sampler2D blendTex;
|
||||
#ifdef _Veloc
|
||||
uniform sampler2D sveloc;
|
||||
#endif
|
||||
|
||||
uniform vec2 screenSizeInv;
|
||||
|
||||
in vec2 texCoord;
|
||||
in vec4 offset;
|
||||
out vec4 fragColor;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Neighborhood Blending Pixel Shader (Third Pass)
|
||||
|
||||
vec4 textureLodA(sampler2D tex, vec2 coords, float lod) {
|
||||
#ifdef _InvY
|
||||
coords.y = 1.0 - coords.y;
|
||||
#endif
|
||||
return textureLod(tex, coords, lod);
|
||||
}
|
||||
|
||||
vec4 SMAANeighborhoodBlendingPS(vec2 texcoord, vec4 offset) {
|
||||
// Fetch the blending weights for current pixel:
|
||||
vec4 a;
|
||||
a.x = textureLod(blendTex, offset.xy, 0.0).a; // Right
|
||||
a.y = textureLod(blendTex, offset.zw, 0.0).g; // Top
|
||||
a.wz = textureLod(blendTex, texcoord, 0.0).xz; // Bottom / Left
|
||||
|
||||
// Is there any blending weight with a value greater than 0.0?
|
||||
//SMAA_BRANCH
|
||||
if (dot(a, vec4(1.0, 1.0, 1.0, 1.0)) < 1e-5) {
|
||||
vec4 color = textureLod(colorTex, texcoord, 0.0);
|
||||
|
||||
#ifdef _Veloc
|
||||
vec2 velocity = textureLod(sveloc, texCoord, 0.0).rg;
|
||||
// Pack velocity into the alpha channel:
|
||||
color.a = sqrt(5.0 * length(velocity));
|
||||
#endif
|
||||
return color;
|
||||
}
|
||||
else {
|
||||
bool h = max(a.x, a.z) > max(a.y, a.w); // max(horizontal) > max(vertical)
|
||||
|
||||
// Calculate the blending offsets:
|
||||
vec4 blendingOffset = vec4(0.0, a.y, 0.0, a.w);
|
||||
vec2 blendingWeight = a.yw;
|
||||
|
||||
if (h) {
|
||||
blendingOffset.x = a.x;
|
||||
blendingOffset.y = 0.0;
|
||||
blendingOffset.z = a.z;
|
||||
blendingOffset.w = 0.0;
|
||||
blendingWeight.x = a.x;
|
||||
blendingWeight.y = a.z;
|
||||
}
|
||||
|
||||
blendingWeight /= dot(blendingWeight, vec2(1.0, 1.0));
|
||||
|
||||
// Calculate the texture coordinates:
|
||||
#ifdef _InvY
|
||||
vec2 tc = vec2(texcoord.x, 1.0 - texcoord.y);
|
||||
#else
|
||||
vec2 tc = texcoord;
|
||||
#endif
|
||||
vec4 blendingCoord = blendingOffset * vec4(screenSizeInv.xy, -screenSizeInv.xy) + tc.xyxy;
|
||||
|
||||
// We exploit bilinear filtering to mix current pixel with the chosen
|
||||
// neighbor:
|
||||
vec4 color = blendingWeight.x * textureLodA(colorTex, blendingCoord.xy, 0.0);
|
||||
color += blendingWeight.y * textureLodA(colorTex, blendingCoord.zw, 0.0);
|
||||
|
||||
#ifdef _Veloc
|
||||
// Antialias velocity for proper reprojection in a later stage:
|
||||
vec2 velocity = blendingWeight.x * textureLodA(sveloc, blendingCoord.xy, 0.0).rg;
|
||||
velocity += blendingWeight.y * textureLodA(sveloc, blendingCoord.zw, 0.0).rg;
|
||||
|
||||
// Pack velocity into the alpha channel:
|
||||
color.a = sqrt(5.0 * length(velocity));
|
||||
#endif
|
||||
return color;
|
||||
}
|
||||
return vec4(0.0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
fragColor = SMAANeighborhoodBlendingPS(texCoord, offset);
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"contexts": [
|
||||
{
|
||||
"name": "smaa_neighborhood_blend",
|
||||
"depth_write": false,
|
||||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "screenSizeInv",
|
||||
"link": "_screenSizeInv"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "smaa_neighborhood_blend.vert.glsl",
|
||||
"fragment_shader": "smaa_neighborhood_blend.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
#version 450
|
||||
|
||||
#include "compiled.inc"
|
||||
|
||||
in vec2 pos;
|
||||
|
||||
uniform vec2 screenSizeInv;
|
||||
|
||||
out vec2 texCoord;
|
||||
out vec4 offset;
|
||||
|
||||
#ifdef _InvY
|
||||
#define V_DIR(v) -(v)
|
||||
#else
|
||||
#define V_DIR(v) v
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
// Scale vertex attribute to [0-1] range
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
texCoord = pos.xy * madd + madd;
|
||||
#ifdef _InvY
|
||||
texCoord.y = 1.0 - texCoord.y;
|
||||
#endif
|
||||
|
||||
// Neighborhood Blending Vertex Shader
|
||||
offset = screenSizeInv.xyxy * vec4(1.0, 0.0, 0.0, V_DIR(1.0)) + texCoord.xyxy;
|
||||
gl_Position = vec4(pos.xy, 0.0, 1.0);
|
||||
}
|