2017-08-14 14 views
1

実際に私のhtmlに含まれているシェーダを外部ファイルにどのように移動させることができますか?このようにして、私は麻薬の仕事にそれらを含めることができます。私はJavaScriptのシェーダファイルがどのように書かれているかを見てきましたが、よく分かりません。シェーダスクリプトを外部ファイルに移動する方法は?

たとえば、以下のグローシェイダーコードでは、どうすれば外部ファイルに移動できますか?

<script type="x-shader/x-vertex" id="vertexShaderGlow"> 
    uniform vec3 viewVector; 
    uniform float c; 
    uniform float p; 
    varying float intensity; 
    void main() 
    { 
     vec3 vNormal = normalize(normalMatrix * normal); 
     vec3 vNormel = normalize(normalMatrix * viewVector); 
     intensity = pow(c - dot(vNormal, vNormel), p); 
     gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 
    } 
</script> 
<script type="x-shader/x-vertex" id="fragmentShaderGlow"> 
    uniform vec3 glowColor; 
    varying float intensity; 
    void main() 
    { 
     vec3 glow = glowColor * intensity; 
     gl_FragColor = vec4(glow, 1.0); 
    } 
</script> 
+0

シェーダコードは文字列としてのみ必要なので、外部ファイルから文字列を取り込むことができる方法であれば使用できます。 – 2pha

+0

私に例を教えてもらえますか? – ClassikD

+0

私はシャオによって与えられた答えを編集しました – 2pha

答えて

0

glsl行の配列に参加することを示唆する答えは、3つのパターンで発生する可能性がありますが、このユースケースでは避けてください。

シェーダの「コンパイルされた」スナップショットのような、ある種のモジュールでは役に立ちますが、変更するつもりはありません。

これ以外の点では、このアプローチの主な欠点は、構文の強調表示がなく、冗長であることです。

今日、ほとんどのjsコードは一方向に変換されています。シェーダコードはこのようにインライン化する必要があります。

const myShader = new THREE.ShaderMaterial({ 
    vertexShader: require('./myVert.vs'), 
    fragmentShader: require('./myFrag.vs'), 
}) 

編集

myVert.vs:

//this is all nicely highlighted in sublime text for example 
void main(){ 
    gl_Position = vec4(position.xy, 0., 1.); 
} 

myVert.fs:

void main(){ 
    gl_FragColor = vec4(1.,0.,0.,1.); 
} 

myClass.js:

