我开始着手编写着色器,并且使用 THREE.js 构建 OpenGL 场景以便使用用 GLSL 编写的着色器非常方便。到目前为止,我一直将 GLSL 代码包含在主 HTML 文件内的脚本字段中:
<html>
<head>
<meta charset=uft-8>
<title>Babby's first three.js app</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="js/three.js"></script>
<script id="fragShader" type="shader-code">
// GLSL shader goes here!
void main(){
/* shader body */
}
</script>
<script>
// Three.js scene setup goes here
// Get shader code from fragShader script element
var shaderCode = document.getElementById("fragShader").innerHTML;
// Apply it to a material
bufferMaterial = new THREE.ShaderMaterial({
uniforms : {
bufferTexture : {type : "t", value : textureA},
},
fragmentShader : shaderCode
});
// Render everything
</script>
</body>
我正在开发一个更复杂的着色器项目,并且希望将主 html 文件分开,以便着色器代码可以保持独立,但我发现这非常难以做到。
我尝试使用 jquery 读取存储在单独文本文件中的着色器代码(我正在运行本地服务器):
<script src ="node_modules/jquery/dist/jquery.js"></script>
<script>
$(function(){
$("#fragShader").load("mainShader.html"); // contains GLSL code
});
</script>
<script id="fragShader"></script>
但是着色器无法编译 - fragment ERROR: Missing main()
.
非常感谢对这个 js 新手的任何帮助!
最佳答案
我经常创建一个单独的 js 文件,其中包含以下形式的对象:
var customShaderObject = {
fragmentShader: /* code (see below) */
vertexShader: /* code (see below) */
... etc.
}
每个着色器都是一个字符串数组,每个索引代表一行,使用新行作为分隔符在末尾连接,例如
fragmentShader: [
'line 1',
'line 2',
'line 3',
' etc. '
].join('\r\n');
在编辑代码方面,一种更简单的方法是使用模板文字语法(反引号 `)而不是数组,因为这样您基本上可以像多行普通代码一样编辑单个字符串。
这种方法(使用数组和模板文字)还有一个额外的优点,即允许您将值创建为函数,以便您可以在运行时将变量插入着色器的各个部分,例如
fragmentShader: function (bar) {
return [
'float foo = ' + bar.toString() + ';',
'line 2',
'line 3',
' etc. '
].join('\r\n');
}
或使用模板文字:
fragmentShader: function (bar) {
return `
float foo = ${bar.toString()};
line 2
line 3
//etc.
`;
}
然后,您可以通过引用着色器的父对象来调用着色器,就像调用任何其他 JS 对象一样。
关于javascript - 如何将 GLSL 着色器代码包含在主 html 的单独文件中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49340900/