├── .gitignore
├── README.md
├── data_prep
├── pop2018.tsv
├── population_2018.json
├── process_data.py
└── value_labels.json
├── gtag_fix.py
├── images
├── bumpy.jpeg
├── dd.jpeg
├── dnb_land_ocean_ice.2012.3600x1800.jpg
├── dot.png
├── europe.png
├── f.png
├── fathom.png
├── fathom_w_guides.png
├── home.jpg
├── nasa_blue_marble.4096.jpg
├── rust.jpg
├── trianglefan.png
├── trianglestrip.png
└── world.png
├── index.html
├── server.tool
├── shader_01
├── frag.glsl
├── index.html
├── main.js
└── vert.glsl
├── shader_02.0
├── frag.glsl
├── index.html
├── main.js
└── vert.glsl
├── shader_02.1
├── frag.glsl
├── index.html
├── main.js
└── vert.glsl
├── shader_02.2
├── frag.glsl
├── index.html
├── main.js
└── vert.glsl
├── shader_02.3
├── frag.glsl
├── index.html
├── main.js
└── vert.glsl
├── shader_03.0
├── frag.glsl
├── index.html
├── main.js
└── vert.glsl
├── shader_03.1
├── frag.glsl
├── index.html
├── main.js
└── vert.glsl
├── shader_03.2
├── frag.glsl
├── index.html
├── main.js
└── vert.glsl
├── shader_03.3
├── frag.glsl
├── index.html
├── main.js
└── vert.glsl
├── shader_03.4
├── frag.glsl
├── index.html
├── main.js
└── vert.glsl
├── shader_04.0
├── frag.glsl
├── gl-matrix-min.js
├── index.html
├── main.js
└── vert.glsl
├── shader_04.1
├── frag.glsl
├── gl-matrix-min.js
├── index.html
├── main.js
└── vert.glsl
├── shader_04.2
├── frag.glsl
├── gl-matrix-min.js
├── index.html
├── main.js
└── vert.glsl
├── shader_04.3
├── frag.glsl
├── gl-matrix-min.js
├── index.html
├── main.js
└── vert.glsl
├── shader_04.4
├── frag.glsl
├── gl-matrix-min.js
├── index.html
├── main.js
└── vert.glsl
├── shader_04.5
├── frag.glsl
├── index.html
├── main.js
└── vert.glsl
├── shader_04.6
├── frag.glsl
├── index.html
├── main.js
└── vert.glsl
├── shader_05.0
├── frag.glsl
├── gl-matrix-min.js
├── index.html
├── main.js
└── vert.glsl
├── shader_05.1
├── frag.glsl
├── gl-matrix-min.js
├── index.html
├── main.js
└── vert.glsl
├── shader_05.2
├── frag.glsl
├── gl-matrix-min.js
├── index.html
├── main.js
└── vert.glsl
├── shader_05.3
├── frag.glsl
├── gl-matrix-min.js
├── index.html
├── main.js
└── vert.glsl
├── shader_05.4
├── frag.glsl
├── gl-matrix-min.js
├── index.html
├── main.js
└── vert.glsl
├── shader_06.0
├── frag.glsl
├── gl-matrix-min.js
├── index.html
├── main.js
└── vert.glsl
├── shader_06.1
├── index.html
├── main.js
└── population_2018.json
└── shader_06.2
├── frag.glsl
├── gl-matrix-min.js
├── index.html
├── main.js
├── population_2018.json
└── vert.glsl
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Intro to Shaders
2 |
3 | This repository is a light introduction to the capabilities of WebGL shaders, as well as some of the complexities of working with them. This set of examples was initially developed for an internal workshop at Fathom Information Design, and is tailored for an audience with a wide range of coding experience. Learn more here.
4 |
5 | The examples get progressively more complex, starting with the basics of textures and images, and evolving to 3D shapes and representing data. As the examples progress, changes are flagged with a comment that reads "New:".
6 |
7 | Browsing and reading the examples can help you appreciate shaders, but if you are comfortable with some light code editing, you are strongly encouraged to edit each of them as you go. They are set up so that you can comment out and uncomment in different features and behaviors as you go.
8 |
9 | Also included is a little python webserver. If you have python on your system, you should be able to run the server.tool. It will launch a little webserver and show the examples in your browser of choice. Assuming that browser is WebGL enabled, you should be good to go.
10 |
11 |
12 | ## License
13 | ```
14 | The MIT License (MIT)
15 |
16 | Copyright (c) 2018 Fathom Information Design
17 |
18 | Permission is hereby granted, free of charge, to any person obtaining a copy
19 | of this software and associated documentation files (the "Software"), to deal
20 | in the Software without restriction, including without limitation the rights
21 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
22 | copies of the Software, and to permit persons to whom the Software is
23 | furnished to do so, subject to the following conditions:
24 |
25 | The above copyright notice and this permission notice shall be included in all
26 | copies or substantial portions of the Software.
27 |
28 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
31 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
33 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34 | SOFTWARE.
35 | ```
36 |
37 |
--------------------------------------------------------------------------------
/data_prep/pop2018.tsv:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Index Region, subregion, country or area Urban Rural Total ISO3
6 | 15 Burundi 1 462 9 755 11 216 BDI
7 | 16 Comoros 241 591 832 COM
8 | 17 Djibouti 756 216 971 DJI
9 | 18 Eritrea 2 079 3 109 5 188 ERI
10 | 19 Ethiopia 22 328 85 207 107 535 ETH
11 | 20 Kenya 13 772 37 179 50 951 KEN
12 | 21 Madagascar 9 767 16 496 26 263 MDG
13 | 22 Malawi 3 246 15 919 19 165 MWI
14 | 23 Mauritius 517 751 1 268 MUS
15 | 24 Mayotte 120 140 260 MYT
16 | 25 Mozambique 10 987 19 542 30 529 MOZ
17 | 26 Réunion 879 4 883 REU
18 | 27 Rwanda 2 152 10 350 12 501 RWA
19 | 28 Seychelles 54 41 95 SYC
20 | 29 Somalia 6 827 8 355 15 182 SOM
21 | 30 South Sudan 2 534 10 385 12 919 SSD
22 | 31 Uganda 10 525 33 745 44 271 UGA
23 | 32 United Republic of Tanzania 19 959 39 133 59 091 TZA
24 | 33 Zambia 7 664 9 946 17 609 ZMB
25 | 34 Zimbabwe 5 448 11 466 16 913 ZWE
26 | 36 Angola 20 162 10 613 30 774 AGO
27 | 37 Cameroon 13 912 10 766 24 678 CMR
28 | 38 Central African Republic 1 960 2 778 4 737 CAF
29 | 39 Chad 3 540 11 813 15 353 TCD
30 | 40 Congo 3 613 1 786 5 400 COG
31 | 41 Democratic Republic of the Congo 37 349 46 656 84 005 COD
32 | 42 Equatorial Guinea 948 366 1 314 GNQ
33 | 43 Gabon 1 848 220 2 068 GAB
34 | 44 Sao Tome and Principe 152 57 209 STP
35 | 46 Algeria 30 510 11 498 42 008 DZA
36 | 47 Egypt 42 438 56 938 99 376 EGY
37 | 48 Libya 5 183 1 288 6 471 LBY
38 | 49 Morocco 22 603 13 589 36 192 MAR
39 | 50 Sudan 14 380 27 131 41 512 SDN
40 | 51 Tunisia 8 038 3 621 11 659 TUN
41 | 52 Western Sahara 492 76 567 ESH
42 | 54 Botswana 1 620 713 2 333 BWA
43 | 55 Lesotho 637 1 626 2 263 LSO
44 | 56 Namibia 1 295 1 293 2 588 NAM
45 | 57 South Africa 38 087 19 312 57 398 ZAF
46 | 58 Swaziland 331 1 060 1 391 SWZ
47 | 60 Benin 5 434 6 052 11 486 BEN
48 | 61 Burkina Faso 5 799 13 953 19 752 BFA
49 | 62 Cabo Verde 364 190 553 CPV
50 | 63 Côte d'Ivoire 12 647 12 259 24 906 CIV
51 | 64 Gambia 1 326 838 2 164 GMB
52 | 65 Ghana 16 517 12 946 29 464 GHA
53 | 66 Guinea 4 717 8 335 13 053 GIN
54 | 67 Guinea-Bissau 827 1 080 1 907 GNB
55 | 68 Liberia 2 483 2 371 4 854 LBR
56 | 69 Mali 8 093 11 014 19 108 MLI
57 | 70 Mauritania 2 437 2 103 4 540 MRT
58 | 71 Niger 3 665 18 647 22 311 NER
59 | 72 Nigeria 98 611 97 264 195 875 NGA
60 | 73 Saint Helena 2 2 4 SHN
61 | 74 Senegal 7 690 8 605 16 294 SEN
62 | 75 Sierra Leone 3 247 4 473 7 720 SLE
63 | 76 Togo 3 332 4 659 7 991 TGO
64 | 79 China 837 022 578 024 1 415 046 CHN
65 | 80 China, Hong Kong SAR 7 429 0 7 429 HKG
66 | 81 China, Macao SAR 632 0 632 MAC
67 | 82 China, Taiwan Province of China 18 518 5 176 23 694 TWN
68 | 83 Dem. People's Republic of Korea 15 853 9 758 25 611 PRK
69 | 84 Japan 116 522 10 664 127 185 JPN
70 | 85 Mongolia 2 137 985 3 122 MNG
71 | 86 Republic of Korea 41 678 9 486 51 164 KOR
72 | 89 Kazakhstan 10 569 7 835 18 404 KAZ
73 | 90 Kyrgyzstan 2 229 3 904 6 133 KGZ
74 | 91 Tajikistan 2 471 6 636 9 107 TJK
75 | 92 Turkmenistan 3 019 2 832 5 851 TKM
76 | 93 Uzbekistan 16 337 16 028 32 365 UZB
77 | 95 Afghanistan 9 273 27 100 36 373 AFG
78 | 96 Bangladesh 60 944 105 424 166 368 BGD
79 | 97 Bhutan 334 483 817 BTN
80 | 98 India 460 780 893 272 1 354 052 IND
81 | 99 Iran (Islamic Republic of) 61 425 20 587 82 012 IRN
82 | 100 Maldives 177 267 444 MDV
83 | 101 Nepal 5 848 23 776 29 624 NPL
84 | 102 Pakistan 73 630 127 183 200 814 PAK
85 | 103 Sri Lanka 3 871 17 079 20 950 LKA
86 | 105 Brunei Darussalam 337 97 434 BRN
87 | 106 Cambodia 3 800 12 446 16 246 KHM
88 | 107 Indonesia 147 603 119 192 266 795 IDN
89 | 108 Lao People's Democratic Republic 2 437 4 524 6 961 LAO
90 | 109 Malaysia 24 364 7 679 32 042 MYS
91 | 110 Myanmar 16 468 37 387 53 856 MMR
92 | 111 Philippines 49 962 56 550 106 512 PHL
93 | 112 Singapore 5 792 0 5 792 SGP
94 | 113 Thailand 34 556 34 627 69 183 THA
95 | 114 Timor-Leste 405 919 1 324 TLS
96 | 115 Viet Nam 34 659 61 832 96 491 VNM
97 | 117 Armenia 1 853 1 081 2 934 ARM
98 | 118 Azerbaijan 5 526 4 398 9 924 AZE
99 | 119 Bahrain 1 399 168 1 567 BHR
100 | 120 Cyprus 794 395 1 189 CYP
101 | 121 Georgia 2 291 1 616 3 907 GEO
102 | 122 Iraq 27 724 11 616 39 340 IRQ
103 | 123 Israel 7 812 641 8 453 ISR
104 | 124 Jordan 9 010 893 9 904 JOR
105 | 125 Kuwait 4 197 0 4 197 KWT
106 | 126 Lebanon 5 398 695 6 094 LBN
107 | 127 Oman 4 083 747 4 830 OMN
108 | 128 Qatar 2 672 23 2 695 QAT
109 | 129 Saudi Arabia 28 133 5 421 33 554 SAU
110 | 130 State of Palestine 3 848 1 204 5 053 PSE
111 | 131 Syrian Arab Republic 9 903 8 381 18 284 SYR
112 | 132 Turkey 61 555 20 362 81 917 TUR
113 | 133 United Arab Emirates 8 256 1 286 9 542 ARE
114 | 134 Yemen 10 595 18 320 28 915 YEM
115 | 137 Belarus 7 429 2 023 9 452 BLR
116 | 138 Bulgaria 5 278 1 759 7 037 BGR
117 | 139 Czechia 7 841 2 785 10 625 CZE
118 | 140 Hungary 6 913 2 776 9 689 HUN
119 | 141 Poland 22 885 15 220 38 105 POL
120 | 142 Republic of Moldova 1 723 2 318 4 041 MDA
121 | 143 Romania 10 573 9 008 19 581 ROU
122 | 144 Russian Federation 107 157 36 808 143 965 RUS
123 | 145 Slovakia 2 928 2 522 5 450 SVK
124 | 146 Ukraine 30 521 13 488 44 009 UKR
125 | 148 Channel Islands 51 115 166 CHI
126 | 149 Denmark 5 057 698 5 754 DNK
127 | 150 Estonia 900 407 1 307 EST
128 | 151 Faeroe Islands 21 29 49 FRO
129 | 152 Finland 4 732 810 5 543 FIN
130 | 153 Iceland 317 21 338 ISL
131 | 154 Ireland 3 035 1 769 4 804 IRL
132 | 155 Isle of Man 45 40 85 IMN
133 | 156 Latvia 1 315 615 1 930 LVA
134 | 157 Lithuania 1 947 930 2 876 LTU
135 | 158 Norway 4 403 950 5 353 NOR
136 | 159 Sweden 8 728 1 255 9 983 SWE
137 | 160 United Kingdom 55 521 11 052 66 574 GBR
138 | 162 Albania 1 770 1 164 2 934 ALB
139 | 163 Andorra 68 9 77 AND
140 | 164 Bosnia and Herzegovina 1 690 1 813 3 504 BIH
141 | 165 Croatia 2 372 1 793 4 165 HRV
142 | 166 Gibraltar 35 0 35 GIB
143 | 167 Greece 8 809 2 333 11 142 GRC
144 | 168 Holy See 1 0 1 VAT
145 | 169 Italy 41 763 17 528 59 291 ITA
146 | 170 Malta 409 23 432 MLT
147 | 171 Montenegro 420 209 629 MNE
148 | 172 Portugal 6 711 3 580 10 291 PRT
149 | 173 San Marino 33 1 34 SMR
150 | 174 Serbia 4 915 3 847 8 762 SRB
151 | 175 Slovenia 1 135 946 2 081 SVN
152 | 176 Spain 37 267 9 130 46 397 ESP
153 | 177 TFYR Macedonia 1 209 876 2 085 MKD
154 | 179 Austria 5 102 3 650 8 752 AUT
155 | 180 Belgium 11 269 230 11 499 BEL
156 | 181 France 52 476 12 757 65 233 FRA
157 | 182 Germany 63 622 18 671 82 293 DEU
158 | 183 Liechtenstein 5 33 38 LIE
159 | 184 Luxembourg 537 53 590 LUX
160 | 185 Monaco 39 0 39 MCO
161 | 186 Netherlands 15 631 1 454 17 084 NLD
162 | 187 Switzerland 6 305 2 239 8 544 CHE
163 | 190 Anguilla 15 0 15 AIA
164 | 191 Antigua and Barbuda 25 78 103 ATG
165 | 192 Aruba 46 60 106 ABW
166 | 193 Bahamas 332 68 399 BHS
167 | 194 Barbados 89 197 286 BRB
168 | 195 British Virgin Islands 15 17 32 VGB
169 | 196 Caribbean Netherlands 19 6 26 BES
170 | 197 Cayman Islands 62 0 62 CYM
171 | 198 Cuba 8 851 2 638 11 489 CUB
172 | 199 Curaçao 144 18 162 CUW
173 | 200 Dominica 52 22 74 DMA
174 | 201 Dominican Republic 8 823 2 060 10 883 DOM
175 | 202 Grenada 39 69 108 GRD
176 | 203 Guadeloupe 442 7 449 GLP
177 | 204 Haiti 6 143 4 970 11 113 HTI
178 | 205 Jamaica 1 614 1 285 2 899 JAM
179 | 206 Martinique 343 42 385 MTQ
180 | 207 Montserrat 0 5 5 MSR
181 | 208 Puerto Rico 3 424 235 3 659 PRI
182 | 209 Saint Kitts and Nevis 17 39 56 KNA
183 | 210 Saint Lucia 34 146 180 LCA
184 | 211 Saint Vincent and the Grenadines 58 53 110 VCT
185 | 212 Sint Maarten (Dutch part) 41 0 41 SXM
186 | 213 Trinidad and Tobago 730 643 1 373 TTO
187 | 214 Turks and Caicos Islands 33 2 36 TCA
188 | 215 United States Virgin Islands 100 4 105 VIR
189 | 217 Belize 175 208 382 BLZ
190 | 218 Costa Rica 3 930 1 023 4 953 CRI
191 | 219 El Salvador 4 618 1 794 6 412 SLV
192 | 220 Guatemala 8 804 8 441 17 245 GTM
193 | 221 Honduras 5 377 4 040 9 417 HND
194 | 222 Mexico 104 811 25 948 130 759 MEX
195 | 223 Nicaragua 3 678 2 607 6 285 NIC
196 | 224 Panama 2 818 1 344 4 163 PAN
197 | 226 Argentina 41 056 3 633 44 689 ARG
198 | 227 Bolivia (Plurinational State of) 7 786 3 429 11 216 BOL
199 | 228 Brazil 182 546 28 321 210 868 BRA
200 | 229 Chile 15 934 2 263 18 197 CHL
201 | 230 Colombia 39 956 9 508 49 465 COL
202 | 231 Ecuador 10 762 6 101 16 863 ECU
203 | 232 Falkland Islands (Malvinas) 2 1 3 FLK
204 | 233 French Guiana 247 43 290 GUF
205 | 234 Guyana 208 574 782 GUY
206 | 235 Paraguay 4 247 2 649 6 897 PRY
207 | 236 Peru 25 360 7 192 32 552 PER
208 | 237 Suriname 375 193 568 SUR
209 | 238 Uruguay 3 308 162 3 470 URY
210 | 239 Venezuela (Bolivarian Republic of) 28 563 3 819 32 381 VEN
211 | 241 Bermuda 61 0 61 BMU
212 | 242 Canada 30 084 6 869 36 954 CAN
213 | 243 Greenland 49 7 57 GRL
214 | 244 Saint Pierre and Miquelon 6 1 6 SPM
215 | 245 United States of America 268 787 57 980 326 767 USA
216 | 248 Australia 21 307 3 465 24 772 AUS
217 | 249 New Zealand 4 110 639 4 750 NZL
218 | 251 Fiji 513 399 912 FJI
219 | 252 New Caledonia 198 82 280 NCL
220 | 253 Papua New Guinea 1 109 7 310 8 418 PNG
221 | 254 Solomon Islands 148 475 623 SLB
222 | 255 Vanuatu 71 211 282 VUT
223 | 257 Guam 157 9 166 GUM
224 | 258 Kiribati 64 54 118 KIR
225 | 259 Marshall Islands 41 12 53 MHL
226 | 260 Micronesia (Fed. States of) 24 82 106 FSM
227 | 261 Nauru 11 0 11 NRU
228 | 262 Northern Mariana Islands 51 5 55 MNP
229 | 263 Palau 18 4 22 PLW
230 | 265 American Samoa 49 7 56 ASM
231 | 266 Cook Islands 13 4 17 COK
232 | 267 French Polynesia 177 109 286 PYF
233 | 268 Niue 1 1 2 NIU
234 | 269 Samoa 36 162 198 WSM
235 | 270 Tokelau 0 1 1 TKL
236 | 271 Tonga 25 84 109 TON
237 | 272 Tuvalu 7 4 11 TUV
238 | 273 Wallis and Futuna Islands 0 12 12 WLF
239 |
--------------------------------------------------------------------------------
/data_prep/process_data.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | import json
4 |
5 | f = open('pop2018.tsv', 'r')
6 | lookup = {}
7 | for line in f.readlines():
8 | tokens = line.strip().split("\t")
9 | if len(tokens) > 4:
10 | name = tokens[1].strip()
11 | try:
12 | urban = int(tokens[2].replace(' ', ''))
13 | rural = int(tokens[3].replace(' ', ''))
14 | total = int(tokens[4].replace(' ', ''))
15 | iso3 = tokens[5].strip()
16 | # print(iso3, total, name)
17 | lookup[iso3] = [total, urban, rural, name]
18 | except ValueError:
19 | print("Error: ", line.strip())
20 |
21 |
22 |
23 | f = open('value_labels.json', 'r')
24 | jj = json.loads(f.read())
25 | seq = jj['country']
26 | labels = jj['countries']
27 | backup_lookup = {}
28 | for item in labels:
29 | iso3 = item['iso3']
30 | name = item['name']
31 | if len(iso3) > 0:
32 | backup_lookup[iso3] = name
33 |
34 | countries_in_order = []
35 | for code in seq:
36 | name = ''
37 | total = -1
38 | urban = -1
39 | rural = -1
40 | if code in lookup:
41 | item = lookup[code]
42 | name = item[3]
43 | total = item[0]
44 | urban = item[1]
45 | rural = item[2]
46 | elif code in backup_lookup:
47 | name = backup_lookup[code]
48 | countries_in_order.append({
49 | "name" : name,
50 | "total" : total,
51 | "urban" : urban,
52 | "rural" : rural
53 | })
54 |
55 | s = json.dumps(countries_in_order)
56 | f = open('population_2018.json', 'w')
57 | f.write(s)
58 | f.close()
--------------------------------------------------------------------------------
/gtag_fix.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python2.7
2 |
3 | import os
4 |
5 | SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
6 |
7 | TAG = """
8 |
9 |
10 |
17 | """
18 |
19 | # def find_all(name, path):
20 | # result = []
21 | # for root, dirs, files in os.walk(path):
22 | # if name in files:
23 | # result.append(os.path.join(root, name))
24 | # return result
25 |
26 |
27 |
28 | indices = os.popen('find %s -name index.html' % (SCRIPT_DIR)).readlines()
29 | indices = [f.strip() for f in indices]
30 |
31 | for fname in indices:
32 | f = open(fname)
33 | lines = f.readlines()
34 | f.close()
35 |
36 | needs_analytics = True
37 | style_end_tag_line = -1
38 | for i, l in enumerate(lines):
39 | if "www.googletagmanager.com" in l:
40 | needs_analytics = False
41 | elif "" in l:
42 | style_end_tag_line = i
43 |
44 | if needs_analytics:
45 | print("tagging %s" % (fname))
46 | lines.insert(style_end_tag_line + 1, TAG)
47 | f = open(fname, 'w')
48 | f.write("".join(lines))
49 | f.close()
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/images/bumpy.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fathominfo/intro-to-shaders/d0fe9f2d2cc02d5911e76eeaa67f40e573083821/images/bumpy.jpeg
--------------------------------------------------------------------------------
/images/dd.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fathominfo/intro-to-shaders/d0fe9f2d2cc02d5911e76eeaa67f40e573083821/images/dd.jpeg
--------------------------------------------------------------------------------
/images/dnb_land_ocean_ice.2012.3600x1800.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fathominfo/intro-to-shaders/d0fe9f2d2cc02d5911e76eeaa67f40e573083821/images/dnb_land_ocean_ice.2012.3600x1800.jpg
--------------------------------------------------------------------------------
/images/dot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fathominfo/intro-to-shaders/d0fe9f2d2cc02d5911e76eeaa67f40e573083821/images/dot.png
--------------------------------------------------------------------------------
/images/europe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fathominfo/intro-to-shaders/d0fe9f2d2cc02d5911e76eeaa67f40e573083821/images/europe.png
--------------------------------------------------------------------------------
/images/f.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fathominfo/intro-to-shaders/d0fe9f2d2cc02d5911e76eeaa67f40e573083821/images/f.png
--------------------------------------------------------------------------------
/images/fathom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fathominfo/intro-to-shaders/d0fe9f2d2cc02d5911e76eeaa67f40e573083821/images/fathom.png
--------------------------------------------------------------------------------
/images/fathom_w_guides.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fathominfo/intro-to-shaders/d0fe9f2d2cc02d5911e76eeaa67f40e573083821/images/fathom_w_guides.png
--------------------------------------------------------------------------------
/images/home.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fathominfo/intro-to-shaders/d0fe9f2d2cc02d5911e76eeaa67f40e573083821/images/home.jpg
--------------------------------------------------------------------------------
/images/nasa_blue_marble.4096.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fathominfo/intro-to-shaders/d0fe9f2d2cc02d5911e76eeaa67f40e573083821/images/nasa_blue_marble.4096.jpg
--------------------------------------------------------------------------------
/images/rust.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fathominfo/intro-to-shaders/d0fe9f2d2cc02d5911e76eeaa67f40e573083821/images/rust.jpg
--------------------------------------------------------------------------------
/images/trianglefan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fathominfo/intro-to-shaders/d0fe9f2d2cc02d5911e76eeaa67f40e573083821/images/trianglefan.png
--------------------------------------------------------------------------------
/images/trianglestrip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fathominfo/intro-to-shaders/d0fe9f2d2cc02d5911e76eeaa67f40e573083821/images/trianglestrip.png
--------------------------------------------------------------------------------
/images/world.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fathominfo/intro-to-shaders/d0fe9f2d2cc02d5911e76eeaa67f40e573083821/images/world.png
--------------------------------------------------------------------------------
/server.tool:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python2.7
2 |
3 | import os
4 | import sys
5 |
6 | from random import randint
7 |
8 | from BaseHTTPServer import HTTPServer
9 | from SimpleHTTPServer import SimpleHTTPRequestHandler
10 | from SocketServer import ThreadingMixIn
11 |
12 | class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
13 | pass
14 |
15 | port = randint(8000, 9000)
16 | dir = os.path.dirname(os.path.realpath(__file__))
17 | os.chdir(dir)
18 |
19 | url = 'http://localhost:%s/%s' % (port, 'index.html')
20 | print "serving at %s" % (url)
21 | os.system('open ' + url)
22 |
23 | server_address = ('', port)
24 | httpd = ThreadedHTTPServer(server_address, SimpleHTTPRequestHandler)
25 | httpd.serve_forever()
26 |
--------------------------------------------------------------------------------
/shader_01/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | // this function gets called for each pixel within the shape we set up
6 | // in the vertex shader
7 | void main(){
8 | // assigning to gl_FragColor sets the color for this pixel
9 | gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
10 | }
--------------------------------------------------------------------------------
/shader_01/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/shader_01/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | gl = canvas.getContext('webgl', {}),
4 | program,
5 | W = window.innerWidth,
6 | H = window.innerHeight,
7 | frameCount = 0,
8 |
9 | positionLocation;
10 |
11 | // make the canvas fill the window
12 | canvas.width = W;
13 | canvas.height = H;
14 |
15 |
16 |
17 | function initGLData() {
18 | // now we can get some config info
19 | gl.viewport(0, 0, W, H);
20 | // Even though we aren't drawing anything really fancy,
21 | // we have to tell the GL Context how much of the screen we are drawing
22 | positionLocation = gl.getAttribLocation(program, "a_position");
23 | gl.enableVertexAttribArray(positionLocation);
24 | var buffer = gl.createBuffer();
25 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
26 | gl.bufferData(
27 | gl.ARRAY_BUFFER,
28 | /**
29 | note that unlike processing or canvas.getContext('2d'),
30 | the screen coordinates are
31 | -1, 1 left to right
32 | 1, -1 top to bottom
33 | and 0, 0 is the center
34 | and because GL is finicky, you have to specify them as floats,
35 | not ints, so add that '.0' to the end
36 | */
37 | new Float32Array([
38 | -1.0, 1.0,
39 | 1.0, 1.0,
40 | -1.0, -1.0,
41 | 1.0, -1.0]),
42 | gl.STATIC_DRAW
43 | );
44 | gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
45 | }
46 |
47 |
48 |
49 |
50 | function draw() {
51 | // Set clear color to black, fully opaque
52 | gl.clearColor(0.0, 0.0, 0.0, 1.0);
53 | // Clear the color buffer with specified clear color
54 | gl.clear(gl.COLOR_BUFFER_BIT);
55 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
56 | }
57 |
58 |
59 |
60 |
61 |
62 |
63 | // ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ ███████╗████████╗██╗ ██╗███████╗███████╗
64 | // ██╔══██╗██╔═══██╗██╔══██╗██║████╗ ██║██╔════╝ ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔════╝
65 | // ██████╔╝██║ ██║██████╔╝██║██╔██╗ ██║██║ ███╗ ███████╗ ██║ ██║ ██║█████╗ █████╗
66 | // ██╔══██╗██║ ██║██╔══██╗██║██║╚██╗██║██║ ██║ ╚════██║ ██║ ██║ ██║██╔══╝ ██╔══╝
67 | // ██████╔╝╚██████╔╝██║ ██║██║██║ ╚████║╚██████╔╝ ███████║ ██║ ╚██████╔╝██║ ██║
68 | // ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
69 |
70 |
71 | // load files
72 | fetch('frag.glsl')
73 | .then(function(response) {
74 | return response.text();
75 | }).then(fragShaderText=>{
76 | // console.log(fragShaderText)
77 | fetch('vert.glsl')
78 | .then(function(response) {
79 | return response.text();
80 | }).then(vertShaderText=>{
81 | // console.log(vertShaderText);
82 | compileGL(fragShaderText, vertShaderText);
83 | initGLData();
84 | requestDraw();
85 | });
86 | });
87 |
88 |
89 |
90 | // build our program
91 | function compileGL(fragShaderText, vertShaderText) {
92 | var frag = loadShader(gl, gl.FRAGMENT_SHADER, fragShaderText);
93 | var vert = loadShader(gl, gl.VERTEX_SHADER, vertShaderText);
94 | program = gl.createProgram();
95 | gl.attachShader(program, vert);
96 | gl.attachShader(program, frag);
97 | gl.linkProgram(program);
98 | gl.useProgram(program);
99 | }
100 |
101 | function requestDraw() {
102 | requestAnimationFrame(draw);
103 | }
104 |
105 | // straight outta mozilla
106 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
107 | function loadShader(gl, type, source) {
108 | const shader = gl.createShader(type);
109 | // Send the source to the shader object
110 | gl.shaderSource(shader, source);
111 | // Compile the shader program
112 | gl.compileShader(shader);
113 | // See if it compiled successfully
114 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
115 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
116 | gl.deleteShader(shader);
117 | return null;
118 | }
119 | return shader;
120 | }
121 |
122 |
123 | })();
124 |
125 |
--------------------------------------------------------------------------------
/shader_01/vert.glsl:
--------------------------------------------------------------------------------
1 | attribute vec2 a_position;
2 |
3 | void main() {
4 | gl_Position = vec4(a_position, 0, 1);
5 | }
--------------------------------------------------------------------------------
/shader_02.0/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | uniform float u_time;
6 |
7 | // this function gets called for each pixel within the shape we set up
8 | // in the vertex shader
9 | void main(){
10 | // instead of raw time, we will make a nice loop by taking the sine
11 | // of the elapsed time. Keep it above 0 with abs()
12 | float t = abs(sin(u_time / 1000.0));
13 | gl_FragColor = vec4(t, 0.0, 1.0, 1.0);
14 | }
--------------------------------------------------------------------------------
/shader_02.0/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/shader_02.0/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | gl = canvas.getContext('webgl', {}),
4 | program,
5 | W = window.innerWidth,
6 | H = window.innerHeight,
7 | // New: our shader will change over time, so we need to know when it starts
8 | startTime,
9 |
10 | // New: we will pass the elapsed time to the shader
11 | // so we need to know where the shader wants us to put it.
12 | timeUniformLocation,
13 | positionLocation;
14 |
15 | // make the canvas fill the window
16 | canvas.width = W;
17 | canvas.height = H;
18 |
19 | function initGLData() {
20 | // now we can get some config info
21 | gl.viewport(0, 0, W, H);
22 | // New: so this is where we will put the elpased time in our draw function
23 | timeUniformLocation = gl.getUniformLocation(program, "u_time");
24 |
25 | // Even though we aren't drawing anything really fancy,
26 | // we have to tell the GL Context how much of the screen we are drawing
27 | positionLocation = gl.getAttribLocation(program, "a_position");
28 | gl.enableVertexAttribArray(positionLocation);
29 | var buffer = gl.createBuffer();
30 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
31 | gl.bufferData(
32 | gl.ARRAY_BUFFER,
33 | /**
34 | note that unlike processing or canvas.getContext('2d'),
35 | the screen coordinates are
36 | -1, 1 left to right
37 | 1, -1 top to bottom
38 | and 0, 0 is the center
39 | and because GL is finicky, you have to specify them as floats,
40 | not ints, so add that '.0' to the end
41 | */
42 | new Float32Array([
43 | -1.0, 1.0,
44 | 1.0, 1.0,
45 | -1.0, -1.0,
46 | 1.0, -1.0]),
47 | gl.STATIC_DRAW
48 | );
49 | gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
50 | }
51 |
52 |
53 | function draw() {
54 | // Set clear color to black, fully opaque
55 | gl.clearColor(0.0, 0.0, 0.0, 1.0);
56 | // Clear the color buffer with specified clear color
57 | gl.clear(gl.COLOR_BUFFER_BIT);
58 | // New: calculate how much time has passed, and pass it to the shader
59 | var elapsed = Date.now() - startTime;
60 | gl.uniform1f(timeUniformLocation, elapsed);
61 | // console.log(elapsed / 100.0)
62 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
63 | }
64 |
65 |
66 |
67 | // ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ ███████╗████████╗██╗ ██╗███████╗███████╗
68 | // ██╔══██╗██╔═══██╗██╔══██╗██║████╗ ██║██╔════╝ ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔════╝
69 | // ██████╔╝██║ ██║██████╔╝██║██╔██╗ ██║██║ ███╗ ███████╗ ██║ ██║ ██║█████╗ █████╗
70 | // ██╔══██╗██║ ██║██╔══██╗██║██║╚██╗██║██║ ██║ ╚════██║ ██║ ██║ ██║██╔══╝ ██╔══╝
71 | // ██████╔╝╚██████╔╝██║ ██║██║██║ ╚████║╚██████╔╝ ███████║ ██║ ╚██████╔╝██║ ██║
72 | // ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
73 |
74 |
75 | // load files
76 | fetch('frag.glsl')
77 | .then(function(response) {
78 | return response.text();
79 | }).then(fragShaderText=>{
80 | // console.log(fragShaderText)
81 | fetch('vert.glsl')
82 | .then(function(response) {
83 | return response.text();
84 | }).then(vertShaderText=>{
85 | // console.log(vertShaderText);
86 | compileGL(fragShaderText, vertShaderText);
87 | initGLData();
88 | // New: instead of just drawing once,
89 | // we track the start time and call the draw loop every 30 milliseconds
90 | // roughly 30 times a second
91 | startTime = Date.now();
92 | setInterval(requestDraw, 33);
93 | });
94 | });
95 |
96 |
97 |
98 | // build our program
99 | function compileGL(fragShaderText, vertShaderText) {
100 | var frag = loadShader(gl, gl.FRAGMENT_SHADER, fragShaderText);
101 | var vert = loadShader(gl, gl.VERTEX_SHADER, vertShaderText);
102 | program = gl.createProgram();
103 | gl.attachShader(program, vert);
104 | gl.attachShader(program, frag);
105 | gl.linkProgram(program);
106 | gl.useProgram(program);
107 | }
108 |
109 | function requestDraw() {
110 | requestAnimationFrame(draw);
111 | }
112 |
113 | // straight outta mozilla
114 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
115 | function loadShader(gl, type, source) {
116 | const shader = gl.createShader(type);
117 | // Send the source to the shader object
118 | gl.shaderSource(shader, source);
119 | // Compile the shader program
120 | gl.compileShader(shader);
121 | // See if it compiled successfully
122 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
123 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
124 | gl.deleteShader(shader);
125 | return null;
126 | }
127 | return shader;
128 | }
129 |
130 |
131 |
132 | })();
133 |
134 |
--------------------------------------------------------------------------------
/shader_02.0/vert.glsl:
--------------------------------------------------------------------------------
1 | attribute vec2 a_position;
2 |
3 | void main() {
4 | gl_Position = vec4(a_position, 0, 1);
5 | }
--------------------------------------------------------------------------------
/shader_02.1/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | // New: the screen resolution
6 | uniform vec2 u_resolution;
7 |
8 | // this function gets called for each pixel within the shape we set up
9 | // in the vertex shader
10 | void main(){
11 | // assigning to gl_FragColor sets the color for this pixel
12 | // New: the screen resolution
13 | // the shader space is in 0-1, but we want to color each pixel according to a gradient.
14 | // So we need to rescale the coordinate space by the screen resolution
15 | vec2 st = gl_FragCoord.xy/u_resolution;
16 | gl_FragColor = vec4(0.0, st.x, st.y, 1.0);
17 | }
--------------------------------------------------------------------------------
/shader_02.1/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/shader_02.1/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | gl = canvas.getContext('webgl', {}),
4 | program,
5 | W = window.innerWidth,
6 | H = window.innerHeight,
7 |
8 | // New: we have a new global variable that represents the screen size
9 | resolutionUniformLocation,
10 | positionLocation;
11 |
12 | // make the canvas fill the window
13 | canvas.width = W;
14 | canvas.height = H;
15 |
16 | function initGLData() {
17 | // now we can get some config info
18 | gl.viewport(0, 0, W, H);
19 | // New: just where does the shader store the information about screen resolution?
20 | resolutionUniformLocation = gl.getUniformLocation(program, "u_resolution");
21 | // New: pass in the width and height of the canvas so we can use it in the shader
22 | gl.uniform2f(resolutionUniformLocation, W, H);
23 |
24 | // Even though we aren't drawing anything really fancy,
25 | // we have to tell the GL Context how much of the screen we are drawing
26 | positionLocation = gl.getAttribLocation(program, "a_position");
27 | gl.enableVertexAttribArray(positionLocation);
28 | var buffer = gl.createBuffer();
29 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
30 | gl.bufferData(
31 | gl.ARRAY_BUFFER,
32 | /**
33 | note that unlike processing or canvas.getContext('2d'),
34 | the screen coordinates are
35 | -1, 1 left to right
36 | 1, -1 top to bottom
37 | and 0, 0 is the center
38 | and because GL is finicky, you have to specify them as floats,
39 | not ints, so add that '.0' to the end
40 | */
41 | new Float32Array([
42 | -1.0, 1.0,
43 | 1.0, 1.0,
44 | -1.0, -1.0,
45 | 1.0, -1.0]),
46 | gl.STATIC_DRAW
47 | );
48 | gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
49 | }
50 |
51 |
52 | function draw() {
53 | // Set clear color to black, fully opaque
54 | gl.clearColor(0.0, 0.0, 0.0, 1.0);
55 | // Clear the color buffer with specified clear color
56 | gl.clear(gl.COLOR_BUFFER_BIT);
57 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
58 | }
59 |
60 |
61 | // ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ ███████╗████████╗██╗ ██╗███████╗███████╗
62 | // ██╔══██╗██╔═══██╗██╔══██╗██║████╗ ██║██╔════╝ ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔════╝
63 | // ██████╔╝██║ ██║██████╔╝██║██╔██╗ ██║██║ ███╗ ███████╗ ██║ ██║ ██║█████╗ █████╗
64 | // ██╔══██╗██║ ██║██╔══██╗██║██║╚██╗██║██║ ██║ ╚════██║ ██║ ██║ ██║██╔══╝ ██╔══╝
65 | // ██████╔╝╚██████╔╝██║ ██║██║██║ ╚████║╚██████╔╝ ███████║ ██║ ╚██████╔╝██║ ██║
66 | // ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
67 |
68 |
69 | // load files
70 | fetch('frag.glsl')
71 | .then(function(response) {
72 | return response.text();
73 | }).then(fragShaderText=>{
74 | // console.log(fragShaderText)
75 | fetch('vert.glsl')
76 | .then(function(response) {
77 | return response.text();
78 | }).then(vertShaderText=>{
79 | // console.log(vertShaderText);
80 | compileGL(fragShaderText, vertShaderText);
81 | initGLData();
82 | startTime = Date.now();
83 | setInterval(requestDraw, 33);
84 | });
85 | });
86 |
87 |
88 |
89 | // build our program
90 | function compileGL(fragShaderText, vertShaderText) {
91 | var frag = loadShader(gl, gl.FRAGMENT_SHADER, fragShaderText);
92 | var vert = loadShader(gl, gl.VERTEX_SHADER, vertShaderText);
93 | program = gl.createProgram();
94 | gl.attachShader(program, vert);
95 | gl.attachShader(program, frag);
96 | gl.linkProgram(program);
97 | gl.useProgram(program);
98 | }
99 |
100 | function requestDraw() {
101 | requestAnimationFrame(draw);
102 | }
103 |
104 | // straight outta mozilla
105 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
106 | function loadShader(gl, type, source) {
107 | const shader = gl.createShader(type);
108 | // Send the source to the shader object
109 | gl.shaderSource(shader, source);
110 | // Compile the shader program
111 | gl.compileShader(shader);
112 | // See if it compiled successfully
113 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
114 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
115 | gl.deleteShader(shader);
116 | return null;
117 | }
118 | return shader;
119 | }
120 |
121 |
122 | })();
123 |
124 |
--------------------------------------------------------------------------------
/shader_02.1/vert.glsl:
--------------------------------------------------------------------------------
1 | attribute vec2 a_position;
2 |
3 | void main() {
4 | gl_Position = vec4(a_position, 0, 1);
5 | }
--------------------------------------------------------------------------------
/shader_02.2/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | uniform vec2 u_resolution;
6 | // New: the mouse position
7 | uniform vec2 u_mouse;
8 |
9 | void main(){
10 | vec2 st = gl_FragCoord.xy/u_resolution;
11 | // New: the mouse position
12 | vec2 mouse = u_mouse/u_resolution;
13 | // draw something differnt on the left and right sides of the mouse
14 | if (st.x < mouse.x) {
15 | gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
16 | } else {
17 | gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0);
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/shader_02.2/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/shader_02.2/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | gl = canvas.getContext('webgl', {}),
4 | program,
5 | W = window.innerWidth,
6 | H = window.innerHeight,
7 |
8 | // New: track the mouse position, and pass it to the shader
9 | mouseX, mouseY,
10 | mouseUniformLocation,
11 |
12 | resolutionUniformLocation,
13 | positionLocation;
14 |
15 | // make the canvas fill the window
16 | canvas.width = W;
17 | canvas.height = H;
18 |
19 |
20 | function initGLData() {
21 | // now we can get some config info
22 | gl.viewport(0, 0, W, H);
23 | // New: just where does the shader track the mouse position?
24 | mouseUniformLocation = gl.getUniformLocation(program, "u_mouse");
25 | resolutionUniformLocation = gl.getUniformLocation(program, "u_resolution");
26 |
27 | gl.uniform2f(resolutionUniformLocation, W, H);
28 |
29 | // Even though we aren't drawing anything really fancy,
30 | // we have to tell the GL Context how much of the screen we are drawing
31 | positionLocation = gl.getAttribLocation(program, "a_position");
32 | gl.enableVertexAttribArray(positionLocation);
33 | var buffer = gl.createBuffer();
34 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
35 | gl.bufferData(
36 | gl.ARRAY_BUFFER,
37 | /**
38 | note that unlike processing or canvas.getContext('2d'),
39 | the screen coordinates are
40 | -1, 1 left to right
41 | 1, -1 top to bottom
42 | and 0, 0 is the center
43 | and because GL is finicky, you have to specify them as floats,
44 | not ints, so add that '.0' to the end
45 | */
46 | new Float32Array([
47 | -1.0, 1.0,
48 | 1.0, 1.0,
49 | -1.0, -1.0,
50 | 1.0, -1.0]),
51 | gl.STATIC_DRAW
52 | );
53 | gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
54 | }
55 |
56 |
57 | function draw() {
58 | // Set clear color to black, fully opaque
59 | gl.clearColor(0.0, 0.0, 0.0, 1.0);
60 | // Clear the color buffer with specified clear color
61 | gl.clear(gl.COLOR_BUFFER_BIT);
62 | gl.uniform2f(mouseUniformLocation, mouseX, mouseY);
63 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
64 | }
65 |
66 |
67 |
68 |
69 | // ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ ███████╗████████╗██╗ ██╗███████╗███████╗
70 | // ██╔══██╗██╔═══██╗██╔══██╗██║████╗ ██║██╔════╝ ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔════╝
71 | // ██████╔╝██║ ██║██████╔╝██║██╔██╗ ██║██║ ███╗ ███████╗ ██║ ██║ ██║█████╗ █████╗
72 | // ██╔══██╗██║ ██║██╔══██╗██║██║╚██╗██║██║ ██║ ╚════██║ ██║ ██║ ██║██╔══╝ ██╔══╝
73 | // ██████╔╝╚██████╔╝██║ ██║██║██║ ╚████║╚██████╔╝ ███████║ ██║ ╚██████╔╝██║ ██║
74 | // ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
75 |
76 |
77 | // load files
78 | fetch('frag.glsl')
79 | .then(function(response) {
80 | return response.text();
81 | }).then(fragShaderText=>{
82 | // console.log(fragShaderText)
83 | fetch('vert.glsl')
84 | .then(function(response) {
85 | return response.text();
86 | }).then(vertShaderText=>{
87 | // console.log(vertShaderText);
88 | compileGL(fragShaderText, vertShaderText);
89 | initGLData();
90 | // New: track the mouse
91 | canvas.addEventListener('mousemove',(event) => {
92 | mouseX = event.offsetX;
93 | mouseY = event.offsetY;
94 | });
95 | startTime = Date.now();
96 | setInterval(requestDraw, 33);
97 | });
98 | });
99 |
100 |
101 |
102 | // build our program
103 | function compileGL(fragShaderText, vertShaderText) {
104 | var frag = loadShader(gl, gl.FRAGMENT_SHADER, fragShaderText);
105 | var vert = loadShader(gl, gl.VERTEX_SHADER, vertShaderText);
106 | program = gl.createProgram();
107 | gl.attachShader(program, vert);
108 | gl.attachShader(program, frag);
109 | gl.linkProgram(program);
110 | gl.useProgram(program);
111 | }
112 |
113 | function requestDraw() {
114 | requestAnimationFrame(draw);
115 | }
116 |
117 | // straight outta mozilla
118 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
119 | function loadShader(gl, type, source) {
120 | const shader = gl.createShader(type);
121 | // Send the source to the shader object
122 | gl.shaderSource(shader, source);
123 | // Compile the shader program
124 | gl.compileShader(shader);
125 | // See if it compiled successfully
126 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
127 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
128 | gl.deleteShader(shader);
129 | return null;
130 | }
131 | return shader;
132 | }
133 |
134 |
135 | })();
136 |
137 |
--------------------------------------------------------------------------------
/shader_02.2/vert.glsl:
--------------------------------------------------------------------------------
1 | attribute vec2 a_position;
2 |
3 | void main() {
4 | gl_Position = vec4(a_position, 0, 1);
5 | }
--------------------------------------------------------------------------------
/shader_02.3/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | uniform float u_time;
6 | uniform vec2 u_resolution;
7 | uniform vec2 u_mouse;
8 |
9 | void main(){
10 | vec2 st = gl_FragCoord.xy/u_resolution;
11 | // instead of raw time, we will make a nice loop by taking the sine
12 | // of the elapsed time. Keep it above 0 with abs()
13 | float t = u_time / 1000.0;
14 | vec2 mouse = u_mouse/u_resolution;
15 | // draw something different on the left and right sides of the mouse
16 | if (st.x < mouse.x) {
17 | gl_FragColor = vec4(abs(sin(t)), st.x, st.y, 1.0);
18 | } else {
19 | gl_FragColor = vec4(st.y, abs(sin(st.x)), abs(cos(t)), 1.0);
20 | }
21 | }
--------------------------------------------------------------------------------
/shader_02.3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/shader_02.3/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | gl = canvas.getContext('webgl', {}),
4 | program,
5 | W = window.innerWidth,
6 | H = window.innerHeight,
7 | startTime,
8 | mouseX, mouseY,
9 |
10 | mouseUniformLocation,
11 | resolutionUniformLocation,
12 | timeUniformLocation,
13 | positionLocation;
14 |
15 | // make the canvas fill the window
16 | canvas.width = W;
17 | canvas.height = H;
18 |
19 | function initGLData() {
20 | // now we can get some config info
21 | gl.viewport(0, 0, W, H);
22 | // New: just where does the shader track the mouse position?
23 | mouseUniformLocation = gl.getUniformLocation(program, "u_mouse");
24 | resolutionUniformLocation = gl.getUniformLocation(program, "u_resolution");
25 | timeUniformLocation = gl.getUniformLocation(program, "u_time");
26 |
27 | gl.uniform2f(resolutionUniformLocation, W, H);
28 |
29 | // Even though we aren't drawing anything really fancy,
30 | // we have to tell the GL Context how much of the screen we are drawing
31 | positionLocation = gl.getAttribLocation(program, "a_position");
32 | gl.enableVertexAttribArray(positionLocation);
33 | var buffer = gl.createBuffer();
34 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
35 | gl.bufferData(
36 | gl.ARRAY_BUFFER,
37 | /**
38 | note that unlike processing or canvas.getContext('2d'),
39 | the screen coordinates are
40 | -1, 1 left to right
41 | 1, -1 top to bottom
42 | and 0, 0 is the center
43 | and because GL is finicky, you have to specify them as floats,
44 | not ints, so add that '.0' to the end
45 | */
46 | new Float32Array([
47 | -1.0, 1.0,
48 | 1.0, 1.0,
49 | -1.0, -1.0,
50 | 1.0, -1.0]),
51 | gl.STATIC_DRAW
52 | );
53 | gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
54 | }
55 |
56 |
57 | function draw() {
58 | // Set clear color to black, fully opaque
59 | gl.clearColor(0.0, 0.0, 0.0, 1.0);
60 | // Clear the color buffer with specified clear color
61 | gl.clear(gl.COLOR_BUFFER_BIT);
62 | var elapsed = Date.now() - startTime;
63 | gl.uniform1f(timeUniformLocation, elapsed);
64 | gl.uniform2f(mouseUniformLocation, mouseX, mouseY);
65 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
66 | }
67 |
68 |
69 | // ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ ███████╗████████╗██╗ ██╗███████╗███████╗
70 | // ██╔══██╗██╔═══██╗██╔══██╗██║████╗ ██║██╔════╝ ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔════╝
71 | // ██████╔╝██║ ██║██████╔╝██║██╔██╗ ██║██║ ███╗ ███████╗ ██║ ██║ ██║█████╗ █████╗
72 | // ██╔══██╗██║ ██║██╔══██╗██║██║╚██╗██║██║ ██║ ╚════██║ ██║ ██║ ██║██╔══╝ ██╔══╝
73 | // ██████╔╝╚██████╔╝██║ ██║██║██║ ╚████║╚██████╔╝ ███████║ ██║ ╚██████╔╝██║ ██║
74 | // ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
75 |
76 |
77 | // load files
78 | fetch('frag.glsl')
79 | .then(function(response) {
80 | return response.text();
81 | }).then(fragShaderText=>{
82 | // console.log(fragShaderText)
83 | fetch('vert.glsl')
84 | .then(function(response) {
85 | return response.text();
86 | }).then(vertShaderText=>{
87 | // console.log(vertShaderText);
88 | compileGL(fragShaderText, vertShaderText);
89 | initGLData();
90 | startTime = Date.now();
91 | canvas.addEventListener('mousemove',(event) => {
92 | mouseX = event.offsetX;
93 | mouseY = event.offsetY;
94 | });
95 | setInterval(requestDraw, 30);
96 |
97 | });
98 | });
99 |
100 |
101 |
102 | // build our program
103 | function compileGL(fragShaderText, vertShaderText) {
104 | var frag = loadShader(gl, gl.FRAGMENT_SHADER, fragShaderText);
105 | var vert = loadShader(gl, gl.VERTEX_SHADER, vertShaderText);
106 | program = gl.createProgram();
107 | gl.attachShader(program, vert);
108 | gl.attachShader(program, frag);
109 | gl.linkProgram(program);
110 | gl.useProgram(program);
111 | }
112 |
113 | function requestDraw() {
114 | requestAnimationFrame(draw);
115 | }
116 |
117 | // straight outta mozilla
118 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
119 | function loadShader(gl, type, source) {
120 | const shader = gl.createShader(type);
121 | // Send the source to the shader object
122 | gl.shaderSource(shader, source);
123 | // Compile the shader program
124 | gl.compileShader(shader);
125 | // See if it compiled successfully
126 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
127 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
128 | gl.deleteShader(shader);
129 | return null;
130 | }
131 | return shader;
132 | }
133 |
134 |
135 | })();
136 |
137 |
--------------------------------------------------------------------------------
/shader_02.3/vert.glsl:
--------------------------------------------------------------------------------
1 | attribute vec2 a_position;
2 |
3 | void main() {
4 | gl_Position = vec4(a_position, 0, 1);
5 | }
--------------------------------------------------------------------------------
/shader_03.0/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | uniform float u_time;
6 | // New: the screen resolution
7 | uniform vec2 u_resolution;
8 |
9 | // this function gets called for each pixel within the shape we set up
10 | // in the vertex shader
11 | void main(){
12 | // assigning to gl_FragColor sets the color for this pixel
13 | // New: the screen resolution
14 | // the shader space is in 0-1, but we want to color each pixel according to a gradient.
15 | // So we need to rescale the coordinate space by the screen resolution
16 | vec2 st = gl_FragCoord.xy/u_resolution;
17 | vec2 st2 = st * 10.0;
18 | st2 = fract(st2);
19 | // st2 = fract(st2) * 1.0/st;
20 | // if (mod(floor(st.x * 10.0),2.0) == 0.0) {
21 | // st2 = st * 30.0;
22 | // st2 = fract(st2);
23 | // // st2 = 1.0 - st2;
24 | // }
25 | gl_FragColor = vec4(0.0, st2.x, st2.y, 1.0);
26 | }
--------------------------------------------------------------------------------
/shader_03.0/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/shader_03.0/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | gl = canvas.getContext('webgl', {}),
4 | program,
5 | W = window.innerWidth,
6 | H = window.innerHeight,
7 |
8 | // we have a new global variable that represents the screen size
9 | resolutionUniformLocation,
10 | positionLocation;
11 |
12 | // make the canvas fill the window
13 | canvas.width = W;
14 | canvas.height = H;
15 |
16 |
17 | function initGLData() {
18 | // now we can get some config info
19 | gl.viewport(0, 0, W, H);
20 | // New: just where does the shader store the information about screen resolution?
21 | resolutionUniformLocation = gl.getUniformLocation(program, "u_resolution");
22 |
23 | // New: pass in the width and height of the canvas so we can use it in the shader
24 | gl.uniform2f(resolutionUniformLocation, W, H);
25 |
26 | // Even though we aren't drawing anything really fancy,
27 | // we have to tell the GL Context how much of the screen we are drawing
28 | positionLocation = gl.getAttribLocation(program, "a_position");
29 | gl.enableVertexAttribArray(positionLocation);
30 | var buffer = gl.createBuffer();
31 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
32 | gl.bufferData(
33 | gl.ARRAY_BUFFER,
34 | /**
35 | note that unlike processing or canvas.getContext('2d'),
36 | the screen coordinates are
37 | -1, 1 left to right
38 | 1, -1 top to bottom
39 | and 0, 0 is the center
40 | and because GL is finicky, you have to specify them as floats,
41 | not ints, so add that '.0' to the end
42 | */
43 | new Float32Array([
44 | -1.0, 1.0,
45 | 1.0, 1.0,
46 | -1.0, -1.0,
47 | 1.0, -1.0]),
48 | gl.STATIC_DRAW
49 | );
50 | gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
51 | }
52 |
53 |
54 | function draw() {
55 | // Set clear color to black, fully opaque
56 | gl.clearColor(0.0, 0.0, 0.0, 1.0);
57 | // Clear the color buffer with specified clear color
58 | gl.clear(gl.COLOR_BUFFER_BIT);
59 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
60 | }
61 |
62 |
63 | // ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ ███████╗████████╗██╗ ██╗███████╗███████╗
64 | // ██╔══██╗██╔═══██╗██╔══██╗██║████╗ ██║██╔════╝ ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔════╝
65 | // ██████╔╝██║ ██║██████╔╝██║██╔██╗ ██║██║ ███╗ ███████╗ ██║ ██║ ██║█████╗ █████╗
66 | // ██╔══██╗██║ ██║██╔══██╗██║██║╚██╗██║██║ ██║ ╚════██║ ██║ ██║ ██║██╔══╝ ██╔══╝
67 | // ██████╔╝╚██████╔╝██║ ██║██║██║ ╚████║╚██████╔╝ ███████║ ██║ ╚██████╔╝██║ ██║
68 | // ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
69 |
70 |
71 | // load files
72 | fetch('frag.glsl')
73 | .then(function(response) {
74 | return response.text();
75 | }).then(fragShaderText=>{
76 | // console.log(fragShaderText)
77 | fetch('vert.glsl')
78 | .then(function(response) {
79 | return response.text();
80 | }).then(vertShaderText=>{
81 | // console.log(vertShaderText);
82 | compileGL(fragShaderText, vertShaderText);
83 | initGLData();
84 | requestDraw();
85 | });
86 | });
87 |
88 |
89 |
90 | // build our program
91 | function compileGL(fragShaderText, vertShaderText) {
92 | var frag = loadShader(gl, gl.FRAGMENT_SHADER, fragShaderText);
93 | var vert = loadShader(gl, gl.VERTEX_SHADER, vertShaderText);
94 | program = gl.createProgram();
95 | gl.attachShader(program, vert);
96 | gl.attachShader(program, frag);
97 | gl.linkProgram(program);
98 | gl.useProgram(program);
99 | }
100 |
101 | function requestDraw() {
102 | requestAnimationFrame(draw);
103 | }
104 |
105 | // straight outta mozilla
106 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
107 | function loadShader(gl, type, source) {
108 | const shader = gl.createShader(type);
109 | // Send the source to the shader object
110 | gl.shaderSource(shader, source);
111 | // Compile the shader program
112 | gl.compileShader(shader);
113 | // See if it compiled successfully
114 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
115 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
116 | gl.deleteShader(shader);
117 | return null;
118 | }
119 | return shader;
120 | }
121 |
122 |
123 |
124 | })();
125 |
126 |
--------------------------------------------------------------------------------
/shader_03.0/vert.glsl:
--------------------------------------------------------------------------------
1 | attribute vec2 a_position;
2 |
3 | void main() {
4 | gl_Position = vec4(a_position, 0, 1);
5 | }
--------------------------------------------------------------------------------
/shader_03.1/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | uniform float u_time;
6 | uniform vec2 u_resolution;
7 |
8 | float circle(in vec2 st, in float radius ) {
9 | vec2 l = st - vec2(0.5);
10 | return 1.0 - smoothstep(
11 | radius - radius * 0.01,
12 | radius + radius * 0.01,
13 | dot(l,l) * 4.0
14 | );
15 |
16 | }
17 |
18 |
19 | void main() {
20 | vec2 st = gl_FragCoord.xy/min(u_resolution.x,u_resolution.y);
21 | vec3 rgb = vec3(0.0);
22 | // vec2 st2 = st * 10.0;
23 | vec2 st2 = st * 5.0;
24 | // float t = u_time / 1000.0;
25 | // st2 *= 0.1 + (sin(t) + 1.0) * 10.0 ;
26 | // st2 *= (1.1 + cos(t) ) * 10.0;
27 | // st2 *= (1.1 + cos(t) * sin(st2.y)*cos(st2.x)) * 10.0;
28 | st2 = fract(st2);
29 | // st2 *= st2;
30 | // rgb = vec3(st2,0.0);
31 | // float c = min(st2.x, st2.y);
32 | // rgb = vec3(c);
33 |
34 | float c = circle(st2,0.5);
35 | // // rgb = vec3(c, 0.5 + 0.5*c, 1.0);
36 | rgb = vec3(c);
37 | // rgb = vec3(c, 1.0-st.x, st.y);
38 | // float c2 = circle(st2,0.15);
39 | // if (c2 > 0.5) {
40 | // rgb = vec3(0.0, 0.0, 0.0);
41 | // // rgb = vec3(c2, 1.0-st.x, st.y);
42 | // }
43 | // rgb = vec3(c, 1.0-st.x, st.y);
44 | gl_FragColor = vec4(rgb,1.0);
45 | }
--------------------------------------------------------------------------------
/shader_03.1/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/shader_03.1/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | gl = canvas.getContext('webgl', {}),
4 | program,
5 | W = window.innerWidth,
6 | H = window.innerHeight,
7 | startTime,
8 |
9 | // we have a new global variable that represents the screen size
10 | timeUniformLocation,
11 | resolutionUniformLocation,
12 | positionLocation;
13 |
14 | // make the canvas fill the window
15 | canvas.width = W;
16 | canvas.height = H;
17 |
18 | function initGLData() {
19 | // now we can get some config info
20 | gl.viewport(0, 0, W, H);
21 | timeUniformLocation = gl.getUniformLocation(program, "u_time");
22 | resolutionUniformLocation = gl.getUniformLocation(program, "u_resolution");
23 | gl.uniform2f(resolutionUniformLocation, W, H);
24 |
25 | // Even though we aren't drawing anything really fancy,
26 | // we have to tell the GL Context how much of the screen we are drawing
27 | positionLocation = gl.getAttribLocation(program, "a_position");
28 | gl.enableVertexAttribArray(positionLocation);
29 | var buffer = gl.createBuffer();
30 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
31 | gl.bufferData(
32 | gl.ARRAY_BUFFER,
33 | /**
34 | note that unlike processing or canvas.getContext('2d'),
35 | the screen coordinates are
36 | -1, 1 left to right
37 | 1, -1 top to bottom
38 | and 0, 0 is the center
39 | and because GL is finicky, you have to specify them as floats,
40 | not ints, so add that '.0' to the end
41 | */
42 | new Float32Array([
43 | -1.0, 1.0,
44 | 1.0, 1.0,
45 | -1.0, -1.0,
46 | 1.0, -1.0]),
47 | gl.STATIC_DRAW
48 | );
49 | gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
50 | }
51 |
52 |
53 | function draw() {
54 | // Set clear color to black, fully opaque
55 | gl.clearColor(0.0, 0.0, 0.0, 1.0);
56 | // Clear the color buffer with specified clear color
57 | gl.clear(gl.COLOR_BUFFER_BIT);
58 | var elapsed = Date.now() - startTime;
59 | gl.uniform1f(timeUniformLocation, elapsed);
60 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
61 | }
62 |
63 |
64 |
65 |
66 | // ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ ███████╗████████╗██╗ ██╗███████╗███████╗
67 | // ██╔══██╗██╔═══██╗██╔══██╗██║████╗ ██║██╔════╝ ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔════╝
68 | // ██████╔╝██║ ██║██████╔╝██║██╔██╗ ██║██║ ███╗ ███████╗ ██║ ██║ ██║█████╗ █████╗
69 | // ██╔══██╗██║ ██║██╔══██╗██║██║╚██╗██║██║ ██║ ╚════██║ ██║ ██║ ██║██╔══╝ ██╔══╝
70 | // ██████╔╝╚██████╔╝██║ ██║██║██║ ╚████║╚██████╔╝ ███████║ ██║ ╚██████╔╝██║ ██║
71 | // ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
72 |
73 |
74 |
75 | // load files
76 | fetch('frag.glsl')
77 | .then(function(response) {
78 | return response.text();
79 | }).then(fragShaderText=>{
80 | // console.log(fragShaderText)
81 | fetch('vert.glsl')
82 | .then(function(response) {
83 | return response.text();
84 | }).then(vertShaderText=>{
85 | // console.log(vertShaderText);
86 | compileGL(fragShaderText, vertShaderText);
87 | initGLData();
88 | startTime = Date.now();
89 | setInterval(requestDraw, 33);
90 | });
91 | });
92 |
93 |
94 |
95 | // build our program
96 | function compileGL(fragShaderText, vertShaderText) {
97 | var frag = loadShader(gl, gl.FRAGMENT_SHADER, fragShaderText);
98 | var vert = loadShader(gl, gl.VERTEX_SHADER, vertShaderText);
99 | program = gl.createProgram();
100 | gl.attachShader(program, vert);
101 | gl.attachShader(program, frag);
102 | gl.linkProgram(program);
103 | gl.useProgram(program);
104 | }
105 |
106 | function requestDraw() {
107 | requestAnimationFrame(draw);
108 | }
109 |
110 | // straight outta mozilla
111 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
112 | function loadShader(gl, type, source) {
113 | const shader = gl.createShader(type);
114 | // Send the source to the shader object
115 | gl.shaderSource(shader, source);
116 | // Compile the shader program
117 | gl.compileShader(shader);
118 | // See if it compiled successfully
119 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
120 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
121 | gl.deleteShader(shader);
122 | return null;
123 | }
124 | return shader;
125 | }
126 |
127 |
128 |
129 |
130 | })();
131 |
132 |
--------------------------------------------------------------------------------
/shader_03.1/vert.glsl:
--------------------------------------------------------------------------------
1 | attribute vec2 a_position;
2 |
3 | void main() {
4 | gl_Position = vec4(a_position, 0, 1);
5 | }
--------------------------------------------------------------------------------
/shader_03.2/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | uniform vec2 u_resolution;
6 |
7 | // New: the image
8 | uniform sampler2D u_image;
9 |
10 | // New: the image coordinate, passed from the vertex shader
11 | varying vec2 v_imagePosition;
12 |
13 | void main(){
14 | vec4 color = texture2D(u_image, v_imagePosition);
15 | // copy the color from the image, and use it for the current pixel
16 | gl_FragColor = color;
17 | // You could also write that as:
18 | // gl_FragColor = color.rgba;
19 |
20 | // And here's where it gets fun. GLSL makes it really easy to switch up the colors
21 | // instead of Roy G Biv, let's Ruth Bader Ginsburg!
22 | // that is swap the blue and green values
23 | // gl_FragColor = color.rbga;
24 | // or we can swap to blue, red, and green
25 | // gl_FragColor = color.brga;
26 |
27 | // it's also trivial to make it negative
28 | // gl_FragColor = vec4(1.0 - color.rgb, 1.0);
29 |
30 | // or grayscale
31 | // float grayscale = max(max(color.r, color.g), color.b);
32 | // gl_FragColor = vec4(vec3(grayscale), 1.0);
33 |
34 | // and we can add a threshold to that to make it black and white
35 | // float bw = step(0.5, grayscale);
36 |
37 | // or instead we can add contrast but not a harsh black and white
38 | // float bw = smoothstep(0.1, 0.8, grayscale);
39 | // gl_FragColor = vec4(vec3(bw), 1.0);
40 |
41 | // or replace white with red
42 | // gl_FragColor = vec4(bw, 0.0, 0.0, 1.0);
43 |
44 | // or replace black with red
45 | // gl_FragColor = vec4(1.0, bw, bw, 1.0);
46 |
47 |
48 |
49 | }
--------------------------------------------------------------------------------
/shader_03.2/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/shader_03.2/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | gl = canvas.getContext('webgl', {}),
4 | program,
5 | W = window.innerWidth,
6 | H = window.innerHeight,
7 |
8 | resolutionUniformLocation,
9 | positionLocation,
10 |
11 | // New: let's mess with an image
12 | img,
13 | // and we will need to pass in image coordinates separate from
14 | // the general vertex positions
15 | imagePositionLocation
16 | ;
17 |
18 | // make the canvas fill the window
19 | canvas.width = W;
20 | canvas.height = H;
21 |
22 |
23 |
24 |
25 | function initGLData() {
26 | // now we can get some config info
27 | gl.viewport(0, 0, W, H);
28 | resolutionUniformLocation = gl.getUniformLocation(program, "u_resolution");
29 | gl.uniform2f(resolutionUniformLocation, W, H);
30 |
31 | // Even though we aren't drawing anything really fancy,
32 | // we have to tell the GL Context how much of the screen we are drawing
33 | positionLocation = gl.getAttribLocation(program, "a_position");
34 | imagePositionLocation = gl.getAttribLocation(program, "a_imagePosition");
35 | gl.enableVertexAttribArray(positionLocation);
36 | var buffer = gl.createBuffer();
37 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
38 | gl.bufferData(
39 | gl.ARRAY_BUFFER,
40 | /**
41 | note that unlike processing or canvas.getContext('2d'),
42 | the screen coordinates are
43 | -1, 1 left to right
44 | 1, -1 top to bottom
45 | and 0, 0 is the center
46 | and because GL is finicky, you have to specify them as floats,
47 | not ints, so add that '.0' to the end
48 | */
49 | new Float32Array([
50 | -1.0, 1.0,
51 | 1.0, 1.0,
52 | -1.0, -1.0,
53 | 1.0, -1.0]),
54 | gl.STATIC_DRAW );
55 | gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
56 |
57 |
58 | // scale the image up to cover
59 | var aspect = W/H,
60 | imgAspect = img.width / img.height,
61 | imgW, imgH,
62 | imgL, imgR,
63 | imgT, imgB;
64 | if (imgAspect == aspect) {
65 | imgH = 1.0;
66 | imgW = 1.0;
67 | imgL = 0.0;
68 | imgT = 0.0;
69 | } else if (imgAspect > aspect) {
70 | imgT = 0.0;
71 | imgH = 1.0;
72 | imgW = aspect / imgAspect;
73 | imgL = (imgW - 1.0) * -.5;
74 | } else {
75 | imgW = 1.0;
76 | imgL = 0.0;
77 | imgH = imgAspect / aspect;
78 | imgT = (imgH - 1.0) * -.5;
79 | imgT = 0.0;
80 | }
81 | imgR = imgL + imgW;
82 | imgB = imgT + imgH;
83 |
84 |
85 | var texCoordBuffer = gl.createBuffer();
86 | gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
87 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
88 | imgL, imgT,
89 | imgR, imgT,
90 | imgL, imgB,
91 | imgR, imgB]), gl.STATIC_DRAW);
92 | gl.enableVertexAttribArray(imagePositionLocation);
93 | gl.vertexAttribPointer(imagePositionLocation, 2, gl.FLOAT, false, 0, 0);
94 |
95 | // Images are referred to as textures, and setting one up
96 | // is a bureaucratic operation.
97 | // Create a texture, and tell the shader that it is the one you want
98 | // to work with. Note that it is not yet attached to our image.
99 | var texture = gl.createTexture();
100 | gl.bindTexture(gl.TEXTURE_2D, texture);
101 |
102 | // Set up texture so we can render any size image and so we are
103 | // working with pixels.
104 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
105 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
106 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
107 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
108 |
109 | // Upload the image into the texture.
110 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
111 | }
112 |
113 |
114 | function draw() {
115 | // Set clear color to black, fully opaque
116 | gl.clearColor(0.0, 0.0, 0.0, 1.0);
117 | // Clear the color buffer with specified clear color
118 | gl.clear(gl.COLOR_BUFFER_BIT);
119 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
120 | }
121 |
122 |
123 |
124 | // ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ ███████╗████████╗██╗ ██╗███████╗███████╗
125 | // ██╔══██╗██╔═══██╗██╔══██╗██║████╗ ██║██╔════╝ ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔════╝
126 | // ██████╔╝██║ ██║██████╔╝██║██╔██╗ ██║██║ ███╗ ███████╗ ██║ ██║ ██║█████╗ █████╗
127 | // ██╔══██╗██║ ██║██╔══██╗██║██║╚██╗██║██║ ██║ ╚════██║ ██║ ██║ ██║██╔══╝ ██╔══╝
128 | // ██████╔╝╚██████╔╝██║ ██║██║██║ ╚████║╚██████╔╝ ███████║ ██║ ╚██████╔╝██║ ██║
129 | // ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
130 |
131 |
132 |
133 |
134 | img = new Image();
135 | img.addEventListener('load', ()=> {
136 | // new: fetch the shaders after the image is loaded
137 | fetch('frag.glsl')
138 | .then(function(response) {
139 | return response.text();
140 | }).then(fragShaderText=>{
141 | // console.log(fragShaderText)
142 | fetch('vert.glsl')
143 | .then(function(response) {
144 | return response.text();
145 | }).then(vertShaderText=>{
146 | // console.log(vertShaderText);
147 | compileGL(fragShaderText, vertShaderText);
148 | initGLData();
149 | requestDraw();
150 | });
151 | });
152 | });
153 | img.src = "../images/home.jpg";
154 | // img.src = "../images/dd.jpeg";
155 |
156 |
157 |
158 |
159 | // build our program
160 | function compileGL(fragShaderText, vertShaderText) {
161 | var frag = loadShader(gl, gl.FRAGMENT_SHADER, fragShaderText);
162 | var vert = loadShader(gl, gl.VERTEX_SHADER, vertShaderText);
163 | program = gl.createProgram();
164 | gl.attachShader(program, vert);
165 | gl.attachShader(program, frag);
166 | gl.linkProgram(program);
167 | gl.useProgram(program);
168 | }
169 |
170 | function requestDraw() {
171 | requestAnimationFrame(draw);
172 | }
173 |
174 | // straight outta mozilla
175 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
176 | function loadShader(gl, type, source) {
177 | const shader = gl.createShader(type);
178 | // Send the source to the shader object
179 | gl.shaderSource(shader, source);
180 | // Compile the shader program
181 | gl.compileShader(shader);
182 | // See if it compiled successfully
183 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
184 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
185 | gl.deleteShader(shader);
186 | return null;
187 | }
188 | return shader;
189 | }
190 |
191 |
192 |
193 | })();
194 |
195 |
--------------------------------------------------------------------------------
/shader_03.2/vert.glsl:
--------------------------------------------------------------------------------
1 | attribute vec2 a_position;
2 |
3 | // New: the image coordinates
4 | // the attribute gets it from the js program
5 | attribute vec2 a_imagePosition;
6 | // and stashes it in the varying version, which allows
7 | // it to pass to the fragment shader
8 | varying vec2 v_imagePosition;
9 |
10 | void main() {
11 | v_imagePosition = a_imagePosition;
12 | gl_Position = vec4(a_position, 0, 1);
13 | }
--------------------------------------------------------------------------------
/shader_03.3/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | uniform float u_time;
6 | uniform vec2 u_resolution;
7 | uniform vec2 u_mouse;
8 |
9 | // New: the image
10 | uniform sampler2D u_image;
11 |
12 | // New: the image coordinate, passed from the vertex shader
13 | varying vec2 v_imagePosition;
14 |
15 | void main(){
16 | vec4 color = texture2D(u_image, v_imagePosition);
17 |
18 | // vec2 xy = fract(v_imagePosition.st * 10.0);
19 | // vec4 color = texture2D(u_image, xy);
20 |
21 | float grayscale = max(max(color.r, color.g), color.b);
22 | // float bw = step(0.5, grayscale);
23 | // or we can soften the edges a bit
24 | float bw = smoothstep(0.3, 0.5, grayscale);
25 |
26 | // we can use that B&W to mask the original color
27 | gl_FragColor = vec4(vec3(bw) * color.rgb, 1.0);
28 |
29 | // or we can use some other color based on pixel position
30 | vec2 st = gl_FragCoord.xy/u_resolution;
31 | float t = u_time / 1000.0;
32 | vec2 mouse = u_mouse/u_resolution;
33 |
34 | vec3 fillColor;
35 | if (st.x < mouse.x) {
36 | fillColor = vec3(abs(sin(t)), st.x, st.y);
37 | } else {
38 | fillColor = vec3(st.y, abs(sin(st.x)), abs(cos(t)));
39 | }
40 |
41 | gl_FragColor = vec4(bw * fillColor, 1.0);
42 | }
--------------------------------------------------------------------------------
/shader_03.3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/shader_03.3/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | gl = canvas.getContext('webgl', {}),
4 | vert,
5 | frag,
6 | program,
7 | W = window.innerWidth,
8 | H = window.innerHeight,
9 | startTime,
10 |
11 | mouseX, mouseY,
12 | mouseUniformLocation,
13 | resolutionUniformLocation,
14 | timeUniformLocation,
15 | positionLocation,
16 |
17 | img,
18 | imagePositionLocation
19 | ;
20 |
21 | // make the canvas fill the window
22 | canvas.width = W;
23 | canvas.height = H;
24 |
25 |
26 | function initGLData() {
27 | // now we can get some config info
28 | gl.viewport(0, 0, W, H);
29 | mouseUniformLocation = gl.getUniformLocation(program, "u_mouse");
30 | resolutionUniformLocation = gl.getUniformLocation(program, "u_resolution");
31 | timeUniformLocation = gl.getUniformLocation(program, "u_time");
32 |
33 | gl.uniform2f(resolutionUniformLocation, W, H);
34 |
35 | // Even though we aren't drawing anything really fancy,
36 | // we have to tell the GL Context how much of the screen we are drawing
37 | positionLocation = gl.getAttribLocation(program, "a_position");
38 | imagePositionLocation = gl.getAttribLocation(program, "a_imagePosition");
39 | gl.enableVertexAttribArray(positionLocation);
40 | var buffer = gl.createBuffer();
41 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
42 | gl.bufferData(
43 | gl.ARRAY_BUFFER,
44 | /**
45 | note that unlike processing or canvas.getContext('2d'),
46 | the screen coordinates are
47 | -1, 1 left to right
48 | 1, -1 top to bottom
49 | and 0, 0 is the center
50 | and because GL is finicky, you have to specify them as floats,
51 | not ints, so add that '.0' to the end
52 | */
53 | new Float32Array([
54 | -1.0, 1.0,
55 | 1.0, 1.0,
56 | -1.0, -1.0,
57 | 1.0, -1.0]),
58 | gl.STATIC_DRAW );
59 | gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
60 |
61 |
62 | // scale the image up to cover
63 | var aspect = W/H,
64 | imgAspect = img.width / img.height,
65 | imgW, imgH,
66 | imgL, imgR,
67 | imgT, imgB;
68 | if (imgAspect == aspect) {
69 | imgH = 1.0;
70 | imgW = 1.0;
71 | imgL = 0.0;
72 | imgT = 0.0;
73 | } else if (imgAspect > aspect) {
74 | imgT = 0.0;
75 | imgH = 1.0;
76 | imgW = aspect / imgAspect;
77 | imgL = (imgW - 1.0) * -.5;
78 | } else {
79 | imgW = 1.0;
80 | imgL = 0.0;
81 | imgH = imgAspect / aspect;
82 | imgT = (imgH - 1.0) * -.5;
83 | imgT = 0.0;
84 | }
85 | imgR = imgL + imgW;
86 | imgB = imgT + imgH;
87 |
88 |
89 | var texCoordBuffer = gl.createBuffer();
90 | gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
91 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
92 | imgL, imgT,
93 | imgR, imgT,
94 | imgL, imgB,
95 | imgR, imgB]), gl.STATIC_DRAW);
96 | gl.enableVertexAttribArray(imagePositionLocation);
97 | gl.vertexAttribPointer(imagePositionLocation, 2, gl.FLOAT, false, 0, 0);
98 |
99 | var texture = gl.createTexture();
100 | gl.bindTexture(gl.TEXTURE_2D, texture);
101 |
102 | // Set the parameters so we can render any size image.
103 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
104 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
105 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
106 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
107 |
108 | // Upload the image into the texture.
109 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
110 | }
111 |
112 |
113 | function draw() {
114 | // Set clear color to black, fully opaque
115 | gl.clearColor(0.0, 0.0, 0.0, 1.0);
116 | // Clear the color buffer with specified clear color
117 | gl.clear(gl.COLOR_BUFFER_BIT);
118 | var elapsed = Date.now() - startTime;
119 | gl.uniform1f(timeUniformLocation, elapsed);
120 | gl.uniform2f(mouseUniformLocation, mouseX, mouseY);
121 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
122 | }
123 |
124 | // ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ ███████╗████████╗██╗ ██╗███████╗███████╗
125 | // ██╔══██╗██╔═══██╗██╔══██╗██║████╗ ██║██╔════╝ ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔════╝
126 | // ██████╔╝██║ ██║██████╔╝██║██╔██╗ ██║██║ ███╗ ███████╗ ██║ ██║ ██║█████╗ █████╗
127 | // ██╔══██╗██║ ██║██╔══██╗██║██║╚██╗██║██║ ██║ ╚════██║ ██║ ██║ ██║██╔══╝ ██╔══╝
128 | // ██████╔╝╚██████╔╝██║ ██║██║██║ ╚████║╚██████╔╝ ███████║ ██║ ╚██████╔╝██║ ██║
129 | // ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
130 |
131 |
132 |
133 |
134 | img = new Image();
135 | img.addEventListener('load', ()=> {
136 | // new: fetch the shaders after the image is loaded
137 | fetch('frag.glsl')
138 | .then(function(response) {
139 | return response.text();
140 | }).then(fragShaderText=>{
141 | // console.log(fragShaderText)
142 | fetch('vert.glsl')
143 | .then(function(response) {
144 | return response.text();
145 | }).then(vertShaderText=>{
146 | // console.log(vertShaderText);
147 | compileGL(fragShaderText, vertShaderText);
148 | initGLData();
149 | startTime = Date.now();
150 | canvas.addEventListener('mousemove',(event) => {
151 | mouseX = event.offsetX;
152 | mouseY = event.offsetY;
153 | });
154 | setInterval(requestDraw, 30);
155 | });
156 | });
157 | });
158 | img.src = "../images/home.jpg";
159 | // img.src = "../images/dd.jpeg";
160 |
161 |
162 |
163 |
164 |
165 | // build our program
166 | function compileGL(fragShaderText, vertShaderText) {
167 | var frag = loadShader(gl, gl.FRAGMENT_SHADER, fragShaderText);
168 | var vert = loadShader(gl, gl.VERTEX_SHADER, vertShaderText);
169 | program = gl.createProgram();
170 | gl.attachShader(program, vert);
171 | gl.attachShader(program, frag);
172 | gl.linkProgram(program);
173 | gl.useProgram(program);
174 | }
175 |
176 | function requestDraw() {
177 | requestAnimationFrame(draw);
178 | }
179 |
180 | // straight outta mozilla
181 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
182 | function loadShader(gl, type, source) {
183 | const shader = gl.createShader(type);
184 | // Send the source to the shader object
185 | gl.shaderSource(shader, source);
186 | // Compile the shader program
187 | gl.compileShader(shader);
188 | // See if it compiled successfully
189 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
190 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
191 | gl.deleteShader(shader);
192 | return null;
193 | }
194 | return shader;
195 | }
196 |
197 |
198 | })();
199 |
200 |
--------------------------------------------------------------------------------
/shader_03.3/vert.glsl:
--------------------------------------------------------------------------------
1 | attribute vec2 a_position;
2 |
3 |
4 | // New: the image coordinates
5 | // the attribute gets it from the js program
6 | attribute vec2 a_imagePosition;
7 | // and stashes it in the varying version, which allows
8 | // it to pass to the fragment shader
9 | varying vec2 v_imagePosition;
10 |
11 | void main() {
12 | v_imagePosition = a_imagePosition;
13 | gl_Position = vec4(a_position, 0, 1);
14 | }
--------------------------------------------------------------------------------
/shader_03.4/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | uniform float u_time;
6 | uniform vec2 u_resolution;
7 | uniform vec2 u_mouse;
8 | uniform float u_matrix[9];
9 |
10 |
11 | // New: the image
12 | uniform sampler2D u_image;
13 |
14 | // New: the image coordinate, passed from the vertex shader
15 | varying vec2 v_imagePosition;
16 |
17 | void main(){
18 | vec4 color = vec4(vec3(0.0), 1.0);
19 | for ( float i=0.0;i < 9.0;i++) {
20 | float xoff = mod(i, 3.0) - 1.0;
21 | float yoff = floor(i / 3.0) - 1.0;
22 | vec2 coord = vec2(xoff, yoff) / u_resolution;
23 | vec4 c = texture2D(u_image, v_imagePosition.st + coord);
24 | float matVal = u_matrix[int(i)];
25 | color += matVal * c;
26 | }
27 | float gray = max(max(color.r, color.g), color.b);
28 | // gray = pow(gray, .25);
29 | color = texture2D(u_image, v_imagePosition);
30 | color.rgb = vec3(gray);
31 | // color.rgb = vec3(pow(color.r, .5), pow(color.g, .5), pow(color.b, .5));
32 | gl_FragColor = color;
33 | }
--------------------------------------------------------------------------------
/shader_03.4/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/shader_03.4/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | gl = canvas.getContext('webgl', {}),
4 | program,
5 | W = window.innerWidth,
6 | H = window.innerHeight,
7 | startTime,
8 | frameCount = 0,
9 |
10 | mouseX, mouseY,
11 | mouseUniformLocation,
12 | resolutionUniformLocation,
13 | timeUniformLocation,
14 | matrixUniformLocation,
15 | positionLocation,
16 |
17 | // New: let's mess with an image
18 | img,
19 | // and we will need to pass in image coordinates separate from
20 | // the general vertex positions
21 | imagePositionLocation
22 | ;
23 |
24 | // make the canvas fill the window
25 | canvas.width = W;
26 | canvas.height = H;
27 |
28 |
29 | function initGLData() {
30 | // now we can get some config info
31 | gl.viewport(0, 0, W, H);
32 | mouseUniformLocation = gl.getUniformLocation(program, "u_mouse");
33 | resolutionUniformLocation = gl.getUniformLocation(program, "u_resolution");
34 | timeUniformLocation = gl.getUniformLocation(program, "u_time");
35 | matrixUniformLocation = gl.getUniformLocation(program, "u_matrix");
36 |
37 | gl.uniform2f(resolutionUniformLocation, W, H);
38 |
39 | // Even though we aren't drawing anything really fancy,
40 | // we have to tell the GL Context how much of the screen we are drawing
41 | positionLocation = gl.getAttribLocation(program, "a_position");
42 | imagePositionLocation = gl.getAttribLocation(program, "a_imagePosition");
43 | gl.enableVertexAttribArray(positionLocation);
44 | var buffer = gl.createBuffer();
45 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
46 | gl.bufferData(
47 | gl.ARRAY_BUFFER,
48 | /**
49 | note that unlike processing or canvas.getContext('2d'),
50 | the screen coordinates are
51 | -1, 1 left to right
52 | 1, -1 top to bottom
53 | and 0, 0 is the center
54 | and because GL is finicky, you have to specify them as floats,
55 | not ints, so add that '.0' to the end
56 | */
57 | new Float32Array([
58 | -1.0, 1.0,
59 | 1.0, 1.0,
60 | -1.0, -1.0,
61 | 1.0, -1.0]),
62 | gl.STATIC_DRAW );
63 | gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
64 |
65 |
66 |
67 | // scale the image up to cover
68 | var aspect = W/H,
69 | imgAspect = img.width / img.height,
70 | imgW, imgH,
71 | imgL, imgR,
72 | imgT, imgB;
73 | if (imgAspect == aspect) {
74 | imgH = 1.0;
75 | imgW = 1.0;
76 | imgL = 0.0;
77 | imgT = 0.0;
78 | } else if (imgAspect > aspect) {
79 | imgT = 0.0;
80 | imgH = 1.0;
81 | imgW = aspect / imgAspect;
82 | imgL = (imgW - 1.0) * -.5;
83 | } else {
84 | imgW = 1.0;
85 | imgL = 0.0;
86 | imgH = imgAspect / aspect;
87 | imgT = (imgH - 1.0) * -.5;
88 | imgT = 0.0;
89 | }
90 | imgR = imgL + imgW;
91 | imgB = imgT + imgH;
92 |
93 |
94 | var texCoordBuffer = gl.createBuffer();
95 | gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
96 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
97 | imgL, imgT,
98 | imgR, imgT,
99 | imgL, imgB,
100 | imgR, imgB]), gl.STATIC_DRAW);
101 | gl.enableVertexAttribArray(imagePositionLocation);
102 | gl.vertexAttribPointer(imagePositionLocation, 2, gl.FLOAT, false, 0, 0);
103 |
104 | var texture = gl.createTexture();
105 | gl.bindTexture(gl.TEXTURE_2D, texture);
106 |
107 | // Set the parameters so we can render any size image.
108 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
109 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
110 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
111 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
112 |
113 | // Upload the image into the texture.
114 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
115 | /*****
116 |
117 | Try these different versions of the 'matrix' variable
118 | to get different effects in the image.
119 |
120 |
121 | **/
122 | // set the matrix
123 | // var matrix = [0, 0, 0,
124 | // 0, 1.0, 0,
125 | // 0, 0, 0]; // untransformed
126 | // var matrix = [-1, -1, -1,
127 | // -1, 8, -1,
128 | // -1, -1, -1]; // edge
129 | // var matrix = [-1, -1, -1,
130 | // -1, 9, -1,
131 | // -1, -1, -1]; // sharpen
132 | // var matrix = [-1, 1, 1,
133 | // -1, .5, 1,
134 | // -1, -1, 1]; // emboss
135 | // var matrix = [1/9.0, 1/9.0, 1/9.0,
136 | // 1/9.0, 1/9.0, 1/9.0,
137 | // 1/9.0, 1/9.0, 1/9.0]; // blur
138 | var matrix = [0, 2, 0,
139 | -2, 0, 2,
140 | 0, -2, 0]; // gettin' wiggy!
141 | gl.uniform1fv(matrixUniformLocation, matrix);
142 | }
143 |
144 |
145 | function draw() {
146 | // Set clear color to black, fully opaque
147 | gl.clearColor(0.0, 0.0, 0.0, 1.0);
148 | // Clear the color buffer with specified clear color
149 | gl.clear(gl.COLOR_BUFFER_BIT);
150 | var elapsed = Date.now() - startTime;
151 | gl.uniform1f(timeUniformLocation, elapsed / 1000.0);
152 | gl.uniform2f(mouseUniformLocation, mouseX, mouseY);
153 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
154 | }
155 |
156 |
157 |
158 |
159 | // ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ ███████╗████████╗██╗ ██╗███████╗███████╗
160 | // ██╔══██╗██╔═══██╗██╔══██╗██║████╗ ██║██╔════╝ ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔════╝
161 | // ██████╔╝██║ ██║██████╔╝██║██╔██╗ ██║██║ ███╗ ███████╗ ██║ ██║ ██║█████╗ █████╗
162 | // ██╔══██╗██║ ██║██╔══██╗██║██║╚██╗██║██║ ██║ ╚════██║ ██║ ██║ ██║██╔══╝ ██╔══╝
163 | // ██████╔╝╚██████╔╝██║ ██║██║██║ ╚████║╚██████╔╝ ███████║ ██║ ╚██████╔╝██║ ██║
164 | // ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
165 |
166 |
167 |
168 |
169 | img = new Image();
170 | img.addEventListener('load', ()=> {
171 | // new: fetch the shaders after the image is loaded
172 | fetch('frag.glsl')
173 | .then(function(response) {
174 | return response.text();
175 | }).then(fragShaderText=>{
176 | // console.log(fragShaderText)
177 | fetch('vert.glsl')
178 | .then(function(response) {
179 | return response.text();
180 | }).then(vertShaderText=>{
181 | // console.log(vertShaderText);
182 | compileGL(fragShaderText, vertShaderText);
183 | initGLData();
184 | requestDraw();
185 | });
186 | });
187 | });
188 | img.src = "../images/home.jpg";
189 | // img.src = "../images/dd.jpeg";
190 |
191 |
192 |
193 |
194 | // build our program
195 | function compileGL(fragShaderText, vertShaderText) {
196 | var frag = loadShader(gl, gl.FRAGMENT_SHADER, fragShaderText);
197 | var vert = loadShader(gl, gl.VERTEX_SHADER, vertShaderText);
198 | program = gl.createProgram();
199 | gl.attachShader(program, vert);
200 | gl.attachShader(program, frag);
201 | gl.linkProgram(program);
202 | gl.useProgram(program);
203 | }
204 |
205 | function requestDraw() {
206 | requestAnimationFrame(draw);
207 | }
208 |
209 | // straight outta mozilla
210 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
211 | function loadShader(gl, type, source) {
212 | const shader = gl.createShader(type);
213 | // Send the source to the shader object
214 | gl.shaderSource(shader, source);
215 | // Compile the shader program
216 | gl.compileShader(shader);
217 | // See if it compiled successfully
218 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
219 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
220 | gl.deleteShader(shader);
221 | return null;
222 | }
223 | return shader;
224 | }
225 |
226 |
227 | })();
228 |
229 |
--------------------------------------------------------------------------------
/shader_03.4/vert.glsl:
--------------------------------------------------------------------------------
1 | attribute vec2 a_position;
2 |
3 |
4 | // New: the image coordinates
5 | // the attribute gets it from the js program
6 | attribute vec2 a_imagePosition;
7 | // and stashes it in the varying version, which allows
8 | // it to pass to the fragment shader
9 | varying vec2 v_imagePosition;
10 |
11 | void main() {
12 | v_imagePosition = a_imagePosition;
13 | gl_Position = vec4(a_position, 0, 1);
14 | }
--------------------------------------------------------------------------------
/shader_04.0/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | // New: a place where we can get a color passed from the wertex shader
6 | varying vec4 v_color;
7 |
8 | void main(){
9 | gl_FragColor = v_color;
10 | }
--------------------------------------------------------------------------------
/shader_04.0/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/shader_04.0/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | gl = canvas.getContext('webgl', {}),
4 | program,
5 | W = window.innerWidth,
6 | H = window.innerHeight,
7 |
8 | positionLocation,
9 |
10 | // New: we are going to pass some colors from js to the shader
11 | colorLocation
12 | ;
13 |
14 | // make the canvas fill the window
15 | canvas.width = W;
16 | canvas.height = H;
17 |
18 | function initGLData() {
19 | // now we can get some config info
20 | gl.viewport(0, 0, W, H);
21 |
22 | positionLocation = gl.getAttribLocation(program, "a_position");
23 | gl.enableVertexAttribArray(positionLocation);
24 | var buffer = gl.createBuffer();
25 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
26 | gl.bufferData(
27 | gl.ARRAY_BUFFER,
28 | /**
29 | note that unlike processing or canvas.getContext('2d'),
30 | the screen coordinates are
31 | -1, 1 left to right
32 | 1, -1 top to bottom
33 | and 0, 0 is the center
34 | and because GL is finicky, you have to specify them as floats,
35 | not ints, so add that '.0' to the end
36 | */
37 | new Float32Array([
38 | -1.0, 1.0,
39 | 1.0, 1.0,
40 | -1.0, -1.0,
41 | 1.0, -1.0
42 | ]),
43 | gl.STATIC_DRAW
44 | );
45 | gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
46 |
47 |
48 | // New: get the place where the shader wants us to put colors
49 | colorLocation = gl.getAttribLocation(program, "a_color");
50 | gl.enableVertexAttribArray(colorLocation);
51 | buffer = gl.createBuffer();
52 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
53 | gl.bufferData(gl.ARRAY_BUFFER,
54 | // we send over a color for each vertex
55 | new Float32Array([
56 | 1.0, 1.0, 1.0, 1.0, // white
57 | 1.0, 0.0, 0.0, 1.0, // red
58 | 0.0, 1.0, 0.0, 1.0, // green
59 | 0.0, 0.0, 1.0, 1.0, // blue
60 | ]),
61 | gl.STATIC_DRAW);
62 | gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0);
63 |
64 | }
65 |
66 |
67 |
68 |
69 | function draw() {
70 | // Set clear color to black, fully opaque
71 | gl.clearColor(0.0, 0.0, 0.0, 1.0);
72 | // Clear the color buffer with specified clear color
73 | gl.clear(gl.COLOR_BUFFER_BIT);
74 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
75 | }
76 |
77 |
78 |
79 |
80 |
81 |
82 | // ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ ███████╗████████╗██╗ ██╗███████╗███████╗
83 | // ██╔══██╗██╔═══██╗██╔══██╗██║████╗ ██║██╔════╝ ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔════╝
84 | // ██████╔╝██║ ██║██████╔╝██║██╔██╗ ██║██║ ███╗ ███████╗ ██║ ██║ ██║█████╗ █████╗
85 | // ██╔══██╗██║ ██║██╔══██╗██║██║╚██╗██║██║ ██║ ╚════██║ ██║ ██║ ██║██╔══╝ ██╔══╝
86 | // ██████╔╝╚██████╔╝██║ ██║██║██║ ╚████║╚██████╔╝ ███████║ ██║ ╚██████╔╝██║ ██║
87 | // ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
88 |
89 |
90 | // load files
91 | fetch('frag.glsl')
92 | .then(function(response) {
93 | return response.text();
94 | }).then(fragShaderText=>{
95 | // console.log(fragShaderText)
96 | fetch('vert.glsl')
97 | .then(function(response) {
98 | return response.text();
99 | }).then(vertShaderText=>{
100 | // console.log(vertShaderText);
101 | compileGL(fragShaderText, vertShaderText);
102 | initGLData();
103 | requestDraw();
104 | });
105 | });
106 |
107 |
108 |
109 | // build our program
110 | function compileGL(fragShaderText, vertShaderText) {
111 | var frag = loadShader(gl, gl.FRAGMENT_SHADER, fragShaderText);
112 | var vert = loadShader(gl, gl.VERTEX_SHADER, vertShaderText);
113 | program = gl.createProgram();
114 | gl.attachShader(program, vert);
115 | gl.attachShader(program, frag);
116 | gl.linkProgram(program);
117 | gl.useProgram(program);
118 | }
119 |
120 | function requestDraw() {
121 | requestAnimationFrame(draw);
122 | }
123 |
124 | // straight outta mozilla
125 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
126 | function loadShader(gl, type, source) {
127 | const shader = gl.createShader(type);
128 | // Send the source to the shader object
129 | gl.shaderSource(shader, source);
130 | // Compile the shader program
131 | gl.compileShader(shader);
132 | // See if it compiled successfully
133 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
134 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
135 | gl.deleteShader(shader);
136 | return null;
137 | }
138 | return shader;
139 | }
140 |
141 |
142 | })();
143 |
144 |
--------------------------------------------------------------------------------
/shader_04.0/vert.glsl:
--------------------------------------------------------------------------------
1 | attribute vec2 a_position;
2 | // New: a place to get the color passed from js
3 | attribute vec4 a_color;
4 |
5 | // New: a place where we can tell the fragment shader what the color is
6 | varying vec4 v_color;
7 |
8 | void main() {
9 | gl_Position = vec4(a_position, 0, 1);
10 | v_color = a_color;
11 | }
--------------------------------------------------------------------------------
/shader_04.1/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | varying vec4 v_color;
6 |
7 | void main(){
8 | gl_FragColor = v_color;
9 | }
--------------------------------------------------------------------------------
/shader_04.1/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/shader_04.1/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | gl = canvas.getContext('webgl', {}),
4 | program,
5 | W = window.innerWidth,
6 | H = window.innerHeight,
7 |
8 |
9 |
10 | positionLocation,
11 | colorLocation,
12 |
13 | resolutionUniformLocation,
14 |
15 |
16 | // New: we are going to start moving the vertices around in space.
17 | // Or more accuratly, we are going to move the space in which
18 | // the vertices are placed. According to convention, the layout
19 | // of the vertices is called the "model".
20 | modelUniform,
21 |
22 | // New: to move the vertices, we will use math! Each type of motion
23 | // will be in its own matrix.
24 | translationMatrix,
25 | rotationMatrix,
26 | scaleMatrix,
27 | //And then we will merge all different types of motion into one matrix
28 | // to hand over to the shader
29 | modelMatrix
30 |
31 | ;
32 |
33 | // make the canvas fill the window
34 | canvas.width = W;
35 | canvas.height = H;
36 |
37 |
38 |
39 | function initGLData() {
40 | // now we can get some config info
41 | gl.viewport(0, 0, W, H);
42 |
43 | resolutionUniformLocation = gl.getUniformLocation(program, "u_resolution");
44 | gl.uniform2f(resolutionUniformLocation, W, H);
45 |
46 | // New: where does the shader store the model
47 | modelUniform = gl.getUniformLocation(program, "u_model");
48 | // There are several ways we will move the model, and we will
49 | // track each in its own matrix.
50 | // Translation is the technical term for changing the location.
51 | translationMatrix = mat4.create();
52 | // Rotation rotates
53 | rotationMatrix = mat4.create();
54 | // and scale isgrowing or shrinking
55 | scaleMatrix = mat4.create();
56 | // we will combine translation, rotation, and scale into one matrix
57 | modelMatrix = mat4.create();
58 |
59 | // move the drawing position a bit to where we want to
60 | // start drawing the square.
61 | // note: with glmatrix.js, the first parameter
62 | // is always the matrix that you are writing to. Any values
63 | // in that matrix will be overwritten.
64 | mat4.translate(
65 | translationMatrix, // the matrix that tracks the translated location
66 | translationMatrix, // matrix to start from (which is not moved at this point)
67 | [-0.25, 0.25, 0.0]); // amount to translate
68 |
69 | mat4.rotate(
70 | rotationMatrix, // the matrix that tracks the rotation
71 | rotationMatrix, // matrix to to start from (unrotated here)
72 | Math.PI * .25, // amount to rotate it
73 | [0, 0, 1] // the axis it rotates around: the center of the square
74 | );
75 |
76 | mat4.scale(
77 | scaleMatrix, // the matrix that will track the scaling
78 | scaleMatrix, // source matrix
79 | [2, .5, 1.0]); // the scaling amount in the x, y, and z directions
80 |
81 |
82 | // the positions of our vertices
83 | var corners = [
84 | 0.0, 0.5,
85 | 0.75, 0.0,
86 | -0.5, -0.0,
87 | 0.0, -0.5
88 | ];
89 | // the colors for each vertex
90 | var colors = [
91 | 1.0, 1.0, 1.0, 1.0, // white
92 | 1.0, 0.0, 0.0, 1.0, // red
93 | 0.0, 1.0, 0.0, 1.0, // green
94 | 0.0, 0.0, 1.0, 1.0, // blue,
95 | ];
96 |
97 | // pass our vertex locations to the vertex shader
98 | positionLocation = gl.getAttribLocation(program, "a_position");
99 | var positionBuffer = gl.createBuffer();
100 | gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
101 | gl.bufferData( gl.ARRAY_BUFFER, new Float32Array(corners), gl.STATIC_DRAW);
102 | gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
103 | gl.enableVertexAttribArray(positionLocation);
104 |
105 | colorLocation = gl.getAttribLocation(program, "a_color");
106 | gl.enableVertexAttribArray(colorLocation);
107 | var colorBuffer = gl.createBuffer();
108 | gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
109 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
110 | gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0);
111 | gl.enableVertexAttribArray(colorLocation);
112 | }
113 |
114 |
115 |
116 |
117 | function draw() {
118 | // Set clear color to black, fully opaque
119 | gl.clearColor(0.0, 0.0, 0.0, 1.0);
120 | gl.clearDepth(1.0);
121 | // Clear the color buffer with specified clear color
122 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
123 |
124 |
125 | // New: combine the translation matrix and rotation matrix,
126 | // and store it in the modelMatrix
127 | mat4.multiply(modelMatrix, translationMatrix, rotationMatrix);
128 |
129 | // if you want to scale the positions as well,
130 | // mulitply the model matrix by the scale matrix
131 | // mat4.multiply(modelMatrix, modelMatrix, scaleMatrix);
132 |
133 | // order matters! Instead of translation and rotation first, try scaling and rotation first
134 | // mat4.multiply(modelMatrix, scaleMatrix, rotationMatrix);
135 | // mat4.multiply(modelMatrix, modelMatrix, translationMatrix);
136 |
137 | // make the rotation change a little each frame
138 | // mat4.rotate(
139 | // rotationMatrix, // destination matrix
140 | // rotationMatrix, // matrix to rotate
141 | // Math.PI * .01 , // amount it rotates each frame
142 | // [0, 0, 1] // the axis it rotates around: the center of the square
143 | // );
144 |
145 | gl.uniformMatrix4fv(modelUniform, false, modelMatrix);
146 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
147 | }
148 |
149 |
150 |
151 |
152 |
153 |
154 | // ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ ███████╗████████╗██╗ ██╗███████╗███████╗
155 | // ██╔══██╗██╔═══██╗██╔══██╗██║████╗ ██║██╔════╝ ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔════╝
156 | // ██████╔╝██║ ██║██████╔╝██║██╔██╗ ██║██║ ███╗ ███████╗ ██║ ██║ ██║█████╗ █████╗
157 | // ██╔══██╗██║ ██║██╔══██╗██║██║╚██╗██║██║ ██║ ╚════██║ ██║ ██║ ██║██╔══╝ ██╔══╝
158 | // ██████╔╝╚██████╔╝██║ ██║██║██║ ╚████║╚██████╔╝ ███████║ ██║ ╚██████╔╝██║ ██║
159 | // ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
160 |
161 |
162 | // load files
163 | fetch('frag.glsl')
164 | .then(function(response) {
165 | return response.text();
166 | }).then(fragShaderText=>{
167 | // console.log(fragShaderText)
168 | fetch('vert.glsl')
169 | .then(function(response) {
170 | return response.text();
171 | }).then(vertShaderText=>{
172 | // console.log(vertShaderText);
173 | compileGL(fragShaderText, vertShaderText);
174 | initGLData();
175 | setInterval(requestDraw, 33);
176 | });
177 | });
178 |
179 |
180 |
181 | // build our program
182 | function compileGL(fragShaderText, vertShaderText) {
183 | var frag = loadShader(gl, gl.FRAGMENT_SHADER, fragShaderText);
184 | var vert = loadShader(gl, gl.VERTEX_SHADER, vertShaderText);
185 | program = gl.createProgram();
186 | gl.attachShader(program, vert);
187 | gl.attachShader(program, frag);
188 | gl.linkProgram(program);
189 | gl.useProgram(program);
190 | }
191 |
192 | function requestDraw() {
193 | requestAnimationFrame(draw);
194 | }
195 |
196 | // straight outta mozilla
197 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
198 | function loadShader(gl, type, source) {
199 | const shader = gl.createShader(type);
200 | // Send the source to the shader object
201 | gl.shaderSource(shader, source);
202 | // Compile the shader program
203 | gl.compileShader(shader);
204 | // See if it compiled successfully
205 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
206 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
207 | gl.deleteShader(shader);
208 | return null;
209 | }
210 | return shader;
211 | }
212 |
213 |
214 | })();
215 |
216 |
--------------------------------------------------------------------------------
/shader_04.1/vert.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | attribute vec4 a_position;
6 | attribute vec4 a_color;
7 |
8 | varying vec4 v_color;
9 |
10 | uniform mat4 u_model;
11 |
12 | uniform vec2 u_resolution;
13 |
14 | void main() {
15 | float s = min(u_resolution.x, u_resolution.y);
16 | vec4 scale = vec4(vec2(s, s) / u_resolution, 1.0, 1.0);
17 | gl_Position = u_model * a_position * scale;
18 | v_color = a_color;
19 | }
--------------------------------------------------------------------------------
/shader_04.2/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | varying vec4 v_color;
6 |
7 | void main(){
8 | gl_FragColor = v_color;
9 | }
--------------------------------------------------------------------------------
/shader_04.2/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/shader_04.2/vert.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | attribute vec4 a_position;
6 | attribute vec4 a_color;
7 |
8 | varying vec4 v_color;
9 |
10 | uniform mat4 u_model;
11 | uniform mat4 u_projection;
12 |
13 | void main() {
14 | gl_Position = u_projection * u_model * a_position;
15 | v_color = a_color;
16 | }
--------------------------------------------------------------------------------
/shader_04.3/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | varying vec4 v_color;
6 |
7 | void main(){
8 | gl_FragColor = v_color;
9 | }
--------------------------------------------------------------------------------
/shader_04.3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/shader_04.3/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | gl = canvas.getContext('webgl', {}),
4 | program,
5 | W = window.innerWidth,
6 | H = window.innerHeight,
7 | startTime,
8 |
9 | positionLocation,
10 | colorLocation,
11 |
12 | modelUniform,
13 |
14 |
15 | // New: we are going to define where we are watching from,
16 | // which will enable a sense of foreshortening
17 | projectionUniform,
18 | // the matrix for the projection that will be passed to the shader
19 | projectionMatrix,
20 |
21 | translationMatrix,
22 | rotationMatrix,
23 | scaleMatrix,
24 |
25 | modelMatrix,
26 |
27 | pointCount
28 |
29 | ;
30 |
31 |
32 | const ARC_PRECISION = 50;
33 |
34 | // make the canvas fill the window
35 | canvas.width = W;
36 | canvas.height = H;
37 |
38 |
39 |
40 | function initGLData() {
41 | // now we can get some config info
42 | gl.viewport(0, 0, W, H);
43 |
44 | // New: get the locations where the shader wants the model and projection
45 | modelUniform = gl.getUniformLocation(program, "u_model");
46 | // We will be positioning things in 3d space, so tell the program
47 | // how we want it to handle things behind or in front of each other
48 | gl.enable(gl.DEPTH_TEST);
49 | gl.depthFunc(gl.LEQUAL);
50 |
51 | // straight from mozilla!
52 | // Create a perspective matrix, a special matrix that is
53 | // used to simulate the distortion of perspective in a camera.
54 | // Our field of view is 45 degrees, with a width/height
55 | // ratio that matches the display size of the canvas
56 | // and we only want to see objects between 0.1 units
57 | // and 100 units away from the camera.
58 | const fieldOfView = 45 * Math.PI / 180; // in radians
59 | const aspect = W / H;
60 | const zNear = 0.1;
61 | const zFar = 100.0;
62 | projectionMatrix = mat4.create();
63 | projectionUniform = gl.getUniformLocation(program, "u_projection");
64 |
65 | // note: with glmatrix.js, the first parameter
66 | // is always the matrix that you are writing to. Any values
67 | // in that matrix will be overwritten.
68 | mat4.perspective(projectionMatrix,
69 | fieldOfView,
70 | aspect,
71 | zNear,
72 | zFar);
73 |
74 | translationMatrix = mat4.create();
75 | rotationMatrix = mat4.create();
76 | scaleMatrix = mat4.create();
77 | modelMatrix = mat4.create();
78 | // Now move the drawing position a bit to where we want to
79 | // start drawing the square.
80 | mat4.translate(
81 | translationMatrix, // the matrix that tracks the translated location
82 | translationMatrix, // matrix to start from (which is not moved at this point)
83 | [-0.0, 0.0, -6.0]); // amount to translate
84 |
85 | mat4.rotate(
86 | rotationMatrix, // the matrix that tracks the rotation
87 | rotationMatrix, // matrix to to start from (unrotated here)
88 | Math.PI * .25, // amount to rotate it
89 | [0, 0, 1] // the axis it rotates around: the center of the square
90 | );
91 |
92 | positionLocation = gl.getAttribLocation(program, "a_position");
93 | var positionBuffer = gl.createBuffer();
94 | gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
95 |
96 |
97 | // New: we will creatig a lot or vertices, too many to hand curate the
98 | // color for each vertex. So here we create a list of colors, which we
99 | // will draw from programmatically as we set up the sphere coordinates.
100 | const colorSources = [
101 | [1.0, 1.0, 1.0, 1.0], // white
102 | [1.0, 0.0, 0.0, 1.0], // red
103 | [0.0, 1.0, 0.0, 1.0], // green
104 |
105 | [0.0, 0.0, 1.0, 1.0], // blue,
106 | [1.0, 0.5, 0.0, 1.0], // orange
107 | [0.0, 1.0, 0.5, 1.0], // violet
108 |
109 | [0.5, 0.0, 1.0, 1.0], // yellow
110 | [1.0, 1.0, 0.0, 1.0], // yellow
111 | [0.0, 1.0, 1.0, 1.0], // cyan
112 | [1.0, 0.0, 1.0, 1.0], // magenta
113 | [0.0, 0.5, 1.2, 1.0]
114 | ];
115 |
116 |
117 | // New: rather than curate the vertices, we will generate them using
118 | // good ole trigonometry.
119 | var coords = [],
120 | colors = [];
121 | const cos = Math.cos,
122 | sin = Math.sin,
123 | PI = Math.PI,
124 | TAU = PI * 2,
125 | HALF_PI = PI * .5,
126 | INCREMENT = PI / ARC_PRECISION,
127 | // because floats can get imprecise, allow ourselves to
128 | // overshoot the last row a little bit
129 | LIMIT = HALF_PI + INCREMENT/2;
130 | // we need to track many vertices we will draw
131 | pointCount = 0;
132 | // we will build out the sphere row by row
133 | for (var lat = -HALF_PI; lat <= LIMIT; lat += INCREMENT) {
134 | var previousRow = lat - INCREMENT;
135 | var prevY = sin(previousRow),
136 | currentY = sin(lat),
137 | // var prevY = sin(previousRow * 2),
138 | // currentY = sin(lat * 2),
139 | cosPrevious = cos(previousRow),
140 | cosCurrent = cos(lat),
141 | // cosPrevious = cos(previousRow * 3),
142 | // cosCurrent = cos(lat * 3),
143 | colorIndex = 0;
144 | // build out the triangles for this row
145 | for (var lon = 0; lon <= TAU; lon += INCREMENT) {
146 | var cosLon = cos(lon),
147 | sinLon = sin(lon),
148 | // sinLon = sin(Math.pow(lon/TAU, 2) * TAU),
149 | previousX = cosPrevious * cosLon,
150 | currentX = cosCurrent * cosLon,
151 | previousZ = cosPrevious * sinLon,
152 | currentZ = cosCurrent * sinLon,
153 | color = colorSources[colorIndex];
154 | coords.push(previousX);
155 | coords.push(prevY);
156 | coords.push(previousZ);
157 | // add each elemnt of the color to the color array
158 | for (var i=0; i{
262 | // console.log(fragShaderText)
263 | fetch('vert.glsl')
264 | .then(function(response) {
265 | return response.text();
266 | }).then(vertShaderText=>{
267 | // console.log(vertShaderText);
268 | compileGL(fragShaderText, vertShaderText);
269 | initGLData();
270 | startTime = Date.now();
271 | setInterval(requestDraw, 33);
272 | });
273 | });
274 |
275 |
276 |
277 | // build our program
278 | function compileGL(fragShaderText, vertShaderText) {
279 | var frag = loadShader(gl, gl.FRAGMENT_SHADER, fragShaderText);
280 | var vert = loadShader(gl, gl.VERTEX_SHADER, vertShaderText);
281 | program = gl.createProgram();
282 | gl.attachShader(program, vert);
283 | gl.attachShader(program, frag);
284 | gl.linkProgram(program);
285 | gl.useProgram(program);
286 | }
287 |
288 | function requestDraw() {
289 | requestAnimationFrame(draw);
290 | }
291 |
292 | // straight outta mozilla
293 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
294 | function loadShader(gl, type, source) {
295 | const shader = gl.createShader(type);
296 | // Send the source to the shader object
297 | gl.shaderSource(shader, source);
298 | // Compile the shader program
299 | gl.compileShader(shader);
300 | // See if it compiled successfully
301 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
302 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
303 | gl.deleteShader(shader);
304 | return null;
305 | }
306 | return shader;
307 | }
308 |
309 |
310 | })();
311 |
312 |
--------------------------------------------------------------------------------
/shader_04.3/vert.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | attribute vec4 a_position;
6 | attribute vec4 a_color;
7 |
8 | varying vec4 v_color;
9 |
10 | uniform mat4 u_model;
11 | uniform mat4 u_projection;
12 |
13 | void main() {
14 | gl_Position = u_projection * u_model * a_position;
15 | v_color = a_color;
16 | }
--------------------------------------------------------------------------------
/shader_04.4/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | varying vec4 v_color;
6 |
7 | void main(){
8 | gl_FragColor = v_color;
9 | }
--------------------------------------------------------------------------------
/shader_04.4/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/shader_04.4/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | gl = canvas.getContext('webgl', {}),
4 | program,
5 | W = window.innerWidth,
6 | H = window.innerHeight,
7 | startTime,
8 |
9 | positionLocation,
10 | colorLocation,
11 | positionBuffer,
12 | colorBUffer,
13 |
14 | // New: we are going to start positioning vertices in space!
15 | modelUniform,
16 | projectionUniform,
17 |
18 | translationMatrix,
19 | rotationMatrix,
20 | scaleMatrix,
21 |
22 | modelMatrix,
23 | projectionMatrix
24 |
25 | ;
26 |
27 | // make the canvas fill the window
28 | canvas.width = W;
29 | canvas.height = H;
30 |
31 |
32 |
33 | function initGLData() {
34 | // now we can get some config info
35 | gl.viewport(0, 0, W, H);
36 |
37 | // New: get the locations where the shader wants the model and projection
38 | modelUniform = gl.getUniformLocation(program, "u_model");
39 | projectionUniform = gl.getUniformLocation(program, "u_projection");
40 | // We will be positioning things in 3d space, so tell the program
41 | // how we want it to handle things behind or in front of each other
42 | gl.enable(gl.DEPTH_TEST);
43 | gl.depthFunc(gl.LEQUAL);
44 |
45 | // straight from mozilla!
46 | // Create a perspective matrix, a special matrix that is
47 | // used to simulate the distortion of perspective in a camera.
48 | // Our field of view is 45 degrees, with a width/height
49 | // ratio that matches the display size of the canvas
50 | // and we only want to see objects between 0.1 units
51 | // and 100 units away from the camera.
52 | const fieldOfView = 45 * Math.PI / 180; // in radians
53 | const aspect = W / H;
54 | const zNear = 0.1;
55 | const zFar = 100.0;
56 | projectionMatrix = mat4.create();
57 |
58 | // note: glmatrix.js always has the first argument
59 | // as the destination to receive the result.
60 | mat4.perspective(projectionMatrix,
61 | fieldOfView,
62 | aspect,
63 | zNear,
64 | zFar);
65 |
66 |
67 | translationMatrix = mat4.create();
68 | rotationMatrix = mat4.create();
69 | scaleMatrix = mat4.create();
70 | modelMatrix = mat4.create();
71 | // Now move the drawing position a bit to where we want to
72 | // start drawing the square.
73 | mat4.translate(
74 | translationMatrix, // destination matrix
75 | translationMatrix, // matrix to translate
76 | [-0.0, 0.0, -6.0]); // amount to translate
77 |
78 |
79 | mat4.rotate(
80 | rotationMatrix, // destination matrix
81 | rotationMatrix, // matrix to rotate
82 | Math.PI * .2 , // amount it rotates each frame
83 | [0, 0, 1] // the axis it rotates around: the center of the square
84 | );
85 |
86 | mat4.scale(
87 | scaleMatrix, // destination matrix
88 | scaleMatrix, // matrix to rotate
89 | [2, .5, 1.5]); // axis to rotate around
90 |
91 |
92 | // Even though we aren't drawing anything really fancy,
93 | // we have to tell the GL Context how much of the screen we are drawing
94 | positionLocation = gl.getAttribLocation(program, "a_position");
95 | positionBuffer = gl.createBuffer();
96 | gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
97 |
98 |
99 | /*
100 | New: we aren;'t building a cube this time,
101 | but a more abstract shape. The coordinates are tweaked so that
102 | they work with TRIANGLES, TRIANGLE_STRIP, or TRIANGLE_FAN.
103 | */
104 |
105 | gl.bufferData(
106 | gl.ARRAY_BUFFER,
107 | new Float32Array([
108 | 0.0, -1.0, 0.0,
109 | 0.5, 0.0, 0.5,
110 | -0.5, 0.0, 0.5,
111 |
112 | 0.0, 0.0, 0.25,
113 | -1.0, 0.0, -0.5,
114 | 0.0, 1.0, -0.5,
115 |
116 | 0.0, 0.0, -1.0,
117 | 0.25, 1.0, -1.5,
118 | 1.0, 0.0, -1.5
119 |
120 | ]),
121 | gl.STATIC_DRAW
122 | );
123 | gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
124 | gl.enableVertexAttribArray(positionLocation);
125 |
126 | colorLocation = gl.getAttribLocation(program, "a_color");
127 | gl.enableVertexAttribArray(colorLocation);
128 | colorBuffer = gl.createBuffer();
129 | gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
130 | gl.bufferData(gl.ARRAY_BUFFER,
131 | // we send over a color for each vertex
132 | new Float32Array([
133 | 1.0, 1.0, 1.0, 1.0, // white
134 | 1.0, 0.0, 0.0, 1.0, // red
135 | 0.0, 1.0, 0.0, 1.0, // green
136 |
137 | 0.0, 0.0, 1.0, 1.0, // blue,
138 | 1.0, 0.5, 0.0, 1.0, // orange
139 | 0.5, 0.0, 1.0, 1.0, // violet
140 |
141 | 1.0, 1.0, 0.0, 1.0, // yellow
142 | 0.0, 1.0, 1.0, 1.0, // cyan
143 | 1.0, 0.0, 1.0, 1.0, // magenta
144 | ]),
145 | gl.STATIC_DRAW);
146 | gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0);
147 | gl.enableVertexAttribArray(colorLocation);
148 |
149 |
150 | gl.uniformMatrix4fv(projectionUniform, false, projectionMatrix);
151 |
152 |
153 | }
154 |
155 |
156 |
157 |
158 | function draw() {
159 | // Set clear color to black, fully opaque
160 | gl.clearColor(0.0, 0.0, 0.0, 1.0);
161 | gl.clearDepth(1.0);
162 | // Clear the color buffer with specified clear color
163 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
164 |
165 | var elapsed = Date.now() - startTime;
166 |
167 | // // rotate the square a little each time
168 | mat4.rotate(
169 | rotationMatrix, // destination matrix
170 | rotationMatrix, // matrix to rotate
171 | Math.PI * .01 , // amount it rotates each frame
172 | // [0, 0, 1] // the axis it rotates around: the center of the square
173 | // [0, 1, 0] // rotate around a vertical axis
174 | // [0, 1, 1] // rotate around a tilting axis
175 | [(Math.cos(elapsed * .001)+1)*.5, .5, 1] // rotate around a moving axis
176 | );
177 |
178 |
179 |
180 | mat4.multiply(
181 | modelMatrix, // the results go here
182 | translationMatrix, // when you multiply this matrix
183 | rotationMatrix // by this matrix
184 | );
185 |
186 | // mat4.multiply(
187 | // modelMatrix, // the results go here
188 | // modelMatrix, // even when we are multiplying the same matrix
189 | // scaleMatrix // by a different matrix
190 | // );
191 |
192 |
193 | gl.uniformMatrix4fv(modelUniform, false, modelMatrix);
194 |
195 | // New: try different ways of grouping the vertices we pass to the shader
196 | gl.drawArrays(gl.TRIANGLES, 0, 9);
197 | // gl.drawArrays(gl.TRIANGLE_STRIP, 0, 9);
198 | // gl.drawArrays(gl.TRIANGLE_FAN, 0, 9);
199 | // gl.drawArrays(gl.LINES, 0, 9);
200 | // gl.drawArrays(gl.LINE_STRIP, 0, 9);
201 | // gl.drawArrays(gl.LINE_LOOP, 0, 9);
202 | // gl.drawArrays(gl.POINTS, 0, 9);
203 | }
204 |
205 |
206 |
207 |
208 |
209 |
210 | // ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ ███████╗████████╗██╗ ██╗███████╗███████╗
211 | // ██╔══██╗██╔═══██╗██╔══██╗██║████╗ ██║██╔════╝ ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔════╝
212 | // ██████╔╝██║ ██║██████╔╝██║██╔██╗ ██║██║ ███╗ ███████╗ ██║ ██║ ██║█████╗ █████╗
213 | // ██╔══██╗██║ ██║██╔══██╗██║██║╚██╗██║██║ ██║ ╚════██║ ██║ ██║ ██║██╔══╝ ██╔══╝
214 | // ██████╔╝╚██████╔╝██║ ██║██║██║ ╚████║╚██████╔╝ ███████║ ██║ ╚██████╔╝██║ ██║
215 | // ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
216 |
217 |
218 | // load files
219 | fetch('frag.glsl')
220 | .then(function(response) {
221 | return response.text();
222 | }).then(fragShaderText=>{
223 | // console.log(fragShaderText)
224 | fetch('vert.glsl')
225 | .then(function(response) {
226 | return response.text();
227 | }).then(vertShaderText=>{
228 | // console.log(vertShaderText);
229 | compileGL(fragShaderText, vertShaderText);
230 | initGLData();
231 | startTime = Date.now();
232 | setInterval(requestDraw, 33);
233 | });
234 | });
235 |
236 |
237 |
238 | // build our program
239 | function compileGL(fragShaderText, vertShaderText) {
240 | var frag = loadShader(gl, gl.FRAGMENT_SHADER, fragShaderText);
241 | var vert = loadShader(gl, gl.VERTEX_SHADER, vertShaderText);
242 | program = gl.createProgram();
243 | gl.attachShader(program, vert);
244 | gl.attachShader(program, frag);
245 | gl.linkProgram(program);
246 | gl.useProgram(program);
247 | }
248 |
249 | function requestDraw() {
250 | requestAnimationFrame(draw);
251 | }
252 |
253 | // straight outta mozilla
254 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
255 | function loadShader(gl, type, source) {
256 | const shader = gl.createShader(type);
257 | // Send the source to the shader object
258 | gl.shaderSource(shader, source);
259 | // Compile the shader program
260 | gl.compileShader(shader);
261 | // See if it compiled successfully
262 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
263 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
264 | gl.deleteShader(shader);
265 | return null;
266 | }
267 | return shader;
268 | }
269 |
270 |
271 | })();
272 |
273 |
--------------------------------------------------------------------------------
/shader_04.4/vert.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | attribute vec4 a_position;
6 | attribute vec4 a_color;
7 |
8 | varying vec4 v_color;
9 |
10 | uniform mat4 u_model;
11 | uniform mat4 u_projection;
12 |
13 | void main() {
14 | gl_Position = u_projection * u_model * a_position;
15 | // New: should we decide to render points, how big should they be?
16 | gl_PointSize = 10.0;
17 | v_color = a_color;
18 | }
--------------------------------------------------------------------------------
/shader_04.5/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | varying vec4 v_color;
6 |
7 | void main(){
8 | gl_FragColor = v_color;
9 | }
--------------------------------------------------------------------------------
/shader_04.5/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/shader_04.5/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | gl = canvas.getContext('webgl', {}),
4 | program,
5 | W = window.innerWidth,
6 | H = window.innerHeight,
7 |
8 | positionLocation,
9 | colorLocation,
10 | positionBuffer,
11 | colorBuffer,
12 |
13 | points,
14 |
15 |
16 | activePositions
17 | ;
18 |
19 | const cos = Math.cos,
20 | sin = Math.sin;
21 |
22 | // make the canvas fill the window
23 | canvas.width = W;
24 | canvas.height = H;
25 |
26 |
27 |
28 | function initGLData() {
29 | // now we can get some config info
30 | gl.viewport(0, 0, W, H);
31 |
32 | // We will be positioning things in 3d space, so tell the program
33 | // how we want it to handle things behind or in front of each other
34 | gl.enable(gl.DEPTH_TEST);
35 | gl.depthFunc(gl.LEQUAL);
36 |
37 |
38 | positionLocation = gl.getAttribLocation(program, "a_position");
39 | positionBuffer = gl.createBuffer();
40 |
41 | // New: create some points that will rotate around
42 | points = [];
43 | for (var i=0; i< 9; i++) {
44 | let xrot = .1 * (1 - Math.random()),
45 | yrot = .1 * (1 - Math.random()),
46 | radius = 1 - Math.random();
47 | radius += radius < 0 ? -.25 : .25;
48 | radius *= .5;
49 | var point = {
50 | "x_rotation_amount" : xrot,
51 | "y_rotation_amount" : yrot,
52 | "x_rotation" : xrot,
53 | "y_rotation" : yrot,
54 | "radius" : radius,
55 | "x" : cos(xrot) * cos(yrot) * radius,
56 | "y" : sin(yrot) * radius,
57 | "z" : sin(xrot) * cos(yrot) * radius
58 | }
59 | points.push(point);
60 | }
61 |
62 |
63 | activePositions = [];
64 | for (var i=0; i{
156 | // console.log(fragShaderText)
157 | fetch('vert.glsl')
158 | .then(function(response) {
159 | return response.text();
160 | }).then(vertShaderText=>{
161 | // console.log(vertShaderText);
162 | compileGL(fragShaderText, vertShaderText);
163 | initGLData();
164 | setInterval(requestDraw, 33);
165 | });
166 | });
167 |
168 |
169 |
170 | // build our program
171 | function compileGL(fragShaderText, vertShaderText) {
172 | var frag = loadShader(gl, gl.FRAGMENT_SHADER, fragShaderText);
173 | var vert = loadShader(gl, gl.VERTEX_SHADER, vertShaderText);
174 | program = gl.createProgram();
175 | gl.attachShader(program, vert);
176 | gl.attachShader(program, frag);
177 | gl.linkProgram(program);
178 | gl.useProgram(program);
179 | }
180 |
181 | function requestDraw() {
182 | requestAnimationFrame(draw);
183 | }
184 |
185 | // straight outta mozilla
186 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
187 | function loadShader(gl, type, source) {
188 | const shader = gl.createShader(type);
189 | // Send the source to the shader object
190 | gl.shaderSource(shader, source);
191 | // Compile the shader program
192 | gl.compileShader(shader);
193 | // See if it compiled successfully
194 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
195 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
196 | gl.deleteShader(shader);
197 | return null;
198 | }
199 | return shader;
200 | }
201 |
202 |
203 | })();
204 |
205 |
--------------------------------------------------------------------------------
/shader_04.5/vert.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | attribute vec4 a_position;
6 | attribute vec4 a_color;
7 |
8 | varying vec4 v_color;
9 |
10 | void main() {
11 | gl_Position = a_position;
12 | gl_PointSize = 10.0;
13 | v_color = a_color;
14 | }
--------------------------------------------------------------------------------
/shader_04.6/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | varying vec4 v_color;
6 |
7 | void main(){
8 | gl_FragColor = v_color;
9 | }
--------------------------------------------------------------------------------
/shader_04.6/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/shader_04.6/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | gl = canvas.getContext('webgl', {}),
4 | program,
5 | W = window.innerWidth,
6 | H = window.innerHeight,
7 |
8 | positionLocation,
9 | colorLocation,
10 | positionBuffer,
11 | colorBuffer,
12 |
13 | // New: track how many frames have gone on
14 | frameCount,
15 | frameCountUniformLocation
16 |
17 |
18 | ;
19 |
20 | const cos = Math.cos,
21 | sin = Math.sin,
22 | POINT_COUNT = 9;
23 |
24 | // make the canvas fill the window
25 | canvas.width = W;
26 | canvas.height = H;
27 |
28 |
29 |
30 | function initGLData() {
31 | // now we can get some config info
32 | gl.viewport(0, 0, W, H);
33 |
34 | // We will be positioning things in 3d space, so tell the program
35 | // how we want it to handle things behind or in front of each other
36 | gl.enable(gl.DEPTH_TEST);
37 | gl.depthFunc(gl.LEQUAL);
38 |
39 | // New: we need to pass the number of frames to the shader,
40 | // so that it can calculate the updated position of each particle
41 | frameCountUniformLocation = gl.getUniformLocation(program, "u_frameCount");
42 | frameCount = 0;
43 |
44 | positionLocation = gl.getAttribLocation(program, "a_position");
45 | positionBuffer = gl.createBuffer();
46 |
47 | // New: we don't need to save the points so that they can
48 | // be adjusted in the draw loop. And the variables that
49 | // track their current position aren't needed either.
50 | var points = [];
51 | for (var i=0; i < POINT_COUNT; i++) {
52 | let xrot = .1 * (1 - Math.random()),
53 | yrot = .1 * (1 - Math.random()),
54 | radius = 1 - Math.random();
55 | radius += radius < 0 ? -.25 : .25;
56 | radius *= .5;
57 | var point = {
58 | "x_rotation_amount" : xrot,
59 | "y_rotation_amount" : yrot,
60 | "radius" : radius
61 | }
62 | points.push(point);
63 | }
64 |
65 | // New: Before, we declared activePositions globally so we could
66 | // update it every time we called draw. Now we can declare it locally,
67 | // and just pass it once to the shader.
68 | // Instead of tracking actual positions, it now tracks the parameters
69 | // required to calculate each point's position.
70 | var activePositions = [];
71 | for (var i=0; i{
142 | // console.log(fragShaderText)
143 | fetch('vert.glsl')
144 | .then(function(response) {
145 | return response.text();
146 | }).then(vertShaderText=>{
147 | // console.log(vertShaderText);
148 | compileGL(fragShaderText, vertShaderText);
149 | initGLData();
150 | setInterval(requestDraw, 33);
151 | });
152 | });
153 |
154 |
155 |
156 | // build our program
157 | function compileGL(fragShaderText, vertShaderText) {
158 | var frag = loadShader(gl, gl.FRAGMENT_SHADER, fragShaderText);
159 | var vert = loadShader(gl, gl.VERTEX_SHADER, vertShaderText);
160 | program = gl.createProgram();
161 | gl.attachShader(program, vert);
162 | gl.attachShader(program, frag);
163 | gl.linkProgram(program);
164 | gl.useProgram(program);
165 | }
166 |
167 | function requestDraw() {
168 | requestAnimationFrame(draw);
169 | }
170 |
171 | // straight outta mozilla
172 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
173 | function loadShader(gl, type, source) {
174 | const shader = gl.createShader(type);
175 | // Send the source to the shader object
176 | gl.shaderSource(shader, source);
177 | // Compile the shader program
178 | gl.compileShader(shader);
179 | // See if it compiled successfully
180 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
181 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
182 | gl.deleteShader(shader);
183 | return null;
184 | }
185 | return shader;
186 | }
187 |
188 |
189 | })();
190 |
191 |
--------------------------------------------------------------------------------
/shader_04.6/vert.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | attribute vec4 a_position;
6 | attribute vec4 a_color;
7 |
8 | varying vec4 v_color;
9 |
10 | // New: how many frames have been drawn
11 | uniform float u_frameCount;
12 |
13 | void main() {
14 | // New: in this version, a_position tracks the parameters
15 | // used to calculate the point's position"
16 | // how much to rotate around the x axis every frame
17 | // how much to rotate around the y axis every frame
18 | // the distance from the center.
19 | // where this point lies in the list of vertices
20 | // GLSL lets you access these paramters under different names,
21 | // but they all reference the same data points. The different
22 | // names can be intuitive for whatever you are working with.
23 | // You can use rgba when working with color, xyzw when working
24 | // with locations, and stpq when working with othter stuff.
25 | // Why not stuv instead of stpq? It's not entirely clear.
26 | // Here, we use s, t, and p (and maybe q), since the stufff
27 | // in a_position is not the actual x, y, and z coordinates
28 | // of the point.
29 | float x_rotation = a_position.s * u_frameCount;
30 | float y_rotation = a_position.t * u_frameCount;
31 | float radius = a_position.p;
32 | float x = cos(x_rotation) * cos(y_rotation) * radius;
33 | float y = sin(y_rotation) * radius;
34 | float z = sin(x_rotation) * cos(y_rotation) * radius;
35 |
36 | gl_Position = vec4(x, y, z, 1.0);
37 | gl_PointSize = 10.0;
38 | // gl_PointSize = a_position.q * 2.0;
39 | v_color = a_color;
40 | }
--------------------------------------------------------------------------------
/shader_05.0/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | varying vec4 v_color;
6 |
7 | // New: the image
8 | uniform sampler2D u_image;
9 |
10 | void main(){
11 | vec4 imageColor = texture2D(u_image, gl_PointCoord.st);
12 | gl_FragColor = imageColor;
13 | }
--------------------------------------------------------------------------------
/shader_05.0/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/shader_05.0/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | // New: when we create the WebGL context, we can pass it some options.
4 | // What we will be doing later is using an image to draw each point.
5 | // The images have a transparent background, so we want the shader to
6 | // mix colors when those images overlap. We tell the shader to do that
7 | // by passing in the "premultipliedAlpha : false" option
8 | gl = canvas.getContext('webgl', {premultipliedAlpha: false}),
9 | program,
10 | W = window.innerWidth,
11 | H = window.innerHeight,
12 |
13 |
14 | frameCount,
15 | frameCountUniformLocation,
16 |
17 | // New: the image we will use to draw each point / particle.
18 | dotTexture
19 | ;
20 |
21 | const cos = Math.cos,
22 | sin = Math.sin,
23 | POINT_COUNT = 9;
24 |
25 | // make the canvas fill the window
26 | canvas.width = W;
27 | canvas.height = H;
28 |
29 |
30 |
31 | function initGLData() {
32 | // now we can get some config info
33 | gl.viewport(0, 0, W, H);
34 |
35 | // New: the images we use to blend particles have transparent
36 | // backgrounds. FOr this to work as expected, we need to turn off
37 | // depth testing. If we don't the backgrounds don't show up as
38 | // transparent: they show up as black and block other particles.
39 | gl.disable(gl.DEPTH_TEST);
40 | // tell the shader that we want blending
41 | gl.enable(gl.BLEND);
42 | // and specify just how we want the blending to work
43 | gl.blendFunc(gl.SRC_ALPHA, gl.DST_ALPHA);
44 | gl.blendEquation(gl.FUNC_ADD);
45 | // there are many options for how you want blending to work
46 | // gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
47 | // gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE)
48 |
49 |
50 | // New: pass an image to the shader so it can be used to draw the points.
51 | // where is it gonna go?
52 | var imageUniform = gl.getUniformLocation(program, "u_image");
53 | // Images are referred to as textures, and setting one up
54 | // is a bureaucratic operation.
55 | // Create a texture, and tell the shader that it is the one you want
56 | // to work with. Note that it is not yet attached to our image.
57 | var texture = gl.createTexture();
58 | gl.bindTexture(gl.TEXTURE_2D, texture);
59 | // Set up texture so we can render any size image and so we are
60 | // working with pixels.
61 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
62 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
63 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
64 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
65 | // now tell the texture to use our image
66 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, dotTexture);
67 | // and tell the shader that we want to use this image for the uniform
68 | gl.uniform1i(imageUniform, 1);
69 | // and that this is the image to use for now
70 | gl.activeTexture(gl.TEXTURE1);
71 | gl.bindTexture(gl.TEXTURE_2D, texture);
72 |
73 |
74 |
75 | frameCountUniformLocation = gl.getUniformLocation(program, "u_frameCount");
76 | frameCount = 0;
77 |
78 | var positionLocation = gl.getAttribLocation(program, "a_position");
79 | var positionBuffer = gl.createBuffer();
80 |
81 | var points = [];
82 | for (var i=0; i < POINT_COUNT; i++) {
83 | let xrot = .1 * (1 - Math.random()),
84 | yrot = .1 * (1 - Math.random()),
85 | radius = 1 - Math.random();
86 | radius += radius < 0 ? -.25 : .25;
87 | radius *= .5;
88 | var point = {
89 | "x_rotation_amount" : xrot,
90 | "y_rotation_amount" : yrot,
91 | "radius" : radius
92 | }
93 | points.push(point);
94 | }
95 |
96 | var activePositions = [];
97 | for (var i=0; i {
166 | // new: fetch the shaders after the image is loaded
167 | // load files
168 | fetch('frag.glsl')
169 | .then(function(response) {
170 | return response.text();
171 | }).then(fragShaderText=>{
172 | // console.log(fragShaderText)
173 | fetch('vert.glsl')
174 | .then(function(response) {
175 | return response.text();
176 | }).then(vertShaderText=>{
177 | // console.log(vertShaderText);
178 | compileGL(fragShaderText, vertShaderText);
179 | initGLData();
180 | setInterval(requestDraw, 33);
181 | });
182 | });
183 | });
184 | dotTexture.src = "../images/dot.png";
185 |
186 |
187 |
188 | // build our program
189 | function compileGL(fragShaderText, vertShaderText) {
190 | var frag = loadShader(gl, gl.FRAGMENT_SHADER, fragShaderText);
191 | var vert = loadShader(gl, gl.VERTEX_SHADER, vertShaderText);
192 | program = gl.createProgram();
193 | gl.attachShader(program, vert);
194 | gl.attachShader(program, frag);
195 | gl.linkProgram(program);
196 | gl.useProgram(program);
197 | }
198 |
199 | function requestDraw() {
200 | requestAnimationFrame(draw);
201 | }
202 |
203 | // straight outta mozilla
204 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
205 | function loadShader(gl, type, source) {
206 | const shader = gl.createShader(type);
207 | // Send the source to the shader object
208 | gl.shaderSource(shader, source);
209 | // Compile the shader program
210 | gl.compileShader(shader);
211 | // See if it compiled successfully
212 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
213 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
214 | gl.deleteShader(shader);
215 | return null;
216 | }
217 | return shader;
218 | }
219 |
220 |
221 | })();
222 |
223 |
--------------------------------------------------------------------------------
/shader_05.0/vert.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | attribute vec4 a_position;
6 | attribute vec4 a_color;
7 |
8 | varying vec4 v_color;
9 |
10 | uniform float u_frameCount;
11 |
12 | void main() {
13 | float x_rotation = a_position.x * u_frameCount;
14 | float y_rotation = a_position.y * u_frameCount;
15 | float radius = a_position.z;
16 | float x = cos(x_rotation) * cos(y_rotation) * radius;
17 | float y = sin(y_rotation) * radius;
18 | float z = sin(x_rotation) * cos(y_rotation) * radius;
19 |
20 | gl_Position = vec4(x, y, z, 1.0);
21 | gl_PointSize = 32.0;
22 | // gl_PointSize = a_position.w * 10.0;
23 | v_color = a_color;
24 | }
--------------------------------------------------------------------------------
/shader_05.1/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | varying vec4 v_color;
6 |
7 | uniform sampler2D u_image;
8 |
9 | varying vec2 v_imagePosition;
10 |
11 |
12 | void main(){
13 | vec4 color = texture2D(u_image, v_imagePosition);
14 | // copy the color from the image, and use it for the current pixel
15 | gl_FragColor = color;
16 | // or use the red channel to drive how dark a pixel is
17 | // and use the position in the screen to drive the rbg value
18 | // float bw = color.r;
19 | // vec2 st = gl_FragCoord.xy/1024.0;
20 | // gl_FragColor = vec4(0.0, st.x * bw, st.y * bw, 1.0);
21 | // Or use the position on the face of the cube to drive the rbg value
22 | // vec2 st2 = v_imagePosition.xy;
23 | // gl_FragColor = vec4(0.0, st2.x * bw, st2.y * bw, 1.0);
24 | // or combine them
25 | // gl_FragColor = vec4(st2.x * bw, st.x * st2.y * bw, st.y * bw, 1.0);
26 | }
--------------------------------------------------------------------------------
/shader_05.1/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/shader_05.1/vert.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | attribute vec4 a_position;
6 |
7 | // New: the image coordinates
8 | // the attribute gets it from the js program
9 | attribute vec2 a_imagePosition;
10 | // and stashes it in the varying version, which allows
11 | // it to pass to the fragment shader
12 | varying vec2 v_imagePosition;
13 |
14 | uniform mat4 u_model;
15 | uniform mat4 u_projection;
16 |
17 |
18 | void main() {
19 | gl_Position = u_projection * u_model * a_position;
20 | v_imagePosition = a_imagePosition;
21 | }
--------------------------------------------------------------------------------
/shader_05.2/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | varying vec4 v_color;
6 |
7 | uniform sampler2D u_image;
8 |
9 | varying vec2 v_imagePosition;
10 |
11 |
12 | void main(){
13 | vec4 color = texture2D(u_image, v_imagePosition);
14 | // copy the color from the image, and use it for the current pixel
15 | gl_FragColor = color;
16 | }
--------------------------------------------------------------------------------
/shader_05.2/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/shader_05.2/vert.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | attribute vec4 a_position;
6 |
7 | // New: the image coordinates
8 | // the attribute gets it from the js program
9 | attribute vec2 a_imagePosition;
10 | // and stashes it in the varying version, which allows
11 | // it to pass to the fragment shader
12 | varying vec2 v_imagePosition;
13 |
14 | uniform mat4 u_model;
15 | uniform mat4 u_projection;
16 |
17 |
18 | void main() {
19 | gl_Position = u_projection * u_model * a_position;
20 | v_imagePosition = a_imagePosition;
21 | }
--------------------------------------------------------------------------------
/shader_05.3/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | varying vec4 v_color;
6 |
7 | uniform sampler2D u_image;
8 |
9 | varying vec2 v_imagePosition;
10 |
11 |
12 | void main(){
13 | vec4 color = texture2D(u_image, v_imagePosition);
14 | // copy the color from the image, and use it for the current pixel
15 | gl_FragColor = color;
16 | // or replace it with nicer colors
17 | // if (color.a >= .5) {
18 | // gl_FragColor = vec4(0.4, 0.4, 0.4, 1.0);
19 | // } else {
20 | // gl_FragColor = vec4(1.0);
21 | // }
22 | }
--------------------------------------------------------------------------------
/shader_05.3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/shader_05.3/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | gl = canvas.getContext('webgl', {premultipliedAlpha: false}),
4 | program,
5 | W = window.innerWidth,
6 | H = window.innerHeight,
7 | startTime,
8 |
9 | positionLocation,
10 |
11 | modelUniform,
12 |
13 |
14 | projectionUniform,
15 | projectionMatrix,
16 |
17 | translationMatrix,
18 | rotationMatrix,
19 | scaleMatrix,
20 |
21 | modelMatrix,
22 |
23 | faceTexture
24 |
25 |
26 | ;
27 |
28 |
29 | const ARC_PRECISION = 50;
30 |
31 |
32 | // make the canvas fill the window
33 | canvas.width = W;
34 | canvas.height = H;
35 |
36 |
37 |
38 | function initGLData() {
39 | // now we can get some config info
40 | gl.viewport(0, 0, W, H);
41 |
42 | modelUniform = gl.getUniformLocation(program, "u_model");
43 | gl.enable(gl.DEPTH_TEST);
44 | gl.depthFunc(gl.LEQUAL);
45 |
46 | // tell the shader that we want blending
47 | // gl.enable(gl.BLEND);
48 | // // and specify just how we want the blending to work
49 | // // gl.blendFunc(gl.SRC_ALPHA, gl.DST_ALPHA);
50 | // gl.blendFunc(gl.SRC_ALPHA, gl.DST_ALPHA);
51 | // gl.blendEquation(gl.FUNC_ADD);
52 |
53 | // straight from mozilla!
54 | // Create a perspective matrix, a special matrix that is
55 | // used to simulate the distortion of perspective in a camera.
56 | // Our field of view is 45 degrees, with a width/height
57 | // ratio that matches the display size of the canvas
58 | // and we only want to see objects between 0.1 units
59 | // and 100 units away from the camera.
60 | const fieldOfView = 45 * Math.PI / 180; // in radians
61 | const aspect = W / H;
62 | const zNear = 0.1;
63 | const zFar = 100.0;
64 | projectionMatrix = mat4.create();
65 | projectionUniform = gl.getUniformLocation(program, "u_projection");
66 |
67 | // note: with glmatrix.js, the first parameter
68 | // is always the matrix that you are writing to. Any values
69 | // in that matrix will be overwritten.
70 | mat4.perspective(projectionMatrix,
71 | fieldOfView,
72 | aspect,
73 | zNear,
74 | zFar);
75 |
76 | gl.uniformMatrix4fv(projectionUniform, false, projectionMatrix);
77 |
78 | translationMatrix = mat4.create();
79 | rotationMatrix = mat4.create();
80 | scaleMatrix = mat4.create();
81 | modelMatrix = mat4.create();
82 | // Now move the drawing position a bit to where we want to
83 | // start drawing the square.
84 | mat4.translate(
85 | translationMatrix, // the matrix that tracks the translated location
86 | translationMatrix, // matrix to start from (which is not moved at this point)
87 | [-0.0, 0.0, -6.0]); // amount to translate
88 |
89 | mat4.rotate(
90 | rotationMatrix, // the matrix that tracks the rotation
91 | rotationMatrix, // matrix to to start from (unrotated here)
92 | Math.PI, // amount to rotate it
93 | [1, 0, 0] // the axis it rotates around: the center of the square
94 | );
95 |
96 | mat4.scale(
97 | scaleMatrix, // the matrix that tracks the rotation
98 | scaleMatrix, // matrix to to start from (unrotated here)
99 | [1.5, 1.5, 1.5]
100 | );
101 |
102 |
103 |
104 | positionLocation = gl.getAttribLocation(program, "a_position");
105 | var positionBuffer = gl.createBuffer();
106 | gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
107 |
108 | var coords = [],
109 | textureCoords = [];
110 | const cos = Math.cos,
111 | sin = Math.sin,
112 | PI = Math.PI,
113 | TAU = PI * 2,
114 | HALF_PI = PI * .5,
115 | INCREMENT = PI / ARC_PRECISION,
116 | // because floats can get imprecise, allow ourselves to
117 | // overshoot the last row a little bit
118 | LIMIT = HALF_PI + INCREMENT/2;
119 | pointCount = 0;
120 |
121 |
122 | for (var lat = -HALF_PI + INCREMENT; lat <= LIMIT; lat += INCREMENT) {
123 | var previousRow = lat - INCREMENT,
124 | prevY = sin(previousRow),
125 | currentY = sin(lat),
126 | cosPrevious = cos(previousRow),
127 | cosCurrent = cos(lat),
128 | previousTextureY = (previousRow+HALF_PI)/PI,
129 | currentTextureY = (lat+HALF_PI)/PI;
130 |
131 | for (var lon = 0; lon <= TAU + .001; lon += INCREMENT) {
132 | var cosLon = cos(lon),
133 | sinLon = sin(lon),
134 | previousX = cosPrevious * cosLon,
135 | currentX = cosCurrent * cosLon,
136 | previousZ = cosPrevious * sinLon,
137 | currentZ = cosCurrent * sinLon,
138 | textureX = lon/TAU;
139 | coords.push(previousX);
140 | coords.push(prevY);
141 | coords.push(previousZ);
142 | textureCoords.push(textureX);
143 | textureCoords.push(previousTextureY);
144 | pointCount++;
145 | coords.push(currentX);
146 | coords.push(currentY);
147 | coords.push(currentZ);
148 | textureCoords.push(textureX);
149 | textureCoords.push(currentTextureY);
150 | pointCount++;
151 | }
152 | }
153 |
154 |
155 | gl.bufferData(
156 | gl.ARRAY_BUFFER,
157 | new Float32Array(coords),
158 | gl.STATIC_DRAW
159 | );
160 | gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
161 | gl.enableVertexAttribArray(positionLocation);
162 |
163 | // New: Our goal here is to place the same image
164 | // on each face of the cube. So for each corner
165 | // of each triangle above, we have to tell it which
166 | // corner of the image to use.
167 | var imagePositionBuffer = gl.createBuffer();
168 | gl.bindBuffer(gl.ARRAY_BUFFER, imagePositionBuffer);
169 | gl.bufferData(
170 | gl.ARRAY_BUFFER,
171 | new Float32Array(textureCoords),
172 | gl.STATIC_DRAW
173 | );
174 | var imagePositionLocation = gl.getAttribLocation(program, "a_imagePosition");
175 | gl.enableVertexAttribArray(imagePositionLocation);
176 | gl.vertexAttribPointer(imagePositionLocation, 2, gl.FLOAT, false, 0, 0);
177 |
178 | // pass an image to the shader so it can be used to draw the points.
179 | // where is it gonna go?
180 | var imageUniform = gl.getUniformLocation(program, "u_image");
181 | // Images are referred to as textures, and setting one up
182 | // is a bureaucratic operation.
183 | // Create a texture, and tell the shader that it is the one you want
184 | // to work with. Note that it is not yet attached to our image.
185 | var texture = gl.createTexture();
186 | gl.bindTexture(gl.TEXTURE_2D, texture);
187 | // Set up texture so we can render any size image and so we are
188 | // working with pixels.
189 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
190 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
191 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
192 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
193 | // Upload the image into the texture.
194 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, faceTexture);
195 | // and tell the shader that we want to use this image for the uniform
196 | gl.uniform1i(imageUniform, 1);
197 | // and that this is the image to use for now
198 | gl.activeTexture(gl.TEXTURE1);
199 | gl.bindTexture(gl.TEXTURE_2D, texture);
200 |
201 | }
202 |
203 |
204 |
205 |
206 | function draw() {
207 | // Set clear color to black, fully opaque
208 | gl.clearColor(1.0, 1.0, 1.0, 0.1);
209 | gl.clearDepth(1.0);
210 | // Clear the color buffer with specified clear color
211 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
212 |
213 |
214 | elapsed = Date.now() - startTime;
215 |
216 |
217 |
218 | // and store it in the modelMatrix
219 | mat4.multiply(modelMatrix, translationMatrix, rotationMatrix);
220 |
221 | // if you want to scale the positions as well,
222 | // mulitply the model matrix by the scale matrix
223 | mat4.multiply(modelMatrix, modelMatrix, scaleMatrix);
224 |
225 | // order matters! Instead of translation and rotation first, try scaling and rotation first
226 | // mat4.multiply(modelMatrix, rotationMatrix, scaleMatrix);
227 | // mat4.multiply(modelMatrix, modelMatrix, translationMatrix);
228 |
229 | // rotate the square a little each time
230 | mat4.rotate(
231 | rotationMatrix, // destination matrix
232 | rotationMatrix, // matrix to rotate
233 | Math.PI * -.005, // amount it rotates each frame
234 | // [0, 0, 1] // the axis it rotates around: the center of the front face
235 | [0, 1, 0] // the axis it rotates around: a vertical axis
236 | // [0, 1, 1] // the axis it rotates around: tilted
237 | // [(Math.cos(elapsed * .001)+1)*.5, .5, 1] // the axis it rotates around: a moving axis
238 | );
239 |
240 |
241 | gl.uniformMatrix4fv(modelUniform, false, modelMatrix);
242 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, pointCount);
243 | }
244 |
245 |
246 |
247 |
248 |
249 |
250 | // ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ ███████╗████████╗██╗ ██╗███████╗███████╗
251 | // ██╔══██╗██╔═══██╗██╔══██╗██║████╗ ██║██╔════╝ ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔════╝
252 | // ██████╔╝██║ ██║██████╔╝██║██╔██╗ ██║██║ ███╗ ███████╗ ██║ ██║ ██║█████╗ █████╗
253 | // ██╔══██╗██║ ██║██╔══██╗██║██║╚██╗██║██║ ██║ ╚════██║ ██║ ██║ ██║██╔══╝ ██╔══╝
254 | // ██████╔╝╚██████╔╝██║ ██║██║██║ ╚████║╚██████╔╝ ███████║ ██║ ╚██████╔╝██║ ██║
255 | // ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
256 |
257 |
258 | // load files
259 |
260 | faceTexture = new Image();
261 | faceTexture.addEventListener('load', ()=> {
262 | // new: fetch the shaders after the image is loaded
263 | // load files
264 | fetch('frag.glsl')
265 | .then(function(response) {
266 | return response.text();
267 | }).then(fragShaderText=>{
268 | // console.log(fragShaderText)
269 | fetch('vert.glsl')
270 | .then(function(response) {
271 | return response.text();
272 | }).then(vertShaderText=>{
273 | // console.log(vertShaderText);
274 | compileGL(fragShaderText, vertShaderText);
275 | initGLData();
276 | startTime = Date.now();
277 | setInterval(requestDraw, 33);
278 | });
279 | });
280 | });
281 | // faceTexture.src = "../images/bumpy.jpeg";
282 | // faceTexture.src = "../images/rust.jpg";
283 | // faceTexture.src = "../images/f.png";
284 | // faceTexture.src = "../images/world.png";
285 | // faceTexture.src = "../images/dnb_land_ocean_ice.2012.3600x1800.jpg";
286 | faceTexture.src = "../images/nasa_blue_marble.4096.jpg";
287 | // dnb_land_ocean_ice.2012.3600x1800.jpg courtesy of NASA
288 | // https://visibleearth.nasa.gov/view.php?id=79765
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 | // build our program
297 | function compileGL(fragShaderText, vertShaderText) {
298 | var frag = loadShader(gl, gl.FRAGMENT_SHADER, fragShaderText);
299 | var vert = loadShader(gl, gl.VERTEX_SHADER, vertShaderText);
300 | program = gl.createProgram();
301 | gl.attachShader(program, vert);
302 | gl.attachShader(program, frag);
303 | gl.linkProgram(program);
304 | gl.useProgram(program);
305 | }
306 |
307 | function requestDraw() {
308 | requestAnimationFrame(draw);
309 | }
310 |
311 | // straight outta mozilla
312 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
313 | function loadShader(gl, type, source) {
314 | const shader = gl.createShader(type);
315 | // Send the source to the shader object
316 | gl.shaderSource(shader, source);
317 | // Compile the shader program
318 | gl.compileShader(shader);
319 | // See if it compiled successfully
320 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
321 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
322 | gl.deleteShader(shader);
323 | return null;
324 | }
325 | return shader;
326 | }
327 |
328 |
329 | })();
330 |
331 |
--------------------------------------------------------------------------------
/shader_05.3/vert.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | attribute vec4 a_position;
6 |
7 | // New: the image coordinates
8 | // the attribute gets it from the js program
9 | attribute vec2 a_imagePosition;
10 | // and stashes it in the varying version, which allows
11 | // it to pass to the fragment shader
12 | varying vec2 v_imagePosition;
13 |
14 | uniform mat4 u_model;
15 | uniform mat4 u_projection;
16 |
17 |
18 | void main() {
19 | gl_Position = u_projection * u_model * a_position;
20 | v_imagePosition = a_imagePosition;
21 | }
--------------------------------------------------------------------------------
/shader_05.4/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | varying vec4 v_color;
6 |
7 | uniform sampler2D u_dayImage;
8 | uniform sampler2D u_nightImage;
9 | uniform vec2 u_resolution;
10 |
11 | varying vec2 v_imagePosition;
12 |
13 |
14 | void main(){
15 | vec4 dayColor = texture2D(u_dayImage, v_imagePosition);
16 | vec4 nightColor = texture2D(u_nightImage, v_imagePosition);
17 | // copy the color from the image, and use it for the current pixel
18 | // gl_FragColor = dayColor;
19 | // gl_FragColor = dayColor;
20 | vec2 st = gl_FragCoord.xy / u_resolution;
21 | if (st.x >= 0.6) {
22 | gl_FragColor = dayColor;
23 | } else if (st.x < 0.5) {
24 | gl_FragColor = nightColor;
25 | } else {
26 | float f = smoothstep(0.5, 0.6, st.x);
27 | gl_FragColor = ((1.0 - f) * nightColor + f * dayColor);
28 | }
29 | }
--------------------------------------------------------------------------------
/shader_05.4/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/shader_05.4/vert.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | attribute vec4 a_position;
6 |
7 | // New: the image coordinates
8 | // the attribute gets it from the js program
9 | attribute vec2 a_imagePosition;
10 | // and stashes it in the varying version, which allows
11 | // it to pass to the fragment shader
12 | varying vec2 v_imagePosition;
13 |
14 | uniform mat4 u_model;
15 | uniform mat4 u_projection;
16 |
17 |
18 | void main() {
19 | gl_Position = u_projection * u_model * a_position;
20 | v_imagePosition = a_imagePosition;
21 | }
--------------------------------------------------------------------------------
/shader_06.0/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | varying vec4 v_color;
6 | varying vec2 v_imagePosition;
7 |
8 | uniform sampler2D u_image;
9 | uniform sampler2D u_dataColors;
10 |
11 |
12 | void main(){
13 | vec4 color = texture2D(u_image, v_imagePosition);
14 | gl_FragColor = color;
15 |
16 |
17 | /*
18 | To see the country lookup values, we can isolate the red channel.
19 | Oceans and things that are not countries are transparent.
20 | */
21 | // if (color.a <= 0.5) {
22 | // gl_FragColor = vec4(1.0);
23 | // } else {
24 | // gl_FragColor = vec4(color.r, 0.0, 0.0, 1.0);
25 | // }
26 |
27 |
28 | /*
29 | We can also test whether the country lookup is working
30 | */
31 | // if (color.a <= 0.5) {
32 | // gl_FragColor = vec4(1.0);
33 | // } else {
34 | // // get the color, and scale up from the shader range of 0-1 to
35 | // // integers in the 0-255 range
36 | // float countryColor = floor(color.r * 255.0);
37 | // // Looking at the data file population_2018.json, the country at
38 | // // index position 3.0 is China,
39 | // // 1.0 is the USA
40 | // // 24.0 is Chile
41 | // // 33.0 is Ireland
42 | // // 53.0 is Egypt
43 | // // 212 is New Guinea
44 | // if (countryColor == 212.0) {
45 | // gl_FragColor = vec4(0.0, 0.5, 1.0, 1.0);
46 | // } else {
47 | // gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
48 | // }
49 | // }
50 | }
--------------------------------------------------------------------------------
/shader_06.0/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/shader_06.0/vert.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | attribute vec4 a_position;
6 |
7 | // New: the image coordinates
8 | // the attribute gets it from the js program
9 | attribute vec2 a_imagePosition;
10 | // and stashes it in the varying version, which allows
11 | // it to pass to the fragment shader
12 | varying vec2 v_imagePosition;
13 |
14 | uniform mat4 u_model;
15 | uniform mat4 u_projection;
16 |
17 |
18 | void main() {
19 | gl_Position = u_projection * u_model * a_position;
20 | v_imagePosition = a_imagePosition;
21 | }
--------------------------------------------------------------------------------
/shader_06.1/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/shader_06.1/main.js:
--------------------------------------------------------------------------------
1 | (()=>{
2 | var canvas = document.getElementById('shade'),
3 | gl = canvas.getContext('webgl', {premultipliedAlpha: false}),
4 | program,
5 | W = window.innerWidth,
6 | H = window.innerHeight,
7 | startTime,
8 |
9 | dataColorUniform,
10 |
11 | countryRGB,
12 |
13 | dataColorCanvas,
14 | dataColorCtx,
15 | dataColorImg = new Image(),
16 | dataTexture,
17 |
18 | popData
19 |
20 | ;
21 |
22 |
23 |
24 |
25 |
26 |
27 | function draw() {
28 |
29 | // Set clear color to black, fully opaque
30 |
31 | }
32 |
33 |
34 | function colorByPopulation() {
35 | // what is the max population?
36 | var maxTotal = 0,
37 | maxUrbanPct = 0,
38 | maxRuralPct = 0;
39 | popData.forEach(item=>{
40 | if (item.total > 0) {
41 | maxTotal = Math.max(maxTotal, item.total);
42 | maxUrbanPct = Math.max(maxUrbanPct, item.urban / item.total);
43 | maxRuralPct = Math.max(maxRuralPct, item.rural / item.total);
44 | }
45 | });
46 | dataColorCtx.clearRect(0,0,16,16);
47 | var countryIndex = 0;
48 | for ( var y=0;y<16;y++) {
49 | for ( var x=0;x<16;x++) {
50 | // we will use red, green, and blue channels to encode
51 | // total, urban and rural populations for each country.
52 | let countryData = popData[countryIndex],
53 | r = 0,
54 | g = 0,
55 | b = 0;
56 | if (countryData) {
57 | if (countryData.total > 0) {
58 | let urbanPct = countryData.urban / countryData.total,
59 | ruralPct = countryData.rural / countryData.total;
60 | // we will let 0 mean there is no data
61 | // so the lowest value will be 1, and the highest
62 | // will be 255 (or 1 + 254)
63 | r = 1 + countryData.total / maxTotal * 254;
64 | g = 1 + urbanPct / maxUrbanPct * 254;
65 | b = 1 + ruralPct / maxRuralPct * 254;
66 | } else {
67 | }
68 | }
69 | /* to see just the population in the red channel */
70 | // let fs = 'rgb(' + Math.round(r) + ',0,0)';
71 | /* to see just the urban population percent in the green channel */
72 | // let fs = 'rgb(0,' + Math.round(g) + ',0)';
73 | /* to see just the rural population percent in the blue channel */
74 | // let fs = 'rgb(0,0,' + Math.round(b) + ')';
75 | /* to see them all combined */
76 | let fs = 'rgb(' + Math.round(r) + ',' + Math.round(g) + ',' + Math.round(b) + ')';
77 | // console.log(fs, countryData ? countryData.name : '', x, y);
78 | dataColorCtx.fillStyle = fs;
79 | dataColorCtx.fillRect(x,y,1,1);
80 | countryIndex++;
81 | }
82 | }
83 | dataColorImg.src = dataColorCanvas.toDataURL();
84 | // Append the data image to the document to inspect it
85 | var body = document.getElementById('b');
86 | dataColorImg.style.width = '512px';
87 | dataColorImg.style.height = '512px';
88 | dataColorImg.style.position = 'absolute';
89 | dataColorImg.style.top = '0';
90 | dataColorImg.style.left = '0';
91 | dataColorImg.style.zIndex = '1000';
92 | body.appendChild(dataColorImg);
93 | }
94 |
95 |
96 |
97 |
98 |
99 | function initDataImage(){
100 | countryRGB = new Float32Array(256*3);
101 | for ( var i=0;i<256;i++) {
102 | let i3 = i*3;
103 | countryRGB[i3] = 0; //Math.abs(Math.sin(Math.random() * Math.PI * 2)) * 255;
104 | countryRGB[i3+1] = 0;
105 | countryRGB[i3+2] = 0;
106 | }
107 | // create an image we can use for setting colors in the globe fragment shader
108 | dataColorCanvas = document.createElement('canvas');
109 | var scale = 8;
110 | dataColorCanvas.width = 16 * scale;
111 | dataColorCanvas.height = 16 * scale;
112 | dataColorImg.width = 16 * scale;
113 | dataColorImg.height = 16 * scale;
114 | dataColorCtx = dataColorCanvas.getContext('2d');
115 | dataColorCtx.scale(scale, scale);
116 | dataColorCtx.fillStyle = 'white';
117 | dataColorCtx.fillRect(0,0,16,16);
118 |
119 | var launchShader = ()=>{
120 | dataColorImg.removeEventListener('load', launchShader);
121 | colorByPopulation();
122 | // setInterval(requestDraw, 33);
123 | }
124 | dataColorImg.addEventListener('load', launchShader);
125 | dataColorImg.src = dataColorCanvas.toDataURL();
126 | }
127 |
128 |
129 |
130 |
131 |
132 | // ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ ███████╗████████╗██╗ ██╗███████╗███████╗
133 | // ██╔══██╗██╔═══██╗██╔══██╗██║████╗ ██║██╔════╝ ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔════╝
134 | // ██████╔╝██║ ██║██████╔╝██║██╔██╗ ██║██║ ███╗ ███████╗ ██║ ██║ ██║█████╗ █████╗
135 | // ██╔══██╗██║ ██║██╔══██╗██║██║╚██╗██║██║ ██║ ╚════██║ ██║ ██║ ██║██╔══╝ ██╔══╝
136 | // ██████╔╝╚██████╔╝██║ ██║██║██║ ╚████║╚██████╔╝ ███████║ ██║ ╚██████╔╝██║ ██║
137 | // ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
138 |
139 |
140 | // load files
141 | fetch('population_2018.json')
142 | .then(function(response) {
143 | return response.json();
144 | }).then(popDataResponse=>{
145 | popData = popDataResponse;
146 | // New: we have one more step before launching the shader.
147 | // We are going to encode our data into an image, and then
148 | // kick off the shader program.
149 | initDataImage();
150 | });
151 |
152 |
153 | function requestDraw() {
154 | requestAnimationFrame(draw);
155 | }
156 |
157 | // straight outta mozilla
158 | //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context
159 | function loadShader(gl, type, source) {
160 | const shader = gl.createShader(type);
161 | // Send the source to the shader object
162 | gl.shaderSource(shader, source);
163 | // Compile the shader program
164 | gl.compileShader(shader);
165 | // See if it compiled successfully
166 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
167 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
168 | gl.deleteShader(shader);
169 | return null;
170 | }
171 | return shader;
172 | }
173 |
174 |
175 | })();
176 |
177 |
--------------------------------------------------------------------------------
/shader_06.2/frag.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | varying vec4 v_color;
6 | varying vec2 v_imagePosition;
7 |
8 | uniform sampler2D u_image;
9 | uniform sampler2D u_dataColors;
10 |
11 |
12 | void main(){
13 | vec4 color = texture2D(u_image, v_imagePosition);
14 | gl_FragColor = color;
15 | if (color.a <= 0.5) {
16 | gl_FragColor = vec4(1.0);
17 | } else {
18 | /*
19 | what country is this on the map?
20 | scale up the red channel to the 0-255 range
21 | */
22 | float countryColor = floor(color.r * 255.0);
23 | /* What are the x and y coordinates for this country on the data image? */
24 | float x = mod(countryColor,16.0)/16.0 + 0.5/16.0;
25 | float y = floor(countryColor/16.0)/16.0 + 0.5/16.0;
26 | /* grab the data for this country from the data image */
27 | vec4 dataColor = texture2D(u_dataColors,vec2(x,y));
28 | // gl_FragColor = vec4(dataColor.rgb, 1.0);
29 | /* red encodes population as a % of the largest population */
30 | float popPct = dataColor.r;
31 | /* green encodes urban population as a % of the country's total */
32 | float urbanPct = dataColor.g;
33 | /* blue encodes rural population as a % of the country's total */
34 | float ruralPct = dataColor.b;
35 | // float c = popPct;
36 | float c = urbanPct;
37 | // float c = ruralPct;
38 |
39 | /* 0 indicates no data */
40 | if (c < 1.0/ 255.0) {
41 | /* if there's no data, color it dark gray */
42 | gl_FragColor = vec4(0.4, 0.4, 0.4, 1.0);
43 | } else {
44 | /* color it according to the data */
45 | gl_FragColor = vec4(0.0, c, c, 1.0);
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/shader_06.2/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SHADER SHADER FRIDAY
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/shader_06.2/vert.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | precision mediump float;
3 | #endif
4 |
5 | attribute vec4 a_position;
6 |
7 | // New: the image coordinates
8 | // the attribute gets it from the js program
9 | attribute vec2 a_imagePosition;
10 | // and stashes it in the varying version, which allows
11 | // it to pass to the fragment shader
12 | varying vec2 v_imagePosition;
13 |
14 | uniform mat4 u_model;
15 | uniform mat4 u_projection;
16 |
17 |
18 | void main() {
19 | gl_Position = u_projection * u_model * a_position;
20 | v_imagePosition = a_imagePosition;
21 | }
--------------------------------------------------------------------------------