2018年アップデート
2018年には、シェーダーをバッククォートで囲むように複数行のテンプレートリテラルを使用することをお勧めします。これは複数の行にまたがることができます
const someShaderSource = `
attribute vec4 position;
uniform mat4 matrix;
void main() {
gl_Position = matrix * position;
}
`;
シェーダーを別々のファイルに入れたい場合は、2018 年に JavaScript モジュールを使用して簡単に行うことができます。シェーダー ファイルは次のようになります。
// someshader.glsl.js
export default `
attribute vec4 position;
uniform mat4 matrix;
void main() {
gl_Position = matrix * position;
}
`;
JavaScript モジュールを使用するには、メインの JavaScript を別のファイルにする必要があります。インポートすることで、シェーダー ソースにアクセスできます。
// main.js
import someShaderSource from './someshader.glsl.js';
// use someShadeSource
そして、それをHTMLに含めます
<script src="main.js" type="module"></script>
または、このようにページ自体のスクリプトタグから使用できます
<script type="module">
import someShaderSource from './someshader.glsl.js';
// use someShadeSource
</script>
古いブラウザーをサポートしたい場合は、すべてのステートメントを読み取り、1 つの大きな JavaScript ファイルを生成するロールアップなどのツールを使用できます。import
これが three.js の機能です。
IE11 をサポートする必要がある場合は、babelを使用して複数行のテンプレートを変換できます。他のすべてのブラウザーは、長年にわたって複数行のテンプレートをサポートしてきました。
元の回答
webgl プログラムでシェーダーを html ファイルにする必要があるのはなぜですか?
彼らはしません
シェーダーを外部 JavaScript に配置できます。例えば
// --myshader.js--
var myFragmentShader =
"void main() {\n" +
" gl_FragColor = vec4(1,0,0,1);\n" +
"}n\";
または別の一般的な形式
// --myshader.js--
var myFragmentShader = [
"void main() {",
" gl_FragColor = vec4(1,0,0,1);",
"}",
].join("\n");
WebGL をサポートするすべてのブラウザで、テンプレート リテラルを使用できます
// --myshader.js--
var myFragmentShader = `
void main() {
gl_FragColor = vec4(1,0,0,1);
}
`;
それ以外の場合は、それらをテキスト ファイルに入れて、XMLHTTPRequest でロードできます。
// --myshader.txt
void main() {
gl_FragColor = vec4(1,0,0,1);
}
次に、JavaScript で次のようにします。
function loadTextFile(url, callback) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.addEventListener('load', function() {
callback(request.responseText);
});
request.send();
}
loadTextFile("myshader.txt", function(text) {
// use text...
});
人々がそれらを HTML に入れる理由は、それが簡単で、効率的で、同期的だからです。
簡単: JS ファイル バージョンとは異なり、すべての行を引用符やその他の句読点で囲む必要はありません。es6 になった今では、それはもはや問題ではありません。WebGL をサポートするすべてのブラウザーは、es6 テンプレート文字列をサポートします。
効率的: テキスト ファイルや js ファイルとは異なり、サーバーへの要求は 1 つだけです。もちろん、js ファイルで連結子を実行してその一部を修正する人もいます。
synchronous : テキスト ファイルとは異なり、それらの使用は同期的です。コールバックや約束、またはファイルのダウンロードの非同期の問題を処理する必要はありません。
あなたの例が機能しない理由については、クロスオリジンリソースアクセスが許可されることが理由だと確信しています。この<script>
タグは、クロス オリジン アクセスが問題であると人々が理解する前に設計されたため、多くのサイトを壊さずにクロス オリジン スクリプトをオフにすることはできませんでした。彼らは他のすべてをより厳密にすることができました。
たとえば、XMLHttpRequest は、接続しているサーバーが許可を与えない限り、クロス オリジン アクセスを許可しません。スクリプト タグを使用してそのコンテンツにアクセスできる場合は、スクリプト タグを使用してその制限を回避できます。つまり、XMLHttpRequest を作成しrequest.responseText
て結果を読み取る代わりに、プログラムでスクリプト タグを作成し、src
目的の URL に設定し、終了時にそのtext
フィールドを読み取るだけです。属性text
を持つスクリプトタグのフィールドを読み取ることが許可されていないことを確認するにはsrc