Как включить шейдеры в качестве внешних файлов - PullRequest
0 голосов
/ 16 ноября 2018

Есть ли способ включить этот код шейдера как внешний vertexShader.js без кавычек и включить между тегами "script"?

var vertCode =
'attribute vec3 coordinates;' +

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

Ответы [ 2 ]

0 голосов
/ 19 ноября 2018

Вы спрашивали, как включить шейдеры как внешние файлы

Есть несколько способов, но сначала важно отметить, что использование обратных галочек для строк, которые называются multilineлитералы шаблона позволяют иметь многострочные строки

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

Так что нет необходимости использовать 'this' + 'that', как вы делали.

Если вы действительно хотитечтобы поместить их в отдельные файлы, тогда вот как минимум 3 из множества способов, которыми вы могли бы это сделать

  • поместить их в отдельные файлы сценариев, назначив их некоторым глобальным.Пример

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

    в вашем html

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

    Обратите внимание, что ваш окончательный сценарий JavaScript также может находиться в отдельном файле, если он имеетсяпосле файлов шейдеров.

  • Поместите их в отдельный модуль JavaScript

    Современные браузеры поддерживают ES6-модули

    vertexShader.js

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

    В этом случае ваш скрипт JavaScript должен находиться во внешнем файле, чтобы ваш HTML мог выглядеть примерно так

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

    и main.js будет выглядетькак-то так

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

    Вот пример здесь

  • Загрузите их с помощью fetch

    В этом случае в файле шейдера нет JavaScript

    vertexShader.shader

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

    Тогда в вашем скрипте

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

    Самая большая проблема с этим методомСценарии загружаются асинхронно, поэтому вам придется вручную ждать их загрузки.Однако использовать async / await довольно просто.

    Представьте, что вы хотите загрузить 6 файлов шейдеров, а затем использовать их.Этот код будет ждать загрузки всех 6 файлов перед запуском

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

Если бы это был я, и я действительно хотел бы поместить свои шейдеры во внешние файлы, я бы, вероятно, использовал importи затем либо предназначаются только для современных браузеров, либо используют какую-либо программу, такую ​​как webpack или rollup , чтобы упаковать их в один файл для отправки.Это то, что THREE.js делает в настоящее время.

0 голосов
/ 16 ноября 2018

Вы можете добавить код шейдера к тегу <script> типа "x-shader/x-vertex" для вершинного шейдера и "x-shader/x-fragment" для фрагментного шейдера. См. Также Тип шейдеров WebGL и HTML

<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>

Код шейдера можно легко "загрузить":

var vertCode = document.getElementById("my_vertex_shader").text;
var fragCode = document.getElementById("my_fragment_shader").text;

WebGL - есть ли альтернатива встраиванию шейдеров в HTML? тоже может представлять интерес.

...