p5 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/{src → dist}/accessibility/color_namer.js +48 -3
  2. package/{src → dist}/accessibility/describe.js +12 -2
  3. package/{src → dist}/accessibility/gridOutput.js +2 -2
  4. package/dist/accessibility/index.js +60 -0
  5. package/{src → dist}/accessibility/outputs.js +23 -2
  6. package/{src → dist}/accessibility/textOutput.js +2 -2
  7. package/dist/app.js +120 -0
  8. package/{src → dist}/color/color_conversion.js +48 -10
  9. package/{src → dist}/color/color_spaces/hsb.js +3 -1
  10. package/dist/color/creating_reading.js +3 -0
  11. package/dist/color/index.js +13 -0
  12. package/dist/color/p5.Color.culori.js +1 -0
  13. package/dist/color/p5.Color.js +3 -0
  14. package/{src → dist}/color/setting.js +9 -6
  15. package/{src/core/constants.js → dist/constants-tYr0tCl8.js} +284 -132
  16. package/{src → dist}/core/States.js +3 -1
  17. package/dist/core/constants.js +1 -0
  18. package/{src → dist}/core/environment.js +12 -10
  19. package/{src → dist}/core/friendly_errors/browser_errors.js +1 -1
  20. package/{src → dist}/core/friendly_errors/fes_core.js +14 -44
  21. package/{src → dist}/core/friendly_errors/file_errors.js +6 -3
  22. package/dist/core/friendly_errors/index.js +23 -0
  23. package/dist/core/friendly_errors/param_validator.js +5421 -0
  24. package/{src → dist}/core/friendly_errors/sketch_reader.js +50 -4
  25. package/{src → dist}/core/friendly_errors/sketch_verifier.js +6 -6
  26. package/{src → dist}/core/friendly_errors/stacktrace.js +3 -5
  27. package/{src → dist}/core/friendly_errors/validate_params.js +50 -41
  28. package/{src → dist}/core/helpers.js +9 -6
  29. package/dist/core/init.js +105 -0
  30. package/dist/core/internationalization.js +302 -0
  31. package/dist/core/legacy.js +73 -0
  32. package/dist/core/main.js +44 -0
  33. package/dist/core/noop.js +3 -0
  34. package/dist/core/p5.Graphics.js +40 -0
  35. package/dist/core/p5.Renderer.js +11 -0
  36. package/dist/core/p5.Renderer2D.js +44 -0
  37. package/dist/core/reference.js +1 -0
  38. package/dist/core/rendering.js +40 -0
  39. package/{src → dist}/core/structure.js +3 -3
  40. package/{src → dist}/core/transform.js +2 -2
  41. package/{src/color/creating_reading.js → dist/creating_reading-Cr8L2Jnm.js} +841 -13
  42. package/{src → dist}/data/index.js +3 -1
  43. package/{src → dist}/data/local_storage.js +2 -8
  44. package/{src → dist}/dom/dom.js +19 -13
  45. package/dist/dom/index.js +18 -0
  46. package/{src → dist}/dom/p5.Element.js +14 -12
  47. package/{src → dist}/dom/p5.File.js +4 -4
  48. package/{src → dist}/dom/p5.MediaElement.js +10 -4
  49. package/{src → dist}/events/acceleration.js +26 -26
  50. package/{src → dist}/events/index.js +3 -1
  51. package/{src → dist}/events/keyboard.js +14 -12
  52. package/{src → dist}/events/pointer.js +16 -17
  53. package/dist/image/const.js +9 -0
  54. package/{src → dist}/image/filterRenderer2D.js +57 -37
  55. package/{src → dist}/image/filters.js +1 -3
  56. package/dist/image/image.js +40 -0
  57. package/dist/image/index.js +51 -0
  58. package/dist/image/loading_displaying.js +40 -0
  59. package/dist/image/p5.Image.js +11 -0
  60. package/{src → dist}/image/pixels.js +5 -3
  61. package/{src → dist}/io/csv.js +72 -70
  62. package/dist/io/files.js +40 -0
  63. package/dist/io/index.js +51 -0
  64. package/{src → dist}/io/p5.Table.js +6 -6
  65. package/{src → dist}/io/p5.TableRow.js +5 -6
  66. package/{src → dist}/io/p5.XML.js +2 -5
  67. package/{src → dist}/io/utilities.js +1 -1
  68. package/{src/core/p5.Renderer2D.js → dist/main-CAxvgiOV.js} +738 -57
  69. package/{src → dist}/math/Matrices/Matrix.js +10 -8
  70. package/{src → dist}/math/Matrices/MatrixInterface.js +5 -3
  71. package/{src → dist}/math/Matrices/MatrixNumjs.js +12 -26
  72. package/{src → dist}/math/calculation.js +2 -2
  73. package/{src → dist}/math/index.js +6 -3
  74. package/{src → dist}/math/math.js +3 -3
  75. package/{src → dist}/math/noise.js +2 -2
  76. package/{src → dist}/math/p5.Matrix.js +7 -4
  77. package/{src → dist}/math/p5.Vector.js +6 -6
  78. package/{src → dist}/math/random.js +2 -2
  79. package/{src → dist}/math/trigonometry.js +16 -15
  80. package/{src/image/p5.Image.js → dist/p5.Renderer-Swjl9HQO.js} +393 -22
  81. package/dist/rendering-B5TRR7aY.js +24960 -0
  82. package/{src → dist}/shape/2d_primitives.js +18 -17
  83. package/{src → dist}/shape/attributes.js +18 -17
  84. package/{src → dist}/shape/curves.js +2 -2
  85. package/{src → dist}/shape/custom_shapes.js +44 -64
  86. package/{src → dist}/shape/index.js +10 -2
  87. package/{src → dist}/shape/vertex.js +2 -3
  88. package/dist/type/index.js +25 -0
  89. package/{src → dist}/type/lib/Typr.js +76 -94
  90. package/{src → dist}/type/p5.Font.js +37 -63
  91. package/{src → dist}/type/textCore.js +35 -58
  92. package/{src → dist}/type/unicodeRanges.js +3 -1
  93. package/{src → dist}/utilities/conversion.js +2 -2
  94. package/{src → dist}/utilities/index.js +3 -1
  95. package/{src → dist}/utilities/time_date.js +6 -7
  96. package/{src → dist}/utilities/utility_functions.js +2 -2
  97. package/dist/webgl/3d_primitives.js +40 -0
  98. package/{src → dist}/webgl/GeometryBufferCache.js +3 -1
  99. package/{src → dist}/webgl/GeometryBuilder.js +12 -8
  100. package/{src → dist}/webgl/ShaderGenerator.js +79 -82
  101. package/{src → dist}/webgl/ShapeBuilder.js +26 -23
  102. package/dist/webgl/index.js +76 -0
  103. package/{src → dist}/webgl/interaction.js +7 -6
  104. package/dist/webgl/light.js +40 -0
  105. package/{src → dist}/webgl/loading.js +45 -12
  106. package/dist/webgl/material.js +40 -0
  107. package/dist/webgl/p5.Camera.js +40 -0
  108. package/{src → dist}/webgl/p5.DataArray.js +3 -5
  109. package/dist/webgl/p5.Framebuffer.js +40 -0
  110. package/{src → dist}/webgl/p5.Geometry.js +12 -15
  111. package/{src → dist}/webgl/p5.Quat.js +5 -4
  112. package/{src → dist}/webgl/p5.RenderBuffer.js +2 -3
  113. package/dist/webgl/p5.RendererGL.js +40 -0
  114. package/dist/webgl/p5.Shader.js +40 -0
  115. package/dist/webgl/p5.Texture.js +40 -0
  116. package/{src → dist}/webgl/text.js +78 -38
  117. package/lib/p5.esm.js +296 -194
  118. package/lib/p5.js +296 -194
  119. package/lib/p5.min.js +1 -1
  120. package/package.json +17 -17
  121. package/translations/dev.js +6 -6
  122. package/translations/index.js +1 -1
  123. package/types/accessibility/color_namer.d.ts +8 -0
  124. package/types/accessibility/describe.d.ts +184 -0
  125. package/types/accessibility/gridOutput.d.ts +8 -0
  126. package/types/accessibility/outputs.d.ts +235 -0
  127. package/types/accessibility/textOutput.d.ts +8 -0
  128. package/types/color/color_conversion.d.ts +47 -0
  129. package/types/color/creating_reading.d.ts +1348 -0
  130. package/types/color/p5.Color.d.ts +1070 -0
  131. package/types/color/setting.d.ts +2085 -0
  132. package/types/core/constants.d.ts +341 -0
  133. package/types/core/environment.d.ts +668 -0
  134. package/types/core/friendly_errors/fes_core.d.ts +8 -0
  135. package/types/core/friendly_errors/file_errors.d.ts +8 -0
  136. package/types/core/friendly_errors/param_validator.d.ts +30 -0
  137. package/types/core/friendly_errors/sketch_reader.d.ts +8 -0
  138. package/types/core/friendly_errors/stacktrace.d.ts +11 -0
  139. package/types/core/friendly_errors/validate_params.d.ts +8 -0
  140. package/types/core/helpers.d.ts +8 -0
  141. package/types/core/legacy.d.ts +8 -0
  142. package/types/core/main.d.ts +5996 -0
  143. package/types/core/p5.Graphics.d.ts +484 -0
  144. package/types/core/p5.Renderer.d.ts +14 -0
  145. package/types/core/reference.d.ts +8 -0
  146. package/types/core/rendering.d.ts +481 -0
  147. package/types/core/structure.d.ts +492 -0
  148. package/types/core/transform.d.ts +1638 -0
  149. package/types/data/local_storage.d.ts +323 -0
  150. package/types/dom/dom.d.ts +1295 -0
  151. package/types/dom/p5.Element.d.ts +2011 -0
  152. package/types/dom/p5.File.d.ts +13 -0
  153. package/types/dom/p5.MediaElement.d.ts +1249 -0
  154. package/types/events/acceleration.d.ts +193 -0
  155. package/types/events/keyboard.d.ts +499 -0
  156. package/types/events/pointer.d.ts +782 -0
  157. package/types/global.d.ts +5542 -0
  158. package/types/image/filterRenderer2D.d.ts +54 -0
  159. package/types/image/image.d.ts +326 -0
  160. package/types/image/loading_displaying.d.ts +580 -0
  161. package/types/image/p5.Image.d.ts +5882 -0
  162. package/types/image/pixels.d.ts +832 -0
  163. package/types/io/files.d.ts +1447 -0
  164. package/types/io/p5.Table.d.ts +1247 -0
  165. package/types/io/p5.TableRow.d.ts +343 -0
  166. package/types/io/p5.XML.d.ts +1188 -0
  167. package/types/math/Matrices/Matrix.d.ts +1029 -0
  168. package/types/math/Matrices/MatrixNumjs.d.ts +8 -0
  169. package/types/math/calculation.d.ts +923 -0
  170. package/types/math/math.d.ts +90 -0
  171. package/types/math/noise.d.ts +311 -0
  172. package/types/math/p5.Matrix.d.ts +8 -0
  173. package/types/math/p5.Vector.d.ts +3416 -0
  174. package/types/math/random.d.ts +267 -0
  175. package/types/math/trigonometry.d.ts +663 -0
  176. package/types/p5.d.ts +6663 -0
  177. package/types/shape/2d_primitives.d.ts +1033 -0
  178. package/types/shape/attributes.d.ts +466 -0
  179. package/types/shape/curves.d.ts +740 -0
  180. package/types/shape/custom_shapes.d.ts +888 -0
  181. package/types/shape/vertex.d.ts +1141 -0
  182. package/types/type/p5.Font.d.ts +575 -0
  183. package/types/type/textCore.d.ts +1198 -0
  184. package/types/utilities/conversion.d.ts +894 -0
  185. package/types/utilities/time_date.d.ts +295 -0
  186. package/types/utilities/utility_functions.d.ts +587 -0
  187. package/types/webgl/3d_primitives.d.ts +1432 -0
  188. package/types/webgl/ShaderGenerator.d.ts +8 -0
  189. package/types/webgl/interaction.d.ts +371 -0
  190. package/types/webgl/light.d.ts +1184 -0
  191. package/types/webgl/loading.d.ts +481 -0
  192. package/types/webgl/material.d.ts +2656 -0
  193. package/types/webgl/p5.Camera.d.ts +3023 -0
  194. package/types/webgl/p5.DataArray.d.ts +61 -0
  195. package/types/webgl/p5.Framebuffer.d.ts +760 -0
  196. package/types/webgl/p5.Geometry.d.ts +1191 -0
  197. package/types/webgl/p5.Quat.d.ts +45 -0
  198. package/types/webgl/p5.RendererGL.d.ts +234 -0
  199. package/types/webgl/p5.Shader.d.ts +660 -0
  200. package/types/webgl/p5.Texture.d.ts +61 -0
  201. package/types/webgl/text.d.ts +74 -0
  202. package/src/README.md +0 -27
  203. package/src/accessibility/index.js +0 -13
  204. package/src/app.js +0 -61
  205. package/src/color/index.js +0 -9
  206. package/src/color/p5.Color.culori.js +0 -66
  207. package/src/color/p5.Color.js +0 -851
  208. package/src/core/README.md +0 -91
  209. package/src/core/friendly_errors/index.js +0 -13
  210. package/src/core/friendly_errors/param_validator.js +0 -561
  211. package/src/core/init.js +0 -58
  212. package/src/core/internationalization.js +0 -195
  213. package/src/core/legacy.js +0 -29
  214. package/src/core/main.js +0 -689
  215. package/src/core/noop.js +0 -1
  216. package/src/core/p5.Graphics.js +0 -696
  217. package/src/core/p5.Renderer.js +0 -408
  218. package/src/core/reference.js +0 -2060
  219. package/src/core/rendering.js +0 -697
  220. package/src/dom/index.js +0 -11
  221. package/src/image/const.js +0 -6
  222. package/src/image/image.js +0 -731
  223. package/src/image/index.js +0 -15
  224. package/src/image/loading_displaying.js +0 -1431
  225. package/src/io/files.js +0 -2210
  226. package/src/io/index.js +0 -11
  227. package/src/math/README.md +0 -40
  228. package/src/type/index.js +0 -9
  229. package/src/webgl/3d_primitives.js +0 -2741
  230. package/src/webgl/index.js +0 -37
  231. package/src/webgl/light.js +0 -1851
  232. package/src/webgl/material.js +0 -3854
  233. package/src/webgl/p5.Camera.js +0 -4010
  234. package/src/webgl/p5.Framebuffer.js +0 -1865
  235. package/src/webgl/p5.RendererGL.js +0 -2867
  236. package/src/webgl/p5.Shader.js +0 -1505
  237. package/src/webgl/p5.Texture.js +0 -541
  238. package/src/webgl/shaders/basic.frag +0 -6
  239. package/src/webgl/shaders/filters/base.frag +0 -22
  240. package/src/webgl/shaders/filters/base.vert +0 -19
  241. package/src/webgl/shaders/filters/blur.frag +0 -60
  242. package/src/webgl/shaders/filters/default.vert +0 -18
  243. package/src/webgl/shaders/filters/dilate.frag +0 -39
  244. package/src/webgl/shaders/filters/erode.frag +0 -39
  245. package/src/webgl/shaders/filters/gray.frag +0 -16
  246. package/src/webgl/shaders/filters/invert.frag +0 -15
  247. package/src/webgl/shaders/filters/opaque.frag +0 -12
  248. package/src/webgl/shaders/filters/posterize.frag +0 -29
  249. package/src/webgl/shaders/filters/threshold.frag +0 -23
  250. package/src/webgl/shaders/font.frag +0 -216
  251. package/src/webgl/shaders/font.vert +0 -44
  252. package/src/webgl/shaders/imageLight.vert +0 -33
  253. package/src/webgl/shaders/imageLightDiffused.frag +0 -82
  254. package/src/webgl/shaders/imageLightSpecular.frag +0 -134
  255. package/src/webgl/shaders/light.vert +0 -37
  256. package/src/webgl/shaders/light_texture.frag +0 -26
  257. package/src/webgl/shaders/lighting.glsl +0 -227
  258. package/src/webgl/shaders/line.frag +0 -74
  259. package/src/webgl/shaders/line.vert +0 -294
  260. package/src/webgl/shaders/normal.frag +0 -6
  261. package/src/webgl/shaders/normal.vert +0 -72
  262. package/src/webgl/shaders/phong.frag +0 -84
  263. package/src/webgl/shaders/phong.vert +0 -87
  264. package/src/webgl/shaders/point.frag +0 -29
  265. package/src/webgl/shaders/point.vert +0 -19
  266. package/src/webgl/shaders/sphereMapping.frag +0 -26
  267. package/src/webgl/shaders/webgl2Compatibility.glsl +0 -34
