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.
- package/{src → dist}/accessibility/color_namer.js +48 -3
- package/{src → dist}/accessibility/describe.js +12 -2
- package/{src → dist}/accessibility/gridOutput.js +2 -2
- package/dist/accessibility/index.js +60 -0
- package/{src → dist}/accessibility/outputs.js +23 -2
- package/{src → dist}/accessibility/textOutput.js +2 -2
- package/dist/app.js +120 -0
- package/{src → dist}/color/color_conversion.js +48 -10
- package/{src → dist}/color/color_spaces/hsb.js +3 -1
- package/dist/color/creating_reading.js +3 -0
- package/dist/color/index.js +13 -0
- package/dist/color/p5.Color.culori.js +1 -0
- package/dist/color/p5.Color.js +3 -0
- package/{src → dist}/color/setting.js +9 -6
- package/{src/core/constants.js → dist/constants-tYr0tCl8.js} +284 -132
- package/{src → dist}/core/States.js +3 -1
- package/dist/core/constants.js +1 -0
- package/{src → dist}/core/environment.js +12 -10
- package/{src → dist}/core/friendly_errors/browser_errors.js +1 -1
- package/{src → dist}/core/friendly_errors/fes_core.js +14 -44
- package/{src → dist}/core/friendly_errors/file_errors.js +6 -3
- package/dist/core/friendly_errors/index.js +23 -0
- package/dist/core/friendly_errors/param_validator.js +5421 -0
- package/{src → dist}/core/friendly_errors/sketch_reader.js +50 -4
- package/{src → dist}/core/friendly_errors/sketch_verifier.js +6 -6
- package/{src → dist}/core/friendly_errors/stacktrace.js +3 -5
- package/{src → dist}/core/friendly_errors/validate_params.js +50 -41
- package/{src → dist}/core/helpers.js +9 -6
- package/dist/core/init.js +105 -0
- package/dist/core/internationalization.js +302 -0
- package/dist/core/legacy.js +73 -0
- package/dist/core/main.js +44 -0
- package/dist/core/noop.js +3 -0
- package/dist/core/p5.Graphics.js +40 -0
- package/dist/core/p5.Renderer.js +11 -0
- package/dist/core/p5.Renderer2D.js +44 -0
- package/dist/core/reference.js +1 -0
- package/dist/core/rendering.js +40 -0
- package/{src → dist}/core/structure.js +3 -3
- package/{src → dist}/core/transform.js +2 -2
- package/{src/color/creating_reading.js → dist/creating_reading-Cr8L2Jnm.js} +841 -13
- package/{src → dist}/data/index.js +3 -1
- package/{src → dist}/data/local_storage.js +2 -8
- package/{src → dist}/dom/dom.js +19 -13
- package/dist/dom/index.js +18 -0
- package/{src → dist}/dom/p5.Element.js +14 -12
- package/{src → dist}/dom/p5.File.js +4 -4
- package/{src → dist}/dom/p5.MediaElement.js +10 -4
- package/{src → dist}/events/acceleration.js +26 -26
- package/{src → dist}/events/index.js +3 -1
- package/{src → dist}/events/keyboard.js +14 -12
- package/{src → dist}/events/pointer.js +16 -17
- package/dist/image/const.js +9 -0
- package/{src → dist}/image/filterRenderer2D.js +57 -37
- package/{src → dist}/image/filters.js +1 -3
- package/dist/image/image.js +40 -0
- package/dist/image/index.js +51 -0
- package/dist/image/loading_displaying.js +40 -0
- package/dist/image/p5.Image.js +11 -0
- package/{src → dist}/image/pixels.js +5 -3
- package/{src → dist}/io/csv.js +72 -70
- package/dist/io/files.js +40 -0
- package/dist/io/index.js +51 -0
- package/{src → dist}/io/p5.Table.js +6 -6
- package/{src → dist}/io/p5.TableRow.js +5 -6
- package/{src → dist}/io/p5.XML.js +2 -5
- package/{src → dist}/io/utilities.js +1 -1
- package/{src/core/p5.Renderer2D.js → dist/main-CAxvgiOV.js} +738 -57
- package/{src → dist}/math/Matrices/Matrix.js +10 -8
- package/{src → dist}/math/Matrices/MatrixInterface.js +5 -3
- package/{src → dist}/math/Matrices/MatrixNumjs.js +12 -26
- package/{src → dist}/math/calculation.js +2 -2
- package/{src → dist}/math/index.js +6 -3
- package/{src → dist}/math/math.js +3 -3
- package/{src → dist}/math/noise.js +2 -2
- package/{src → dist}/math/p5.Matrix.js +7 -4
- package/{src → dist}/math/p5.Vector.js +6 -6
- package/{src → dist}/math/random.js +2 -2
- package/{src → dist}/math/trigonometry.js +16 -15
- package/{src/image/p5.Image.js → dist/p5.Renderer-Swjl9HQO.js} +393 -22
- package/dist/rendering-B5TRR7aY.js +24960 -0
- package/{src → dist}/shape/2d_primitives.js +18 -17
- package/{src → dist}/shape/attributes.js +18 -17
- package/{src → dist}/shape/curves.js +2 -2
- package/{src → dist}/shape/custom_shapes.js +44 -64
- package/{src → dist}/shape/index.js +10 -2
- package/{src → dist}/shape/vertex.js +2 -3
- package/dist/type/index.js +25 -0
- package/{src → dist}/type/lib/Typr.js +76 -94
- package/{src → dist}/type/p5.Font.js +37 -63
- package/{src → dist}/type/textCore.js +35 -58
- package/{src → dist}/type/unicodeRanges.js +3 -1
- package/{src → dist}/utilities/conversion.js +2 -2
- package/{src → dist}/utilities/index.js +3 -1
- package/{src → dist}/utilities/time_date.js +6 -7
- package/{src → dist}/utilities/utility_functions.js +2 -2
- package/dist/webgl/3d_primitives.js +40 -0
- package/{src → dist}/webgl/GeometryBufferCache.js +3 -1
- package/{src → dist}/webgl/GeometryBuilder.js +12 -8
- package/{src → dist}/webgl/ShaderGenerator.js +79 -82
- package/{src → dist}/webgl/ShapeBuilder.js +26 -23
- package/dist/webgl/index.js +76 -0
- package/{src → dist}/webgl/interaction.js +7 -6
- package/dist/webgl/light.js +40 -0
- package/{src → dist}/webgl/loading.js +45 -12
- package/dist/webgl/material.js +40 -0
- package/dist/webgl/p5.Camera.js +40 -0
- package/{src → dist}/webgl/p5.DataArray.js +3 -5
- package/dist/webgl/p5.Framebuffer.js +40 -0
- package/{src → dist}/webgl/p5.Geometry.js +12 -15
- package/{src → dist}/webgl/p5.Quat.js +5 -4
- package/{src → dist}/webgl/p5.RenderBuffer.js +2 -3
- package/dist/webgl/p5.RendererGL.js +40 -0
- package/dist/webgl/p5.Shader.js +40 -0
- package/dist/webgl/p5.Texture.js +40 -0
- package/{src → dist}/webgl/text.js +78 -38
- package/lib/p5.esm.js +296 -194
- package/lib/p5.js +296 -194
- package/lib/p5.min.js +1 -1
- package/package.json +17 -17
- package/translations/dev.js +6 -6
- package/translations/index.js +1 -1
- package/types/accessibility/color_namer.d.ts +8 -0
- package/types/accessibility/describe.d.ts +184 -0
- package/types/accessibility/gridOutput.d.ts +8 -0
- package/types/accessibility/outputs.d.ts +235 -0
- package/types/accessibility/textOutput.d.ts +8 -0
- package/types/color/color_conversion.d.ts +47 -0
- package/types/color/creating_reading.d.ts +1348 -0
- package/types/color/p5.Color.d.ts +1070 -0
- package/types/color/setting.d.ts +2085 -0
- package/types/core/constants.d.ts +341 -0
- package/types/core/environment.d.ts +668 -0
- package/types/core/friendly_errors/fes_core.d.ts +8 -0
- package/types/core/friendly_errors/file_errors.d.ts +8 -0
- package/types/core/friendly_errors/param_validator.d.ts +30 -0
- package/types/core/friendly_errors/sketch_reader.d.ts +8 -0
- package/types/core/friendly_errors/stacktrace.d.ts +11 -0
- package/types/core/friendly_errors/validate_params.d.ts +8 -0
- package/types/core/helpers.d.ts +8 -0
- package/types/core/legacy.d.ts +8 -0
- package/types/core/main.d.ts +5996 -0
- package/types/core/p5.Graphics.d.ts +484 -0
- package/types/core/p5.Renderer.d.ts +14 -0
- package/types/core/reference.d.ts +8 -0
- package/types/core/rendering.d.ts +481 -0
- package/types/core/structure.d.ts +492 -0
- package/types/core/transform.d.ts +1638 -0
- package/types/data/local_storage.d.ts +323 -0
- package/types/dom/dom.d.ts +1295 -0
- package/types/dom/p5.Element.d.ts +2011 -0
- package/types/dom/p5.File.d.ts +13 -0
- package/types/dom/p5.MediaElement.d.ts +1249 -0
- package/types/events/acceleration.d.ts +193 -0
- package/types/events/keyboard.d.ts +499 -0
- package/types/events/pointer.d.ts +782 -0
- package/types/global.d.ts +5542 -0
- package/types/image/filterRenderer2D.d.ts +54 -0
- package/types/image/image.d.ts +326 -0
- package/types/image/loading_displaying.d.ts +580 -0
- package/types/image/p5.Image.d.ts +5882 -0
- package/types/image/pixels.d.ts +832 -0
- package/types/io/files.d.ts +1447 -0
- package/types/io/p5.Table.d.ts +1247 -0
- package/types/io/p5.TableRow.d.ts +343 -0
- package/types/io/p5.XML.d.ts +1188 -0
- package/types/math/Matrices/Matrix.d.ts +1029 -0
- package/types/math/Matrices/MatrixNumjs.d.ts +8 -0
- package/types/math/calculation.d.ts +923 -0
- package/types/math/math.d.ts +90 -0
- package/types/math/noise.d.ts +311 -0
- package/types/math/p5.Matrix.d.ts +8 -0
- package/types/math/p5.Vector.d.ts +3416 -0
- package/types/math/random.d.ts +267 -0
- package/types/math/trigonometry.d.ts +663 -0
- package/types/p5.d.ts +6663 -0
- package/types/shape/2d_primitives.d.ts +1033 -0
- package/types/shape/attributes.d.ts +466 -0
- package/types/shape/curves.d.ts +740 -0
- package/types/shape/custom_shapes.d.ts +888 -0
- package/types/shape/vertex.d.ts +1141 -0
- package/types/type/p5.Font.d.ts +575 -0
- package/types/type/textCore.d.ts +1198 -0
- package/types/utilities/conversion.d.ts +894 -0
- package/types/utilities/time_date.d.ts +295 -0
- package/types/utilities/utility_functions.d.ts +587 -0
- package/types/webgl/3d_primitives.d.ts +1432 -0
- package/types/webgl/ShaderGenerator.d.ts +8 -0
- package/types/webgl/interaction.d.ts +371 -0
- package/types/webgl/light.d.ts +1184 -0
- package/types/webgl/loading.d.ts +481 -0
- package/types/webgl/material.d.ts +2656 -0
- package/types/webgl/p5.Camera.d.ts +3023 -0
- package/types/webgl/p5.DataArray.d.ts +61 -0
- package/types/webgl/p5.Framebuffer.d.ts +760 -0
- package/types/webgl/p5.Geometry.d.ts +1191 -0
- package/types/webgl/p5.Quat.d.ts +45 -0
- package/types/webgl/p5.RendererGL.d.ts +234 -0
- package/types/webgl/p5.Shader.d.ts +660 -0
- package/types/webgl/p5.Texture.d.ts +61 -0
- package/types/webgl/text.d.ts +74 -0
- package/src/README.md +0 -27
- package/src/accessibility/index.js +0 -13
- package/src/app.js +0 -61
- package/src/color/index.js +0 -9
- package/src/color/p5.Color.culori.js +0 -66
- package/src/color/p5.Color.js +0 -851
- package/src/core/README.md +0 -91
- package/src/core/friendly_errors/index.js +0 -13
- package/src/core/friendly_errors/param_validator.js +0 -561
- package/src/core/init.js +0 -58
- package/src/core/internationalization.js +0 -195
- package/src/core/legacy.js +0 -29
- package/src/core/main.js +0 -689
- package/src/core/noop.js +0 -1
- package/src/core/p5.Graphics.js +0 -696
- package/src/core/p5.Renderer.js +0 -408
- package/src/core/reference.js +0 -2060
- package/src/core/rendering.js +0 -697
- package/src/dom/index.js +0 -11
- package/src/image/const.js +0 -6
- package/src/image/image.js +0 -731
- package/src/image/index.js +0 -15
- package/src/image/loading_displaying.js +0 -1431
- package/src/io/files.js +0 -2210
- package/src/io/index.js +0 -11
- package/src/math/README.md +0 -40
- package/src/type/index.js +0 -9
- package/src/webgl/3d_primitives.js +0 -2741
- package/src/webgl/index.js +0 -37
- package/src/webgl/light.js +0 -1851
- package/src/webgl/material.js +0 -3854
- package/src/webgl/p5.Camera.js +0 -4010
- package/src/webgl/p5.Framebuffer.js +0 -1865
- package/src/webgl/p5.RendererGL.js +0 -2867
- package/src/webgl/p5.Shader.js +0 -1505
- package/src/webgl/p5.Texture.js +0 -541
- package/src/webgl/shaders/basic.frag +0 -6
- package/src/webgl/shaders/filters/base.frag +0 -22
- package/src/webgl/shaders/filters/base.vert +0 -19
- package/src/webgl/shaders/filters/blur.frag +0 -60
- package/src/webgl/shaders/filters/default.vert +0 -18
- package/src/webgl/shaders/filters/dilate.frag +0 -39
- package/src/webgl/shaders/filters/erode.frag +0 -39
- package/src/webgl/shaders/filters/gray.frag +0 -16
- package/src/webgl/shaders/filters/invert.frag +0 -15
- package/src/webgl/shaders/filters/opaque.frag +0 -12
- package/src/webgl/shaders/filters/posterize.frag +0 -29
- package/src/webgl/shaders/filters/threshold.frag +0 -23
- package/src/webgl/shaders/font.frag +0 -216
- package/src/webgl/shaders/font.vert +0 -44
- package/src/webgl/shaders/imageLight.vert +0 -33
- package/src/webgl/shaders/imageLightDiffused.frag +0 -82
- package/src/webgl/shaders/imageLightSpecular.frag +0 -134
- package/src/webgl/shaders/light.vert +0 -37
- package/src/webgl/shaders/light_texture.frag +0 -26
- package/src/webgl/shaders/lighting.glsl +0 -227
- package/src/webgl/shaders/line.frag +0 -74
- package/src/webgl/shaders/line.vert +0 -294
- package/src/webgl/shaders/normal.frag +0 -6
- package/src/webgl/shaders/normal.vert +0 -72
- package/src/webgl/shaders/phong.frag +0 -84
- package/src/webgl/shaders/phong.vert +0 -87
- package/src/webgl/shaders/point.frag +0 -29
- package/src/webgl/shaders/point.vert +0 -19
- package/src/webgl/shaders/sphereMapping.frag +0 -26
- package/src/webgl/shaders/webgl2Compatibility.glsl +0 -34
package/src/webgl/material.js
DELETED
|
@@ -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
|
-
}
|