Update Files

This commit is contained in:
2025-01-22 16:18:30 +01:00
parent ed4603cf95
commit a36294b518
16718 changed files with 2960346 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
leenkx/Assets/brdf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 953 KiB

Binary file not shown.

Binary file not shown.

View 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

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View 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ÀIt€Hr<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>It€ItÀItÀJuÀJuĀU<C480>πT<CF80>΀T<CE80>πS<CF80>΀S̀R~ˀP|ɀO{ǀNzƀMxĀMxĀLwÀLv€Lv€Ku<4B><75>Ku<4B><75>Ku<4B><75>Ku<4B><75>Kv<4B><76>Lv€LwÀ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>

Binary file not shown.

Binary file not shown.

View 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>ހ

View 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>Հ

View 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>Հ

View 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.

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
leenkx/Assets/noise64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
leenkx/Assets/noise8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
leenkx/Assets/smaa_area.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View 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"
}
]
}

View 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"
}
]
}

View 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;
}

View 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;
}

View File

@ -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);
}

View 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"
}
]
}

View File

@ -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);
}

View File

@ -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"
}
]
}

View 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;
}

View 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"
}
]
}

View 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;
}

View 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"
}
]
}

View 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);
}

View 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"
}
]
}

View File

@ -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);
}
}

View File

@ -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"
}
]
}

View File

@ -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;
}

View File

@ -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"]
}
]
}

View File

@ -0,0 +1,8 @@
#version 450
in vec2 texCoord;
out vec4 fragColor;
void main() {
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
}

View 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"]
}
]
}

View File

@ -0,0 +1,8 @@
#version 450
in vec2 texCoord;
out vec4 fragColor;
void main() {
gl_FragDepth = 1.0;
}

View 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"]
}
]
}

View 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
}

View 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"
}
]
}

View 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
}

View 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);
}

View 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"
}
]
}

View 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);
}

View 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"
}
]
}

View 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"
}
]
}

View File

@ -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
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -0,0 +1,8 @@
#version 450
in vec3 color;
out vec4 fragColor;
void main() {
fragColor = vec4(color, 1.0);
}

View 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);
}

View 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
}

View 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
}

View 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"]
}
]
}

View 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
}

View 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"]
}
]
}

View 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
}

View File

@ -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"]
}
]
}

View 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));
}

View 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"
}
]
}

View 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;
}

View 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"
}
]
}

View 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;
}

View 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"
}
]
}

View 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);
}

View File

@ -0,0 +1,10 @@
#version 450
uniform sampler2D tex;
in vec2 texCoord;
out vec4 fragColor;
void main() {
fragColor = textureLod(tex, texCoord, 0.0);
}

View 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;
}

View 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);
}

View 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;
}

View 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;
}

View 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"
}
]
}

View File

@ -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);
}

View File

@ -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"
}
]
}

View 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;
}

View 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"
}
]
}

View 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;
}

View 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"
}
]
}

View 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));
}

View 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"
}
]
}

View 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);
}

View 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);
}

View 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"
}
]
}

View 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);
}

View File

@ -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);
}

View File

@ -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"
}
]
}

View File

@ -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);
}

Some files were not shown because too many files have changed in this diff Show More