在使用 ShaderMaterial 或 RawShaderMaterial (r148) 时,如何查看整个着色器的文本内容,以及 Three.js 的所有前置代码?

问题描述 投票:0回答:1

我知道 Three.js 会在您提供的着色器文本前加上一些包含定义等的代码。我不是“魔法”的忠实粉丝,我希望能够看到着色器的最终文本内容Three.js 实际使用的。

我已经看到,在 Three.js 的早期版本中,如果着色器文件(片段着色器的顶点着色器)中存在错误,着色器的整个文本内容都会记录在控制台中,包括所有 prepended Three.js 的代码

我目前正在使用 r148,如果出现错误,控制台中只会记录包含错误的行。

是否删除了在控制台中记录整个着色器文件的功能,或者有什么方法可以启用它?或者,更一般地说,有没有其他方法可以访问每个着色器的实际文本内容?

three.js shader console.log fragment-shader vertex-shader
1个回答
1
投票

他们进行更改时遇到了完全相同的问题。我写了这个小脚本来输出整个 Three.js 着色器代码:

var Utils = {
    
    init: function(renderer, scene, camera, object) {
        renderer.compile(scene, camera); // Might be unnecessary, the shaders could already be compiled

        window.addEventListener('keydown', function(event) {
            if (event.keyCode == 70) { // F
                Utils.findAndOutputShader(renderer, object, 'fragmentShader', 'Fragment Shader');
            }
            if (event.keyCode == 86) { // V
                Utils.findAndOutputShader(renderer, object, 'vertexShader', 'Vertex Shader');
            }
        }, false);
        
    },
    
    findAndOutputShader: function(renderer, object, shaderIdentifier, shaderName) {
        var programs = renderer.properties.get(object.material).programs;
        for (var program of programs) {
            Utils.outputShader(" ----" + shaderName + " Code----", renderer.getContext().getShaderSource(program[1][shaderIdentifier]));
        }
    },
    
    outputShader: function(prefix, code) {
        code = code.replaceAll("\t", "  ");
        var lines = code.split("\n");
        var linedCode = "";
        var i = 1;
        for (var line of lines) {
            linedCode += (i < 10 ? " " : "") + i + ":\t\t" + line + "\n";
            i++;
        }
        
        var output = prefix + "\n" + linedCode;
        console.log(output);
    }
}

我在绘制循环开始后调用了一次:

Utils.init(renderer, scene, camera, sphere);

哪里

sphere
是我想看其着色器代码的THREE.Mesh对象。然后我可以按 F 显示片段着色器和 V 显示顶点着色器。

它对我有用 r145r150。但请注意,它依赖于 Three.js 的内部结构,因此如果他们更改了它,则需要对其进行更新。仍然。我希望它能帮助您或任何其他想要查看变量和其他可用于 Three.js 着色器编程的前置功能的人。


r151 开始,可以向

onShaderError
添加一个
renderer.debug
回调,这样可以轻松恢复以前显示完整着色器的功能。换句话说,以下将在编译错误时输出 entire 着色器代码:

renderer.debug.onShaderError  = function(gl, program, vs, fs) {

    const parseForErrors = function(gl, shader, name) {
        const errors = gl.getShaderInfoLog(shader).trim();
        const prefix = "Errors in " + name + ":" + "\n\n" + errors;
        
        if (errors !== "") {
            const code = gl.getShaderSource(shader).replaceAll("\t", "  ");
            const lines = code.split("\n");
            var linedCode = "";
            var i = 1;
            for (var line of lines) {
                linedCode += (i < 10 ? " " : "") + i + ":\t\t" + line + "\n";
                i++;
            }
            
            console.error(prefix + "\n" + linedCode);
        }
    }
    
    parseForErrors(gl, vs, 'Vertex Shader');
    parseForErrors(gl, fs, 'Fragment Shader');
};

这个解决方案比之前的解决方案好一点,因为它不再依赖 Three.js 的内部工作,而且范围更广。您必须在着色器代码中故意输入错误才能看到它。但这也可能是一个优点,因为与前面的示例相比,您可以直接使用着色器,在前面的示例中您需要引用特定的对象/网格。

© www.soinside.com 2019 - 2024. All rights reserved.