@@ -1,3854 +0,0 @@
1
- /**
2
- * @module 3D
3
- * @submodule Material
4
- * @for p5
5
- * @requires core
6
- */
7
-
8
- import * as constants from '../core/constants';
9
- import { RendererGL } from './p5.RendererGL';
10
- import { Shader } from './p5.Shader';
11
- import { request } from '../io/files';
12
- import { Color } from '../color/p5.Color';
13
-
14
- function material(p5, fn){
15
- /**
16
- * Loads vertex and fragment shaders to create a
17
- * <a href="#/p5.Shader">p5.Shader</a> object.
18
- *
19
- * Shaders are programs that run on the graphics processing unit (GPU). They
20
- * can process many pixels at the same time, making them fast for many
21
- * graphics tasks. They’re written in a language called
22
- * <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/GLSL_Shaders" target="_blank">GLSL</a>
23
- * and run along with the rest of the code in a sketch.
24
- *
25
- * Once the <a href="#/p5.Shader">p5.Shader</a> object is created, it can be
26
- * used with the <a href="#/p5/shader">shader()</a> function, as in
27
- * `shader(myShader)`. A shader program consists of two files, a vertex shader
28
- * and a fragment shader. The vertex shader affects where 3D geometry is drawn
29
- * on the screen and the fragment shader affects color.
30
- *
31
- * `loadShader()` loads the vertex and fragment shaders from their `.vert` and
32
- * `.frag` files. For example, calling
33
- * `loadShader('assets/shader.vert', 'assets/shader.frag')` loads both
34
- * required shaders and returns a <a href="#/p5.Shader">p5.Shader</a> object.
35
- *
36
- * The third parameter, `successCallback`, is optional. If a function is
37
- * passed, it will be called once the shader has loaded. The callback function
38
- * can use the new <a href="#/p5.Shader">p5.Shader</a> object as its
39
- * parameter. The return value of the `successCallback()` function will be used
40
- * as the final return value of `loadShader()`.
41
- *
42
- * The fourth parameter, `failureCallback`, is also optional. If a function is
43
- * passed, it will be called if the shader fails to load. The callback
44
- * function can use the event error as its parameter. The return value of the `
45
- * failureCallback()` function will be used as the final return value of `loadShader()`.
46
- *
47
- * This function returns a `Promise` and should be used in an `async` setup with
48
- * `await`. See the examples for the usage syntax.
49
- *
50
- * Note: Shaders can only be used in WebGL mode.
51
- *
52
- * @method loadShader
53
- * @param {String|Request} vertFilename path of the vertex shader to be loaded.
54
- * @param {String|Request} fragFilename path of the fragment shader to be loaded.
55
- * @param {Function} [successCallback] function to call once the shader is loaded. Can be passed the
56
- * <a href="#/p5.Shader">p5.Shader</a> object.
57
- * @param {Function} [failureCallback] function to call if the shader fails to load. Can be passed an
58
- * `Error` event object.
59
- * @return {Promise<p5.Shader>} new shader created from the vertex and fragment shader files.
60
- *
61
- * @example
62
- * <div modernizr='webgl'>
63
- * <code>
64
- * // Note: A "uniform" is a global variable within a shader program.
65
- *
66
- * let mandelbrot;
67
- *
68
- * // Load the shader and create a p5.Shader object.
69
- * async function setup() {
70
- * mandelbrot = await loadShader('assets/shader.vert', 'assets/shader.frag');
71
- *
72
- * createCanvas(100, 100, WEBGL);
73
- *
74
- * // Compile and apply the p5.Shader object.
75
- * shader(mandelbrot);
76
- *
77
- * // Set the shader uniform p to an array.
78
- * mandelbrot.setUniform('p', [-0.74364388703, 0.13182590421]);
79
- *
80
- * // Set the shader uniform r to the value 1.5.
81
- * mandelbrot.setUniform('r', 1.5);
82
- *
83
- * // Add a quad as a display surface for the shader.
84
- * quad(-1, -1, 1, -1, 1, 1, -1, 1);
85
- *
86
- * describe('A black fractal image on a magenta background.');
87
- * }
88
- * </code>
89
- * </div>
90
- *
91
- * <div>
92
- * <code>
93
- * // Note: A "uniform" is a global variable within a shader program.
94
- *
95
- * let mandelbrot;
96
- *
97
- * // Load the shader and create a p5.Shader object.
98
- * async function setup() {
99
- * mandelbrot = await loadShader('assets/shader.vert', 'assets/shader.frag');
100
- *
101
- * createCanvas(100, 100, WEBGL);
102
- *
103
- * // Use the p5.Shader object.
104
- * shader(mandelbrot);
105
- *
106
- * // Set the shader uniform p to an array.
107
- * mandelbrot.setUniform('p', [-0.74364388703, 0.13182590421]);
108
- *
109
- * describe('A fractal image zooms in and out of focus.');
110
- * }
111
- *
112
- * function draw() {
113
- * // Set the shader uniform r to a value that oscillates between 0 and 2.
114
- * mandelbrot.setUniform('r', sin(frameCount * 0.01) + 1);
115
- *
116
- * // Add a quad as a display surface for the shader.
117
- * quad(-1, -1, 1, -1, 1, 1, -1, 1);
118
- * }
119
- * </code>
120
- * </div>
121
- */
122
- fn.loadShader = async function (
123
- vertFilename,
124
- fragFilename,
125
- successCallback,
126
- failureCallback
127
- ) {
128
- // p5._validateParameters('loadShader', arguments);
129
-
130
- const loadedShader = new Shader();
131
-
132
- try {
133
- loadedShader._vertSrc = (await request(vertFilename, 'text')).data;
134
- loadedShader._fragSrc = (await request(fragFilename, 'text')).data;
135
-
136
- if (successCallback) {
137
- return successCallback(loadedShader);
138
- } else {
139
- return loadedShader
140
- }
141
- } catch(err) {
142
- if (failureCallback) {
143
- return failureCallback(err);
144
- } else {
145
- throw err;
146
- }
147
- }
148
- };
149
-
150
- /**
151
- * Creates a new <a href="#/p5.Shader">p5.Shader</a> object.
152
- *
153
- * Shaders are programs that run on the graphics processing unit (GPU). They
154
- * can process many pixels at the same time, making them fast for many
155
- * graphics tasks. They’re written in a language called
156
- * <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/GLSL_Shaders" target="_blank">GLSL</a>
157
- * and run along with the rest of the code in a sketch.
158
- *
159
- * Once the <a href="#/p5.Shader">p5.Shader</a> object is created, it can be
160
- * used with the <a href="#/p5/shader">shader()</a> function, as in
161
- * `shader(myShader)`. A shader program consists of two parts, a vertex shader
162
- * and a fragment shader. The vertex shader affects where 3D geometry is drawn
163
- * on the screen and the fragment shader affects color.
164
- *
165
- * The first parameter, `vertSrc`, sets the vertex shader. It’s a string that
166
- * contains the vertex shader program written in GLSL.
167
- *
168
- * The second parameter, `fragSrc`, sets the fragment shader. It’s a string
169
- * that contains the fragment shader program written in GLSL.
170
- *
171
- * A shader can optionally describe *hooks,* which are functions in GLSL that
172
- * users may choose to provide to customize the behavior of the shader using the
173
- * <a href="#/p5.Shader/modify">`modify()`</a> method of `p5.Shader`. These are added by
174
- * describing the hooks in a third parameter, `options`, and referencing the hooks in
175
- * your `vertSrc` or `fragSrc`. Hooks for the vertex or fragment shader are described under
176
- * the `vertex` and `fragment` keys of `options`. Each one is an object. where each key is
177
- * the type and name of a hook function, and each value is a string with the
178
- * parameter list and default implementation of the hook. For example, to let users
179
- * optionally run code at the start of the vertex shader, the options object could
180
- * include:
181
- *
182
- * ```js
183
- * {
184
- * vertex: {
185
- * 'void beforeVertex': '() {}'
186
- * }
187
- * }
188
- * ```
189
- *
190
- * Then, in your vertex shader source, you can run a hook by calling a function
191
- * with the same name prefixed by `HOOK_`. If you want to check if the default
192
- * hook has been replaced, maybe to avoid extra overhead, you can check if the
193
- * same name prefixed by `AUGMENTED_HOOK_` has been defined:
194
- *
195
- * ```glsl
196
- * void main() {
197
- * // In most cases, just calling the hook is fine:
198
- * HOOK_beforeVertex();
199
- *
200
- * // Alternatively, for more efficiency:
201
- * #ifdef AUGMENTED_HOOK_beforeVertex
202
- * HOOK_beforeVertex();
203
- * #endif
204
- *
205
- * // Add the rest of your shader code here!
206
- * }
207
- * ```
208
- *
209
- * Note: Only filter shaders can be used in 2D mode. All shaders can be used
210
- * in WebGL mode.
211
- *
212
- * @method createShader
213
- * @param {String} vertSrc source code for the vertex shader.
214
- * @param {String} fragSrc source code for the fragment shader.
215
- * @param {Object} [options] An optional object describing how this shader can
216
- * be augmented with hooks. It can include:
217
- * - `vertex`: An object describing the available vertex shader hooks.
218
- * - `fragment`: An object describing the available frament shader hooks.
219
- * @returns {p5.Shader} new shader object created from the
220
- * vertex and fragment shaders.
221
- *
222
- * @example
223
- * <div modernizr='webgl'>
224
- * <code>
225
- * // Note: A "uniform" is a global variable within a shader program.
226
- *
227
- * // Create a string with the vertex shader program.
228
- * // The vertex shader is called for each vertex.
229
- * let vertSrc = `
230
- * precision highp float;
231
- * uniform mat4 uModelViewMatrix;
232
- * uniform mat4 uProjectionMatrix;
233
- * attribute vec3 aPosition;
234
- * attribute vec2 aTexCoord;
235
- * varying vec2 vTexCoord;
236
- *
237
- * void main() {
238
- * vTexCoord = aTexCoord;
239
- * vec4 positionVec4 = vec4(aPosition, 1.0);
240
- * gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;
241
- * }
242
- * `;
243
- *
244
- * // Create a string with the fragment shader program.
245
- * // The fragment shader is called for each pixel.
246
- * let fragSrc = `
247
- * precision highp float;
248
- *
249
- * void main() {
250
- * // Set each pixel's RGBA value to yellow.
251
- * gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
252
- * }
253
- * `;
254
- *
255
- * function setup() {
256
- * createCanvas(100, 100, WEBGL);
257
- *
258
- * // Create a p5.Shader object.
259
- * let shaderProgram = createShader(vertSrc, fragSrc);
260
- *
261
- * // Compile and apply the p5.Shader object.
262
- * shader(shaderProgram);
263
- *
264
- * // Style the drawing surface.
265
- * noStroke();
266
- *
267
- * // Add a plane as a drawing surface.
268
- * plane(100, 100);
269
- *
270
- * describe('A yellow square.');
271
- * }
272
- * </code>
273
- * </div>
274
- *
275
- * <div>
276
- * <code>
277
- * // Note: A "uniform" is a global variable within a shader program.
278
- *
279
- * // Create a string with the vertex shader program.
280
- * // The vertex shader is called for each vertex.
281
- * let vertSrc = `
282
- * precision highp float;
283
- * uniform mat4 uModelViewMatrix;
284
- * uniform mat4 uProjectionMatrix;
285
- * attribute vec3 aPosition;
286
- * attribute vec2 aTexCoord;
287
- * varying vec2 vTexCoord;
288
- *
289
- * void main() {
290
- * vTexCoord = aTexCoord;
291
- * vec4 positionVec4 = vec4(aPosition, 1.0);
292
- * gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;
293
- * }
294
- * `;
295
- *
296
- * // Create a string with the fragment shader program.
297
- * // The fragment shader is called for each pixel.
298
- * let fragSrc = `
299
- * precision highp float;
300
- * uniform vec2 p;
301
- * uniform float r;
302
- * const int numIterations = 500;
303
- * varying vec2 vTexCoord;
304
- *
305
- * void main() {
306
- * vec2 c = p + gl_FragCoord.xy * r;
307
- * vec2 z = c;
308
- * float n = 0.0;
309
- *
310
- * for (int i = numIterations; i > 0; i--) {
311
- * if (z.x * z.x + z.y * z.y > 4.0) {
312
- * n = float(i) / float(numIterations);
313
- * break;
314
- * }
315
- * z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + c;
316
- * }
317
- *
318
- * gl_FragColor = vec4(
319
- * 0.5 - cos(n * 17.0) / 2.0,
320
- * 0.5 - cos(n * 13.0) / 2.0,
321
- * 0.5 - cos(n * 23.0) / 2.0,
322
- * 1.0
323
- * );
324
- * }
325
- * `;
326
- *
327
- * function setup() {
328
- * createCanvas(100, 100, WEBGL);
329
- *
330
- * // Create a p5.Shader object.
331
- * let mandelbrot = createShader(vertSrc, fragSrc);
332
- *
333
- * // Compile and apply the p5.Shader object.
334
- * shader(mandelbrot);
335
- *
336
- * // Set the shader uniform p to an array.
337
- * // p is the center point of the Mandelbrot image.
338
- * mandelbrot.setUniform('p', [-0.74364388703, 0.13182590421]);
339
- *
340
- * // Set the shader uniform r to 0.005.
341
- * // r is the size of the image in Mandelbrot-space.
342
- * mandelbrot.setUniform('r', 0.005);
343
- *
344
- * // Style the drawing surface.
345
- * noStroke();
346
- *
347
- * // Add a plane as a drawing surface.
348
- * plane(100, 100);
349
- *
350
- * describe('A black fractal image on a magenta background.');
351
- * }
352
- * </code>
353
- * </div>
354
- *
355
- * <div>
356
- * <code>
357
- * // Note: A "uniform" is a global variable within a shader program.
358
- *
359
- * // Create a string with the vertex shader program.
360
- * // The vertex shader is called for each vertex.
361
- * let vertSrc = `
362
- * precision highp float;
363
- * uniform mat4 uModelViewMatrix;
364
- * uniform mat4 uProjectionMatrix;
365
- *
366
- * attribute vec3 aPosition;
367
- * attribute vec2 aTexCoord;
368
- * varying vec2 vTexCoord;
369
- *
370
- * void main() {
371
- * vTexCoord = aTexCoord;
372
- * vec4 positionVec4 = vec4(aPosition, 1.0);
373
- * gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;
374
- * }
375
- * `;
376
- *
377
- * // Create a string with the fragment shader program.
378
- * // The fragment shader is called for each pixel.
379
- * let fragSrc = `
380
- * precision highp float;
381
- * uniform vec2 p;
382
- * uniform float r;
383
- * const int numIterations = 500;
384
- * varying vec2 vTexCoord;
385
- *
386
- * void main() {
387
- * vec2 c = p + gl_FragCoord.xy * r;
388
- * vec2 z = c;
389
- * float n = 0.0;
390
- *
391
- * for (int i = numIterations; i > 0; i--) {
392
- * if (z.x * z.x + z.y * z.y > 4.0) {
393
- * n = float(i) / float(numIterations);
394
- * break;
395
- * }
396
- *
397
- * z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + c;
398
- * }
399
- *
400
- * gl_FragColor = vec4(
401
- * 0.5 - cos(n * 17.0) / 2.0,
402
- * 0.5 - cos(n * 13.0) / 2.0,
403
- * 0.5 - cos(n * 23.0) / 2.0,
404
- * 1.0
405
- * );
406
- * }
407
- * `;
408
- *
409
- * let mandelbrot;
410
- *
411
- * function setup() {
412
- * createCanvas(100, 100, WEBGL);
413
- *
414
- * // Create a p5.Shader object.
415
- * mandelbrot = createShader(vertSrc, fragSrc);
416
- *
417
- * // Apply the p5.Shader object.
418
- * shader(mandelbrot);
419
- *
420
- * // Set the shader uniform p to an array.
421
- * // p is the center point of the Mandelbrot image.
422
- * mandelbrot.setUniform('p', [-0.74364388703, 0.13182590421]);
423
- *
424
- * describe('A fractal image zooms in and out of focus.');
425
- * }
426
- *
427
- * function draw() {
428
- * // Set the shader uniform r to a value that oscillates
429
- * // between 0 and 0.005.
430
- * // r is the size of the image in Mandelbrot-space.
431
- * let radius = 0.005 * (sin(frameCount * 0.01) + 1);
432
- * mandelbrot.setUniform('r', radius);
433
- *
434
- * // Style the drawing surface.
435
- * noStroke();
436
- *
437
- * // Add a plane as a drawing surface.
438
- * plane(100, 100);
439
- * }
440
- * </code>
441
- * </div>
442
- *
443
- * <div>
444
- * <code>
445
- * // A shader with hooks.
446
- * let myShader;
447
- *
448
- * // A shader with modified hooks.
449
- * let modifiedShader;
450
- *
451
- * // Create a string with the vertex shader program.
452
- * // The vertex shader is called for each vertex.
453
- * let vertSrc = `
454
- * precision highp float;
455
- * uniform mat4 uModelViewMatrix;
456
- * uniform mat4 uProjectionMatrix;
457
- *
458
- * attribute vec3 aPosition;
459
- * attribute vec2 aTexCoord;
460
- *
461
- * void main() {
462
- * vec4 positionVec4 = vec4(aPosition, 1.0);
463
- * gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;
464
- * }
465
- * `;
466
- *
467
- * // Create a fragment shader that uses a hook.
468
- * let fragSrc = `
469
- * precision highp float;
470
- * void main() {
471
- * // Let users override the color
472
- * gl_FragColor = HOOK_getColor(vec4(1., 0., 0., 1.));
473
- * }
474
- * `;
475
- *
476
- * function setup() {
477
- * createCanvas(50, 50, WEBGL);
478
- *
479
- * // Create a shader with hooks
480
- * myShader = createShader(vertSrc, fragSrc, {
481
- * fragment: {
482
- * 'vec4 getColor': '(vec4 color) { return color; }'
483
- * }
484
- * });
485
- *
486
- * // Make a version of the shader with a hook overridden
487
- * modifiedShader = myShader.modify({
488
- * 'vec4 getColor': `(vec4 color) {
489
- * return vec4(0., 0., 1., 1.);
490
- * }`
491
- * });
492
- * }
493
- *
494
- * function draw() {
495
- * noStroke();
496
- *
497
- * push();
498
- * shader(myShader);
499
- * translate(-width/3, 0);
500
- * sphere(10);
501
- * pop();
502
- *
503
- * push();
504
- * shader(modifiedShader);
505
- * translate(width/3, 0);
506
- * sphere(10);
507
- * pop();
508
- * }
509
- * </code>
510
- * </div>
511
- */
512
- fn.createShader = function (vertSrc, fragSrc, options) {
513
- // p5._validateParameters('createShader', arguments);
514
- return new Shader(this._renderer, vertSrc, fragSrc, options);
515
- };
516
-
517
- /**
518
- * Creates and loads a filter shader from an external file.
519
- *
520
- * @method loadFilterShader
521
- * @param {String} fragFilename path to the fragment shader file
522
- * @param {Function} [successCallback] callback to be called once the shader is
523
- * loaded. Will be passed the
524
- * <a href="#/p5.Shader">p5.Shader</a> object.
525
- * @param {Function} [failureCallback] callback to be called if there is an error
526
- * loading the shader. Will be passed the
527
- * error event.
528
- * @return {Promise<p5.Shader>} a promise that resolves with a shader object
529
- *
530
- * @example
531
- * <div modernizr='webgl'>
532
- * <code>
533
- * let myShader;
534
- *
535
- * async function setup() {
536
- * myShader = await loadFilterShader('assets/basic.frag');
537
- * createCanvas(100, 100, WEBGL);
538
- * noStroke();
539
- * }
540
- *
541
- * function draw() {
542
- * // shader() sets the active shader with our shader
543
- * shader(myShader);
544
- *
545
- * // rect gives us some geometry on the screen
546
- * rect(-50, -50, width, height);
547
- * }
548
- * </code>
549
- * </div>
550
- * @alt
551
- * A rectangle with a shader applied to it.
552
- */
553
- fn.loadFilterShader = async function (fragFilename, successCallback, failureCallback) {
554
- // p5._validateParameters('loadFilterShader', arguments);
555
- try {
556
- // Load the fragment shader
557
- const fragSrc = await this.loadStrings(fragFilename);
558
- const fragString = await fragSrc.join('\n');
559
-
560
- // Create the shader using createFilterShader
561
- const loadedShader = this.createFilterShader(fragString, true);
562
-
563
- if (successCallback) {
564
- successCallback(loadedShader);
565
- }
566
-
567
- return loadedShader;
568
- } catch (err) {
569
- if (failureCallback) {
570
- failureCallback(err);
571
- } else {
572
- console.error(err);
573
- }
574
- }
575
- };
576
-
577
- /**
578
- * Creates a <a href="#/p5.Shader">p5.Shader</a> object to be used with the
579
- * <a href="#/p5/filter">filter()</a> function.
580
- *
581
- * `createFilterShader()` works like
582
- * <a href="#/p5/createShader">createShader()</a> but has a default vertex
583
- * shader included. `createFilterShader()` is intended to be used along with
584
- * <a href="#/p5/filter">filter()</a> for filtering the contents of a canvas.
585
- * A filter shader will be applied to the whole canvas instead of just
586
- * <a href="#/p5.Geometry">p5.Geometry</a> objects.
587
- *
588
- * The parameter, `fragSrc`, sets the fragment shader. It’s a string that
589
- * contains the fragment shader program written in
590
- * <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/GLSL_Shaders" target="_blank">GLSL</a>.
591
- *
592
- * The <a href="#/p5.Shader">p5.Shader</a> object that's created has some
593
- * uniforms that can be set:
594
- * - `sampler2D tex0`, which contains the canvas contents as a texture.
595
- * - `vec2 canvasSize`, which is the width and height of the canvas, not including pixel density.
596
- * - `vec2 texelSize`, which is the size of a physical pixel including pixel density. This is calculated as `1.0 / (width * density)` for the pixel width and `1.0 / (height * density)` for the pixel height.
597
- *
598
- * The <a href="#/p5.Shader">p5.Shader</a> that's created also provides
599
- * `varying vec2 vTexCoord`, a coordinate with values between 0 and 1.
600
- * `vTexCoord` describes where on the canvas the pixel will be drawn.
601
- *
602
- * For more info about filters and shaders, see Adam Ferriss' <a href="https://github.com/aferriss/p5jsShaderExamples">repo of shader examples</a>
603
- * or the <a href="https://p5js.org/learn/getting-started-in-webgl-shaders.html">Introduction to Shaders</a> tutorial.
604
- *
605
- * @method createFilterShader
606
- * @param {String} fragSrc source code for the fragment shader.
607
- * @returns {p5.Shader} new shader object created from the fragment shader.
608
- *
609
- * @example
610
- * <div modernizr='webgl'>
611
- * <code>
612
- * function setup() {
613
- * let fragSrc = `precision highp float;
614
- * void main() {
615
- * gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
616
- * }`;
617
- *
618
- * createCanvas(100, 100, WEBGL);
619
- * let s = createFilterShader(fragSrc);
620
- * filter(s);
621
- * describe('a yellow canvas');
622
- * }
623
- * </code>
624
- * </div>
625
- *
626
- * <div modernizr='webgl'>
627
- * <code>
628
- * let img, s;
629
- * async function setup() {
630
- * img = await loadImage('assets/bricks.jpg');
631
- * let fragSrc = `precision highp float;
632
- *
633
- * // x,y coordinates, given from the vertex shader
634
- * varying vec2 vTexCoord;
635
- *
636
- * // the canvas contents, given from filter()
637
- * uniform sampler2D tex0;
638
- * // other useful information from the canvas
639
- * uniform vec2 texelSize;
640
- * uniform vec2 canvasSize;
641
- * // a custom variable from this sketch
642
- * uniform float darkness;
643
- *
644
- * void main() {
645
- * // get the color at current pixel
646
- * vec4 color = texture2D(tex0, vTexCoord);
647
- * // set the output color
648
- * color.b = 1.0;
649
- * color *= darkness;
650
- * gl_FragColor = vec4(color.rgb, 1.0);
651
- * }`;
652
- *
653
- * createCanvas(100, 100, WEBGL);
654
- * s = createFilterShader(fragSrc);
655
- * }
656
- *
657
- * function draw() {
658
- * image(img, -50, -50);
659
- * s.setUniform('darkness', 0.5);
660
- * filter(s);
661
- * describe('a image of bricks tinted dark blue');
662
- * }
663
- * </code>
664
- * </div>
665
- */
666
- fn.createFilterShader = function (fragSrc, skipContextCheck = false) {
667
- // p5._validateParameters('createFilterShader', arguments);
668
- let defaultVertV1 = `
669
- uniform mat4 uModelViewMatrix;
670
- uniform mat4 uProjectionMatrix;
671
-
672
- attribute vec3 aPosition;
673
- // texcoords only come from p5 to vertex shader
674
- // so pass texcoords on to the fragment shader in a varying variable
675
- attribute vec2 aTexCoord;
676
- varying vec2 vTexCoord;
677
-
678
- void main() {
679
- // transferring texcoords for the frag shader
680
- vTexCoord = aTexCoord;
681
-
682
- // copy position with a fourth coordinate for projection (1.0 is normal)
683
- vec4 positionVec4 = vec4(aPosition, 1.0);
684
-
685
- // project to 3D space
686
- gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;
687
- }
688
- `;
689
- let defaultVertV2 = `#version 300 es
690
- uniform mat4 uModelViewMatrix;
691
- uniform mat4 uProjectionMatrix;
692
-
693
- in vec3 aPosition;
694
- in vec2 aTexCoord;
695
- out vec2 vTexCoord;
696
-
697
- void main() {
698
- // transferring texcoords for the frag shader
699
- vTexCoord = aTexCoord;
700
-
701
- // copy position with a fourth coordinate for projection (1.0 is normal)
702
- vec4 positionVec4 = vec4(aPosition, 1.0);
703
-
704
- // project to 3D space
705
- gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;
706
- }
707
- `;
708
- let vertSrc = fragSrc.includes('#version 300 es') ? defaultVertV2 : defaultVertV1;
709
- const shader = new Shader(this._renderer, vertSrc, fragSrc);
710
- if (!skipContextCheck) {
711
- if (this._renderer.GL) {
712
- shader.ensureCompiledOnContext(this._renderer);
713
- } else {
714
- shader.ensureCompiledOnContext(this);
715
- }
716
- }
717
- return shader;
718
- };
719
-
720
- /**
721
- * Sets the <a href="#/p5.Shader">p5.Shader</a> object to apply while drawing.
722
- *
723
- * Shaders are programs that run on the graphics processing unit (GPU). They
724
- * can process many pixels or vertices at the same time, making them fast for
725
- * many graphics tasks. They’re written in a language called
726
- * <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/GLSL_Shaders" target="_blank">GLSL</a>
727
- * and run along with the rest of the code in a sketch.
728
- * <a href="#/p5.Shader">p5.Shader</a> objects can be created using the
729
- * <a href="#/p5/createShader">createShader()</a> and
730
- * <a href="#/p5/loadShader">loadShader()</a> functions.
731
- *
732
- * The parameter, `s`, is the <a href="#/p5.Shader">p5.Shader</a> object to
733
- * apply. For example, calling `shader(myShader)` applies `myShader` to
734
- * process each pixel on the canvas. This only changes the fill (the inner part of shapes),
735
- * but does not affect the outlines (strokes) or any images drawn using the `image()` function.
736
- * The source code from a <a href="#/p5.Shader">p5.Shader</a> object's
737
- * fragment and vertex shaders will be compiled the first time it's passed to
738
- * `shader()`. See
739
- * <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/compileShader" target="_blank">MDN</a>
740
- * for more information about compiling shaders.
741
- *
742
- * Calling <a href="#/p5/resetShader">resetShader()</a> restores a sketch’s
743
- * default shaders.
744
- *
745
- * Note: Shaders can only be used in WebGL mode.
746
- *
747
- * <div>
748
- * <p>
749
- *
750
- * If you want to apply shaders to strokes or images, use the following methods:
751
- * - <a href="#/p5/strokeShader">strokeShader()</a> : Applies a shader to the stroke (outline) of shapes, allowing independent control over the stroke rendering using shaders.
752
- * - <a href="#/p5/imageShader">imageShader()</a> : Applies a shader to images or textures, controlling how the shader modifies their appearance during rendering.
753
- *
754
- * </p>
755
- * </div>
756
- *
757
- *
758
- * @method shader
759
- * @chainable
760
- * @param {p5.Shader} s <a href="#/p5.Shader">p5.Shader</a> object
761
- * to apply.
762
- *
763
- * @example
764
- * <div modernizr='webgl'>
765
- * <code>
766
- * let fillShader;
767
- *
768
- * let vertSrc = `
769
- * precision highp float;
770
- * attribute vec3 aPosition;
771
- * uniform mat4 uModelViewMatrix;
772
- * uniform mat4 uProjectionMatrix;
773
- * varying vec3 vPosition;
774
- *
775
- * void main() {
776
- * vPosition = aPosition;
777
- * gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aPosition, 1.0);
778
- * }
779
- * `;
780
- *
781
- * let fragSrc = `
782
- * precision highp float;
783
- * uniform vec3 uLightDir;
784
- * varying vec3 vPosition;
785
- *
786
- * void main() {
787
- * vec3 lightDir = normalize(uLightDir);
788
- * float brightness = dot(lightDir, normalize(vPosition));
789
- * brightness = clamp(brightness, 0.4, 1.0);
790
- * vec3 color = vec3(0.3, 0.5, 1.0);
791
- * color = color * brightness * 3.0;
792
- * gl_FragColor = vec4(color, 1.0);
793
- * }
794
- * `;
795
- *
796
- * function setup() {
797
- * createCanvas(200, 200, WEBGL);
798
- * fillShader = createShader(vertSrc, fragSrc);
799
- * noStroke();
800
- * describe('A rotating torus with simulated directional lighting.');
801
- * }
802
- *
803
- * function draw() {
804
- * background(20, 20, 40);
805
- * let lightDir = [0.5, 0.5, -1.0];
806
- * fillShader.setUniform('uLightDir', lightDir);
807
- * shader(fillShader);
808
- * rotateY(frameCount * 0.02);
809
- * rotateX(frameCount * 0.02);
810
- * //lights();
811
- * torus(25, 10, 30, 30);
812
- * }
813
- * </code>
814
- * </div>
815
- *
816
- * @example
817
- * <div modernizr='webgl'>
818
- * <code>
819
- * let fillShader;
820
- *
821
- * let vertSrc = `
822
- * precision highp float;
823
- * attribute vec3 aPosition;
824
- * uniform mat4 uProjectionMatrix;
825
- * uniform mat4 uModelViewMatrix;
826
- * varying vec3 vPosition;
827
- * void main() {
828
- * vPosition = aPosition;
829
- * gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aPosition, 1.0);
830
- * }
831
- * `;
832
- *
833
- * let fragSrc = `
834
- * precision highp float;
835
- * uniform vec3 uLightPos;
836
- * uniform vec3 uFillColor;
837
- * varying vec3 vPosition;
838
- * void main() {
839
- * float brightness = dot(normalize(uLightPos), normalize(vPosition));
840
- * brightness = clamp(brightness, 0.0, 1.0);
841
- * vec3 color = uFillColor * brightness;
842
- * gl_FragColor = vec4(color, 1.0);
843
- * }
844
- * `;
845
- *
846
- * function setup() {
847
- * createCanvas(200, 200, WEBGL);
848
- * fillShader = createShader(vertSrc, fragSrc);
849
- * shader(fillShader);
850
- * noStroke();
851
- * describe('A square affected by both fill color and lighting, with lights controlled by mouse.');
852
- * }
853
- *
854
- * function draw() {
855
- * let lightPos = [(mouseX - width / 2) / width,
856
- * (mouseY - height / 2) / height, 1.0];
857
- * fillShader.setUniform('uLightPos', lightPos);
858
- * let fillColor = [map(mouseX, 0, width, 0, 1),
859
- * map(mouseY, 0, height, 0, 1), 0.5];
860
- * fillShader.setUniform('uFillColor', fillColor);
861
- * plane(100, 100);
862
- * }
863
- * </code>
864
- * </div>
865
- *
866
- * @example
867
- * <div modernizr='webgl'>
868
- * <code>
869
- * let myShader;
870
- *
871
- * function setup() {
872
- * createCanvas(200, 200, WEBGL);
873
- *
874
- * myShader = baseMaterialShader().modify({
875
- * declarations: 'uniform float time;',
876
- * 'vec4 getFinalColor': `(vec4 color) {
877
- * float r = 0.2 + 0.5 * abs(sin(time + 0.0));
878
- * float g = 0.2 + 0.5 * abs(sin(time + 1.0));
879
- * float b = 0.2 + 0.5 * abs(sin(time + 2.0));
880
- * color.rgb = vec3(r, g, b);
881
- * return color;
882
- * }`
883
- * });
884
- *
885
- * noStroke();
886
- * describe('A 3D cube with dynamically changing colors on a beige background.');
887
- * }
888
- *
889
- * function draw() {
890
- * background(245, 245, 220);
891
- * shader(myShader);
892
- * myShader.setUniform('time', millis() / 1000.0);
893
- *
894
- * box(50);
895
- * }
896
- * </code>
897
- * </div>
898
- *
899
- */
900
- fn.shader = function (s) {
901
- this._assert3d('shader');
902
- // p5._validateParameters('shader', arguments);
903
-
904
- this._renderer.shader(s);
905
-
906
- return this;
907
- };
908
-
909
- /**
910
- * Sets the <a href="#/p5.Shader">p5.Shader</a> object to apply for strokes.
911
- *
912
- * This method applies the given shader to strokes, allowing customization of
913
- * how lines and outlines are drawn in 3D space. The shader will be used for
914
- * strokes until <a href="#/p5/resetShader">resetShader()</a> is called or another
915
- * strokeShader is applied.
916
- *
917
- * The shader will be used for:
918
- * - Strokes only, regardless of whether the uniform `uStrokeWeight` is present.
919
- *
920
- * To further customize its behavior, refer to the various hooks provided by
921
- * the <a href="#/p5/baseStrokeShader">baseStrokeShader()</a> method, which allow
922
- * control over stroke weight, vertex positions, colors, and more.
923
- *
924
- * @method strokeShader
925
- * @chainable
926
- * @param {p5.Shader} s <a href="#/p5.Shader">p5.Shader</a> object
927
- * to apply for strokes.
928
- *
929
- *
930
- * @example
931
- * <div modernizr='webgl'>
932
- * <code>
933
- * let animatedStrokeShader;
934
- *
935
- * let vertSrc = `
936
- * precision mediump int;
937
- *
938
- * uniform mat4 uModelViewMatrix;
939
- * uniform mat4 uProjectionMatrix;
940
- * uniform float uStrokeWeight;
941
- *
942
- * uniform bool uUseLineColor;
943
- * uniform vec4 uMaterialColor;
944
- *
945
- * uniform vec4 uViewport;
946
- * uniform int uPerspective;
947
- * uniform int uStrokeJoin;
948
- *
949
- * attribute vec4 aPosition;
950
- * attribute vec3 aTangentIn;
951
- * attribute vec3 aTangentOut;
952
- * attribute float aSide;
953
- * attribute vec4 aVertexColor;
954
- *
955
- * void main() {
956
- * vec4 posp = uModelViewMatrix * aPosition;
957
- * vec4 posqIn = uModelViewMatrix * (aPosition + vec4(aTangentIn, 0));
958
- * vec4 posqOut = uModelViewMatrix * (aPosition + vec4(aTangentOut, 0));
959
- *
960
- * float facingCamera = pow(
961
- * abs(normalize(posqIn-posp).z),
962
- * 0.25
963
- * );
964
- *
965
- * float scale = mix(1., 0.995, facingCamera);
966
- *
967
- * posp.xyz = posp.xyz * scale;
968
- * posqIn.xyz = posqIn.xyz * scale;
969
- * posqOut.xyz = posqOut.xyz * scale;
970
- *
971
- * vec4 p = uProjectionMatrix * posp;
972
- * vec4 qIn = uProjectionMatrix * posqIn;
973
- * vec4 qOut = uProjectionMatrix * posqOut;
974
- *
975
- * vec2 tangentIn = normalize((qIn.xy*p.w - p.xy*qIn.w) * uViewport.zw);
976
- * vec2 tangentOut = normalize((qOut.xy*p.w - p.xy*qOut.w) * uViewport.zw);
977
- *
978
- * vec2 curPerspScale;
979
- * if(uPerspective == 1) {
980
- * curPerspScale = (uProjectionMatrix * vec4(1, sign(uProjectionMatrix[1][1]), 0, 0)).xy;
981
- * } else {
982
- * curPerspScale = p.w / (0.5 * uViewport.zw);
983
- * }
984
- *
985
- * vec2 offset;
986
- * vec2 tangent = aTangentIn == vec3(0.) ? tangentOut : tangentIn;
987
- * vec2 normal = vec2(-tangent.y, tangent.x);
988
- * float normalOffset = sign(aSide);
989
- * float tangentOffset = abs(aSide) - 1.;
990
- * offset = (normal * normalOffset + tangent * tangentOffset) *
991
- * uStrokeWeight * 0.5;
992
- *
993
- * gl_Position.xy = p.xy + offset.xy * curPerspScale;
994
- * gl_Position.zw = p.zw;
995
- * }
996
- * `;
997
- *
998
- * let fragSrc = `
999
- * precision mediump float;
1000
- * uniform float uTime;
1001
- *
1002
- * void main() {
1003
- * float wave = sin(gl_FragCoord.x * 0.1 + uTime) * 0.5 + 0.5;
1004
- * gl_FragColor = vec4(wave, 0.5, 1.0, 1.0); // Animated color based on time
1005
- * }
1006
- * `;
1007
- *
1008
- * function setup() {
1009
- * createCanvas(200, 200, WEBGL);
1010
- * animatedStrokeShader = createShader(vertSrc, fragSrc);
1011
- * strokeShader(animatedStrokeShader);
1012
- * strokeWeight(4);
1013
- *
1014
- * describe('A hollow cube rotating continuously with its stroke colors changing dynamically over time against a static gray background.');
1015
- * }
1016
- *
1017
- * function draw() {
1018
- * animatedStrokeShader.setUniform('uTime', millis() / 1000.0);
1019
- * background(250);
1020
- * rotateY(frameCount * 0.02);
1021
- * noFill();
1022
- * orbitControl();
1023
- * box(50);
1024
- * }
1025
- * </code>
1026
- * </div>
1027
- *
1028
- *
1029
- * @example
1030
- * <div modernizr='webgl'>
1031
- * <code>
1032
- * let myShader;
1033
- *
1034
- * function setup() {
1035
- * createCanvas(200, 200, WEBGL);
1036
- * myShader = baseStrokeShader().modify({
1037
- * 'float random': `(vec2 p) {
1038
- * vec3 p3 = fract(vec3(p.xyx) * .1471);
1039
- * p3 += dot(p3, p3.yzx + 32.33);
1040
- * return fract((p3.x + p3.y) * p3.z);
1041
- * }`,
1042
- * 'Inputs getPixelInputs': `(Inputs inputs) {
1043
- * // Modify alpha with dithering effect
1044
- * float a = inputs.color.a;
1045
- * inputs.color.a = 1.0;
1046
- * inputs.color *= random(inputs.position.xy) > a ? 0.0 : 1.0;
1047
- * return inputs;
1048
- * }`
1049
- * });
1050
- * }
1051
- *
1052
- * function draw() {
1053
- * background(255);
1054
- * strokeShader(myShader);
1055
- * strokeWeight(12);
1056
- * beginShape();
1057
- * for (let i = 0; i <= 50; i++) {
1058
- * stroke(
1059
- * map(i, 0, 50, 150, 255),
1060
- * 100 + 155 * sin(i / 5),
1061
- * 255 * map(i, 0, 50, 1, 0)
1062
- * );
1063
- * vertex(
1064
- * map(i, 0, 50, 1, -1) * width / 3,
1065
- * 50 * cos(i / 10 + frameCount / 80)
1066
- * );
1067
- * }
1068
- * endShape();
1069
- * }
1070
- * </code>
1071
- * </div>
1072
- */
1073
- fn.strokeShader = function (s) {
1074
- this._assert3d('strokeShader');
1075
- // p5._validateParameters('strokeShader', arguments);
1076
-
1077
- this._renderer.strokeShader(s);
1078
-
1079
- return this;
1080
- };
1081
-
1082
- /**
1083
- * Sets the <a href="#/p5.Shader">p5.Shader</a> object to apply for images.
1084
- *
1085
- * This method allows the user to apply a custom shader to images, enabling
1086
- * advanced visual effects such as pixel manipulation, color adjustments,
1087
- * or dynamic behavior. The shader will be applied to the image drawn using
1088
- * the <a href="#/p5/image">image()</a> function.
1089
- *
1090
- * The shader will be used exclusively for:
1091
- * - `image()` calls, applying only when drawing 2D images.
1092
- * - This shader will NOT apply to images used in <a href="#/p5/texture">texture()</a> or other 3D contexts.
1093
- * Any attempts to use the imageShader in these cases will be ignored.
1094
- *
1095
- * @method imageShader
1096
- * @chainable
1097
- * @param {p5.Shader} s <a href="#/p5.Shader">p5.Shader</a> object
1098
- * to apply for images.
1099
- *
1100
- * @example
1101
- * <div modernizr='webgl'>
1102
- * <code>
1103
- * let img;
1104
- * let imgShader;
1105
- *
1106
- * async function setup() {
1107
- * img = await loadImage('assets/outdoor_image.jpg');
1108
- *
1109
- * createCanvas(200, 200, WEBGL);
1110
- * noStroke();
1111
- *
1112
- * imgShader = createShader(`
1113
- * precision mediump float;
1114
- * attribute vec3 aPosition;
1115
- * attribute vec2 aTexCoord;
1116
- * varying vec2 vTexCoord;
1117
- * uniform mat4 uModelViewMatrix;
1118
- * uniform mat4 uProjectionMatrix;
1119
- *
1120
- * void main() {
1121
- * vTexCoord = aTexCoord;
1122
- * gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aPosition, 1.0);
1123
- * }
1124
- * `, `
1125
- * precision mediump float;
1126
- * varying vec2 vTexCoord;
1127
- * uniform sampler2D uTexture;
1128
- * uniform vec2 uMousePos;
1129
- *
1130
- * void main() {
1131
- * vec4 texColor = texture2D(uTexture, vTexCoord);
1132
- * // Adjust the color based on mouse position
1133
- * float r = uMousePos.x * texColor.r;
1134
- * float g = uMousePos.y * texColor.g;
1135
- * gl_FragColor = vec4(r, g, texColor.b, texColor.a);
1136
- * }
1137
- * `);
1138
- *
1139
- * describe(
1140
- * 'An image on a gray background where the colors change based on the mouse position.'
1141
- * );
1142
- * }
1143
- *
1144
- * function draw() {
1145
- * background(220);
1146
- *
1147
- * imageShader(imgShader);
1148
- *
1149
- * // Map the mouse position to a range between 0 and 1
1150
- * let mousePosX = map(mouseX, 0, width, 0, 1);
1151
- * let mousePosY = map(mouseY, 0, height, 0, 1);
1152
- *
1153
- * // Pass the mouse position to the shader as a uniform
1154
- * imgShader.setUniform('uMousePos', [mousePosX, mousePosY]);
1155
- *
1156
- * // Bind the image texture to the shader
1157
- * imgShader.setUniform('uTexture', img);
1158
- *
1159
- * image(img, -width / 2, -height / 2, width, height);
1160
- * }
1161
- *
1162
- * </code>
1163
- * </div>
1164
- *
1165
- * @example
1166
- * <div modernizr='webgl'>
1167
- * <code>
1168
- * let img;
1169
- * let imgShader;
1170
- *
1171
- * async function setup() {
1172
- * img = await loadImage('assets/outdoor_image.jpg');
1173
- *
1174
- * createCanvas(200, 200, WEBGL);
1175
- * noStroke();
1176
- *
1177
- * imgShader = createShader(`
1178
- * precision mediump float;
1179
- * attribute vec3 aPosition;
1180
- * attribute vec2 aTexCoord;
1181
- * varying vec2 vTexCoord;
1182
- * uniform mat4 uModelViewMatrix;
1183
- * uniform mat4 uProjectionMatrix;
1184
- *
1185
- * void main() {
1186
- * vTexCoord = aTexCoord;
1187
- * gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aPosition, 1.0);
1188
- * }
1189
- * `, `
1190
- * precision mediump float;
1191
- * varying vec2 vTexCoord;
1192
- * uniform sampler2D uTexture;
1193
- * uniform vec2 uMousePos;
1194
- *
1195
- * void main() {
1196
- * // Distance from the current pixel to the mouse
1197
- * float distFromMouse = distance(vTexCoord, uMousePos);
1198
- *
1199
- * // Adjust pixelation based on distance (closer = more detail, farther = blockier)
1200
- * float pixelSize = mix(0.002, 0.05, distFromMouse);
1201
- * vec2 pixelatedCoord = vec2(floor(vTexCoord.x / pixelSize) * pixelSize,
1202
- * floor(vTexCoord.y / pixelSize) * pixelSize);
1203
- *
1204
- * vec4 texColor = texture2D(uTexture, pixelatedCoord);
1205
- * gl_FragColor = texColor;
1206
- * }
1207
- * `);
1208
- *
1209
- * describe('A static image with a grid-like, pixelated effect created by the shader. Each cell in the grid alternates visibility, producing a dithered visual effect.');
1210
- * }
1211
- *
1212
- * function draw() {
1213
- * background(220);
1214
- * imageShader(imgShader);
1215
- *
1216
- * let mousePosX = map(mouseX, 0, width, 0, 1);
1217
- * let mousePosY = map(mouseY, 0, height, 0, 1);
1218
- *
1219
- * imgShader.setUniform('uMousePos', [mousePosX, mousePosY]);
1220
- * imgShader.setUniform('uTexture', img);
1221
- * image(img, -width / 2, -height / 2, width, height);
1222
- * }
1223
- * </code>
1224
- * </div>
1225
- */
1226
- fn.imageShader = function (s) {
1227
- this._assert3d('imageShader');
1228
- // p5._validateParameters('imageShader', arguments);
1229
-
1230
- this._renderer.imageShader(s);
1231
-
1232
- return this;
1233
- };
1234
-
1235
- /**
1236
- * Get the default shader used with lights, materials,
1237
- * and textures.
1238
- *
1239
- * You can call <a href="#/p5.Shader/modify">`baseMaterialShader().modify()`</a>
1240
- * and change any of the following hooks:
1241
- *
1242
- * <table>
1243
- * <tr><th>Hook</th><th>Description</th></tr>
1244
- * <tr><td>
1245
- *
1246
- * `void beforeVertex`
1247
- *
1248
- * </td><td>
1249
- *
1250
- * Called at the start of the vertex shader.
1251
- *
1252
- * </td></tr>
1253
- * <tr><td>
1254
- *
1255
- * `Vertex getObjectInputs`
1256
- *
1257
- * </td><td>
1258
- *
1259
- * Update the vertex data of the model being drawn before any positioning has been applied. It takes in a `Vertex` struct, which includes:
1260
- * - `vec3 position`, the position of the vertex
1261
- * - `vec3 normal`, the direction facing out of the surface
1262
- * - `vec2 texCoord`, the texture coordinates associeted with the vertex
1263
- * - `vec4 color`, the per-vertex color
1264
- * The struct can be modified and returned.
1265
- *
1266
- * </td></tr>
1267
- * <tr><td>
1268
- *
1269
- * `Vertex getWorldInputs`
1270
- *
1271
- * </td><td>
1272
- *
1273
- * Update the vertex data of the model being drawn after transformations such as `translate()` and `scale()` have been applied, but before the camera has been applied. It takes in a `Vertex` struct like, in the `getObjectInputs` hook above, that can be modified and returned.
1274
- *
1275
- * </td></tr>
1276
- * <tr><td>
1277
- *
1278
- * `Vertex getCameraInputs`
1279
- *
1280
- * </td><td>
1281
- *
1282
- * Update the vertex data of the model being drawn as they appear relative to the camera. It takes in a `Vertex` struct like, in the `getObjectInputs` hook above, that can be modified and returned.
1283
- *
1284
- * </td></tr>
1285
- * <tr><td>
1286
- *
1287
- * `void afterVertex`
1288
- *
1289
- * </td><td>
1290
- *
1291
- * Called at the end of the vertex shader.
1292
- *
1293
- * </td></tr>
1294
- * <tr><td>
1295
- *
1296
- * `void beforeFragment`
1297
- *
1298
- * </td><td>
1299
- *
1300
- * Called at the start of the fragment shader.
1301
- *
1302
- * </td></tr>
1303
- * <tr><td>
1304
- *
1305
- * `Inputs getPixelInputs`
1306
- *
1307
- * </td><td>
1308
- *
1309
- * Update the per-pixel inputs of the material. It takes in an `Inputs` struct, which includes:
1310
- * - `vec3 normal`, the direction pointing out of the surface
1311
- * - `vec2 texCoord`, a vector where `x` and `y` are between 0 and 1 describing the spot on a texture the pixel is mapped to, as a fraction of the texture size
1312
- * - `vec3 ambientLight`, the ambient light color on the vertex
1313
- * - `vec4 color`, the base material color of the pixel
1314
- * - `vec3 ambientMaterial`, the color of the pixel when affected by ambient light
1315
- * - `vec3 specularMaterial`, the color of the pixel when reflecting specular highlights
1316
- * - `vec3 emissiveMaterial`, the light color emitted by the pixel
1317
- * - `float shininess`, a number representing how sharp specular reflections should be, from 1 to infinity
1318
- * - `float metalness`, a number representing how mirrorlike the material should be, between 0 and 1
1319
- * The struct can be modified and returned.
1320
- * </td></tr>
1321
- * <tr><td>
1322
- *
1323
- * `vec4 combineColors`
1324
- *
1325
- * </td><td>
1326
- *
1327
- * Take in a `ColorComponents` struct containing all the different components of light, and combining them into
1328
- * a single final color. The struct contains:
1329
- * - `vec3 baseColor`, the base color of the pixel
1330
- * - `float opacity`, the opacity between 0 and 1 that it should be drawn at
1331
- * - `vec3 ambientColor`, the color of the pixel when affected by ambient light
1332
- * - `vec3 specularColor`, the color of the pixel when affected by specular reflections
1333
- * - `vec3 diffuse`, the amount of diffused light hitting the pixel
1334
- * - `vec3 ambient`, the amount of ambient light hitting the pixel
1335
- * - `vec3 specular`, the amount of specular reflection hitting the pixel
1336
- * - `vec3 emissive`, the amount of light emitted by the pixel
1337
- *
1338
- * </td></tr>
1339
- * <tr><td>
1340
- *
1341
- * `vec4 getFinalColor`
1342
- *
1343
- * </td><td>
1344
- *
1345
- * Update the final color after mixing. It takes in a `vec4 color` and must return a modified version.
1346
- *
1347
- * </td></tr>
1348
- * <tr><td>
1349
- *
1350
- * `void afterFragment`
1351
- *
1352
- * </td><td>
1353
- *
1354
- * Called at the end of the fragment shader.
1355
- *
1356
- * </td></tr>
1357
- * </table>
1358
- *
1359
- * Most of the time, you will need to write your hooks in GLSL ES version 300. If you
1360
- * are using WebGL 1 instead of 2, write your hooks in GLSL ES 100 instead.
1361
- *
1362
- * Call `baseMaterialShader().inspectHooks()` to see all the possible hooks and
1363
- * their default implementations.
1364
- *
1365
- * @method baseMaterialShader
1366
- * @beta
1367
- * @returns {p5.Shader} The material shader
1368
- *
1369
- * @example
1370
- * <div modernizr='webgl'>
1371
- * <code>
1372
- * let myShader;
1373
- *
1374
- * function setup() {
1375
- * createCanvas(200, 200, WEBGL);
1376
- * myShader = baseMaterialShader().modify(() => {
1377
- * let time = uniformFloat(() => millis());
1378
- * getWorldInputs((inputs) => {
1379
- * inputs.position.y +=
1380
- * 20 * sin(time * 0.001 + inputs.position.x * 0.05);
1381
- * return inputs;
1382
- * });
1383
- * });
1384
- * }
1385
- *
1386
- * function draw() {
1387
- * background(255);
1388
- * shader(myShader);
1389
- * lights();
1390
- * noStroke();
1391
- * fill('red');
1392
- * sphere(50);
1393
- * }
1394
- * </code>
1395
- * </div>
1396
- *
1397
- * @example
1398
- * <div modernizr='webgl'>
1399
- * <code>
1400
- * let myShader;
1401
- *
1402
- * function setup() {
1403
- * createCanvas(200, 200, WEBGL);
1404
- * myShader = baseMaterialShader().modify({
1405
- * declarations: 'vec3 myNormal;',
1406
- * 'Inputs getPixelInputs': `(Inputs inputs) {
1407
- * myNormal = inputs.normal;
1408
- * return inputs;
1409
- * }`,
1410
- * 'vec4 getFinalColor': `(vec4 color) {
1411
- * return mix(
1412
- * vec4(1.0, 1.0, 1.0, 1.0),
1413
- * color,
1414
- * abs(dot(myNormal, vec3(0.0, 0.0, 1.0)))
1415
- * );
1416
- * }`
1417
- * });
1418
- * }
1419
- *
1420
- * function draw() {
1421
- * background(255);
1422
- * rotateY(millis() * 0.001);
1423
- * shader(myShader);
1424
- * lights();
1425
- * noStroke();
1426
- * fill('red');
1427
- * torus(30);
1428
- * }
1429
- * </code>
1430
- * </div>
1431
- *
1432
- * @example
1433
- * <div modernizr='webgl'>
1434
- * <code>
1435
- * let myShader;
1436
- * let environment;
1437
- *
1438
- * async function setup() {
1439
- * environment = await loadImage('assets/outdoor_spheremap.jpg');
1440
- *
1441
- * createCanvas(200, 200, WEBGL);
1442
- * myShader = baseMaterialShader().modify(() => {
1443
- * getPixelInputs((inputs) => {
1444
- * let factor = sin(
1445
- * TWO_PI * (inputs.texCoord.x + inputs.texCoord.y)
1446
- * );
1447
- * inputs.shininess = mix(1, 100, factor);
1448
- * inputs.metalness = factor;
1449
- * return inputs;
1450
- * })
1451
- * });
1452
- * }
1453
- *
1454
- * function draw() {
1455
- * panorama(environment);
1456
- * ambientLight(100);
1457
- * imageLight(environment);
1458
- * rotateY(millis() * 0.001);
1459
- * shader(myShader);
1460
- * noStroke();
1461
- * fill(255);
1462
- * specularMaterial(150);
1463
- * sphere(50);
1464
- * }
1465
- * </code>
1466
- * </div>
1467
- *
1468
- * @example
1469
- * <div modernizr='webgl'>
1470
- * <code>
1471
- * let myShader;
1472
- *
1473
- * function setup() {
1474
- * createCanvas(200, 200, WEBGL);
1475
- * myShader = baseMaterialShader().modify(() => {
1476
- * getPixelInputs((inputs) => {
1477
- * inputs.normal.x += 0.2 * sin(
1478
- * sin(TWO_PI * dot(inputs.texCoord.yx, vec2(10, 25)))
1479
- * );
1480
- * inputs.normal.y += 0.2 * sin(
1481
- * sin(TWO_PI * dot(inputs.texCoord, vec2(10, 25)))
1482
- * );
1483
- * inputs.normal = normalize(inputs.normal);
1484
- * return inputs;
1485
- * });
1486
- * });
1487
- * }
1488
- *
1489
- * function draw() {
1490
- * background(255);
1491
- * shader(myShader);
1492
- * ambientLight(150);
1493
- * pointLight(
1494
- * 255, 255, 255,
1495
- * 100*cos(frameCount*0.04), -50, 100*sin(frameCount*0.04)
1496
- * );
1497
- * noStroke();
1498
- * fill('red');
1499
- * shininess(200);
1500
- * specularMaterial(255);
1501
- * sphere(50);
1502
- * }
1503
- * </code>
1504
- * </div>
1505
- */
1506
- fn.baseMaterialShader = function() {
1507
- this._assert3d('baseMaterialShader');
1508
- return this._renderer.baseMaterialShader();
1509
- };
1510
-
1511
- /**
1512
- * Get the base shader for filters.
1513
- *
1514
- * You can then call <a href="#/p5.Shader/modify">`baseFilterShader().modify()`</a>
1515
- * and change the following hook:
1516
- *
1517
- * <table>
1518
- * <tr><th>Hook</th><th>Description</th></tr>
1519
- * <tr><td>
1520
- *
1521
- * `vec4 getColor`
1522
- *
1523
- * </td><td>
1524
- *
1525
- * Output the final color for the current pixel. It takes in two parameters:
1526
- * `FilterInputs inputs`, and `in sampler2D canvasContent`, and must return a color
1527
- * as a `vec4`.
1528
- *
1529
- * `FilterInputs inputs` is a scruct with the following properties:
1530
- * - `vec2 texCoord`, the position on the canvas, with coordinates between 0 and 1. Calling
1531
- * `getTexture(canvasContent, texCoord)` returns the original color of the current pixel.
1532
- * - `vec2 canvasSize`, the width and height of the sketch.
1533
- * - `vec2 texelSize`, the size of one real pixel relative to the size of the whole canvas.
1534
- * This is equivalent to `1 / (canvasSize * pixelDensity)`.
1535
- *
1536
- * `in sampler2D canvasContent` is a texture with the contents of the sketch, pre-filter. Call
1537
- * `getTexture(canvasContent, someCoordinate)` to retrieve the color of the sketch at that coordinate,
1538
- * with coordinate values between 0 and 1.
1539
- *
1540
- * </td></tr>
1541
- * </table>
1542
- *
1543
- * Most of the time, you will need to write your hooks in GLSL ES version 300. If you
1544
- * are using WebGL 1, write your hooks in GLSL ES 100 instead.
1545
- *
1546
- * @method baseFilterShader
1547
- * @beta
1548
- * @returns {p5.Shader} The filter shader
1549
- *
1550
- * @example
1551
- * <div modernizr='webgl'>
1552
- * <code>
1553
- * let img;
1554
- * let myShader;
1555
- *
1556
- * async function setup() {
1557
- * img = await loadImage('assets/bricks.jpg');
1558
- * createCanvas(100, 100, WEBGL);
1559
- * myShader = baseFilterShader().modify(() => {
1560
- * let time = uniformFloat(() => millis());
1561
- * getColor((inputs, canvasContent) => {
1562
- * inputs.texCoord.y +=
1563
- * 0.02 * sin(time * 0.001 + inputs.texCoord.x * 5);
1564
- * return texture(canvasContent, inputs.texCoord);
1565
- * });
1566
- * });
1567
- * }
1568
- *
1569
- * function draw() {
1570
- * image(img, -50, -50);
1571
- * filter(myShader);
1572
- * describe('an image of bricks, distorting over time');
1573
- * }
1574
- * </code>
1575
- * </div>
1576
- */
1577
- fn.baseFilterShader = function() {
1578
- return (this._renderer.filterRenderer || this._renderer)
1579
- .baseFilterShader();
1580
- };
1581
-
1582
- /**
1583
- * Get the shader used by <a href="#/p5/normalMaterial">`normalMaterial()`</a>.
1584
- *
1585
- * You can call <a href="#/p5.Shader/modify">`baseNormalShader().modify()`</a>
1586
- * and change any of the following hooks:
1587
- *
1588
- * <table>
1589
- * <tr><th>Hook</th><th>Description</th></tr>
1590
- * <tr><td>
1591
- *
1592
- * `void beforeVertex`
1593
- *
1594
- * </td><td>
1595
- *
1596
- * Called at the start of the vertex shader.
1597
- *
1598
- * </td></tr>
1599
- * <tr><td>
1600
- *
1601
- * `Vertex getObjectInputs`
1602
- *
1603
- * </td><td>
1604
- *
1605
- * Update the vertex data of the model being drawn before any positioning has been applied. It takes in a `Vertex` struct, which includes:
1606
- * - `vec3 position`, the position of the vertex
1607
- * - `vec3 normal`, the direction facing out of the surface
1608
- * - `vec2 texCoord`, the texture coordinates associeted with the vertex
1609
- * - `vec4 color`, the per-vertex color
1610
- * The struct can be modified and returned.
1611
- *
1612
- * </td></tr>
1613
- * <tr><td>
1614
- *
1615
- * `Vertex getWorldInputs`
1616
- *
1617
- * </td><td>
1618
- *
1619
- * Update the vertex data of the model being drawn after transformations such as `translate()` and `scale()` have been applied, but before the camera has been applied. It takes in a `Vertex` struct like, in the `getObjectInputs` hook above, that can be modified and returned.
1620
- *
1621
- * </td></tr>
1622
- * <tr><td>
1623
- *
1624
- * `Vertex getCameraInputs`
1625
- *
1626
- * </td><td>
1627
- *
1628
- * Update the vertex data of the model being drawn as they appear relative to the camera. It takes in a `Vertex` struct like, in the `getObjectInputs` hook above, that can be modified and returned.
1629
- *
1630
- * </td></tr>
1631
- * <tr><td>
1632
- *
1633
- * `void afterVertex`
1634
- *
1635
- * </td><td>
1636
- *
1637
- * Called at the end of the vertex shader.
1638
- *
1639
- * </td></tr>
1640
- * <tr><td>
1641
- *
1642
- * `void beforeFragment`
1643
- *
1644
- * </td><td>
1645
- *
1646
- * Called at the start of the fragment shader.
1647
- *
1648
- * </td></tr>
1649
- * <tr><td>
1650
- *
1651
- * `vec4 getFinalColor`
1652
- *
1653
- * </td><td>
1654
- *
1655
- * Update the final color after mixing. It takes in a `vec4 color` and must return a modified version.
1656
- *
1657
- * </td></tr>
1658
- * <tr><td>
1659
- *
1660
- * `void afterFragment`
1661
- *
1662
- * </td><td>
1663
- *
1664
- * Called at the end of the fragment shader.
1665
- *
1666
- * </td></tr>
1667
- * </table>
1668
- *
1669
- * Most of the time, you will need to write your hooks in GLSL ES version 300. If you
1670
- * are using WebGL 1 instead of 2, write your hooks in GLSL ES 100 instead.
1671
- *
1672
- * Call `baseNormalShader().inspectHooks()` to see all the possible hooks and
1673
- * their default implementations.
1674
- *
1675
- * @method baseNormalShader
1676
- * @beta
1677
- * @returns {p5.Shader} The `normalMaterial` shader
1678
- *
1679
- * @example
1680
- * <div modernizr='webgl'>
1681
- * <code>
1682
- * let myShader;
1683
- *
1684
- * function setup() {
1685
- * createCanvas(200, 200, WEBGL);
1686
- * myShader = baseNormalShader().modify({
1687
- * uniforms: {
1688
- * 'float time': () => millis()
1689
- * },
1690
- * 'Vertex getWorldInputs': `(Vertex inputs) {
1691
- * inputs.position.y +=
1692
- * 20. * sin(time * 0.001 + inputs.position.x * 0.05);
1693
- * return inputs;
1694
- * }`
1695
- * });
1696
- * }
1697
- *
1698
- * function draw() {
1699
- * background(255);
1700
- * shader(myShader);
1701
- * noStroke();
1702
- * sphere(50);
1703
- * }
1704
- * </code>
1705
- * </div>
1706
- *
1707
- * @example
1708
- * <div modernizr='webgl'>
1709
- * <code>
1710
- * let myShader;
1711
- *
1712
- * function setup() {
1713
- * createCanvas(200, 200, WEBGL);
1714
- * myShader = baseNormalShader().modify({
1715
- * 'Vertex getCameraInputs': `(Vertex inputs) {
1716
- * inputs.normal = abs(inputs.normal);
1717
- * return inputs;
1718
- * }`,
1719
- * 'vec4 getFinalColor': `(vec4 color) {
1720
- * // Map the r, g, and b values of the old normal to new colors
1721
- * // instead of just red, green, and blue:
1722
- * vec3 newColor =
1723
- * color.r * vec3(89.0, 240.0, 232.0) / 255.0 +
1724
- * color.g * vec3(240.0, 237.0, 89.0) / 255.0 +
1725
- * color.b * vec3(205.0, 55.0, 222.0) / 255.0;
1726
- * newColor = newColor / (color.r + color.g + color.b);
1727
- * return vec4(newColor, 1.0) * color.a;
1728
- * }`
1729
- * });
1730
- * }
1731
- *
1732
- * function draw() {
1733
- * background(255);
1734
- * shader(myShader);
1735
- * noStroke();
1736
- * rotateX(frameCount * 0.01);
1737
- * rotateY(frameCount * 0.015);
1738
- * box(100);
1739
- * }
1740
- * </code>
1741
- * </div>
1742
- */
1743
- fn.baseNormalShader = function() {
1744
- this._assert3d('baseNormalShader');
1745
- return this._renderer.baseNormalShader();
1746
- };
1747
-
1748
- /**
1749
- * Get the shader used when no lights or materials are applied.
1750
- *
1751
- * You can call <a href="#/p5.Shader/modify">`baseColorShader().modify()`</a>
1752
- * and change any of the following hooks:
1753
- *
1754
- * <table>
1755
- * <tr><th>Hook</th><th>Description</th></tr>
1756
- * <tr><td>
1757
- *
1758
- * `void beforeVertex`
1759
- *
1760
- * </td><td>
1761
- *
1762
- * Called at the start of the vertex shader.
1763
- *
1764
- * </td></tr>
1765
- * <tr><td>
1766
- *
1767
- * `Vertex getObjectInputs`
1768
- *
1769
- * </td><td>
1770
- *
1771
- * Update the vertex data of the model being drawn before any positioning has been applied. It takes in a `Vertex` struct, which includes:
1772
- * - `vec3 position`, the position of the vertex
1773
- * - `vec3 normal`, the direction facing out of the surface
1774
- * - `vec2 texCoord`, the texture coordinates associeted with the vertex
1775
- * - `vec4 color`, the per-vertex color
1776
- * The struct can be modified and returned.
1777
- *
1778
- * </td></tr>
1779
- * <tr><td>
1780
- *
1781
- * `Vertex getWorldInputs`
1782
- *
1783
- * </td><td>
1784
- *
1785
- * Update the vertex data of the model being drawn after transformations such as `translate()` and `scale()` have been applied, but before the camera has been applied. It takes in a `Vertex` struct like, in the `getObjectInputs` hook above, that can be modified and returned.
1786
- *
1787
- * </td></tr>
1788
- * <tr><td>
1789
- *
1790
- * `Vertex getCameraInputs`
1791
- *
1792
- * </td><td>
1793
- *
1794
- * Update the vertex data of the model being drawn as they appear relative to the camera. It takes in a `Vertex` struct like, in the `getObjectInputs` hook above, that can be modified and returned.
1795
- *
1796
- * </td></tr>
1797
- * <tr><td>
1798
- *
1799
- * `void afterVertex`
1800
- *
1801
- * </td><td>
1802
- *
1803
- * Called at the end of the vertex shader.
1804
- *
1805
- * </td></tr>
1806
- * <tr><td>
1807
- *
1808
- * `void beforeFragment`
1809
- *
1810
- * </td><td>
1811
- *
1812
- * Called at the start of the fragment shader.
1813
- *
1814
- * </td></tr>
1815
- * <tr><td>
1816
- *
1817
- * `vec4 getFinalColor`
1818
- *
1819
- * </td><td>
1820
- *
1821
- * Update the final color after mixing. It takes in a `vec4 color` and must return a modified version.
1822
- *
1823
- * </td></tr>
1824
- * <tr><td>
1825
- *
1826
- * `void afterFragment`
1827
- *
1828
- * </td><td>
1829
- *
1830
- * Called at the end of the fragment shader.
1831
- *
1832
- * </td></tr>
1833
- * </table>
1834
- *
1835
- * Most of the time, you will need to write your hooks in GLSL ES version 300. If you
1836
- * are using WebGL 1 instead of 2, write your hooks in GLSL ES 100 instead.
1837
- *
1838
- * Call `baseColorShader().inspectHooks()` to see all the possible hooks and
1839
- * their default implementations.
1840
- *
1841
- * @method baseColorShader
1842
- * @beta
1843
- * @returns {p5.Shader} The color shader
1844
- *
1845
- * @example
1846
- * <div modernizr='webgl'>
1847
- * <code>
1848
- * let myShader;
1849
- *
1850
- * function setup() {
1851
- * createCanvas(200, 200, WEBGL);
1852
- * myShader = baseColorShader().modify({
1853
- * uniforms: {
1854
- * 'float time': () => millis()
1855
- * },
1856
- * 'Vertex getWorldInputs': `(Vertex inputs) {
1857
- * inputs.position.y +=
1858
- * 20. * sin(time * 0.001 + inputs.position.x * 0.05);
1859
- * return inputs;
1860
- * }`
1861
- * });
1862
- * }
1863
- *
1864
- * function draw() {
1865
- * background(255);
1866
- * shader(myShader);
1867
- * noStroke();
1868
- * fill('red');
1869
- * circle(0, 0, 50);
1870
- * }
1871
- * </code>
1872
- * </div>
1873
- */
1874
- fn.baseColorShader = function() {
1875
- this._assert3d('baseColorShader');
1876
- return this._renderer.baseColorShader();
1877
- };
1878
-
1879
- /**
1880
- * Get the shader used when drawing the strokes of shapes.
1881
- *
1882
- * You can call <a href="#/p5.Shader/modify">`baseStrokeShader().modify()`</a>
1883
- * and change any of the following hooks:
1884
- *
1885
- * <table>
1886
- * <tr><th>Hook</th><th>Description</th></tr>
1887
- * <tr><td>
1888
- *
1889
- * `void beforeVertex`
1890
- *
1891
- * </td><td>
1892
- *
1893
- * Called at the start of the vertex shader.
1894
- *
1895
- * </td></tr>
1896
- * <tr><td>
1897
- *
1898
- * `StrokeVertex getObjectInputs`
1899
- *
1900
- * </td><td>
1901
- *
1902
- * Update the vertex data of the stroke being drawn before any positioning has been applied. It takes in a `StrokeVertex` struct, which includes:
1903
- * - `vec3 position`, the position of the vertex
1904
- * - `vec3 tangentIn`, the tangent coming in to the vertex
1905
- * - `vec3 tangentOut`, the tangent coming out of the vertex. In straight segments, this will be the same as `tangentIn`. In joins, it will be different. In caps, one of the tangents will be 0.
1906
- * - `vec4 color`, the per-vertex color
1907
- * - `float weight`, the stroke weight
1908
- * The struct can be modified and returned.
1909
- *
1910
- * </td></tr>
1911
- * <tr><td>
1912
- *
1913
- * `StrokeVertex getWorldInputs`
1914
- *
1915
- * </td><td>
1916
- *
1917
- * Update the vertex data of the model being drawn after transformations such as `translate()` and `scale()` have been applied, but before the camera has been applied. It takes in a `StrokeVertex` struct like, in the `getObjectInputs` hook above, that can be modified and returned.
1918
- *
1919
- * </td></tr>
1920
- * <tr><td>
1921
- *
1922
- * `StrokeVertex getCameraInputs`
1923
- *
1924
- * </td><td>
1925
- *
1926
- * Update the vertex data of the model being drawn as they appear relative to the camera. It takes in a `StrokeVertex` struct like, in the `getObjectInputs` hook above, that can be modified and returned.
1927
- *
1928
- * </td></tr>
1929
- * <tr><td>
1930
- *
1931
- * `void afterVertex`
1932
- *
1933
- * </td><td>
1934
- *
1935
- * Called at the end of the vertex shader.
1936
- *
1937
- * </td></tr>
1938
- * <tr><td>
1939
- *
1940
- * `void beforeFragment`
1941
- *
1942
- * </td><td>
1943
- *
1944
- * Called at the start of the fragment shader.
1945
- *
1946
- * </td></tr>
1947
- * <tr><td>
1948
- *
1949
- * `Inputs getPixelInputs`
1950
- *
1951
- * </td><td>
1952
- *
1953
- * Update the inputs to the shader. It takes in a struct `Inputs inputs`, which includes:
1954
- * - `vec4 color`, the color of the stroke
1955
- * - `vec2 tangent`, the direction of the stroke in screen space
1956
- * - `vec2 center`, the coordinate of the center of the stroke in screen space p5.js pixels
1957
- * - `vec2 position`, the coordinate of the current pixel in screen space p5.js pixels
1958
- * - `float strokeWeight`, the thickness of the stroke in p5.js pixels
1959
- *
1960
- * </td></tr>
1961
- * <tr><td>
1962
- *
1963
- * `bool shouldDiscard`
1964
- *
1965
- * </td><td>
1966
- *
1967
- * Caps and joins are made by discarded pixels in the fragment shader to carve away unwanted areas. Use this to change this logic. It takes in a `bool willDiscard` and must return a modified version.
1968
- *
1969
- * </td></tr>
1970
- * <tr><td>
1971
- *
1972
- * `vec4 getFinalColor`
1973
- *
1974
- * </td><td>
1975
- *
1976
- * Update the final color after mixing. It takes in a `vec4 color` and must return a modified version.
1977
- *
1978
- * </td></tr>
1979
- * <tr><td>
1980
- *
1981
- * `void afterFragment`
1982
- *
1983
- * </td><td>
1984
- *
1985
- * Called at the end of the fragment shader.
1986
- *
1987
- * </td></tr>
1988
- * </table>
1989
- *
1990
- * Most of the time, you will need to write your hooks in GLSL ES version 300. If you
1991
- * are using WebGL 1 instead of 2, write your hooks in GLSL ES 100 instead.
1992
- *
1993
- * Call `baseStrokeShader().inspectHooks()` to see all the possible hooks and
1994
- * their default implementations.
1995
- *
1996
- * @method baseStrokeShader
1997
- * @beta
1998
- * @returns {p5.Shader} The stroke shader
1999
- *
2000
- * @example
2001
- * <div modernizr='webgl'>
2002
- * <code>
2003
- * let myShader;
2004
- *
2005
- * function setup() {
2006
- * createCanvas(200, 200, WEBGL);
2007
- * myShader = baseStrokeShader().modify({
2008
- * 'Inputs getPixelInputs': `(Inputs inputs) {
2009
- * float opacity = 1.0 - smoothstep(
2010
- * 0.0,
2011
- * 15.0,
2012
- * length(inputs.position - inputs.center)
2013
- * );
2014
- * inputs.color *= opacity;
2015
- * return inputs;
2016
- * }`
2017
- * });
2018
- * }
2019
- *
2020
- * function draw() {
2021
- * background(255);
2022
- * strokeShader(myShader);
2023
- * strokeWeight(30);
2024
- * line(
2025
- * -width/3,
2026
- * sin(millis()*0.001) * height/4,
2027
- * width/3,
2028
- * sin(millis()*0.001 + 1) * height/4
2029
- * );
2030
- * }
2031
- * </code>
2032
- * </div>
2033
- *
2034
- * @example
2035
- * <div modernizr='webgl'>
2036
- * <code>
2037
- * let myShader;
2038
- *
2039
- * function setup() {
2040
- * createCanvas(200, 200, WEBGL);
2041
- * myShader = baseStrokeShader().modify({
2042
- * uniforms: {
2043
- * 'float time': () => millis()
2044
- * },
2045
- * 'StrokeVertex getWorldInputs': `(StrokeVertex inputs) {
2046
- * // Add a somewhat random offset to the weight
2047
- * // that varies based on position and time
2048
- * float scale = 0.8 + 0.2*sin(10.0 * sin(
2049
- * floor(time/250.) +
2050
- * inputs.position.x*0.01 +
2051
- * inputs.position.y*0.01
2052
- * ));
2053
- * inputs.weight *= scale;
2054
- * return inputs;
2055
- * }`
2056
- * });
2057
- * }
2058
- *
2059
- * function draw() {
2060
- * background(255);
2061
- * strokeShader(myShader);
2062
- * myShader.setUniform('time', millis());
2063
- * strokeWeight(10);
2064
- * beginShape();
2065
- * for (let i = 0; i <= 50; i++) {
2066
- * let r = map(i, 0, 50, 0, width/3);
2067
- * let x = r*cos(i*0.2);
2068
- * let y = r*sin(i*0.2);
2069
- * vertex(x, y);
2070
- * }
2071
- * endShape();
2072
- * }
2073
- * </code>
2074
- * </div>
2075
- *
2076
- * @example
2077
- * <div modernizr='webgl'>
2078
- * <code>
2079
- * let myShader;
2080
- *
2081
- * function setup() {
2082
- * createCanvas(200, 200, WEBGL);
2083
- * myShader = baseStrokeShader().modify({
2084
- * 'float random': `(vec2 p) {
2085
- * vec3 p3 = fract(vec3(p.xyx) * .1031);
2086
- * p3 += dot(p3, p3.yzx + 33.33);
2087
- * return fract((p3.x + p3.y) * p3.z);
2088
- * }`,
2089
- * 'Inputs getPixelInputs': `(Inputs inputs) {
2090
- * // Replace alpha in the color with dithering by
2091
- * // randomly setting pixel colors to 0 based on opacity
2092
- * float a = inputs.color.a;
2093
- * inputs.color.a = 1.0;
2094
- * inputs.color *= random(inputs.position.xy) > a ? 0.0 : 1.0;
2095
- * return inputs;
2096
- * }`
2097
- * });
2098
- * }
2099
- *
2100
- * function draw() {
2101
- * background(255);
2102
- * strokeShader(myShader);
2103
- * strokeWeight(10);
2104
- * beginShape();
2105
- * for (let i = 0; i <= 50; i++) {
2106
- * stroke(
2107
- * 0,
2108
- * 255
2109
- * * map(i, 0, 20, 0, 1, true)
2110
- * * map(i, 30, 50, 1, 0, true)
2111
- * );
2112
- * vertex(
2113
- * map(i, 0, 50, -1, 1) * width/3,
2114
- * 50 * sin(i/10 + frameCount/100)
2115
- * );
2116
- * }
2117
- * endShape();
2118
- * }
2119
- * </code>
2120
- * </div>
2121
- */
2122
- fn.baseStrokeShader = function() {
2123
- this._assert3d('baseStrokeShader');
2124
- return this._renderer.baseStrokeShader();
2125
- };
2126
-
2127
- /**
2128
- * Restores the default shaders.
2129
- *
2130
- * `resetShader()` deactivates any shaders previously applied by
2131
- * <a href="#/p5/shader">shader()</a>, <a href="#/p5/strokeShader">strokeShader()</a>,
2132
- * or <a href="#/p5/imageShader">imageShader()</a>.
2133
- *
2134
- * Note: Shaders can only be used in WebGL mode.
2135
- *
2136
- * @method resetShader
2137
- * @chainable
2138
- *
2139
- * @example
2140
- * <div>
2141
- * <code>
2142
- * // Create a string with the vertex shader program.
2143
- * // The vertex shader is called for each vertex.
2144
- * let vertSrc = `
2145
- * attribute vec3 aPosition;
2146
- * attribute vec2 aTexCoord;
2147
- * uniform mat4 uProjectionMatrix;
2148
- * uniform mat4 uModelViewMatrix;
2149
- * varying vec2 vTexCoord;
2150
- *
2151
- * void main() {
2152
- * vTexCoord = aTexCoord;
2153
- * vec4 position = vec4(aPosition, 1.0);
2154
- * gl_Position = uProjectionMatrix * uModelViewMatrix * position;
2155
- * }
2156
- * `;
2157
- *
2158
- * // Create a string with the fragment shader program.
2159
- * // The fragment shader is called for each pixel.
2160
- * let fragSrc = `
2161
- * precision mediump float;
2162
- * varying vec2 vTexCoord;
2163
- *
2164
- * void main() {
2165
- * vec2 uv = vTexCoord;
2166
- * vec3 color = vec3(uv.x, uv.y, min(uv.x + uv.y, 1.0));
2167
- * gl_FragColor = vec4(color, 1.0);
2168
- * }
2169
- * `;
2170
- *
2171
- * let myShader;
2172
- *
2173
- * function setup() {
2174
- * createCanvas(100, 100, WEBGL);
2175
- *
2176
- * // Create a p5.Shader object.
2177
- * myShader = createShader(vertSrc, fragSrc);
2178
- *
2179
- * describe(
2180
- * 'Two rotating cubes on a gray background. The left one has a blue-purple gradient on each face. The right one is red.'
2181
- * );
2182
- * }
2183
- *
2184
- * function draw() {
2185
- * background(200);
2186
- *
2187
- * // Draw a box using the p5.Shader.
2188
- * // shader() sets the active shader to myShader.
2189
- * shader(myShader);
2190
- * push();
2191
- * translate(-25, 0, 0);
2192
- * rotateX(frameCount * 0.01);
2193
- * rotateY(frameCount * 0.01);
2194
- * box(width / 4);
2195
- * pop();
2196
- *
2197
- * // Draw a box using the default fill shader.
2198
- * // resetShader() restores the default fill shader.
2199
- * resetShader();
2200
- * fill(255, 0, 0);
2201
- * push();
2202
- * translate(25, 0, 0);
2203
- * rotateX(frameCount * 0.01);
2204
- * rotateY(frameCount * 0.01);
2205
- * box(width / 4);
2206
- * pop();
2207
- * }
2208
- * </code>
2209
- * </div>
2210
- */
2211
- fn.resetShader = function () {
2212
- this._renderer.resetShader();
2213
- return this;
2214
- };
2215
-
2216
- /**
2217
- * Sets the texture that will be used on shapes.
2218
- *
2219
- * A texture is like a skin that wraps around a shape. `texture()` works with
2220
- * built-in shapes, such as <a href="#/p5/square">square()</a> and
2221
- * <a href="#/p5/sphere">sphere()</a>, and custom shapes created with
2222
- * functions such as <a href="#/p5/buildGeometry">buildGeometry()</a>. To
2223
- * texture a geometry created with <a href="#/p5/beginShape">beginShape()</a>,
2224
- * uv coordinates must be passed to each
2225
- * <a href="#/p5/vertex">vertex()</a> call.
2226
- *
2227
- * The parameter, `tex`, is the texture to apply. `texture()` can use a range
2228
- * of sources including images, videos, and offscreen renderers such as
2229
- * <a href="#/p5.Graphics">p5.Graphics</a> and
2230
- * <a href="#/p5.Framebuffer">p5.Framebuffer</a> objects.
2231
- *
2232
- * To texture a geometry created with <a href="#/p5/beginShape">beginShape()</a>,
2233
- * you will need to specify uv coordinates in <a href="#/p5/vertex">vertex()</a>.
2234
- *
2235
- * Note: `texture()` can only be used in WebGL mode.
2236
- *
2237
- * @method texture
2238
- * @param {p5.Image|p5.MediaElement|p5.Graphics|p5.Texture|p5.Framebuffer|p5.FramebufferTexture} tex media to use as the texture.
2239
- * @chainable
2240
- *
2241
- * @example
2242
- * <div>
2243
- * <code>
2244
- * let img;
2245
- *
2246
- * async function setup() {
2247
- * // Load an image and create a p5.Image object.
2248
- * img = await loadImage('assets/laDefense.jpg');
2249
- *
2250
- * createCanvas(100, 100, WEBGL);
2251
- *
2252
- * describe('A spinning cube with an image of a ceiling on each face.');
2253
- * }
2254
- *
2255
- * function draw() {
2256
- * background(0);
2257
- *
2258
- * // Rotate around the x-, y-, and z-axes.
2259
- * rotateZ(frameCount * 0.01);
2260
- * rotateX(frameCount * 0.01);
2261
- * rotateY(frameCount * 0.01);
2262
- *
2263
- * // Apply the image as a texture.
2264
- * texture(img);
2265
- *
2266
- * // Draw the box.
2267
- * box(50);
2268
- * }
2269
- * </code>
2270
- * </div>
2271
- *
2272
- * <div>
2273
- * <code>
2274
- * let pg;
2275
- *
2276
- * function setup() {
2277
- * createCanvas(100, 100, WEBGL);
2278
- *
2279
- * // Create a p5.Graphics object.
2280
- * pg = createGraphics(100, 100);
2281
- *
2282
- * // Draw a circle to the p5.Graphics object.
2283
- * pg.background(200);
2284
- * pg.circle(50, 50, 30);
2285
- *
2286
- * describe('A spinning cube with circle at the center of each face.');
2287
- * }
2288
- *
2289
- * function draw() {
2290
- * background(0);
2291
- *
2292
- * // Rotate around the x-, y-, and z-axes.
2293
- * rotateZ(frameCount * 0.01);
2294
- * rotateX(frameCount * 0.01);
2295
- * rotateY(frameCount * 0.01);
2296
- *
2297
- * // Apply the p5.Graphics object as a texture.
2298
- * texture(pg);
2299
- *
2300
- * // Draw the box.
2301
- * box(50);
2302
- * }
2303
- * </code>
2304
- * </div>
2305
- *
2306
- * <div>
2307
- * <code>
2308
- * let vid;
2309
- *
2310
- * function setup() {
2311
- * // Load a video and create a p5.MediaElement object.
2312
- * vid = createVideo('assets/fingers.mov');
2313
- *
2314
- * createCanvas(100, 100, WEBGL);
2315
- *
2316
- * // Hide the video.
2317
- * vid.hide();
2318
- *
2319
- * // Set the video to loop.
2320
- * vid.loop();
2321
- *
2322
- * describe('A rectangle with video as texture');
2323
- * }
2324
- *
2325
- * function draw() {
2326
- * background(0);
2327
- *
2328
- * // Rotate around the y-axis.
2329
- * rotateY(frameCount * 0.01);
2330
- *
2331
- * // Apply the video as a texture.
2332
- * texture(vid);
2333
- *
2334
- * // Draw the rectangle.
2335
- * rect(-40, -40, 80, 80);
2336
- * }
2337
- * </code>
2338
- * </div>
2339
- *
2340
- * <div>
2341
- * <code>
2342
- * let vid;
2343
- *
2344
- * function setup() {
2345
- * // Load a video and create a p5.MediaElement object.
2346
- * vid = createVideo('assets/fingers.mov');
2347
- *
2348
- * createCanvas(100, 100, WEBGL);
2349
- *
2350
- * // Hide the video.
2351
- * vid.hide();
2352
- *
2353
- * // Set the video to loop.
2354
- * vid.loop();
2355
- *
2356
- * describe('A rectangle with video as texture');
2357
- * }
2358
- *
2359
- * function draw() {
2360
- * background(0);
2361
- *
2362
- * // Rotate around the y-axis.
2363
- * rotateY(frameCount * 0.01);
2364
- *
2365
- * // Set the texture mode.
2366
- * textureMode(NORMAL);
2367
- *
2368
- * // Apply the video as a texture.
2369
- * texture(vid);
2370
- *
2371
- * // Draw a custom shape using uv coordinates.
2372
- * beginShape();
2373
- * vertex(-40, -40, 0, 0);
2374
- * vertex(40, -40, 1, 0);
2375
- * vertex(40, 40, 1, 1);
2376
- * vertex(-40, 40, 0, 1);
2377
- * endShape();
2378
- * }
2379
- * </code>
2380
- * </div>
2381
- */
2382
- fn.texture = function (tex) {
2383
- this._assert3d('texture');
2384
- // p5._validateParameters('texture', arguments);
2385
-
2386
- // NOTE: make generic or remove need for
2387
- if (tex.gifProperties) {
2388
- tex._animateGif(this);
2389
- }
2390
-
2391
- this._renderer.texture(tex);
2392
-
2393
- return this;
2394
- };
2395
-
2396
- /**
2397
- * Changes the coordinate system used for textures when they’re applied to
2398
- * custom shapes.
2399
- *
2400
- * In order for <a href="#/p5/texture">texture()</a> to work, a shape needs a
2401
- * way to map the points on its surface to the pixels in an image. Built-in
2402
- * shapes such as <a href="#/p5/rect">rect()</a> and
2403
- * <a href="#/p5/box">box()</a> already have these texture mappings based on
2404
- * their vertices. Custom shapes created with
2405
- * <a href="#/p5/vertex">vertex()</a> require texture mappings to be passed as
2406
- * uv coordinates.
2407
- *
2408
- * Each call to <a href="#/p5/vertex">vertex()</a> must include 5 arguments,
2409
- * as in `vertex(x, y, z, u, v)`, to map the vertex at coordinates `(x, y, z)`
2410
- * to the pixel at coordinates `(u, v)` within an image. For example, the
2411
- * corners of a rectangular image are mapped to the corners of a rectangle by default:
2412
- *
2413
- * <code>
2414
- * // Apply the image as a texture.
2415
- * texture(img);
2416
- *
2417
- * // Draw the rectangle.
2418
- * rect(0, 0, 30, 50);
2419
- * </code>
2420
- *
2421
- * If the image in the code snippet above has dimensions of 300 x 500 pixels,
2422
- * the same result could be achieved as follows:
2423
- *
2424
- * <code>
2425
- * // Apply the image as a texture.
2426
- * texture(img);
2427
- *
2428
- * // Draw the rectangle.
2429
- * beginShape();
2430
- *
2431
- * // Top-left.
2432
- * // u: 0, v: 0
2433
- * vertex(0, 0, 0, 0, 0);
2434
- *
2435
- * // Top-right.
2436
- * // u: 300, v: 0
2437
- * vertex(30, 0, 0, 300, 0);
2438
- *
2439
- * // Bottom-right.
2440
- * // u: 300, v: 500
2441
- * vertex(30, 50, 0, 300, 500);
2442
- *
2443
- * // Bottom-left.
2444
- * // u: 0, v: 500
2445
- * vertex(0, 50, 0, 0, 500);
2446
- *
2447
- * endShape();
2448
- * </code>
2449
- *
2450
- * `textureMode()` changes the coordinate system for uv coordinates.
2451
- *
2452
- * The parameter, `mode`, accepts two possible constants. If `NORMAL` is
2453
- * passed, as in `textureMode(NORMAL)`, then the texture’s uv coordinates can
2454
- * be provided in the range 0 to 1 instead of the image’s dimensions. This can
2455
- * be helpful for using the same code for multiple images of different sizes.
2456
- * For example, the code snippet above could be rewritten as follows:
2457
- *
2458
- * <code>
2459
- * // Set the texture mode to use normalized coordinates.
2460
- * textureMode(NORMAL);
2461
- *
2462
- * // Apply the image as a texture.
2463
- * texture(img);
2464
- *
2465
- * // Draw the rectangle.
2466
- * beginShape();
2467
- *
2468
- * // Top-left.
2469
- * // u: 0, v: 0
2470
- * vertex(0, 0, 0, 0, 0);
2471
- *
2472
- * // Top-right.
2473
- * // u: 1, v: 0
2474
- * vertex(30, 0, 0, 1, 0);
2475
- *
2476
- * // Bottom-right.
2477
- * // u: 1, v: 1
2478
- * vertex(30, 50, 0, 1, 1);
2479
- *
2480
- * // Bottom-left.
2481
- * // u: 0, v: 1
2482
- * vertex(0, 50, 0, 0, 1);
2483
- *
2484
- * endShape();
2485
- * </code>
2486
- *
2487
- * By default, `mode` is `IMAGE`, which scales uv coordinates to the
2488
- * dimensions of the image. Calling `textureMode(IMAGE)` applies the default.
2489
- *
2490
- * Note: `textureMode()` can only be used in WebGL mode.
2491
- *
2492
- * @method textureMode
2493
- * @param {(IMAGE|NORMAL)} mode either IMAGE or NORMAL.
2494
- *
2495
- * @example
2496
- * <div>
2497
- * <code>
2498
- * let img;
2499
- *
2500
- * async function setup() {
2501
- * // Load an image and create a p5.Image object.
2502
- * img = await loadImage('assets/laDefense.jpg');
2503
- *
2504
- * createCanvas(100, 100, WEBGL);
2505
- *
2506
- * describe('An image of a ceiling against a black background.');
2507
- * }
2508
- *
2509
- * function draw() {
2510
- * background(0);
2511
- *
2512
- * // Apply the image as a texture.
2513
- * texture(img);
2514
- *
2515
- * // Draw the custom shape.
2516
- * // Use the image's width and height as uv coordinates.
2517
- * beginShape();
2518
- * vertex(-30, -30, 0, 0);
2519
- * vertex(30, -30, img.width, 0);
2520
- * vertex(30, 30, img.width, img.height);
2521
- * vertex(-30, 30, 0, img.height);
2522
- * endShape();
2523
- * }
2524
- * </code>
2525
- * </div>
2526
- *
2527
- * <div>
2528
- * <code>
2529
- * let img;
2530
- *
2531
- * async function setup() {
2532
- * // Load an image and create a p5.Image object.
2533
- * img = await loadImage('assets/laDefense.jpg');
2534
- *
2535
- * createCanvas(100, 100, WEBGL);
2536
- *
2537
- * describe('An image of a ceiling against a black background.');
2538
- * }
2539
- *
2540
- * function draw() {
2541
- * background(0);
2542
- *
2543
- * // Set the texture mode.
2544
- * textureMode(NORMAL);
2545
- *
2546
- * // Apply the image as a texture.
2547
- * texture(img);
2548
- *
2549
- * // Draw the custom shape.
2550
- * // Use normalized uv coordinates.
2551
- * beginShape();
2552
- * vertex(-30, -30, 0, 0);
2553
- * vertex(30, -30, 1, 0);
2554
- * vertex(30, 30, 1, 1);
2555
- * vertex(-30, 30, 0, 1);
2556
- * endShape();
2557
- * }
2558
- * </code>
2559
- * </div>
2560
- */
2561
- fn.textureMode = function (mode) {
2562
- if (mode !== constants.IMAGE && mode !== constants.NORMAL) {
2563
- console.warn(
2564
- `You tried to set ${mode} textureMode only supports IMAGE & NORMAL `
2565
- );
2566
- } else {
2567
- this._renderer.states.setValue('textureMode', mode);
2568
- }
2569
- };
2570
-
2571
- /**
2572
- * Changes the way textures behave when a shape’s uv coordinates go beyond the
2573
- * texture.
2574
- *
2575
- * In order for <a href="#/p5/texture">texture()</a> to work, a shape needs a
2576
- * way to map the points on its surface to the pixels in an image. Built-in
2577
- * shapes such as <a href="#/p5/rect">rect()</a> and
2578
- * <a href="#/p5/box">box()</a> already have these texture mappings based on
2579
- * their vertices. Custom shapes created with
2580
- * <a href="#/p5/vertex">vertex()</a> require texture mappings to be passed as
2581
- * uv coordinates.
2582
- *
2583
- * Each call to <a href="#/p5/vertex">vertex()</a> must include 5 arguments,
2584
- * as in `vertex(x, y, z, u, v)`, to map the vertex at coordinates `(x, y, z)`
2585
- * to the pixel at coordinates `(u, v)` within an image. For example, the
2586
- * corners of a rectangular image are mapped to the corners of a rectangle by default:
2587
- *
2588
- * ```js
2589
- * // Apply the image as a texture.
2590
- * texture(img);
2591
- *
2592
- * // Draw the rectangle.
2593
- * rect(0, 0, 30, 50);
2594
- * ```
2595
- *
2596
- * If the image in the code snippet above has dimensions of 300 x 500 pixels,
2597
- * the same result could be achieved as follows:
2598
- *
2599
- * ```js
2600
- * // Apply the image as a texture.
2601
- * texture(img);
2602
- *
2603
- * // Draw the rectangle.
2604
- * beginShape();
2605
- *
2606
- * // Top-left.
2607
- * // u: 0, v: 0
2608
- * vertex(0, 0, 0, 0, 0);
2609
- *
2610
- * // Top-right.
2611
- * // u: 300, v: 0
2612
- * vertex(30, 0, 0, 300, 0);
2613
- *
2614
- * // Bottom-right.
2615
- * // u: 300, v: 500
2616
- * vertex(30, 50, 0, 300, 500);
2617
- *
2618
- * // Bottom-left.
2619
- * // u: 0, v: 500
2620
- * vertex(0, 50, 0, 0, 500);
2621
- *
2622
- * endShape();
2623
- * ```
2624
- *
2625
- * `textureWrap()` controls how textures behave when their uv's go beyond the
2626
- * texture. Doing so can produce interesting visual effects such as tiling.
2627
- * For example, the custom shape above could have u-coordinates are greater
2628
- * than the image’s width:
2629
- *
2630
- * ```js
2631
- * // Apply the image as a texture.
2632
- * texture(img);
2633
- *
2634
- * // Draw the rectangle.
2635
- * beginShape();
2636
- * vertex(0, 0, 0, 0, 0);
2637
- *
2638
- * // Top-right.
2639
- * // u: 600
2640
- * vertex(30, 0, 0, 600, 0);
2641
- *
2642
- * // Bottom-right.
2643
- * // u: 600
2644
- * vertex(30, 50, 0, 600, 500);
2645
- *
2646
- * vertex(0, 50, 0, 0, 500);
2647
- * endShape();
2648
- * ```
2649
- *
2650
- * The u-coordinates of 600 are greater than the texture image’s width of 300.
2651
- * This creates interesting possibilities.
2652
- *
2653
- * The first parameter, `wrapX`, accepts three possible constants. If `CLAMP`
2654
- * is passed, as in `textureWrap(CLAMP)`, the pixels at the edge of the
2655
- * texture will extend to the shape’s edges. If `REPEAT` is passed, as in
2656
- * `textureWrap(REPEAT)`, the texture will tile repeatedly until reaching the
2657
- * shape’s edges. If `MIRROR` is passed, as in `textureWrap(MIRROR)`, the
2658
- * texture will tile repeatedly until reaching the shape’s edges, flipping
2659
- * its orientation between tiles. By default, textures `CLAMP`.
2660
- *
2661
- * The second parameter, `wrapY`, is optional. It accepts the same three
2662
- * constants, `CLAMP`, `REPEAT`, and `MIRROR`. If one of these constants is
2663
- * passed, as in `textureWRAP(MIRROR, REPEAT)`, then the texture will `MIRROR`
2664
- * horizontally and `REPEAT` vertically. By default, `wrapY` will be set to
2665
- * the same value as `wrapX`.
2666
- *
2667
- * Note: `textureWrap()` can only be used in WebGL mode.
2668
- *
2669
- * @method textureWrap
2670
- * @param {(CLAMP|REPEAT|MIRROR)} wrapX either CLAMP, REPEAT, or MIRROR
2671
- * @param {(CLAMP|REPEAT|MIRROR)} [wrapY=wrapX] either CLAMP, REPEAT, or MIRROR
2672
- *
2673
- * @example
2674
- * <div>
2675
- * <code>
2676
- * let img;
2677
- *
2678
- * async function setup() {
2679
- * img = await loadImage('assets/rockies128.jpg');
2680
- *
2681
- * createCanvas(100, 100, WEBGL);
2682
- *
2683
- * describe(
2684
- * 'An image of a landscape occupies the top-left corner of a square. Its edge colors smear to cover the other thre quarters of the square.'
2685
- * );
2686
- * }
2687
- *
2688
- * function draw() {
2689
- * background(0);
2690
- *
2691
- * // Set the texture mode.
2692
- * textureMode(NORMAL);
2693
- *
2694
- * // Set the texture wrapping.
2695
- * // Note: CLAMP is the default mode.
2696
- * textureWrap(CLAMP);
2697
- *
2698
- * // Apply the image as a texture.
2699
- * texture(img);
2700
- *
2701
- * // Style the shape.
2702
- * noStroke();
2703
- *
2704
- * // Draw the shape.
2705
- * // Use uv coordinates > 1.
2706
- * beginShape();
2707
- * vertex(-30, -30, 0, 0, 0);
2708
- * vertex(30, -30, 0, 2, 0);
2709
- * vertex(30, 30, 0, 2, 2);
2710
- * vertex(-30, 30, 0, 0, 2);
2711
- * endShape();
2712
- * }
2713
- * </code>
2714
- * </div>
2715
- *
2716
- * <div>
2717
- * <code>
2718
- * let img;
2719
- *
2720
- * async function setup() {
2721
- * img = await loadImage('assets/rockies128.jpg');
2722
- *
2723
- * createCanvas(100, 100, WEBGL);
2724
- *
2725
- * describe('Four identical images of a landscape arranged in a grid.');
2726
- * }
2727
- *
2728
- * function draw() {
2729
- * background(0);
2730
- *
2731
- * // Set the texture mode.
2732
- * textureMode(NORMAL);
2733
- *
2734
- * // Set the texture wrapping.
2735
- * textureWrap(REPEAT);
2736
- *
2737
- * // Apply the image as a texture.
2738
- * texture(img);
2739
- *
2740
- * // Style the shape.
2741
- * noStroke();
2742
- *
2743
- * // Draw the shape.
2744
- * // Use uv coordinates > 1.
2745
- * beginShape();
2746
- * vertex(-30, -30, 0, 0, 0);
2747
- * vertex(30, -30, 0, 2, 0);
2748
- * vertex(30, 30, 0, 2, 2);
2749
- * vertex(-30, 30, 0, 0, 2);
2750
- * endShape();
2751
- * }
2752
- * </code>
2753
- * </div>
2754
- *
2755
- * <div>
2756
- * <code>
2757
- * let img;
2758
- *
2759
- * async function setup() {
2760
- * img = await loadImage('assets/rockies128.jpg');
2761
- *
2762
- * createCanvas(100, 100, WEBGL);
2763
- *
2764
- * describe(
2765
- * 'Four identical images of a landscape arranged in a grid. The images are reflected horizontally and vertically, creating a kaleidoscope effect.'
2766
- * );
2767
- * }
2768
- *
2769
- * function draw() {
2770
- * background(0);
2771
- *
2772
- * // Set the texture mode.
2773
- * textureMode(NORMAL);
2774
- *
2775
- * // Set the texture wrapping.
2776
- * textureWrap(MIRROR);
2777
- *
2778
- * // Apply the image as a texture.
2779
- * texture(img);
2780
- *
2781
- * // Style the shape.
2782
- * noStroke();
2783
- *
2784
- * // Draw the shape.
2785
- * // Use uv coordinates > 1.
2786
- * beginShape();
2787
- * vertex(-30, -30, 0, 0, 0);
2788
- * vertex(30, -30, 0, 2, 0);
2789
- * vertex(30, 30, 0, 2, 2);
2790
- * vertex(-30, 30, 0, 0, 2);
2791
- * endShape();
2792
- * }
2793
- * </code>
2794
- * </div>
2795
- *
2796
- * <div>
2797
- * <code>
2798
- * let img;
2799
- *
2800
- * async function setup() {
2801
- * img = await loadImage('assets/rockies128.jpg');
2802
- *
2803
- * createCanvas(100, 100, WEBGL);
2804
- *
2805
- * describe(
2806
- * 'Four identical images of a landscape arranged in a grid. The top row and bottom row are reflections of each other.'
2807
- * );
2808
- * }
2809
- *
2810
- * function draw() {
2811
- * background(0);
2812
- *
2813
- * // Set the texture mode.
2814
- * textureMode(NORMAL);
2815
- *
2816
- * // Set the texture wrapping.
2817
- * textureWrap(REPEAT, MIRROR);
2818
- *
2819
- * // Apply the image as a texture.
2820
- * texture(img);
2821
- *
2822
- * // Style the shape.
2823
- * noStroke();
2824
- *
2825
- * // Draw the shape.
2826
- * // Use uv coordinates > 1.
2827
- * beginShape();
2828
- * vertex(-30, -30, 0, 0, 0);
2829
- * vertex(30, -30, 0, 2, 0);
2830
- * vertex(30, 30, 0, 2, 2);
2831
- * vertex(-30, 30, 0, 0, 2);
2832
- * endShape();
2833
- * }
2834
- * </code>
2835
- * </div>
2836
- */
2837
- fn.textureWrap = function (wrapX, wrapY = wrapX) {
2838
- this._renderer.states.setValue('textureWrapX', wrapX);
2839
- this._renderer.states.setValue('textureWrapY', wrapY);
2840
-
2841
- for (const texture of this._renderer.textures.values()) {
2842
- texture.setWrapMode(wrapX, wrapY);
2843
- }
2844
- };
2845
-
2846
- /**
2847
- * Sets the current material as a normal material.
2848
- *
2849
- * A normal material sets surfaces facing the x-axis to red, those facing the
2850
- * y-axis to green, and those facing the z-axis to blue. Normal material isn't
2851
- * affected by light. It’s often used as a placeholder material when debugging.
2852
- *
2853
- * Note: `normalMaterial()` can only be used in WebGL mode.
2854
- *
2855
- * @method normalMaterial
2856
- * @chainable
2857
- *
2858
- * @example
2859
- * <div>
2860
- * <code>
2861
- * // Click and drag the mouse to view the scene from different angles.
2862
- *
2863
- * function setup() {
2864
- * createCanvas(100, 100, WEBGL);
2865
- *
2866
- * describe('A multicolor torus drawn on a gray background.');
2867
- * }
2868
- *
2869
- * function draw() {
2870
- * background(200);
2871
- *
2872
- * // Enable orbiting with the mouse.
2873
- * orbitControl();
2874
- *
2875
- * // Style the torus.
2876
- * normalMaterial();
2877
- *
2878
- * // Draw the torus.
2879
- * torus(30);
2880
- * }
2881
- * </code>
2882
- * </div>
2883
- */
2884
- fn.normalMaterial = function (...args) {
2885
- this._assert3d('normalMaterial');
2886
- // p5._validateParameters('normalMaterial', args);
2887
-
2888
- this._renderer.normalMaterial(...args);
2889
-
2890
- return this;
2891
- };
2892
-
2893
- /**
2894
- * Sets the ambient color of shapes’ surface material.
2895
- *
2896
- * The `ambientMaterial()` color sets the components of the
2897
- * <a href="#/p5/ambientLight">ambientLight()</a> color that shapes will
2898
- * reflect. For example, calling `ambientMaterial(255, 255, 0)` would cause a
2899
- * shape to reflect red and green light, but not blue light.
2900
- *
2901
- * `ambientMaterial()` can be called three ways with different parameters to
2902
- * set the material’s color.
2903
- *
2904
- * The first way to call `ambientMaterial()` has one parameter, `gray`.
2905
- * Grayscale values between 0 and 255, as in `ambientMaterial(50)`, can be
2906
- * passed to set the material’s color. Higher grayscale values make shapes
2907
- * appear brighter.
2908
- *
2909
- * The second way to call `ambientMaterial()` has one parameter, `color`. A
2910
- * <a href="#/p5.Color">p5.Color</a> object, an array of color values, or a
2911
- * CSS color string, as in `ambientMaterial('magenta')`, can be passed to set
2912
- * the material’s color.
2913
- *
2914
- * The third way to call `ambientMaterial()` has three parameters, `v1`, `v2`,
2915
- * and `v3`. RGB, HSB, or HSL values, as in `ambientMaterial(255, 0, 0)`, can
2916
- * be passed to set the material’s colors. Color values will be interpreted
2917
- * using the current <a href="#/p5/colorMode">colorMode()</a>.
2918
- *
2919
- * Note: `ambientMaterial()` can only be used in WebGL mode.
2920
- *
2921
- * @method ambientMaterial
2922
- * @param {Number} v1 red or hue value in the current
2923
- * <a href="#/p5/colorMode">colorMode()</a>.
2924
- * @param {Number} v2 green or saturation value in the
2925
- * current <a href="#/p5/colorMode">colorMode()</a>.
2926
- * @param {Number} v3 blue, brightness, or lightness value in the
2927
- * current <a href="#/p5/colorMode">colorMode()</a>.
2928
- * @chainable
2929
- *
2930
- * @example
2931
- * <div>
2932
- * <code>
2933
- * // Click and drag the mouse to view the scene from different angles.
2934
- *
2935
- * function setup() {
2936
- * createCanvas(100, 100, WEBGL);
2937
- *
2938
- * describe('A magenta cube drawn on a gray background.');
2939
- * }
2940
- *
2941
- * function draw() {
2942
- * background(200);
2943
- *
2944
- * // Enable orbiting with the mouse.
2945
- * orbitControl();
2946
- *
2947
- * // Turn on a magenta ambient light.
2948
- * ambientLight(255, 0, 255);
2949
- *
2950
- * // Draw the box.
2951
- * box();
2952
- * }
2953
- * </code>
2954
- * </div>
2955
- *
2956
- * <div>
2957
- * <code>
2958
- * // Click and drag the mouse to view the scene from different angles.
2959
- *
2960
- * function setup() {
2961
- * createCanvas(100, 100, WEBGL);
2962
- *
2963
- * describe('A purple cube drawn on a gray background.');
2964
- * }
2965
- *
2966
- * function draw() {
2967
- * background(200);
2968
- *
2969
- * // Enable orbiting with the mouse.
2970
- * orbitControl();
2971
- *
2972
- * // Turn on a magenta ambient light.
2973
- * ambientLight(255, 0, 255);
2974
- *
2975
- * // Add a dark gray ambient material.
2976
- * ambientMaterial(150);
2977
- *
2978
- * // Draw the box.
2979
- * box();
2980
- * }
2981
- * </code>
2982
- * </div>
2983
- *
2984
- * <div>
2985
- * <code>
2986
- * // Click and drag the mouse to view the scene from different angles.
2987
- *
2988
- * function setup() {
2989
- * createCanvas(100, 100, WEBGL);
2990
- *
2991
- * describe('A red cube drawn on a gray background.');
2992
- * }
2993
- *
2994
- * function draw() {
2995
- * background(200);
2996
- *
2997
- * // Enable orbiting with the mouse.
2998
- * orbitControl();
2999
- *
3000
- * // Turn on a magenta ambient light.
3001
- * ambientLight(255, 0, 255);
3002
- *
3003
- * // Add a yellow ambient material using RGB values.
3004
- * ambientMaterial(255, 255, 0);
3005
- *
3006
- * // Draw the box.
3007
- * box();
3008
- * }
3009
- * </code>
3010
- * </div>
3011
- *
3012
- * <div>
3013
- * <code>
3014
- * // Click and drag the mouse to view the scene from different angles.
3015
- *
3016
- * function setup() {
3017
- * createCanvas(100, 100, WEBGL);
3018
- *
3019
- * describe('A red cube drawn on a gray background.');
3020
- * }
3021
- *
3022
- * function draw() {
3023
- * background(200);
3024
- *
3025
- * // Enable orbiting with the mouse.
3026
- * orbitControl();
3027
- *
3028
- * // Turn on a magenta ambient light.
3029
- * ambientLight(255, 0, 255);
3030
- *
3031
- * // Add a yellow ambient material using a p5.Color object.
3032
- * let c = color(255, 255, 0);
3033
- * ambientMaterial(c);
3034
- *
3035
- * // Draw the box.
3036
- * box();
3037
- * }
3038
- * </code>
3039
- * </div>
3040
- *
3041
- * <div>
3042
- * <code>
3043
- * // Click and drag the mouse to view the scene from different angles.
3044
- *
3045
- * function setup() {
3046
- * createCanvas(100, 100, WEBGL);
3047
- *
3048
- * describe('A red cube drawn on a gray background.');
3049
- * }
3050
- *
3051
- * function draw() {
3052
- * background(200);
3053
- *
3054
- * // Enable orbiting with the mouse.
3055
- * orbitControl();
3056
- *
3057
- * // Turn on a magenta ambient light.
3058
- * ambientLight(255, 0, 255);
3059
- *
3060
- * // Add a yellow ambient material using a color string.
3061
- * ambientMaterial('yellow');
3062
- *
3063
- * // Draw the box.
3064
- * box();
3065
- * }
3066
- * </code>
3067
- * </div>
3068
- *
3069
- * <div>
3070
- * <code>
3071
- * // Click and drag the mouse to view the scene from different angles.
3072
- *
3073
- * function setup() {
3074
- * createCanvas(100, 100, WEBGL);
3075
- *
3076
- * describe('A yellow cube drawn on a gray background.');
3077
- * }
3078
- *
3079
- * function draw() {
3080
- * background(200);
3081
- *
3082
- * // Enable orbiting with the mouse.
3083
- * orbitControl();
3084
- *
3085
- * // Turn on a white ambient light.
3086
- * ambientLight(255, 255, 255);
3087
- *
3088
- * // Add a yellow ambient material using a color string.
3089
- * ambientMaterial('yellow');
3090
- *
3091
- * // Draw the box.
3092
- * box();
3093
- * }
3094
- * </code>
3095
- * </div>
3096
- */
3097
-
3098
- /**
3099
- * @method ambientMaterial
3100
- * @param {Number} gray grayscale value between 0 (black) and 255 (white).
3101
- * @chainable
3102
- */
3103
-
3104
- /**
3105
- * @method ambientMaterial
3106
- * @param {p5.Color|Number[]|String} color
3107
- * color as a <a href="#/p5.Color">p5.Color</a> object,
3108
- * an array of color values, or a CSS string.
3109
- * @chainable
3110
- */
3111
- fn.ambientMaterial = function (v1, v2, v3) {
3112
- this._assert3d('ambientMaterial');
3113
- // p5._validateParameters('ambientMaterial', arguments);
3114
-
3115
- const color = fn.color.apply(this, arguments);
3116
- this._renderer.states.setValue('_hasSetAmbient', true);
3117
- this._renderer.states.setValue('curAmbientColor', color._array);
3118
- this._renderer.states.setValue('_useNormalMaterial', false);
3119
- this._renderer.states.setValue('enableLighting', true);
3120
- if (!this._renderer.states.fillColor) {
3121
- this._renderer.states.setValue('fillColor', new Color([1, 1, 1]));
3122
- }
3123
- return this;
3124
- };
3125
-
3126
- /**
3127
- * Sets the emissive color of shapes’ surface material.
3128
- *
3129
- * The `emissiveMaterial()` color sets a color shapes display at full
3130
- * strength, regardless of lighting. This can give the appearance that a shape
3131
- * is glowing. However, emissive materials don’t actually emit light that
3132
- * can affect surrounding objects.
3133
- *
3134
- * `emissiveMaterial()` can be called three ways with different parameters to
3135
- * set the material’s color.
3136
- *
3137
- * The first way to call `emissiveMaterial()` has one parameter, `gray`.
3138
- * Grayscale values between 0 and 255, as in `emissiveMaterial(50)`, can be
3139
- * passed to set the material’s color. Higher grayscale values make shapes
3140
- * appear brighter.
3141
- *
3142
- * The second way to call `emissiveMaterial()` has one parameter, `color`. A
3143
- * <a href="#/p5.Color">p5.Color</a> object, an array of color values, or a
3144
- * CSS color string, as in `emissiveMaterial('magenta')`, can be passed to set
3145
- * the material’s color.
3146
- *
3147
- * The third way to call `emissiveMaterial()` has four parameters, `v1`, `v2`,
3148
- * `v3`, and `alpha`. `alpha` is optional. RGBA, HSBA, or HSLA values can be
3149
- * passed to set the material’s colors, as in `emissiveMaterial(255, 0, 0)` or
3150
- * `emissiveMaterial(255, 0, 0, 30)`. Color values will be interpreted using
3151
- * the current <a href="#/p5/colorMode">colorMode()</a>.
3152
- *
3153
- * Note: `emissiveMaterial()` can only be used in WebGL mode.
3154
- *
3155
- * @method emissiveMaterial
3156
- * @param {Number} v1 red or hue value in the current
3157
- * <a href="#/p5/colorMode">colorMode()</a>.
3158
- * @param {Number} v2 green or saturation value in the
3159
- * current <a href="#/p5/colorMode">colorMode()</a>.
3160
- * @param {Number} v3 blue, brightness, or lightness value in the
3161
- * current <a href="#/p5/colorMode">colorMode()</a>.
3162
- * @param {Number} [alpha] alpha value in the current
3163
- * <a href="#/p5/colorMode">colorMode()</a>.
3164
- * @chainable
3165
- *
3166
- * @example
3167
- * <div>
3168
- * <code>
3169
- * // Click and drag the mouse to view the scene from different angles.
3170
- *
3171
- * function setup() {
3172
- * createCanvas(100, 100, WEBGL);
3173
- *
3174
- * describe('A red cube drawn on a gray background.');
3175
- * }
3176
- *
3177
- * function draw() {
3178
- * background(200);
3179
- *
3180
- * // Enable orbiting with the mouse.
3181
- * orbitControl();
3182
- *
3183
- * // Turn on a white ambient light.
3184
- * ambientLight(255, 255, 255);
3185
- *
3186
- * // Add a red emissive material using RGB values.
3187
- * emissiveMaterial(255, 0, 0);
3188
- *
3189
- * // Draw the box.
3190
- * box();
3191
- * }
3192
- * </code>
3193
- * </div>
3194
- */
3195
-
3196
- /**
3197
- * @method emissiveMaterial
3198
- * @param {Number} gray grayscale value between 0 (black) and 255 (white).
3199
- * @chainable
3200
- */
3201
-
3202
- /**
3203
- * @method emissiveMaterial
3204
- * @param {p5.Color|Number[]|String} color
3205
- * color as a <a href="#/p5.Color">p5.Color</a> object,
3206
- * an array of color values, or a CSS string.
3207
- * @chainable
3208
- */
3209
- fn.emissiveMaterial = function (v1, v2, v3, a) {
3210
- this._assert3d('emissiveMaterial');
3211
- // p5._validateParameters('emissiveMaterial', arguments);
3212
-
3213
- const color = fn.color.apply(this, arguments);
3214
- this._renderer.states.setValue('curEmissiveColor', color._array);
3215
- this._renderer.states.setValue('_useEmissiveMaterial', true);
3216
- this._renderer.states.setValue('_useNormalMaterial', false);
3217
- this._renderer.states.setValue('enableLighting', true);
3218
-
3219
- return this;
3220
- };
3221
-
3222
- /**
3223
- * Sets the specular color of shapes’ surface material.
3224
- *
3225
- * The `specularMaterial()` color sets the components of light color that
3226
- * glossy coats on shapes will reflect. For example, calling
3227
- * `specularMaterial(255, 255, 0)` would cause a shape to reflect red and
3228
- * green light, but not blue light.
3229
- *
3230
- * Unlike <a href="#/p5/ambientMaterial">ambientMaterial()</a>,
3231
- * `specularMaterial()` will reflect the full color of light sources including
3232
- * <a href="#/p5/directionalLight">directionalLight()</a>,
3233
- * <a href="#/p5/pointLight">pointLight()</a>,
3234
- * and <a href="#/p5/spotLight">spotLight()</a>. This is what gives it shapes
3235
- * their "shiny" appearance. The material’s shininess can be controlled by the
3236
- * <a href="#/p5/shininess">shininess()</a> function.
3237
- *
3238
- * `specularMaterial()` can be called three ways with different parameters to
3239
- * set the material’s color.
3240
- *
3241
- * The first way to call `specularMaterial()` has one parameter, `gray`.
3242
- * Grayscale values between 0 and 255, as in `specularMaterial(50)`, can be
3243
- * passed to set the material’s color. Higher grayscale values make shapes
3244
- * appear brighter.
3245
- *
3246
- * The second way to call `specularMaterial()` has one parameter, `color`. A
3247
- * <a href="#/p5.Color">p5.Color> object, an array of color values, or a CSS
3248
- * color string, as in `specularMaterial('magenta')`, can be passed to set the
3249
- * material’s color.
3250
- *
3251
- * The third way to call `specularMaterial()` has four parameters, `v1`, `v2`,
3252
- * `v3`, and `alpha`. `alpha` is optional. RGBA, HSBA, or HSLA values can be
3253
- * passed to set the material’s colors, as in `specularMaterial(255, 0, 0)` or
3254
- * `specularMaterial(255, 0, 0, 30)`. Color values will be interpreted using
3255
- * the current <a href="#/p5/colorMode">colorMode()</a>.
3256
- *
3257
- * @method specularMaterial
3258
- * @param {Number} gray grayscale value between 0 (black) and 255 (white).
3259
- * @param {Number} [alpha] alpha value in the current current
3260
- * <a href="#/p5/colorMode">colorMode()</a>.
3261
- * @chainable
3262
- *
3263
- * @example
3264
- * <div>
3265
- * <code>
3266
- * // Click and drag the mouse to view the scene from different angles.
3267
- * // Double-click the canvas to apply a specular material.
3268
- *
3269
- * let isGlossy = false;
3270
- *
3271
- * function setup() {
3272
- * createCanvas(100, 100, WEBGL);
3273
- *
3274
- * describe('A red torus drawn on a gray background. It becomes glossy when the user double-clicks.');
3275
- * }
3276
- *
3277
- * function draw() {
3278
- * background(200);
3279
- *
3280
- * // Enable orbiting with the mouse.
3281
- * orbitControl();
3282
- *
3283
- * // Turn on a white point light at the top-right.
3284
- * pointLight(255, 255, 255, 30, -40, 30);
3285
- *
3286
- * // Add a glossy coat if the user has double-clicked.
3287
- * if (isGlossy === true) {
3288
- * specularMaterial(255);
3289
- * shininess(50);
3290
- * }
3291
- *
3292
- * // Style the torus.
3293
- * noStroke();
3294
- * fill(255, 0, 0);
3295
- *
3296
- * // Draw the torus.
3297
- * torus(30);
3298
- * }
3299
- *
3300
- * // Make the torus glossy when the user double-clicks.
3301
- * function doubleClicked() {
3302
- * isGlossy = true;
3303
- * }
3304
- * </code>
3305
- * </div>
3306
- *
3307
- * <div>
3308
- * <code>
3309
- * // Click and drag the mouse to view the scene from different angles.
3310
- * // Double-click the canvas to apply a specular material.
3311
- *
3312
- * let isGlossy = false;
3313
- *
3314
- * function setup() {
3315
- * createCanvas(100, 100, WEBGL);
3316
- *
3317
- * describe(
3318
- * 'A red torus drawn on a gray background. It becomes glossy and reflects green light when the user double-clicks.'
3319
- * );
3320
- * }
3321
- *
3322
- * function draw() {
3323
- * background(200);
3324
- *
3325
- * // Enable orbiting with the mouse.
3326
- * orbitControl();
3327
- *
3328
- * // Turn on a white point light at the top-right.
3329
- * pointLight(255, 255, 255, 30, -40, 30);
3330
- *
3331
- * // Add a glossy green coat if the user has double-clicked.
3332
- * if (isGlossy === true) {
3333
- * specularMaterial(0, 255, 0);
3334
- * shininess(50);
3335
- * }
3336
- *
3337
- * // Style the torus.
3338
- * noStroke();
3339
- * fill(255, 0, 0);
3340
- *
3341
- * // Draw the torus.
3342
- * torus(30);
3343
- * }
3344
- *
3345
- * // Make the torus glossy when the user double-clicks.
3346
- * function doubleClicked() {
3347
- * isGlossy = true;
3348
- * }
3349
- * </code>
3350
- * </div>
3351
- *
3352
- * <div>
3353
- * <code>
3354
- * // Click and drag the mouse to view the scene from different angles.
3355
- * // Double-click the canvas to apply a specular material.
3356
- *
3357
- * let isGlossy = false;
3358
- *
3359
- * function setup() {
3360
- * createCanvas(100, 100, WEBGL);
3361
- *
3362
- * describe(
3363
- * 'A red torus drawn on a gray background. It becomes glossy and reflects green light when the user double-clicks.'
3364
- * );
3365
- * }
3366
- *
3367
- * function draw() {
3368
- * background(200);
3369
- *
3370
- * // Enable orbiting with the mouse.
3371
- * orbitControl();
3372
- *
3373
- * // Turn on a white point light at the top-right.
3374
- * pointLight(255, 255, 255, 30, -40, 30);
3375
- *
3376
- * // Add a glossy green coat if the user has double-clicked.
3377
- * if (isGlossy === true) {
3378
- * // Create a p5.Color object.
3379
- * let c = color('green');
3380
- * specularMaterial(c);
3381
- * shininess(50);
3382
- * }
3383
- *
3384
- * // Style the torus.
3385
- * noStroke();
3386
- * fill(255, 0, 0);
3387
- *
3388
- * // Draw the torus.
3389
- * torus(30);
3390
- * }
3391
- *
3392
- * // Make the torus glossy when the user double-clicks.
3393
- * function doubleClicked() {
3394
- * isGlossy = true;
3395
- * }
3396
- * </code>
3397
- * </div>
3398
- *
3399
- * <div>
3400
- * <code>
3401
- * // Click and drag the mouse to view the scene from different angles.
3402
- * // Double-click the canvas to apply a specular material.
3403
- *
3404
- * let isGlossy = false;
3405
- *
3406
- * function setup() {
3407
- * createCanvas(100, 100, WEBGL);
3408
- *
3409
- * describe(
3410
- * 'A red torus drawn on a gray background. It becomes glossy and reflects green light when the user double-clicks.'
3411
- * );
3412
- * }
3413
- *
3414
- * function draw() {
3415
- * background(200);
3416
- *
3417
- * // Enable orbiting with the mouse.
3418
- * orbitControl();
3419
- *
3420
- * // Turn on a white point light at the top-right.
3421
- * pointLight(255, 255, 255, 30, -40, 30);
3422
- *
3423
- * // Add a glossy green coat if the user has double-clicked.
3424
- * if (isGlossy === true) {
3425
- * specularMaterial('#00FF00');
3426
- * shininess(50);
3427
- * }
3428
- *
3429
- * // Style the torus.
3430
- * noStroke();
3431
- * fill(255, 0, 0);
3432
- *
3433
- * // Draw the torus.
3434
- * torus(30);
3435
- * }
3436
- *
3437
- * // Make the torus glossy when the user double-clicks.
3438
- * function doubleClicked() {
3439
- * isGlossy = true;
3440
- * }
3441
- * </code>
3442
- * </div>
3443
- */
3444
-
3445
- /**
3446
- * @method specularMaterial
3447
- * @param {Number} v1 red or hue value in
3448
- * the current <a href="#/p5/colorMode">colorMode()</a>.
3449
- * @param {Number} v2 green or saturation value
3450
- * in the current <a href="#/p5/colorMode">colorMode()</a>.
3451
- * @param {Number} v3 blue, brightness, or lightness value
3452
- * in the current <a href="#/p5/colorMode">colorMode()</a>.
3453
- * @param {Number} [alpha]
3454
- * @chainable
3455
- */
3456
-
3457
- /**
3458
- * @method specularMaterial
3459
- * @param {p5.Color|Number[]|String} color
3460
- * color as a <a href="#/p5.Color">p5.Color</a> object,
3461
- * an array of color values, or a CSS string.
3462
- * @chainable
3463
- */
3464
- fn.specularMaterial = function (v1, v2, v3, alpha) {
3465
- this._assert3d('specularMaterial');
3466
- // p5._validateParameters('specularMaterial', arguments);
3467
-
3468
- const color = fn.color.apply(this, arguments);
3469
- this._renderer.states.setValue('curSpecularColor', color._array);
3470
- this._renderer.states.setValue('_useSpecularMaterial', true);
3471
- this._renderer.states.setValue('_useNormalMaterial', false);
3472
- this._renderer.states.setValue('enableLighting', true);
3473
-
3474
- return this;
3475
- };
3476
-
3477
- /**
3478
- * Sets the amount of gloss ("shininess") of a
3479
- * <a href="#/p5/specularMaterial">specularMaterial()</a>.
3480
- *
3481
- * Shiny materials focus reflected light more than dull materials.
3482
- * `shininess()` affects the way materials reflect light sources including
3483
- * <a href="#/p5/directionalLight">directionalLight()</a>,
3484
- * <a href="#/p5/pointLight">pointLight()</a>,
3485
- * and <a href="#/p5/spotLight">spotLight()</a>.
3486
- *
3487
- * The parameter, `shine`, is a number that sets the amount of shininess.
3488
- * `shine` must be greater than 1, which is its default value.
3489
- *
3490
- * @method shininess
3491
- * @param {Number} shine amount of shine.
3492
- * @chainable
3493
- *
3494
- * @example
3495
- * <div>
3496
- * <code>
3497
- * function setup() {
3498
- * createCanvas(100, 100, WEBGL);
3499
- *
3500
- * describe(
3501
- * 'Two red spheres drawn on a gray background. White light reflects from their surfaces as the mouse moves. The right sphere is shinier than the left sphere.'
3502
- * );
3503
- * }
3504
- *
3505
- * function draw() {
3506
- * background(200);
3507
- *
3508
- * // Turn on a red ambient light.
3509
- * ambientLight(255, 0, 0);
3510
- *
3511
- * // Get the mouse's coordinates.
3512
- * let mx = mouseX - 50;
3513
- * let my = mouseY - 50;
3514
- *
3515
- * // Turn on a white point light that follows the mouse.
3516
- * pointLight(255, 255, 255, mx, my, 50);
3517
- *
3518
- * // Style the sphere.
3519
- * noStroke();
3520
- *
3521
- * // Add a specular material with a grayscale value.
3522
- * specularMaterial(255);
3523
- *
3524
- * // Draw the left sphere with low shininess.
3525
- * translate(-25, 0, 0);
3526
- * shininess(10);
3527
- * sphere(20);
3528
- *
3529
- * // Draw the right sphere with high shininess.
3530
- * translate(50, 0, 0);
3531
- * shininess(100);
3532
- * sphere(20);
3533
- * }
3534
- * </code>
3535
- * </div>
3536
- */
3537
- fn.shininess = function (shine) {
3538
- this._assert3d('shininess');
3539
- // p5._validateParameters('shininess', arguments);
3540
-
3541
- this._renderer.shininess(shine);
3542
-
3543
- return this;
3544
- };
3545
-
3546
- /**
3547
- * Sets the amount of "metalness" of a
3548
- * <a href="#/p5/specularMaterial">specularMaterial()</a>.
3549
- *
3550
- * `metalness()` can make materials appear more metallic. It affects the way
3551
- * materials reflect light sources including
3552
- * affects the way materials reflect light sources including
3553
- * <a href="#/p5/directionalLight">directionalLight()</a>,
3554
- * <a href="#/p5/pointLight">pointLight()</a>,
3555
- * <a href="#/p5/spotLight">spotLight()</a>, and
3556
- * <a href="#/p5/imageLight">imageLight()</a>.
3557
- *
3558
- * The parameter, `metallic`, is a number that sets the amount of metalness.
3559
- * `metallic` must be greater than 1, which is its default value. Higher
3560
- * values, such as `metalness(100)`, make specular materials appear more
3561
- * metallic.
3562
- *
3563
- * @method metalness
3564
- * @param {Number} metallic amount of metalness.
3565
- *
3566
- * @example
3567
- * <div>
3568
- * <code>
3569
- * function setup() {
3570
- * createCanvas(100, 100, WEBGL);
3571
- *
3572
- * describe(
3573
- * 'Two blue spheres drawn on a gray background. White light reflects from their surfaces as the mouse moves. The right sphere is more metallic than the left sphere.'
3574
- * );
3575
- * }
3576
- *
3577
- * function draw() {
3578
- * background(200);
3579
- *
3580
- * // Turn on an ambient light.
3581
- * ambientLight(200);
3582
- *
3583
- * // Get the mouse's coordinates.
3584
- * let mx = mouseX - 50;
3585
- * let my = mouseY - 50;
3586
- *
3587
- * // Turn on a white point light that follows the mouse.
3588
- * pointLight(255, 255, 255, mx, my, 50);
3589
- *
3590
- * // Style the spheres.
3591
- * noStroke();
3592
- * fill(30, 30, 255);
3593
- * specularMaterial(255);
3594
- * shininess(20);
3595
- *
3596
- * // Draw the left sphere with low metalness.
3597
- * translate(-25, 0, 0);
3598
- * metalness(1);
3599
- * sphere(20);
3600
- *
3601
- * // Draw the right sphere with high metalness.
3602
- * translate(50, 0, 0);
3603
- * metalness(50);
3604
- * sphere(20);
3605
- * }
3606
- * </code>
3607
- * </div>
3608
- *
3609
- * <div>
3610
- * <code>
3611
- * // Click and drag the mouse to view the scene from different angles.
3612
- *
3613
- * let img;
3614
- *
3615
- * async function setup() {
3616
- * img = await loadImage('assets/outdoor_spheremap.jpg');
3617
- *
3618
- * createCanvas(100 ,100 ,WEBGL);
3619
- *
3620
- * describe(
3621
- * 'Two spheres floating above a landscape. The surface of the spheres reflect the landscape. The right sphere is more reflective than the left sphere.'
3622
- * );
3623
- * }
3624
- *
3625
- * function draw() {
3626
- * // Add the panorama.
3627
- * panorama(img);
3628
- *
3629
- * // Enable orbiting with the mouse.
3630
- * orbitControl();
3631
- *
3632
- * // Use the image as a light source.
3633
- * imageLight(img);
3634
- *
3635
- * // Style the spheres.
3636
- * noStroke();
3637
- * specularMaterial(50);
3638
- * shininess(200);
3639
- *
3640
- * // Draw the left sphere with low metalness.
3641
- * translate(-25, 0, 0);
3642
- * metalness(1);
3643
- * sphere(20);
3644
- *
3645
- * // Draw the right sphere with high metalness.
3646
- * translate(50, 0, 0);
3647
- * metalness(50);
3648
- * sphere(20);
3649
- * }
3650
- * </code>
3651
- * </div>
3652
- */
3653
- fn.metalness = function (metallic) {
3654
- this._assert3d('metalness');
3655
-
3656
- this._renderer.metalness(metallic);
3657
-
3658
- return this;
3659
- };
3660
-
3661
-
3662
- /**
3663
- * @private blends colors according to color components.
3664
- * If alpha value is less than 1, or non-standard blendMode
3665
- * we need to enable blending on our gl context.
3666
- * @param {Number[]} color The currently set color, with values in 0-1 range
3667
- * @param {Boolean} [hasTransparency] Whether the shape being drawn has other
3668
- * transparency internally, e.g. via vertex colors
3669
- * @return {Number[]} Normalized numbers array
3670
- */
3671
- RendererGL.prototype._applyColorBlend = function (colors, hasTransparency) {
3672
- const gl = this.GL;
3673
-
3674
- const isTexture = this.states.drawMode === constants.TEXTURE;
3675
- const doBlend =
3676
- hasTransparency ||
3677
- this.states.userFillShader ||
3678
- this.states.userStrokeShader ||
3679
- this.states.userPointShader ||
3680
- isTexture ||
3681
- this.states.curBlendMode !== constants.BLEND ||
3682
- colors[colors.length - 1] < 1.0 ||
3683
- this._isErasing;
3684
-
3685
- if (doBlend !== this._isBlending) {
3686
- if (
3687
- doBlend ||
3688
- (this.states.curBlendMode !== constants.BLEND &&
3689
- this.states.curBlendMode !== constants.ADD)
3690
- ) {
3691
- gl.enable(gl.BLEND);
3692
- } else {
3693
- gl.disable(gl.BLEND);
3694
- }
3695
- gl.depthMask(true);
3696
- this._isBlending = doBlend;
3697
- }
3698
- this._applyBlendMode();
3699
- return colors;
3700
- };
3701
-
3702
- /**
3703
- * @private sets blending in gl context to curBlendMode
3704
- * @param {Number[]} color [description]
3705
- * @return {Number[]} Normalized numbers array
3706
- */
3707
- RendererGL.prototype._applyBlendMode = function () {
3708
- if (this._cachedBlendMode === this.states.curBlendMode) {
3709
- return;
3710
- }
3711
- const gl = this.GL;
3712
- switch (this.states.curBlendMode) {
3713
- case constants.BLEND:
3714
- gl.blendEquation(gl.FUNC_ADD);
3715
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
3716
- break;
3717
- case constants.ADD:
3718
- gl.blendEquation(gl.FUNC_ADD);
3719
- gl.blendFunc(gl.ONE, gl.ONE);
3720
- break;
3721
- case constants.REMOVE:
3722
- gl.blendEquation(gl.FUNC_ADD);
3723
- gl.blendFunc(gl.ZERO, gl.ONE_MINUS_SRC_ALPHA);
3724
- break;
3725
- case constants.MULTIPLY:
3726
- gl.blendEquation(gl.FUNC_ADD);
3727
- gl.blendFunc(gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA);
3728
- break;
3729
- case constants.SCREEN:
3730
- gl.blendEquation(gl.FUNC_ADD);
3731
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_COLOR);
3732
- break;
3733
- case constants.EXCLUSION:
3734
- gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
3735
- gl.blendFuncSeparate(
3736
- gl.ONE_MINUS_DST_COLOR,
3737
- gl.ONE_MINUS_SRC_COLOR,
3738
- gl.ONE,
3739
- gl.ONE
3740
- );
3741
- break;
3742
- case constants.REPLACE:
3743
- gl.blendEquation(gl.FUNC_ADD);
3744
- gl.blendFunc(gl.ONE, gl.ZERO);
3745
- break;
3746
- case constants.SUBTRACT:
3747
- gl.blendEquationSeparate(gl.FUNC_REVERSE_SUBTRACT, gl.FUNC_ADD);
3748
- gl.blendFuncSeparate(gl.ONE, gl.ONE, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
3749
- break;
3750
- case constants.DARKEST:
3751
- if (this.blendExt) {
3752
- gl.blendEquationSeparate(
3753
- this.blendExt.MIN || this.blendExt.MIN_EXT,
3754
- gl.FUNC_ADD
3755
- );
3756
- gl.blendFuncSeparate(gl.ONE, gl.ONE, gl.ONE, gl.ONE);
3757
- } else {
3758
- console.warn(
3759
- 'blendMode(DARKEST) does not work in your browser in WEBGL mode.'
3760
- );
3761
- }
3762
- break;
3763
- case constants.LIGHTEST:
3764
- if (this.blendExt) {
3765
- gl.blendEquationSeparate(
3766
- this.blendExt.MAX || this.blendExt.MAX_EXT,
3767
- gl.FUNC_ADD
3768
- );
3769
- gl.blendFuncSeparate(gl.ONE, gl.ONE, gl.ONE, gl.ONE);
3770
- } else {
3771
- console.warn(
3772
- 'blendMode(LIGHTEST) does not work in your browser in WEBGL mode.'
3773
- );
3774
- }
3775
- break;
3776
- default:
3777
- console.error(
3778
- 'Oops! Somehow RendererGL set curBlendMode to an unsupported mode.'
3779
- );
3780
- break;
3781
- }
3782
- this._cachedBlendMode = this.states.curBlendMode;
3783
- };
3784
-
3785
- RendererGL.prototype.shader = function(s) {
3786
- // Always set the shader as a fill shader
3787
- this.states.setValue('userFillShader', s);
3788
- this.states.setValue('_useNormalMaterial', false);
3789
- s.ensureCompiledOnContext(this);
3790
- s.setDefaultUniforms();
3791
- }
3792
-
3793
- RendererGL.prototype.strokeShader = function(s) {
3794
- this.states.setValue('userStrokeShader', s);
3795
- s.ensureCompiledOnContext(this);
3796
- s.setDefaultUniforms();
3797
- }
3798
-
3799
- RendererGL.prototype.imageShader = function(s) {
3800
- this.states.setValue('userImageShader', s);
3801
- s.ensureCompiledOnContext(this);
3802
- s.setDefaultUniforms();
3803
- }
3804
-
3805
- RendererGL.prototype.resetShader = function() {
3806
- this.states.setValue('userFillShader', null);
3807
- this.states.setValue('userStrokeShader', null);
3808
- this.states.setValue('userImageShader', null);
3809
- }
3810
-
3811
- RendererGL.prototype.texture = function(tex) {
3812
- this.states.setValue('drawMode', constants.TEXTURE);
3813
- this.states.setValue('_useNormalMaterial', false);
3814
- this.states.setValue('_tex', tex);
3815
- this.states.setValue('fillColor', new Color([1, 1, 1]));
3816
- };
3817
-
3818
- RendererGL.prototype.normalMaterial = function(...args) {
3819
- this.states.setValue('drawMode', constants.FILL);
3820
- this.states.setValue('_useSpecularMaterial', false);
3821
- this.states.setValue('_useEmissiveMaterial', false);
3822
- this.states.setValue('_useNormalMaterial', true);
3823
- this.states.setValue('curFillColor', [1, 1, 1, 1]);
3824
- this.states.setValue('fillColor', new Color([1, 1, 1]));
3825
- this.states.setValue('strokeColor', null);
3826
- }
3827
-
3828
- // RendererGL.prototype.ambientMaterial = function(v1, v2, v3) {
3829
- // }
3830
-
3831
- // RendererGL.prototype.emissiveMaterial = function(v1, v2, v3, a) {
3832
- // }
3833
-
3834
- // RendererGL.prototype.specularMaterial = function(v1, v2, v3, alpha) {
3835
- // }
3836
-
3837
- RendererGL.prototype.shininess = function(shine) {
3838
- if (shine < 1) {
3839
- shine = 1;
3840
- }
3841
- this.states.setValue('_useShininess', shine);
3842
- }
3843
-
3844
- RendererGL.prototype.metalness = function(metallic) {
3845
- const metalMix = 1 - Math.exp(-metallic / 100);
3846
- this.states.setValue('_useMetalness', metalMix);
3847
- }
3848
- }
3849
-
3850
- export default material;
3851
-
3852
- if(typeof p5 !== 'undefined'){
3853
- loading(p5, p5.prototype);
3854
- }