6

What I want:

<script src="shader.glsl" type="x-shader/x-fragment"></script>
<script src="shader.glsl" type="x-shader/x-vertex"></script>

or:

<script src="shader.frag" type="x-shader/x-fragment"></script>
<script src="shader.vert" type="x-shader/x-vertex"></script>

So I have 2 simple shader types:

  • type=x-shader/x-fragment

    precision mediump float;
    
    void main(void) {
        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
    }
    
  • type=x-shader/x-vertex

    attribute vec3 aVertexPosition;
    
    uniform mat4 uMVMatrix;
    uniform mat4 uPMatrix;
    
    void main(void) {
        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
    }
    

The shaders come from this WebGL tutorial


  1. Can I add these 2 types in one .glsl?
  2. If not are their other file formats for the shader types like:

    • .vert
    • .frag

Q: For what do I want to use this?
A: Dynamically loading my files from JavaScript and insert it to my HTML file.

Q: Do you want to know how to load dynamically files?
A: No that is irrelevant to the question "load GLSL file (WebGL) in HTML?"

Q: What do you want then?
A: Look at the What I want at the start of the question.

Q: Do you want to share your JavaScript import code?
A: Yes but I think that is irrelevant information to be able to answer the question

Jeroen van Langen
  • 21,446
  • 3
  • 42
  • 57
TessavWalstijn
  • 1,698
  • 1
  • 19
  • 36
  • There is not much *dynamic* in statically loading those files... – tevemadar Feb 23 '18 at 11:28
  • @tevemadar I only have 2 JavaScript files in my HTML page. 1: the file loader. 2: the main script that imports the files and executes the start function when the inserting and loading the files is done. – TessavWalstijn Feb 23 '18 at 11:42

4 Answers4

2

It is not possible this way.
See specs: https://www.w3.org/TR/html5/semantics-scripting.html#data-block

When used to include data blocks, the data must be embedded inline, the format of the data must be given using the type attribute, and the contents of the script element must conform to the requirements defined for the format used. The src, charset, async, defer, crossorigin, and nonce attributes must not be specified.

(So data blocks have to be inline, as shown in https://www.w3.org/TR/html5/semantics-scripting.html#dom-htmlscriptelement-text - then they can be accessed via .text or .textContent)

So revert to XMLHttpRequest (or some AJAX wrapper for it) if you want to load GLSL from separate files.

tevemadar
  • 12,389
  • 3
  • 21
  • 49
0

You could use socket io to dynamically load the GLSL as text after page loading. If your server supports Websockets for example, or even just XHR. Surprised that WebGL does not provide this.

This also has the interesting benefit of not directly publishing your precious GLSL files, and also skips the cache.

Dominic Cerisano
  • 3,522
  • 1
  • 31
  • 44
0

I suppose that possible with XMLHttpRequest. We can use it for file reading. But, to my knowledge, we shouldn't use locally adress in src parameter. Because browsers, especially Chrome, will give error like this "Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource." How to read a local text file? But we can run js project and include glsl file in localhost then call this file. Example: http://localhost:8080/webgl/shader.glsl

Steps:

  • Firstly, if you use Windows then install Xampp on computer. There are different options for OSs.
  • Add your WebGL project in htdocs (C:\xampp\htdocs) folder.
  • We need to use XMLHttpRequest for reading glsl file. Create readFile function.

I think, it might works.

shalom
  • 191
  • 1
  • 1
  • 10
-2

In my OpenGL projects in C++ I create a .vs (vertex) and a .fs (fragment). Unless you use a library, fragment or engine that requires a certain extension, this can be anything you want. Shaders (just like any file) are just textfiles. It doesn't really matter what it's called, it's about the content. I'm not entirely sure that webGL works the same as standard OpenGL since I've never worked with it, but it probably is and has the same functions.

When it comes to the script tag, you could use it, but I'm pretty sure it wont pass you the file. So will have to write some code to read the content and create the shader. So I'm guessing you will need to do something like this:

function init()
{
    const scriptElements = document.getElementsByTagName('script');
    const len = scriptElements.length;
    for(let i = 0; i < len; i++)
    {
        const curr = scriptElements[i];
        const type = curr.getAttribute('type');
        if(type == null)
          continue;
         
        if(type.indexOf("x-shader") === -1);
            continue;

        const offset = type.indexOf('/')+1;
        const length = type.length;
        const realType = type.substr(offset, length);
        
        //if realType == x-fragment then its a fragment shader
        //if realType == x-vertex then its a vertex shader
    }
}

init();
<body>
</body>

<script src="test.vertex" type="x-shader/x-fragment"></script>

NOTE: the snippet won't work when you run it, it doesn't grab the script element from the html.

You could also give all your vertex shaders the class "vertex" and all the fragment shaders the class "fragment" and do getElementsByClassName, loop through them and load them in

TessavWalstijn
  • 1,698
  • 1
  • 19
  • 36
danivdwerf
  • 234
  • 2
  • 16
  • Thanks for the answer. I only know the path of the shader file. To correctly load the code I need to know the type of the file: `x-shader/x-vertex` or `x-shader/x-vertex`. I know the file format is `.glsl`. But I can not read what `x-shader` the `.glsl` is. – TessavWalstijn Feb 23 '18 at 11:37
  • 2
    This snippet just does not do what OP describes (because that is not possible to do), and it does not show any other way to load the files in question either. – tevemadar Feb 23 '18 at 20:11