Загрузка пользовательского файла в jquery возвращает ошибку, даже если файл загружен правильно - PullRequest
0 голосов
/ 18 января 2019

У меня есть следующий код для загрузки .glsl файла

$.getScript("path/to/file/vertexShader.glsl", function( vertexShader ) {
    console.log(vertexShader);
});

Содержимое vertexShader.glsl:

#version 300 es

precision highp float;  
precision highp int;

out vec3 world_coords;
void main()
{
    world_coords = position + vec3(0.5);
    gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}

Даже если кажется, что все работаетправильно я получаю следующую ошибку:

VM598:1 Uncaught SyntaxError: Invalid or unexpected token
at m (jquery.min.js:2)
at Function.globalEval (jquery.min.js:2)
at text script (jquery.min.js:2)
at Ut (jquery.min.js:2)
at k (jquery.min.js:2)
at XMLHttpRequest.<anonymous> (jquery.min.js:2)   

Код работает нормально, но я все еще получаю ошибки.Есть идеи как от них избавиться?

Ответы [ 2 ]

0 голосов
/ 19 января 2019

TBH, я не до конца понимаю, нужно ли вам добавлять скрипты glsl на head вашей html-страницы для последующего повторного использования, но если ваша программа на самом деле хорошо компилируется и вам нужно только избавиться из этих ошибок, то решение простое.

$.getScript - это просто сокращение для полной функции Ajax, поэтому используйте его и укажите тип сценария:

function getScript() {
    $.ajax({
        url: "./solid.vert",
        dataType: "text",
        success: function(result){
            // Inside result is the vertex shader
        }
    });
}

Кстати, я использую расширение .vert для вершинных шейдеров и .frag для фрагментных шейдеров, в результате чего тип MIME на сервере установлен на text/plain.

0 голосов
/ 18 января 2019

$.getScript загружает скрипты JavaScript. В отличие от внутренних сценариев, сценариев, содержимое которых находится внутри HTML, нельзя использовать внешний сценарий для загрузки чего-либо, кроме JavaScript.

Для загрузки текстового файла современным простым способом используйте fetch и async / await

async function main() {
  const vertexShader = await fetch("path/to/file/vertexShader.glsl").then(req => req.text());
  ...
}
main();

или, конечно, превратить его в функцию

async function main() {
  const vertexShader = await loadText("path/to/file/vertexShader.glsl");
  ...
}

function loadText(url) {
  return fetch("path/to/file/vertexShader.glsl").then(req => req.text());
}

main();

или без асинхронного / ожидающего

fetch("path/to/file/vertexShader.glsl")
  .then(req => req.text())
  .then(function( vertexShader ) {
    console.log(vertexShader);
  });

или, если хотите, чтобы он выглядел как getScript

getTextFile("path/to/file/vertexShader.glsl", function( vertexShader ) {
  console.log(vertexShader);
});

function getTextFile(url, callback) {
  fetch("path/to/file/vertexShader.glsl")
    .then(req => req.text())
    .then(callback);
}

, который сказал, что если бы я и хотел, чтобы мои шейдеры были внешними, я бы использовал import / export, как в

// myvertexshader.glsl
default export `
  attribute vec4 position
  void main() {
    gl_Position = position;
  }
`;

И затем вы можете import это в другой модуль javascript, как в

// main.js
import vertexShader from './myvertexshader.glsl';
...

main.js должен быть включен как модуль

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

import работает только в современных браузерах (например, в тех, которые запускают WebGL2), но вы можете использовать что-то вроде rollup , чтобы преобразовать его обратно в старый файл JavaScript в одном стиле.

Преимущество заключается в том, что во время разработки все ваши файлы являются отдельными, но для производства / развертывания вы можете встроить свой JavaScript в один большой файл, который будет загружаться намного быстрее, чем многие маленькие файлы

three.js делает это , если вы хотите увидеть пример

...