最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to include shaders as external files - Stack Overflow

programmeradmin4浏览0评论

Is there a way to include this shader code as an external vertexShader.js without quotes and include between "script" tags?

var vertCode =
'attribute vec3 coordinates;' +

'void main(void) {' +
' gl_Position = vec4(coordinates, 1.0);' +
'gl_PointSize = 10.0;'+
'}';

Is there a way to include this shader code as an external vertexShader.js without quotes and include between "script" tags?

var vertCode =
'attribute vec3 coordinates;' +

'void main(void) {' +
' gl_Position = vec4(coordinates, 1.0);' +
'gl_PointSize = 10.0;'+
'}';
Share Improve this question edited Nov 11, 2022 at 13:00 Rabbid76 211k30 gold badges156 silver badges198 bronze badges asked Nov 16, 2018 at 10:49 ApplikApplik 4313 silver badges12 bronze badges 0
Add a comment  | 

2 Answers 2

Reset to default 12

You asked how to include shaders as external files

There are several ways but first off it's important to note that using backticks for strings which are called multiline template literals let you have multiline strings

const str = `
this
string
is
on
multiple lines
`;

So there's no need to use 'this' + 'that' as you were doing.

If you really want to put them in separate files though then here's at least 3 of the many ways you could do it

  • put them in separate script files, assign to some global. Example

    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;'
      }
      `;
    

    in your html

      <script src="vertexShader.js"></script>
      <script>
       // use shader as window.shaders.someVertexShader
       ...
      </script>
    

    Note that your final JavaScript script could also be in a separate file just as long as it comes after the shader files.

  • Put them in a separate JavaScript module

    Modern browsers support ES6 modules

    vertexShader.js

      export default `
      attribute vec3 coordinates;
    
      void main(void) {
          gl_Position = vec4(coordinates, 1.0);
          gl_PointSize = 10.0;'
      }
      `;
    

    In this case your JavaScript script must be in an external file so your HTML might look something like this

      <script src="main.js" type="module"></script>
    

    and main.js would look something like this

      import someVertexShader from './vertexShader.js';
    
      // use someVertexShader
    

    There's an example here

  • Load them with fetch

    In this case there's no JavaScript in the shader file

    vertexShader.shader

      attribute vec3 coordinates;
    
      void main(void) {
          gl_Position = vec4(coordinates, 1.0);
          gl_PointSize = 10.0;'
      }
    

    Then in your script

      fetch('./vertexShader.shader')
      .then(response => response.text())
      .then((shaderSource) => {
         // use shadeSource
      });
    

    The biggest problem with this method is the scripts are downloaded asynchronously so you have to manually wait for them to download. Using async/await that's pretty easy though.

    Imagine you wanted to download 6 shaders files and then use them. This code would wait for all 6 files to download before starting

      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();
    

If it was me and I really wanted to put my shaders in external files I'd probably use import and then either only target modern browsers or else use some program like webpack or rollup to package them into a single file for shipping. This is what THREE.js currently does.

You can add the shader code to a <script> tag of type "x-shader/x-vertex" for the vertex shader and "x-shader/x-fragment" for the fragment shader. See also 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>

The shader code can be "loaded" with ease:

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? may be of interest, too.

发布评论

评论列表(0)

  1. 暂无评论