(shader, src, shaderType)
| 399 | } |
| 400 | |
| 401 | export function populateGLSLHooks(shader, src, shaderType) { |
| 402 | const main = "void main"; |
| 403 | if (!src.includes(main)) return src; |
| 404 | |
| 405 | let [preMain, postMain] = src.split(main); |
| 406 | |
| 407 | let hooks = ""; |
| 408 | let defines = ""; |
| 409 | for (const key in shader.hooks.uniforms) { |
| 410 | hooks += `uniform ${key};\n`; |
| 411 | } |
| 412 | if (shader.hooks.declarations) { |
| 413 | hooks += shader.hooks.declarations + "\n"; |
| 414 | } |
| 415 | if (shader.hooks[shaderType].declarations) { |
| 416 | hooks += shader.hooks[shaderType].declarations + "\n"; |
| 417 | } |
| 418 | |
| 419 | // Handle varying variables from p5.strands |
| 420 | if ( |
| 421 | shader.hooks.varyingVariables && |
| 422 | shader.hooks.varyingVariables.length > 0 |
| 423 | ) { |
| 424 | for (const varyingVar of shader.hooks.varyingVariables) { |
| 425 | // Generate OUT declaration for vertex shader, IN declaration for fragment shader |
| 426 | if (shaderType === "vertex") { |
| 427 | hooks += `OUT ${varyingVar};\n`; |
| 428 | } else if (shaderType === "fragment") { |
| 429 | hooks += `IN ${varyingVar};\n`; |
| 430 | } |
| 431 | } |
| 432 | } |
| 433 | |
| 434 | // Handle instanceID varying for fragment access |
| 435 | if (shader.hooks.instanceIDVarying) { |
| 436 | const { declaration, source, interpolation } = shader.hooks.instanceIDVarying; |
| 437 | const qualifier = interpolation ? `${interpolation} ` : ''; |
| 438 | if (shaderType === "vertex") { |
| 439 | // Emit flat out declaration and inject assignment into main() body |
| 440 | hooks += `${qualifier}OUT ${declaration};\n`; |
| 441 | postMain = postMain.replace(/\{/, `{\n ${declaration.split(' ').pop()} = ${source};`); |
| 442 | } else if (shaderType === "fragment") { |
| 443 | hooks += `${qualifier}IN ${declaration};\n`; |
| 444 | } |
| 445 | } |
| 446 | |
| 447 | for (const hookDef in shader.hooks.helpers) { |
| 448 | hooks += `${hookDef}${shader.hooks.helpers[hookDef]}\n`; |
| 449 | } |
| 450 | for (const hookDef in shader.hooks[shaderType]) { |
| 451 | if (hookDef === "declarations") continue; |
| 452 | const [hookType, hookName] = hookDef.split(" "); |
| 453 | |
| 454 | // Add a #define so that if the shader wants to use preprocessor directives to |
| 455 | // optimize away the extra function calls in main, it can do so |
| 456 | if ( |
| 457 | shader.hooks.modified.vertex[hookDef] || |
| 458 | shader.hooks.modified.fragment[hookDef] |
no test coverage detected