【问题标题】:Can I load a shader into My JavaScript code from an external text file?我可以从外部文本文件将着色器加载到我的 JavaScript 代码中吗?
【发布时间】:2015-02-06 11:50:33
【问题描述】:

learnWebGL。我看到本教程将 JavaScript 代码中的着色器代码作为普通字符串。例如:

var VSHADER_SOURCE =
  'void main(){\n' +
  ' gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n' +
  ' gl_PointSize = 10.0;\n' +
  '}\n';

我想将我的着色器代码放入外部文本文件中,并在必要时将它们加载到我的 JavaScript 代码中。我怎样才能做到正确?我不想在同一个源代码文件中混合 JavaScript 代码和着色器代码。

我查看了示例LoadShaderFromFiles.htmlhere,但它不起作用(我使用的是 Google Chrome 版本 40.0.2214.111 m)。我收到此示例的错误:

【问题讨论】:

标签: webgl shader fragment-shader vertex-shader


【解决方案1】:

这根本不是 webgl 问题,但您可以使用 XMLHttpRequest 加载代码,但前提是您启动本地开发服务器。出于安全原因。

Python 带有一个非常易于使用的服务器。因此,如果您已将 python 安装 cd 到您要在命令行中提供的目录中,只需键入

python -m SimpleHttpServer 8001

然后您可以使用浏览器导航到localhost:8001,并且应该能够向您的本地文件发送请求,而不会影响您的安全性。

另外一个更棘手的设置解决方案是使用 es6,新版本的 javascript 具有很棒的模板字符串,非常适合在 javascript 中嵌入着色器代码。

es6 支持是浏览器仍然非常低,因此您可能需要使用转译器一段时间才能将其编译回 es5(目前广泛支持的 javascript),例如 traceur

这是您的示例使用 es6 模板字符串(以及其他非常有用的功能)的样子,这些字符串可以跨多行:

var VSHADER_SOURCE = `
  void main(){
    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
    gl_PointSize = 10.0;
  }
`;

人们使用的另一种技术是在 html 标记中添加脚本标签并加载他们的.textContent

html:

 <script type="glsl" id="VSHADER_SOURCE">
     void main(){
         gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
         gl_PointSize = 10.0;
     }
 </script>

js:

 var fsCode = document.getElementById("VSHADER_SOURCE").textContent;

【讨论】:

  • 我没有髓。那本书的作者也使用XMLHttpRequest(查看错误消息),我得到了问题。 :(
  • @Bush 这实际上是一个非常常见的问题,如果其他问题中的热门答案并非几乎总是“禁用您的浏览器安全性”,我会将其标记为重复:)
  • var fsCode = document.getElementById("VSHADER_SOURCE").innerText; 这种方式适用于 Google Chrome 40.0.2214 和 Opera 27.0。但它不适用于 IE 11 和 Firefox 35.0.1(如我所见)。
  • @Bush 哦,是的,.textContent 是正确使用的属性。很好的收获:)
  • 谢谢。现在......我尝试将我的着色器代码定位到外部 js 文件中,并在我的 js 代码中以字符串形式获取其内容:&lt;script type="glsl" id="VSHADER_SOURCE" src="./vshader.js"&gt;&lt;/script&gt;。我的 js 代码:var fsh_source = document.getElementById('FSHADER_SOURCE').textContent;。但它不起作用。这是不可能的吗? :(
【解决方案2】:

这是因为您尝试直接从磁盘加载文件,这是所有浏览器都禁止的跨域请求。

非常简单的方法:

var xhr = new XMLHttpRequest();
xhr.addEventListener("load", function(data) {
    console.log(data.target.response);
});
xhr.open("GET","vsshader");
xhr.send();

但是vshader必须是同一个域,例如如果你在http://localhost:8010上运行web vsshader必须有路径http://localhost:8010/vsshader

【讨论】:

  • 我怎样才能“运行网络”?通常我从 Windows 资源管理器手动打开我的 html 文件。
  • 我明白了,你必须运行虚拟服务器。如果你有 Windows,你可以尝试安装 wampserver.com/en 例如。这是我以前用的。它里面有 apache,这正是你想要的。
  • 谢谢。我现在将尝试安装它并尝试再次打开 LoadShaderFromFiles.html 文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-04
  • 1970-01-01
  • 2013-02-12
  • 2011-05-06
  • 1970-01-01
  • 2014-10-25
相关资源
最近更新 更多