Can I load a shader into My JavaScript code from a

2019-08-08 21:02发布

问题:

I learn WebGL. I see the tutorial has the code of shaders inside of JavaScript code as a usual string. For example:

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

I want to place the code of my shaders into the external text files and load them into my JavaScript code when it necessary. How can I do it right? I don't want mix the JavaScript code and shader code in the same source code file.

I looked the sample LoadShaderFromFiles.html here, but it doesn't work (I use the Google Chrome version 40.0.2214.111 m). I get errors for this sample:

回答1:

It's not at all a webgl question, but you can load the code with a XMLHttpRequest but only if you start a local dev server. For security reasons.

Python comes with a very easy to use server. So if you have python installed cd into the directory you want to serve in the command line and just type

python -m SimpleHttpServer 8001

then you can navigate with your browser to localhost:8001 and should be able to send requests to your local files without compromising your security.

Another, a bit more tricky to set up solution would be to use es6, the new version of javascript with awesome template strings, really great for embedding shader code in javascript.

es6 support is browsers is still very low so you may have to use a transpiler for a while to compile it back to es5 ( currently widely supported javascript ), for example traceur.

Here's what your example looks like with es6 template strings (among other really useful features) those can just span multiple lines:

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

Another technique people use is to add script tags in html markup and load their .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;


回答2:

This is because you are trying to load file directly from disk which is cross domain request which is forbidden in all browsers.

Very easy way to do it:

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

But vshader must be same domain, for example if you run web on http://localhost:8010 vsshader must have path http://localhost:8010/vsshader