├── .gitattributes ├── LICENSE ├── README.md ├── advanced ├── Advanced Functions.txt ├── blackbody.glsl ├── complexNumber.glsl └── packing.glsl └── simple ├── Simple Functions.txt ├── color.glsl ├── converters.glsl └── misc.glsl /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # open-source-utility-code 2 | Some open source code made by myself, or that I got permission to include, for people who are a bit newer to shader development. 3 | 4 | 5 | Some of this code, like the entirety of the packing.glsl file, was provided by Zombye and included with permission. 6 | -------------------------------------------------------------------------------- /advanced/Advanced Functions.txt: -------------------------------------------------------------------------------- 1 | This folder has the more advanced functions in it. These are functions that require a relatively heavy amount of math knowledge to be able to understand them, and they are pretty difficult to implement even then. As a result these should only be used by people who know more than the average starter shader dev. -------------------------------------------------------------------------------- /advanced/blackbody.glsl: -------------------------------------------------------------------------------- 1 | vec3 plancks(in float t, in vec3 lambda) { 2 | const float h = 6.63e-16; 3 | const float c = 3.0e17; 4 | const float k = 1.38e-5; 5 | vec3 p1 = (2.0*h*pow(c, 2.0)) / pow(lambda, vec3(5.0)); 6 | vec3 p2 = exp(h*c/(lambda*k*t))-vec3(1); 7 | return (p1 / p2) * pow(1e9, 2.0); 8 | } 9 | 10 | vec3 blackbody(in float t) { 11 | vec3 rgb = plancks(t, vec3(660.0, 550.0, 440.0)); 12 | rgb = rgb / max(rgb.x, max(rgb.y, rgb.z)); 13 | 14 | return rgb; 15 | } 16 | -------------------------------------------------------------------------------- /advanced/complexNumber.glsl: -------------------------------------------------------------------------------- 1 | struct complexFloat { 2 | float r; 3 | float i; 4 | }; 5 | 6 | complexFloat complexAdd(complexFloat a, complexFloat b) 7 | { 8 | complexFloat c; 9 | c.r=a.r+b.r; 10 | c.i=a.i+b.i; 11 | return c; 12 | } 13 | 14 | complexFloat complexSub(complexFloat a, complexFloat b) 15 | { 16 | complexFloat c; 17 | c.r=a.r-b.r; 18 | c.i=a.i-b.i; 19 | return c; 20 | } 21 | 22 | complexFloat complexSub(complexFloat a, float b) 23 | { 24 | complexFloat c; 25 | c.r=a.r-b; 26 | c.i= -a.i; 27 | return c; 28 | } 29 | 30 | complexFloat complexSub(float a, complexFloat b) 31 | { 32 | complexFloat c; 33 | c.r=a-b.r; 34 | c.i= -b.i; 35 | return c; 36 | } 37 | 38 | complexFloat complexMul(complexFloat a, complexFloat b) 39 | { 40 | complexFloat c; 41 | c.r=a.r*b.r-a.i*b.i; 42 | c.i=a.i*b.r+a.r*b.i; 43 | return c; 44 | } 45 | 46 | complexFloat complexMul(float x, complexFloat a) 47 | { 48 | complexFloat c; 49 | c.r=x*a.r; 50 | c.i=x*a.i; 51 | return c; 52 | } 53 | 54 | complexFloat complexMul(complexFloat x, float a) 55 | { 56 | complexFloat c; 57 | c.r=x.r*a; 58 | c.i=x.i*a; 59 | return c; 60 | } 61 | 62 | complexFloat complexConjugate(complexFloat z) 63 | { 64 | complexFloat c; 65 | c.r=z.r; 66 | c.i = -z.i; 67 | return c; 68 | } 69 | 70 | complexFloat complexDiv(complexFloat a, complexFloat b) 71 | { 72 | complexFloat c; 73 | float r,den; 74 | if (abs(b.r) >= abs(b.i)) { 75 | r=b.i/b.r; 76 | den=b.r+r*b.i; 77 | c.r=(a.r+r*a.i)/den; 78 | c.i=(a.i-r*a.r)/den; 79 | } else { 80 | r=b.r/b.i; 81 | den=b.i+r*b.r; 82 | c.r=(a.r*r+a.i)/den; 83 | c.i=(a.i*r-a.r)/den; 84 | } 85 | return c; 86 | } 87 | 88 | float complexAbs(complexFloat z) 89 | { 90 | float x,y,ans,temp; 91 | x=abs(z.r); 92 | y=abs(z.i); 93 | if (x == 0.0) 94 | ans=y; 95 | else if (y == 0.0) 96 | ans=x; 97 | else if (x > y) { 98 | temp=y/x; 99 | ans=x*sqrt(1.0+temp*temp); 100 | } else { 101 | temp=x/y; 102 | ans=y*sqrt(1.0+temp*temp); 103 | } 104 | return ans; 105 | } 106 | 107 | complexFloat complexSqrt(complexFloat z) 108 | { 109 | complexFloat c; 110 | float x,y,w,r; 111 | if ((z.r == 0.0) && (z.i == 0.0)) { 112 | c.r=0.0; 113 | c.i=0.0; 114 | return c; 115 | } else { 116 | x=abs(z.r); 117 | y=abs(z.i); 118 | if (x >= y) { 119 | r=y/x; 120 | w=sqrt(x)*sqrt(0.5*(1.0+sqrt(1.0+r*r))); 121 | } else { 122 | r=x/y; 123 | w=sqrt(y)*sqrt(0.5*(r+sqrt(1.0+r*r))); 124 | } 125 | if (z.r >= 0.0) { 126 | c.r=w; 127 | c.i=z.i/(2.0*w); 128 | } else { 129 | c.i=(z.i >= 0) ? w : -w; 130 | c.r=z.i/(2.0*c.i); 131 | } 132 | return c; 133 | } 134 | } 135 | 136 | complexFloat complexExp(complexFloat z) { 137 | return complexMul(exp(z.r), complexFloat(cos(z.i), sin(z.i))); 138 | } 139 | 140 | vec2 complexToVector(complexFloat z) { 141 | return vec2(z.r, z.i); 142 | } 143 | 144 | 145 | struct complexVec3 { 146 | vec3 r; 147 | vec3 i; 148 | }; 149 | 150 | complexVec3 complexAdd(complexVec3 a, complexVec3 b) 151 | { 152 | complexVec3 c; 153 | c.r=a.r+b.r; 154 | c.i=a.i+b.i; 155 | return c; 156 | } 157 | 158 | complexVec3 complexSub(complexVec3 a, complexVec3 b) 159 | { 160 | complexVec3 c; 161 | c.r=a.r-b.r; 162 | c.i=a.i-b.i; 163 | return c; 164 | } 165 | 166 | complexVec3 complexSub(complexVec3 a, vec3 b) 167 | { 168 | complexVec3 c; 169 | c.r=a.r-b; 170 | c.i= -a.i; 171 | return c; 172 | } 173 | 174 | complexVec3 complexSub(vec3 a, complexVec3 b) 175 | { 176 | complexVec3 c; 177 | c.r=a-b.r; 178 | c.i= -b.i; 179 | return c; 180 | } 181 | 182 | complexVec3 complexMul(complexVec3 a, complexVec3 b) 183 | { 184 | complexVec3 c; 185 | c.r=a.r*b.r-a.i*b.i; 186 | c.i=a.i*b.r+a.r*b.i; 187 | return c; 188 | } 189 | 190 | complexVec3 complexMul(vec3 x, complexVec3 a) 191 | { 192 | complexVec3 c; 193 | c.r=x*a.r; 194 | c.i=x*a.i; 195 | return c; 196 | } 197 | 198 | complexVec3 complexMul(complexVec3 x, vec3 a) 199 | { 200 | complexVec3 c; 201 | c.r=x.r*a; 202 | c.i=x.i*a; 203 | return c; 204 | } 205 | 206 | complexVec3 complexConjugate(complexVec3 z) 207 | { 208 | complexVec3 c; 209 | c.r=z.r; 210 | c.i = -z.i; 211 | return c; 212 | } 213 | 214 | complexVec3 complexDiv(complexVec3 a, complexVec3 b) 215 | { 216 | complexVec3 c; 217 | vec3 r,den; 218 | if (all(greaterThanEqual(abs(b.r), abs(b.i)))) { 219 | r=b.i/b.r; 220 | den=b.r+r*b.i; 221 | c.r=(a.r+r*a.i)/den; 222 | c.i=(a.i-r*a.r)/den; 223 | } else { 224 | r=b.r/b.i; 225 | den=b.i+r*b.r; 226 | c.r=(a.r*r+a.i)/den; 227 | c.i=(a.i*r-a.r)/den; 228 | } 229 | return c; 230 | } 231 | 232 | vec3 complexAbs(complexVec3 z) 233 | { 234 | vec3 x,y,ans,temp; 235 | x=abs(z.r); 236 | y=abs(z.i); 237 | if (all(equal(x, vec3(0.0)))) 238 | ans=y; 239 | else if (all(equal(y, vec3(0.0)))) 240 | ans=x; 241 | else if (all(greaterThanEqual(x, y))) { 242 | temp=y/x; 243 | ans=x*sqrt(1.0+temp*temp); 244 | } else { 245 | temp=x/y; 246 | ans=y*sqrt(1.0+temp*temp); 247 | } 248 | return ans; 249 | } 250 | 251 | complexVec3 complexSqrt(complexVec3 z) 252 | { 253 | complexVec3 c; 254 | vec3 x,y,w,r; 255 | if (all(equal(z.r, vec3(0.0))) && all(equal(z.i, vec3(0.0)))) { 256 | c.r=vec3(0.0); 257 | c.i=vec3(0.0); 258 | return c; 259 | } else { 260 | x=abs(z.r); 261 | y=abs(z.i); 262 | if (all(greaterThanEqual(x, y))) { 263 | r=y/x; 264 | w=sqrt(x)*sqrt(0.5*(1.0+sqrt(1.0+r*r))); 265 | } else { 266 | r=x/y; 267 | w=sqrt(y)*sqrt(0.5*(r+sqrt(1.0+r*r))); 268 | } 269 | if (all(greaterThanEqual(z.r, vec3(0.0)))) { 270 | c.r=w; 271 | c.i=z.i/(2.0*w); 272 | } else { 273 | c.i=(all(greaterThanEqual(z.r, vec3(0.0)))) ? w : -w; 274 | c.r=z.i/(2.0*c.i); 275 | } 276 | return c; 277 | } 278 | } 279 | 280 | complexVec3 complexExp(complexVec3 z) { 281 | return complexMul(exp(z.r), complexVec3(cos(z.i), sin(z.i))); 282 | } -------------------------------------------------------------------------------- /advanced/packing.glsl: -------------------------------------------------------------------------------- 1 | // Octahedral Unit Vector encoding 2 | // Intuitive, fast, and has very little error. 3 | vec2 encodeUnitVector(vec3 vector) { 4 | // Scale down to octahedron, project onto XY plane 5 | vector.xy /= abs(vector.x) + abs(vector.y) + abs(vector.z); 6 | // Reflect -Z hemisphere folds over the diagonals 7 | return vector.z <= 0.0 ? (1.0 - abs(vector.yx)) * vec2(vector.x >= 0.0 ? 1.0 : -1.0, vector.y >= 0.0 ? 1.0 : -1.0) : vector.xy; 8 | } 9 | 10 | vec3 decodeUnitVector(vec2 encoded) { 11 | // Exctract Z component 12 | vec3 vector = vec3(encoded, 1.0 - abs(encoded.x) - abs(encoded.y)); 13 | // Reflect -Z hemisphere folds over the diagonals 14 | float t = max(-vector.z, 0.0); 15 | vector.xy += vec2(vector.x >= 0.0 ? -t : t, vector.y >= 0.0 ? -t : t); 16 | // Normalize and return 17 | return normalize(vector); 18 | } 19 | 20 | vec4 encodeRGBE8(vec3 rgb) { 21 | float exponentPart = floor(log2(max(max(rgb.r, rgb.g), max(rgb.b, exp2(-127.0))))); // can remove the clamp to above exp2(-127) if you're sure you're not going to input any values below that 22 | vec3 mantissaPart = clamp((128.0 / 255.0) * exp2(-exponentPart) * rgb, 0.0, 1.0); 23 | exponentPart = clamp(exponentPart / 255.0 + (127.0 / 255.0), 0.0, 1.0); 24 | 25 | return vec4(mantissaPart, exponentPart); 26 | } 27 | 28 | vec3 decodeRGBE8(vec4 rgbe) { 29 | cFloat add = log2(255.0 / 128.0) - 127.0; 30 | return exp2(rgbe.a * 255.0 + add) * rgbe.rgb; 31 | } 32 | 33 | 34 | 35 | float packUnorm2x4(vec2 xy) { 36 | return dot(floor(15.0 * xy + 0.5), vec2(1.0 / 255.0, 16.0 / 255.0)); 37 | } 38 | float packUnorm2x4(float x, float y) { return packUnorm2x4(vec2(x, y)); } 39 | vec2 unpackUnorm2x4(float pack) { 40 | vec2 xy; xy.x = modf(pack * 255.0 / 16.0, xy.y); 41 | return xy * vec2(16.0 / 15.0, 1.0 / 15.0); 42 | } 43 | float unpackUnorm2x4X(float pack) { return fract(pack * 255.0 / 16.0) * 16.0 / 15.0; } 44 | float unpackUnorm2x4Y(float pack) { return floor(pack * 255.0 / 16.0) / 15.0; } 45 | 46 | float packUnorm2x8(vec2 xy) { 47 | return dot(floor(255.0 * xy + 0.5), vec2(1.0 / 65535.0, 256.0 / 65535.0)); 48 | } 49 | float packUnorm2x8(float x, float y) { return packUnorm2x8(vec2(x, y)); } 50 | vec2 unpackUnorm2x8(float pack) { 51 | vec2 xy; xy.x = modf(pack * 65535.0 / 256.0, xy.y); 52 | return xy * vec2(256.0 / 255.0, 1.0 / 255.0); 53 | } 54 | float unpackUnorm2x8X(float pack) { return fract(pack * 65535.0 / 256.0) * 256.0 / 255.0; } 55 | float unpackUnorm2x8Y(float pack) { return floor(pack * 65535.0 / 256.0) / 255.0; } 56 | 57 | float packSnorm2x8(vec2 xy) { 58 | vec2 xy2 = floor(mix(128.5 + 127.0 * xy, 127.5 + 127.0 * xy, greaterThan(xy, vec2(0.0)))); 59 | return dot(xy2, vec2(1.0 / 65535.0, 256.0 / 65535.0)); 60 | } 61 | float packSnorm2x8(float x, float y) { return packSnorm2x8(vec2(x, y)); } 62 | vec2 UnpackSnorm2x8(float pack) { 63 | vec2 xy; xy.x = modf(pack * 65535.0 / 256.0, xy.y); 64 | return xy * vec2(256.0 / 127.0, 1.0 / 127.0) - mix(vec2(1.0), vec2(128.0 / 127.0), greaterThan(xy, vec2(127.5 / 256.0, 127.5))); 65 | } 66 | float unpackSnorm2x8X(float pack) { return unpackSnorm2x8(pack).x; } 67 | float unpackSnorm2x8Y(float pack) { return unpackSnorm2x8(pack).y; } -------------------------------------------------------------------------------- /simple/Simple Functions.txt: -------------------------------------------------------------------------------- 1 | These are functions that are relatively simple to understand. The most complicated ones only require a decent amount of math knowledge, which is expected from people who want to develop shaderpacks anyway. -------------------------------------------------------------------------------- /simple/color.glsl: -------------------------------------------------------------------------------- 1 | vec3 srgbToLinear(in vec3 srgb) { 2 | return pow(srgb, vec3(2.2)); 3 | } 4 | 5 | vec3 linearToSRGB(in vec3 linear) { 6 | return pow(linear, vec3(1.0/2.2)); 7 | } -------------------------------------------------------------------------------- /simple/converters.glsl: -------------------------------------------------------------------------------- 1 | vec3 screenSpaceToViewSpace(vec3 screenPosition, mat4 projectionInverse) { 2 | screenPosition = screenPosition * 2.0 - 1.0; 3 | 4 | vec3 viewPosition = vec3(vec2(projectionInverse[0].x, projectionInverse[1].y) * screenPosition.xy + projectionInverse[3].xy, projectionInverse[3].z); 5 | 6 | viewPosition /= projectionInverse[2].w * screenPosition.z + projectionInverse[3].w; 7 | 8 | return viewPosition; 9 | } 10 | 11 | float screenSpaceToViewSpace(float depth, mat4 projectionInverse) { 12 | depth = depth * 2.0 - 1.0; 13 | return projectionInverse[3].z / (projectionInverse[2].w * depth + projectionInverse[3].w); 14 | } 15 | 16 | vec3 viewSpaceToScreenSpace(vec3 viewPosition, mat4 projection) { 17 | vec3 screenPosition = vec3(projection[0].x, projection[1].y, projection[2].z) * viewPosition + projection[3].xyz; 18 | screenPosition /= -viewPosition.z; 19 | 20 | return screenPosition * 0.5 + 0.5; 21 | } 22 | 23 | float viewSpaceToScreenSpace(float depth, mat4 projection) { 24 | return ((projection[2].z * depth + projection[3].z) / -depth) * 0.5 + 0.5; 25 | } 26 | 27 | vec3 viewSpaceToSceneSpace(in vec3 viewPosition, in mat4 modelViewInverse) { 28 | return mat3(modelViewInverse) * viewPosition + modelViewInverse[3].xyz; 29 | } 30 | 31 | vec3 sceneSpaceToShadowView(in vec3 scenePosition, in mat4 shadowMV) { 32 | return mat3(shadowMV) * scenePosition + shadowMV[3].xyz; 33 | } 34 | 35 | vec3 shadowViewToShadowClip(in vec3 shadowView, in mat4 shadowProj) { 36 | return mat3(shadowProj) * shadowView + shadowProj[3].xyz; 37 | } -------------------------------------------------------------------------------- /simple/misc.glsl: -------------------------------------------------------------------------------- 1 | #define _square(x) (x*x) 2 | #define _cube(x) (x*x*x) 3 | #define _saturate(x) clamp(x, 0.0, 1.0) 4 | #define _saturateInt(x) clamp(x, 0, 1) 5 | #define _rcp(x) (1.0 / x) 6 | #define _log10(x, y) (log2(x) / log2(y)) 7 | #define _pow5(x) (x*x*x*x*x) 8 | 9 | float square(in float x) { 10 | return _square(x); 11 | } 12 | int square(in int x) { 13 | return _square(x); 14 | } 15 | vec2 square(in vec2 x) { 16 | return _square(x); 17 | } 18 | vec3 square(in vec3 x) { 19 | return _square(x); 20 | } 21 | vec4 square(in vec4 x) { 22 | return _square(x); 23 | } 24 | 25 | float cube(in float x) { 26 | return _cube(x); 27 | } 28 | int cube(in int x) { 29 | return _cube(x); 30 | } 31 | vec2 cube(in vec2 x) { 32 | return _cube(x); 33 | } 34 | vec3 cube(in vec3 x) { 35 | return _cube(x); 36 | } 37 | vec4 cube(in vec4 x) { 38 | return _cube(x); 39 | } 40 | 41 | float pow5(in float x) { 42 | return _pow5(x); 43 | } 44 | int pow5(in int x) { 45 | return _pow5(x); 46 | } 47 | vec2 pow5(in vec2 x) { 48 | return _pow5(x); 49 | } 50 | vec3 pow5(in vec3 x) { 51 | return _pow5(x); 52 | } 53 | vec4 pow5(in vec4 x) { 54 | return _pow5(x); 55 | } 56 | 57 | float saturate(in float x) { 58 | return _saturate(x); 59 | } 60 | int saturate(in int x) { 61 | return _saturateInt(x); 62 | } 63 | vec2 saturate(in vec2 x) { 64 | return _saturate(x); 65 | } 66 | vec3 saturate(in vec3 x) { 67 | return _saturate(x); 68 | } 69 | vec4 saturate(in vec4 x) { 70 | return _saturate(x); 71 | } 72 | 73 | float minof(vec2 x) { 74 | return min(x.x, x.y); 75 | } 76 | float minof(vec3 x) { 77 | return min(min(x.x, x.y), x.z); 78 | } 79 | float minof(vec4 x) { 80 | x.xy = min(x.xy, x.zw); return min(x.x, x.y); 81 | } 82 | 83 | float maxof(vec2 x) { 84 | return max(x.x, x.y); 85 | } 86 | float maxof(vec3 x) { 87 | return max(max(x.x, x.y), x.z); 88 | } 89 | float maxof(vec4 x) { 90 | x.xy = max(x.xy, x.zw); return max(x.x, x.y); 91 | } 92 | 93 | float rcp(in float x) { 94 | return _rcp(x); 95 | } 96 | vec2 rcp(in vec2 x) { 97 | return _rcp(x); 98 | } 99 | vec3 rcp(in vec3 x) { 100 | return _rcp(x); 101 | } 102 | vec4 rcp(in vec4 x) { 103 | return _rcp(x); 104 | } 105 | 106 | float max2(vec2 x) { 107 | return max(x.x, x.y); 108 | } 109 | 110 | float max3(float x, float y, float z) { 111 | return max(x, max(y, z)); 112 | } 113 | float max3(vec3 x) { 114 | return max(x.x, max(x.y, x.z)); 115 | } 116 | float min3(float x, float y, float z) { 117 | return min(x, min(y, z)); 118 | } 119 | float min3(vec3 x) { 120 | return min(x.x, min(x.y, x.z)); 121 | } 122 | float mean(vec3 x) { 123 | return (x.x + x.y + x.z) * rcp(3.0); 124 | } 125 | 126 | float log10(in float x) { 127 | return _log10(x, 10.0); 128 | } 129 | int log10(in int x) { 130 | return int(_log10(x, 10.0)); 131 | } 132 | vec2 log10(in vec2 x) { 133 | return _log10(x, 10.0); 134 | } 135 | vec3 log10(in vec3 x) { 136 | return _log10(x, 10.0); 137 | } 138 | vec4 log10(in vec4 x) { 139 | return _log10(x, 10.0); 140 | } 141 | 142 | float linearstep(in float x, float low, float high) { 143 | float data = x; 144 | float mapped = (data-low)/(high-low); 145 | 146 | return saturate(mapped); 147 | } 148 | vec2 linearstep(in vec2 x, float low, float high) { 149 | vec2 data = x; 150 | vec2 mapped = (data-low)/(high-low); 151 | 152 | return saturate(mapped); 153 | } 154 | vec3 linearstep(in vec3 x, float low, float high) { 155 | vec3 data = x; 156 | vec3 mapped = (data-low)/(high-low); 157 | 158 | return saturate(mapped); 159 | } 160 | vec4 linearstep(in vec4 x, float low, float high) { 161 | vec4 data = x; 162 | vec4 mapped = (data-low)/(high-low); 163 | 164 | return saturate(mapped); 165 | } 166 | 167 | vec2 sincos(float x) { return vec2(sin(x), cos(x)); } 168 | 169 | mat2 rotate(float a) { 170 | vec2 m; 171 | m.x = sin(a); 172 | m.y = cos(a); 173 | return mat2(m.y, -m.x, m.x, m.y); 174 | } 175 | 176 | vec2 rotate(vec2 vector, float angle) { 177 | vec2 sc = sincos(angle); 178 | return vec2(sc.y * vector.x + sc.x * vector.y, sc.y * vector.y - sc.x * vector.x); 179 | } 180 | 181 | vec3 rotate(vec3 vector, vec3 axis, float angle) { 182 | // https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula 183 | vec2 sc = sincos(angle); 184 | return sc.y * vector + sc.x * cross(axis, vector) + (1.0 - sc.y) * dot(axis, vector) * axis; 185 | } 186 | 187 | vec3 rotate(vec3 vector, vec3 from, vec3 to) { 188 | // where "from" and "to" are two unit vectors determining how far to rotate 189 | // adapted version of https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula 190 | 191 | float cosTheta = dot(from, to); 192 | if (abs(cosTheta) >= 0.9999) { return cosTheta < 0.0 ? -vector : vector; } 193 | vec3 axis = normalize(cross(from, to)); 194 | 195 | vec2 sc = vec2(sqrt(1.0 - cosTheta * cosTheta), cosTheta); 196 | return sc.y * vector + sc.x * cross(axis, vector) + (1.0 - sc.y) * dot(axis, vector) * axis; 197 | } 198 | 199 | vec2 circleMap(in float index, in float count) { 200 | float goldenAngle = tau / ((sqrt(5.0) * 0.5 + 0.5) + 1.0); 201 | return vec2(cos(index * goldenAngle), sin(index * goldenAngle)) * sqrt(index / count); 202 | } 203 | 204 | vec3 generateUnitVector(vec2 hash) { 205 | hash.x *= tau; hash.y = hash.y * 2.0 - 1.0; 206 | return vec3(vec2(sin(hash.x), cos(hash.x)) * sqrt(1.0 - hash.y * hash.y), hash.y); 207 | } 208 | 209 | vec3 generateConeVector(vec3 vector, vec2 xy, float angle) { 210 | xy.x *= radians(360.0); 211 | float cosAngle = cos(angle); 212 | xy.y = xy.y * (1.0 - cosAngle) + cosAngle; 213 | vec3 sphereCap = vec3(vec2(cos(xy.x), sin(xy.x)) * sqrt(1.0 - xy.y * xy.y), xy.y); 214 | return rotate(sphereCap, vec3(0, 0, 1), vector); 215 | } --------------------------------------------------------------------------------