3

これは以前 (2 年前) に、ThreeJS github と SO の両方でいくつかの場所で尋ねられました。しかし、まだ多くの人 (私を含む) がこれに問題を抱えています。これは私が今得たものです(これはより大きなシステムの一部です):

function dataLoader()
{
    this.data_count = 0;
    this.data_array = new Array();
}

function loadFile( file, loader ){
    var FileObject = new Object();
    FileObject.data  = "";
    FileObject.ready = false;
    FileObject.id    = loader.data_count;
    loader.data_array[loader.data_count] = false;
    $.ajax({
        type: "GET",
        url: file,
        dataType: "text"
    }).done( function( msg ) {
        FileObject.data = msg;
        FileObject.ready = true;
        loader.data_array[FileObject.id] = true;
    });
    loader.data_count += 1;
    return FileObject;
}

そして、私はこれを行います:

var loader = new dataLoader();
var SkyVertexShader = loadFile( "Shaders/sky.frag", loader );
var SkyFragmentShader = loadFile( "Shaders/sky.vertex", loader );

そして、次のような資料を作成します。

var skyMat = new THREE.ShaderMaterial( { vertexShader: SkyVertexShader.data, fragmentShader: SkyFragmentShader.data, uniforms: uniforms, side: THREE.BackSide } );

sky.frag と sky.vertex のシェーダーは、タグなどのないプレーン テキストです。デバッグすると、SkyFragmentShader.data と SkyVertexShader.data の両方が正しく設定されていることがわかります。シェーダーはwebgl_lights_hemisphereの例のものです。しかし、ロードすると次のエラーが発生します。

ERROR: 0:37: 'modelMatrix' : undeclared identifier
ERROR: 0:37: 'position' : undeclared identifier 
ERROR: 0:37: 'constructor' : not enough data provided for construction 
ERROR: 0:38: 'assign' : l-value required "vWorldPosition" (can't modify a varying) ERROR: 0:40: 'gl_Position' : undeclared identifier 
ERROR: 0:40: 'projectionMatrix' : undeclared identifier 
ERROR: 0:40: 'modelViewMatrix' : undeclared identifier 
ERROR: 0:40: 'constructor' : not enough data provided for construction 
ERROR: 0:40: 'assign' : cannot convert from '4-component vector of float' to 'float' �

しかし、これを行うだけで機能します(例のように):

var fragmentShader = document.getElementById( 'fragmentShader' ).textContent;
var vertexShader = document.getElementById( 'vertexShader' ).textContent;
var skyMat = new THREE.ShaderMaterial( { vertexShader: vertexShader, fragmentShader: fragmentShader, uniforms: uniforms, side: THREE.BackSide } );

もちろん、この最後の部分は、シェーダーが HTML にある場合にのみ機能します。そのため、.textContent メソッドと Ajax GET メソッドの内容は実質的に同じですが (いくつかのタブと改行のみ)、未定義の変数に関する構文エラーが表示されます。では、何が原因でしょうか?

4

3 に答える 3

2

わかりました。それらを逆の順序でロードしていたため、頂点シェーダーが最初のものになり、フラグメントが2番目のものになりました。そのため、ThreeJS が間違った位置にコードを追加し、エラーが発生しました。悲しいことに、エラーが一般的なように見えたため、長い間デバッグする必要がありましたが、Firebug を介して完全に生成されたシェーダー テキストを取得することができ、非常に役立ちました。しかし、gaitat のおかげで、読み込みを詳しく見ることができました。

于 2013-02-27T07:23:59.473 に答える
0

この投稿https://github.com/mrdoob/three.js/issues/283 (これは 2 年前のものです) を参照している場合は、彼らのソリューションを正確にフォローしていません。実際にロードされる前にシェーダーを実行しようとしている可能性があるため、同期要求を行うために ajax 要求に「async: false」を設定しようとしましたか。

于 2013-02-26T22:19:07.570 に答える