我知道 Three.js 会在您提供的着色器文本前加上一些包含定义等的代码。我不是“魔法”的忠实粉丝,我希望能够看到着色器的最终文本内容Three.js 实际使用的。
我已经看到,在 Three.js 的早期版本中,如果着色器文件(片段着色器的顶点着色器)中存在错误,着色器的整个文本内容都会记录在控制台中,包括所有 prepended Three.js 的代码
我目前正在使用 r148,如果出现错误,控制台中只会记录包含错误的行。
是否删除了在控制台中记录整个着色器文件的功能,或者有什么方法可以启用它?或者,更一般地说,有没有其他方法可以访问每个着色器的实际文本内容?
他们进行更改时遇到了完全相同的问题。我写了这个小脚本来输出整个 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 显示顶点着色器。
它对我有用 r145 和 r150。但请注意,它依赖于 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 的内部工作,而且范围更广。您必须在着色器代码中故意输入错误才能看到它。但这也可能是一个优点,因为与前面的示例相比,您可以直接使用着色器,在前面的示例中您需要引用特定的对象/网格。