2

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:

enter image description here

Andrey Bushman
  • 11,712
  • 17
  • 87
  • 182
  • possible duplicate of [WebGL - is there an alternative to embedding shaders in HTML?](http://stackoverflow.com/questions/5878703/webgl-is-there-an-alternative-to-embedding-shaders-in-html) – gman Feb 08 '15 at 02:05

2 Answers2

0

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;
Winchestro
  • 2,138
  • 14
  • 18
  • I have not pithon. Authors of that book use the `XMLHttpRequest` too (look the error message) and I get the problem. :( – Andrey Bushman Feb 06 '15 at 12:11
  • @Bush it's actually a super common question and I would have marked it as a duplicate if the popular answers in other questions weren't almost always "disable your browser security" :) – Winchestro Feb 06 '15 at 12:38
  • `var fsCode = document.getElementById("VSHADER_SOURCE").innerText;` this way works for the Google Chrome 40.0.2214 and Opera 27.0. But it doesn't work for IE 11 and Firefox 35.0.1 (as I see). – Andrey Bushman Feb 09 '15 at 13:37
  • @Bush Oh yeah right `.textContent` is the right property to use. Good catch :) – Winchestro Feb 09 '15 at 13:50
  • thank you. Now... I try to locate code of my shader into the external js-file and to get its content in my js-code as a string: ``. My js code: `var fsh_source = document.getElementById('FSHADER_SOURCE').textContent;`. But it doesn't work. Is it impossible? :( – Andrey Bushman Feb 10 '15 at 08:11
  • yes it's impossible. Script tags are just a lazy workaround. If you don't want that well *click once to install python* *write one line in your command line* - you will need python anyway at some point, it's not a tiny hack for this particular problem. – Winchestro Feb 10 '15 at 08:35
  • I installed the Python 3.4 on my Windows 7 x64 and ran the `python -m http.server 8001` command. I see the *"Serving HTTP on 0.0.0.0 port 8001 ..."* message. What I must to do now? – Andrey Bushman Feb 10 '15 at 08:46
  • go to the url _localhost:8001_ in your browser, this is where your server runs (serving the location you started the server in) – Winchestro Feb 10 '15 at 08:48
  • if you start it in path/to/your/website that path will be the "root" of your server and you can request all resources relative to it. it will automatically try to load `index.html`. All other resources map to that path -> `localhost:8001/scripts/yourscript.js` wll load `path/to/your/website/scripts/yourscript.js` – Winchestro Feb 10 '15 at 08:51
  • It works fine for Opera, Firefox, Google Chrome, but IE doesn't want to display my html file content with external shader files. Why? – Andrey Bushman Feb 10 '15 at 09:24
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/70621/discussion-between-winchestro-and-bush). – Winchestro Feb 10 '15 at 09:25
0

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

Entity Black
  • 3,401
  • 2
  • 23
  • 38
  • How can I to "run web"? Usually I open my html file manually, from windows explorer. – Andrey Bushman Feb 06 '15 at 12:16
  • I see, you will have to run virtual server. If you have windows, you can try to install http://www.wampserver.com/en/ for example. This is what I used before. It has apache inside, which is exactly what you want. – Entity Black Feb 06 '15 at 12:20
  • Thank you. I will try install it now and try to open the LoadShaderFromFiles.html file again. – Andrey Bushman Feb 06 '15 at 12:28