@@ -211,12 +211,21 @@ p5.prototype.loadShader = function (
211
211
* ```
212
212
*
213
213
* Then, in your vertex shader source, you can run a hook by calling a function
214
- * with the same name prefixed by `HOOK_`:
214
+ * with the same name prefixed by `HOOK_`. If you want to check if the default
215
+ * hook has been replaced, maybe to avoid extra overhead, you can check if the
216
+ * same name prefixed by `AUGMENTED_HOOK_` has been defined:
215
217
*
216
218
* ```glsl
217
219
* void main() {
220
+ * // In most cases, just calling the hook is fine:
218
221
* HOOK_beforeVertex();
219
- * // Add the rest ofy our shader code here!
222
+ *
223
+ * // Alternatively, for more efficiency:
224
+ * #ifdef AUGMENTED_HOOK_beforeVertex
225
+ * HOOK_beforeVertex();
226
+ * #endif
227
+ *
228
+ * // Add the rest of your shader code here!
220
229
* }
221
230
* ```
222
231
*
@@ -453,6 +462,75 @@ p5.prototype.loadShader = function (
453
462
* }
454
463
* </code>
455
464
* </div>
465
+ *
466
+ * <div>
467
+ * <code>
468
+ * // A shader with hooks.
469
+ * let myShader;
470
+ *
471
+ * // A shader with modified hooks.
472
+ * let modifiedShader;
473
+ *
474
+ * // Create a string with the vertex shader program.
475
+ * // The vertex shader is called for each vertex.
476
+ * let vertSrc = `
477
+ * precision highp float;
478
+ * uniform mat4 uModelViewMatrix;
479
+ * uniform mat4 uProjectionMatrix;
480
+ *
481
+ * attribute vec3 aPosition;
482
+ * attribute vec2 aTexCoord;
483
+ *
484
+ * void main() {
485
+ * vec4 positionVec4 = vec4(aPosition, 1.0);
486
+ * gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;
487
+ * }
488
+ * `;
489
+ *
490
+ * // Create a fragment shader that uses a hook.
491
+ * let fragSrc = `
492
+ * precision highp float;
493
+ * void main() {
494
+ * // Let users override the color
495
+ * gl_FragColor = HOOK_getColor(vec4(1., 0., 0., 1.));
496
+ * }
497
+ * `;
498
+ *
499
+ * function setup() {
500
+ * createCanvas(50, 50, WEBGL);
501
+ *
502
+ * // Create a shader with hooks
503
+ * myShader = createShader(vertSrc, fragSrc, {
504
+ * fragment: {
505
+ * 'vec4 getColor': '(vec4 color) { return color; }'
506
+ * }
507
+ * });
508
+ *
509
+ * // Make a version of the shader with a hook overridden
510
+ * modifiedShader = myShader.modify({
511
+ * 'vec4 getColor': `(vec4 color) {
512
+ * return vec4(0., 0., 1., 1.);
513
+ * }`
514
+ * });
515
+ * }
516
+ *
517
+ * function draw() {
518
+ * noStroke();
519
+ *
520
+ * push();
521
+ * shader(myShader);
522
+ * translate(-width/3, 0);
523
+ * sphere(10);
524
+ * pop();
525
+ *
526
+ * push();
527
+ * shader(modifiedShader);
528
+ * translate(width/3, 0);
529
+ * sphere(10);
530
+ * pop();
531
+ * }
532
+ * </code>
533
+ * </div>
456
534
*/
457
535
p5 . prototype . createShader = function ( vertSrc , fragSrc , options ) {
458
536
p5 . _validateParameters ( 'createShader' , arguments ) ;
@@ -841,6 +919,9 @@ p5.prototype.shader = function (s) {
841
919
* - `vec4 getFinalColor`: Update the final color after mixing. It takes in a `vec4 color` and must return a modified version.
842
920
* - `void afterFragment`: Called at the end of the fragment shader.
843
921
*
922
+ * Most of the time, you will need to write your hooks in GLSL ES version 300. If you
923
+ * are using WebGL 1 instead of 2, write your hooks in GLSL ES 100 instead.
924
+ *
844
925
* Call `materialShader().inspectHooks()` to see all the possible hooks and
845
926
* their default implementations.
846
927
*
@@ -883,6 +964,41 @@ p5.prototype.shader = function (s) {
883
964
* function setup() {
884
965
* createCanvas(200, 200, WEBGL);
885
966
* myShader = materialShader().modify({
967
+ * declarations: 'vec3 myNormal;',
968
+ * 'Inputs getPixelInputs': `(Inputs inputs) {
969
+ * myNormal = inputs.normal;
970
+ * return inputs;
971
+ * }`,
972
+ * 'vec4 getFinalColor': `(vec4 color) {
973
+ * return mix(
974
+ * vec4(1.0, 1.0, 1.0, 1.0),
975
+ * color,
976
+ * abs(dot(myNormal, vec3(0.0, 0.0, 1.0)))
977
+ * );
978
+ * }`
979
+ * });
980
+ * }
981
+ *
982
+ * function draw() {
983
+ * background(255);
984
+ * rotateY(millis() * 0.001);
985
+ * shader(myShader);
986
+ * lights();
987
+ * noStroke();
988
+ * fill('red');
989
+ * torus(30);
990
+ * }
991
+ * </code>
992
+ * </div>
993
+ *
994
+ * @example
995
+ * <div modernizr='webgl'>
996
+ * <code>
997
+ * let myShader;
998
+ *
999
+ * function setup() {
1000
+ * createCanvas(200, 200, WEBGL);
1001
+ * myShader = materialShader().modify({
886
1002
* 'Inputs getPixelInputs': `(Inputs inputs) {
887
1003
* vec3 newNormal = inputs.normal;
888
1004
* // Simple bump mapping: adjust the normal based on position
@@ -943,6 +1059,9 @@ p5.prototype.materialShader = function() {
943
1059
* - `vec4 getFinalColor`: Update the final color after mixing. It takes in a `vec4 color` and must return a modified version.
944
1060
* - `void afterFragment`: Called at the end of the fragment shader.
945
1061
*
1062
+ * Most of the time, you will need to write your hooks in GLSL ES version 300. If you
1063
+ * are using WebGL 1 instead of 2, write your hooks in GLSL ES 100 instead.
1064
+ *
946
1065
* Call `normalShader().inspectHooks()` to see all the possible hooks and
947
1066
* their default implementations.
948
1067
*
@@ -1030,6 +1149,9 @@ p5.prototype.normalShader = function() {
1030
1149
* - `vec4 getFinalColor`: Update the final color after mixing. It takes in a `vec4 color` and must return a modified version.
1031
1150
* - `void afterFragment`: Called at the end of the fragment shader.
1032
1151
*
1152
+ * Most of the time, you will need to write your hooks in GLSL ES version 300. If you
1153
+ * are using WebGL 1 instead of 2, write your hooks in GLSL ES 100 instead.
1154
+ *
1033
1155
* Call `colorShader().inspectHooks()` to see all the possible hooks and
1034
1156
* their default implementations.
1035
1157
*
@@ -1092,6 +1214,9 @@ p5.prototype.colorShader = function() {
1092
1214
* - `vec4 getFinalColor`: Update the final color after mixing. It takes in a `vec4 color` and must return a modified version.
1093
1215
* - `void afterFragment`: Called at the end of the fragment shader.
1094
1216
*
1217
+ * Most of the time, you will need to write your hooks in GLSL ES version 300. If you
1218
+ * are using WebGL 1 instead of 2, write your hooks in GLSL ES 100 instead.
1219
+ *
1095
1220
* Call `strokeShader().inspectHooks()` to see all the possible hooks and
1096
1221
* their default implementations.
1097
1222
*
0 commit comments