class myMaterial extends THREE.ShaderMaterial{ 
    constructor(){ 
    super({ 
     vertexShader: require('./myVert.vs'), 
     //^ becomes vertexShader: 'void main() {...}' 
     ... 
+0

その方法はうまくいくようですが、 HTTP要求の数が増加しますか? Javascriptファイルに含まれるシェーダは、私がそれらを縮小/マージし、すべての自分のウェブサイトに1つのJavascriptしかロードできなかったので、私にとっては良いことでした。また、.vsファイルのコードはスクリプトタグのコードと同じか、それを適応させる必要がありますか? – ClassikD

+0

これはwebpackやその他のバンドルツールと組み合わせて使用​​するものではありません。 '.vs'は単なるtxtファイルです。バンドルツールがこれを処理すると、 'require(..)'がファイルの内容に置き換えられます。追加のリクエストは行われません。これはメインバンドルにインライン化されています。 – pailhead

+0

** **シェーダは文字列以外何もありません。ここでの問題は、文字列、同期、非同期、フォーマット済みかどうかを取得することです。 Three自体は、GLSLの一部ではない '#import ...'ステートメントのような特殊文字列を処理するためのいくつかの機能を提供します。だから、あなたにとっては、最も適切なフォーマットを選ぶのはあなた次第です。普通の古いjavascriptは、 '\ n'を追加したり、配列に行を追加する必要があるので、複数行の文字列を扱いません。次のステップは、単純に複数の行を書くことができるes6文字列です。 – pailhead

-2

シェーダコードを別のJSファイルに移動し、three.jsの後にそのファイルを含めることができます。

material = new THREE.ShaderMaterial({ 
    uniforms : THREE.ColorifyShader.uniforms, 
    vertexShader : THREE.ColorifyShader.vertexShader, 
    fragmentShader : THREE.ColorifyShader.fragmentShader 
}); 

オブジェクトTHREE.ColorifyShaderを呼び出す必要はありません。勿論、あなたは何でもそれを呼び出すことができます。ここで
はこのように私たちの材料を作成することになります上記でhttps://github.com/timoxley/threejs/blob/master/examples/js/shaders/ColorifyShader.js

/** 
* @author alteredq/http://alteredqualia.com/ 
* 
* Colorify shader 
*/ 

THREE.ColorifyShader = { 

    uniforms: { 

     "tDiffuse": { type: "t", value: null }, 
     "color": { type: "c", value: new THREE.Color(0xffffff) } 

    }, 

    vertexShader: [ 

     "varying vec2 vUv;", 

     "void main() {", 

      "vUv = uv;", 
      "gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);", 

     "}" 

    ].join("\n"), 

    fragmentShader: [ 

     "uniform vec3 color;", 
     "uniform sampler2D tDiffuse;", 

     "varying vec2 vUv;", 

     "void main() {", 

      "vec4 texel = texture2D(tDiffuse, vUv);", 

      "vec3 luma = vec3(0.299, 0.587, 0.114);", 
      "float v = dot(texel.xyz, luma);", 

      "gl_FragColor = vec4(v * color, texel.w);", 

     "}" 

    ].join("\n") 

}; 

から一例であり、あなたは欲しい。

+0

なぜこれがダウン投票を得たかわかりません、私には合理的な答えのように思えます。 – 2pha

+0

シェイダーコードを別のJSファイルに移動し、three.jsの後にそのファイルをインクルードすることができます。これは私の質問ではありません。 – ClassikD

+0

構文を別の構文に変換する方法を知りたいのですが、コードは2つの異なる方法で書かれているようです。 – ClassikD

1

もう1つの答えは、単にGLSLコードを取得し、各行を文字列に変換することです。各文字列は配列内の値です。 join呼び出しでは、すべての文字列を\n文字で連結し、デバッグ時にコードを読みやすくします。私はこれまで何度もやったことがありますし、あなたがしようとしていることに対する正当な解決策です。

しかし、生のGLSLコードを使用して外部ファイルを作成したい場合は、そのようにすることもできます。

  • glow_vertex.glsl
  • glow_fragment.glsl

これらのファイルを使用すると、通常はスクリプトタグを持っているでしょうシェーダコードが含まれています2つのファイルを考えてみましょう。 XMLHTTPRequestを使用してファイルをフェッチし、返されたテキストをシェーダコードとして使用できます。

var vertexShader = null; 
var fragmentShader = null; 

function shadersDone(){ 
    var material = new THREE.ShaderMaterial({ 
     uniforms: { /* define your uniforms */}, 
     vertexShader: vertexShader, 
     fragmentShader: fragmentShader 
    }); 
} 

function vertexDone(code){ 
    vertexShader = code; 
    if(fragmentShader !== null){ 
     shadersDone(); 
    } 
} 

function fragmentDone(code){ 
    fragmentShader = code; 
    if(vertexShader !== null){ 
     shadersDone(); 
    } 
} 

var xhr1 = new XMLHttpRequest(); 
var xhr2 = new XMLHttpRequest(); 

xhr1.open("GET", "/server/glow_vertex.glsl", true); 
xhr2.open("GET", "/server/glow_fragment.glsl", true); 

xhr1.responseType = "text"; 
xhr2.responseType = "text"; 

xhr1.onload = function(){ 
    if(xhr1.readyState === xhr1.DONE && xhr1.status === 200){ 
     vertexDone(xhr1.resultText); 
    } 
}; 
xhr2.onload = function(){ 
    if(xhr2.readyState === xhr2.DONE && xhr2.status === 200){ 
     fragmentDone(xhr2.resultText); 
    } 
}; 

xhr1.send(null); 
xhr2.send(null); 

これはすべて非同期であることに注意してください。また、GLSLファイルをプレーンテキストとして送信するようにサーバーを設定する必要があります。

我々は近代的なウェブの話をしている限り

...

importあなたのシェーダコードのオプションがあります。 VERY BIG現在のところ、ChromeとOperaでのみサポートされています(ただし、ポリフィルは存在します)。 Microsoft Edgeはこの機能を「検討中」としてリストしており、Firefoxは現在の状態で実装するためにインデントしていません。 JavaScriptの中で、後に続いて...

<link id="vertexImport" rel="import" href="/server/glow_vertex.glsl" /> 
<link id="fragmentImport" rel="import" href="/server/glow_fragment.glsl" /> 

をあなたのHTMLではhttp://caniuse.com/#search=import

、およびJavaScriptの前にそれを使用することになる。だから、塩の大粒で、以下のものを取る、とに目を離しません。

var material = new THREE.ShaderMaterial({ 
    vertexShader: document.getElementById("vertexImport").import.body.childNodes[0].data, 
    fragmentShader: document.getElementById("fragmentImport").import.body.childNodes[0].data, 
}); 

また、これは非同期です。リンクごとにonloadハンドラを追加する必要があるかもしれないので、ロードする前にコードにアクセスしようとしないでください。

+0

これは正当な解決策ではありません。その2017年の後半、 '(glsl | vert | frag | fs | vs)'はすべて、あなたのコードで 'require'とinlineのどちらか、あるいはxhr要求をすることができる拡張でなければなりません。第2のアプローチは減価償却されるべきである。 – pailhead

+0

@pailheadあなたは私の興味があるかもしれません。 – TheJim01

+0

非常に興味深いですが、私の欠点はサーバー構成が必要であり、管理するのが少し重いということです。/ – ClassikD

関連する問題