如何在 Processing 3.x 中模块化着色器

How to modularize shaders in Processing 3.x

我想在各种 .glsl 文件中使用相同的噪声函数,而不是每次都复制和粘贴代码。 实现的处理方式是什么?

Afaik,无法在处理中动态执行此操作。但是,您可以使用 glslify 单独编译着色器,这是一个 GLSL compile-time 包含系统。

不过,

glslify (https://github.com/glslify/glslify) 有点矫枉过正。每当我制作 OpenGL / GLSL 应用程序时,我都会推出自己的系统。 像这样的东西(取自我的 Java OpenGL Minecraft 克隆 here):

    private static String process(String code){
        String[]lines=code.split("\n");
        for(int i=0;i<lines.length;i++){
            if(lines[i].startsWith("#include : ")){
                lines[i]=process(Utils.loadFile("path_to_include_directory/"+lines[i].replace("#include : ","")+".glsl"));
            }
        }
        StringBuilder str= new StringBuilder();
        for(String s:lines){
            str.append(s).append("\n");
        }
        return str.toString();
    }

此代码对包含执行 copy-paste。用法:

///// MAIN FILE
#include : bar_module

float foo(vec3 p){
    return bar(p * 5.0);
}
///// path_to_include_directory/bar_module.glsl
float bar(vec3 p) {
    /* ... ... */
}

这是一种在运行时相当有效的递归包含机制。无需静态编译! 唯一的缺点是没有检测到循环依赖。但是无论如何你都不应该处于循环依赖的情况:)

免责声明 我实际上不记得这些东西是如何工作的,但我认为这是一般的想法:

File file=new File("my_shader.vert");
file.setContents(process(file.readContents()));

PShader my_shader=new PShader("my_shader");

注意:setContentsreadContents 实际上并不存在,但你明白了:)

PS Utils.loadFile returns 作为字符串传入的文件名的内容。