Javascript et WebGL, scripts externes

Juste curieux; Comment puis-je placer mes shaders webgl, dans un fichier externe?

Actuellement, je l'ai eu;

<script id="shader-fs" type="x-shader/x-fragment"> #ifdef GL_ES precision highp float; #endif void main(void) { gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); } </script> <script id="shader-vs" 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); } </script> 

Dans mon en-tête html, comment puis-je lier ceci à partir d'un fichier externe? – J'ai essayé l'approche Java habituelle;

 <script type="text/javascript" src="webgl_shader.js"></script> 

Pour les fichiers externes, vous devez arrêter d'utiliser la balise du script. Je suggère d'utiliser quelque chose comme XMLHttpRequest . Je suggère également de renommer vos fichiers, ils sont des shaders pas Javascript, donc utilisez une extension différente pour éviter toute confusion. J'utilise quelque chose comme "shiny_surface.shader".

C'est ce que je fais:

 function loadFile(url, data, callback, errorCallback) { // Set up an asynchronous request var request = new XMLHttpRequest(); request.open('GET', url, true); // Hook the event that gets called as the request progresses request.onreadystatechange = function () { // If the request is "DONE" (completed or failed) if (request.readyState == 4) { // If we got HTTP status 200 (OK) if (request.status == 200) { callback(request.responseText, data) } else { // Failed errorCallback(url); } } }; request.send(null); } function loadFiles(urls, callback, errorCallback) { var numUrls = urls.length; var numComplete = 0; var result = []; // Callback for a single file function partialCallback(text, urlIndex) { result[urlIndex] = text; numComplete++; // When all files have downloaded if (numComplete == numUrls) { callback(result); } } for (var i = 0; i < numUrls; i++) { loadFile(urls[i], i, partialCallback, errorCallback); } } var gl; // ... set up WebGL ... loadFiles(['vertex.shader', 'fragment.shader'], function (shaderText) { var vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, shaderText[0]); // ... compile shader, etc ... var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragmentShader, shaderText[1]); // ... set up shader program and start render loop timer }, function (url) { alert('Failed to download "' + url + '"'); }); 

Si vous utilisez une bibliothèque comme JQuery, elles ont probablement une fonction similaire à celle de mon fichier loadFiles.

J'ai eu le même problème et j'ai constaté que cela a fonctionné pour moi avec jQuery:

 var fragmentShaderSRC = null, var vertexShaderSRC = null; ... function executeProgram(){ //main program } ... $.get("shader.fs", function(data){ fragmentShaderSRC = data.firstChild.textContent; $.get("shader.vs", function(data){ vertexShaderSRC = data.firstChild.textContent; executeProgram(); }); }); 

shader.fs et shader.vs sont mes shaders (et comprennent les
<script type="x-shader/x-fragment"> et <script type="x-shader/x-vertex"> lignes de déclaration)

Mise à jour avec Chrome, la supposition intelligente ne sélectionne pas 'xml'. Le code suivant fonctionne aussi bien en Chrome:

 $.ajax({ url: 'shader.fs', success: function(data){ fragmentShaderSRC = data.firstChild.textContent; $.ajax({ url: 'shader.vs', success: function(data){ vertexShaderSRC = data.firstChild.textContent; executeProgram(); }, dataType: 'xml' }) }, dataType: 'xml' }); 

Mise à jour 2: Comme < et & dans la source de shader doivent être échappés pour charger en tant que XML, cela fonctionne tout le temps, même si vous utilisez moins de comparaison ou les opérateurs logiques:

 var vs_source = null, fs_source = null; $.ajax({ async: false, url: './my_shader.vs', success: function (data) { vs_source = $(data).html(); }, dataType: 'html' }); $.ajax({ async: false, url: './my_shader.fs', success: function (data) { fs_source = $(data).html(); }, dataType: 'html' }); 

Vous pouvez utiliser une bibliothèque de gestion de shader open source comme la mienne:

https://github.com/ILOVEPIE/Shader.js

Il vous permet de charger des shaders à partir des URL et des caches du code source shader pour les visites futures sur le site. Il est également plus simple d'utiliser des uniformes.

Je ne suis pas un gourou WebGL, mais cela fonctionne-t-il?

 <script id="shader-fs" type="x-shader/x-fragment" src="fragment-shader.fs" />