是否有一种方法可以将此着色器代码作为外部 vertexShader.js 而不加引号并将其包含在“ script”标记之间?
var vertCode =
'attribute vec3 coordinates;' +
'void main(void) {' +
' gl_Position = vec4(coordinates, 1.0);' +
'gl_PointSize = 10.0;'+
'}';
答案 0 :(得分:3)
您可以将着色器代码添加到用于顶点着色器的<script>
类型的"x-shader/x-vertex"
标签和用于片段着色器的"x-shader/x-fragment"
中。
另请参见WebGL and HTML shader-type
<script id="my_vertex_shader" type="x-shader/x-vertex">
attribute vec3 coordinates;
void main(void) {
gl_Position = vec4(coordinates, 1.0);
gl_PointSize = 10.0;'
}
</script>
<script id="my_fragment_shader" type="x-shader/x-fragment">
// fragment shader code
</script>
可以轻松地“加载”着色器代码:
var vertCode = document.getElementById("my_vertex_shader").text;
var fragCode = document.getElementById("my_fragment_shader").text;
WebGL - is there an alternative to embedding shaders in HTML?可能也很有趣。
答案 1 :(得分:2)
您询问如何将着色器作为外部文件
有几种方法,但首先要注意的是,对称为multiline template literals的字符串使用反引号可以使您拥有多行字符串
const str = `
this
string
is
on
multiple lines
`;
因此,您无需像以前一样使用'this'+'that'。
但是,如果您确实希望将它们放在单独的文件中,那么至少可以使用以下三种方法
将它们放在单独的脚本文件中,并分配给一些全局文件。例子
vertexShader.js
window.shaders = window.shaders || {};
window.shaders.someVertexShader = `
attribute vec3 coordinates;
void main(void) {
gl_Position = vec4(coordinates, 1.0);
gl_PointSize = 10.0;'
}
`;
在您的html中
<script src="vertexShader.js"></script>
<script>
// use shader as window.shaders.someVertexShader
...
</script>
请注意,您的最终JavaScript脚本也可以位于单独的文件中,只要它位于着色器文件之后即可。
将它们放在单独的JavaScript模块中
现代浏览器支持ES6 modules
vertexShader.js
export default `
attribute vec3 coordinates;
void main(void) {
gl_Position = vec4(coordinates, 1.0);
gl_PointSize = 10.0;'
}
`;
在这种情况下,您的JavaScript脚本必须位于外部文件中,因此您的 HTML可能看起来像这样
<script src="main.js" type="module"></script>
和main.js看起来像这样
import someVertexShader from './vertexShader.js';
// use someVertexShader
有一个示例here
使用fetch
在这种情况下,着色器文件中没有JavaScript
vertexShader.shader
attribute vec3 coordinates;
void main(void) {
gl_Position = vec4(coordinates, 1.0);
gl_PointSize = 10.0;'
}
然后在您的脚本中
fetch('./vertexShader.shader')
.then(response => response.text())
.then((shaderSource) => {
// use shadeSource
});
此方法的最大问题是脚本是异步下载的,因此您必须手动等待它们下载。不过,使用async / await非常简单。
想象一下,您想下载6个着色器文件,然后使用它们。此代码将在开始之前等待所有6个文件下载
function loadTextFile(url) {
return fetch(url).then(response => response.text());
}
const urls = [
'./someShader1.shader',
'./someShader2.shader',
'./someShader3.shader',
'./someShader4.shader',
'./someShader5.shader',
'./someShader6.shader',
});
async function main() {
const files = await Promise.all(urls.map(loadTextFile));
// use files[0] thru files[5]
}
main();
如果是我,并且我真的想将着色器放在外部文件中,则可能会使用import
,然后要么仅针对现代浏览器,要么使用诸如webpack或{{3 }}将它们打包为一个文件进行运输。 rollup目前正在这样做。