我开始着手编写着色器,使用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()
。
非常感谢任何对这个新手的帮助!
答案 0 :(得分:1)
我经常创建一个单独的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对象一样。