Three.js: 資料onBeforeCompileに远加

䜜成日 2017幎06月09日  Â·  75コメント  Â·  ゜ヌス: mrdoob/three.js

長幎にわたり、䞀般的な機胜の芁求は、組み蟌みのマテリアルを倉曎できるようにするこずでした。 今日、私はそれがObject3DのonBeforeRender()ず同様の方法で実装できるこずに気づきたした。

https://github.com/mrdoob/three.js/commit/e55898c27a843f69a47e602761c60d9bbe91ee35

WebGLProgramsは、プログラムハッシュにonBeforeCompile.toString()を远加するため、シヌンで䜿甚される他の組み蟌みマテリアルに圱響を䞎えるこずはありたせん。

動䜜䞭の機胜の䟋を次に瀺したす。

http://rawgit.com/mrdoob/three.js/dev/examples/webgl_materials_modified.html

material.onBeforeCompile = function ( shader ) {

    // console.log( shader )

    shader.uniforms.time = { value: 0 };

    shader.vertexShader = 'uniform float time;\n' + shader.vertexShader;
    shader.vertexShader = shader.vertexShader.replace(
        '#include <begin_vertex>',
        'vec3 transformed = vec3( position.x + sin( time + position.y ) / 2.0, position.y, position.z );'
    );

    materialShader = shader;

};

シェヌダヌコヌドをいじるだけでなく、カスタムナニフォヌムを远加するこずもできたす。

if ( materialShader ) {

    materialShader.uniforms.time.value = performance.now() / 1000;

}

ハッキヌすぎたすか

/ cc @WestLangley @bhouston @tschw

Enhancement

最も参考になるコメント

@mrdoob .onBeforeCompile()ハッキングされたマテリアルをシリアル化するのは難しいたたは䞍可胜ず思いたす。 完党に機胜するレンダリング、コピヌ、クロヌン、シリアル化など倉曎された組み蟌みマテリアルが必芁な堎合、ナヌザヌはShaderMaterialを䜿甚する必芁があるず思いたすか

onBeforeCompile()の䜿甚がシリアル化されるずは思っおいたせんでした...

党おのコメント75件

WebGLProgram.jsがすでに倚くの凊理を行っおいる堎合、カスタムの文字列操䜜を芁求するのは少しハッキヌに思えたす。 関連するナヌスケヌスがありたす。これは、既存の#includeをオヌバヌラむドするのではなく、新しい#includeを远加するこずです。 実行時にTHREE.ShaderLibを倉曎するこずで、今日これを行うこずができたすが、同様に汚れおいるように感じたす。

おそらく、䞡方のより良い解決策は、マテリアルにカスタムShaderLibを提䟛できるようにするこずです。これにより、手動の文字列操䜜や氞続的な砎壊なしに、組み蟌みチャンクをオヌバヌラむド/拡匵​​できたす。 それは他の甚途のためのonBeforeCompileフックを排陀するものではありたせんが、あなたの䟋がやろうずしおいるこずずより䞀臎しおいるようです。

ずはいえ、rawむンクルヌドに基づくシェヌダヌ構成は、バヌゞョンごずに垞に非垞に脆匱になりたす。 すべおのスケルトンコヌド meshphong_vert.glsl を含めおもかたわない堎合は、組み蟌みのマテリアルを次のように拡匵できたす。

export class MyPhongMaterial extends ShaderMaterial {
  constructor({ color, radius, map, normalMap, emissiveMap }) {
    super();
    this.vertexShader = "...."
    this.fragmentShader = "....";
    this.uniforms = UniformsUtils.clone(ShaderLib.phong.uniforms);

    this.isMeshPhongMaterial = true;
    this.lights = true;

    this.uniforms.time = { value: 1 };
    //...
  }
}

いずれの堎合も、リリヌスごずにあたり倉曎しないように、組み蟌みのシェヌダヌの内郚構成に䟝存する必芁がありたす。 各むンクルヌドはすでに停装された関数であり、眲名が正しく指定されおいたせん。 むンクルヌドレベルのオヌバヌラむドではなく、関数レベルのオヌバヌラむドを提䟛するこずで、䞡偎ではるかにクリヌンで保守しやすくなるず思いたす。

今日は思った。

良い 2月10日にこのプルリク゚ストを行ったずきもそう思いたした。

https://github.com/mrdoob/three.js/pull/10791

唯䞀の違いは、コヌルバックを介しおそれを行っおいるこずだず思われたすか WebGLRendererの未䜿甚の匕数を利甚したした。

たずえば、threejsを法線マップで動䜜させるためにこれを䜿甚するのが奜きですが、これで解決するのは簡単だず思われるいく぀かの問題をリンクしたした。

私のブランチを芋お、これを詊しおみるか、この非垞に単玔な䟋を確認しおください照明/圱などを䜿甚しおカスタム倉圢をテストし、いく぀かのナニフォヌムを远加するだけです。

http://dusanbosnjak.com/test/webGL/three-material-shader-override/webgl_materials_shader_override.html

おそらく、䞡方のより良い解決策は、マテリアルにカスタムShaderLibを提䟛できるようにするこずです。これにより、手動の文字列操䜜や氞続的な砎壊なしに、組み蟌みチャンクをオヌバヌラむド/拡匵​​できたす。

https://github.com/mrdoob/three.js/pull/10791で䜕が起こっおいるかを正確に芁玄したす。もっず良い説明を曞けたらいいのにず思いたす:)


私はここで䜕が起こっおいるのかわからないこずを認めなければなりたせん。 3぀に貢献するこずをあきらめお、それを理解しおいなかった人を知っおいるず思いたすが、今ではちょっずむラむラしおいたす。

私が最初の段萜を読んだずきに既芖感を持っおいるので、䞻にむラむラしたす

... Object3DのonBeforeRenderず同様の方法。

これずたったく同じこずがonBeforeRender() https://github.com/mrdoob/three.js/pull/9738でも発生したした。この機胜を導入するには、説埗力のある1幎がかかりたした。

うわあ、2回、同じ開発者で 私は明らかにここで䜕か間違ったこずをしおいたすが、䜕ですか 初めおビルドファむルがチェックむンされたずき、どうしたらいいかわからなかったので、忘れおしたいたした。 しかし、今回はこのプルリク゚ストに加えお、珟圚競合が発生しおいたすが、簡単に解決でき、数か月間競合は発生したせんでした。

誀解しないでください、私はここの䜜品の虚栄心ではないず思いたす、私はただ人々によっおアむデアを実行しおフィヌドバックを埗たいず思いたす。 @unconedあなたが問題に粟通しおいお、おそらく別のこずを詊したこずがあるこずは明らかです。 あなたのようなナヌザヌが他のPRを芋逃した原因は䜕ですか

マテリアルごずのshaderlibに぀いおはかなり良いず感じたしたが、シェヌダヌ党䜓を文字列ずしお衚瀺/比范しおキャッシュを把握する関数がレンダラヌに1぀芋぀かりたしたが、それに぀いおはそれほど気分が良くありたせんでした。 フィヌドバックがあったらいいのに...

䟋に欠陥がありたしたか 頭は私の抜象的なスパむクボヌルよりも䜕が起こっおいるのかをはるかに明癜にするかもしれたせんが、䟋党䜓はより倚くの地面を芆う圱で機胜したす。 どういうわけか重いですが、倚くの頂点でsin / cosが原因だず思いたす。

最初からやり盎しおいるず思いたす...シヌンキットは絶察に恐ろしいですが、このAPIは本圓に玠晎らしいです

https://developer.apple.com/documentation/scenekit/scnshadable

ひどく文曞化されおいたすが、もっず興味のある郚分を芋぀けるこずはできたせんが、基本的には、シェヌダヌのさたざたな段階でフックを抜象化しおいたす。

今幎の初めに、たったく同じではないにしおも、䌌たようなこずをするように芋えるプルリク゚ストを行いたした。

https://github.com/mrdoob/three.js/pull/10791

唯䞀の違いは、コヌルバックを介しおそれを行っおいるこずだず思われたすか WebGLRendererの未䜿甚の匕数を利甚したした。

ただそのPRの䞖話をするこずができなくおすみたせん@pailhead。 私のアプロヌチの䞻な利点は、3぀の新しい行しか必芁ずしないこずだず思いたす。

そうは蚀っおも、私はあなたず@unconedの提案を研究するために少し時間を費やしたす。

これは間違いなくより゚レガントな感じで、たった3行です。 私はもう䞀方のパタヌンずは異なるパタヌンに埓っおいたした。 もう少し冗長かもしれないず蚀う぀もりでしたが、確かではありたせん。 もう1぀の利点は、数か月前に行っお良かったこずだけだず思いたす:)

うわあ、2回、同じ開発者で 私は明らかにここで䜕か間違ったこずをしおいたすが、䜕ですか

申し蚳ありたせん。 私が考えるこずができる唯䞀のこずは、おそらく私が圧倒されたずいうこずです。 長い議論や耇雑なPRで゚ネルギヌを消費しすぎるかもしれないので、埌でそれを残しお、より単玔なPRに移行するこずにしたした。

@pailheadはあなただけではありたせん。 @bhoustonは、このようなのPR、でも@WestLangleyずMugen87 @の倚くを持っおいたした。

繰り返しになりたすが、私がPRが奜きではないずいうこずではなく、PRには、その時点では提䟛できない泚意が必芁であるずいうこずです。 良い䟋はむンスタンス化PRです。 私はなんずかそれを読む時間を芋぀け、私自身の実隓を行い、単玔化を提案したした。 うたくいけば、私はすぐにそれを再蚪するこずができるでしょう。

これらすべおを管理し、すべおのPRに圌らが倀する泚意を払うこずは困難です。

䟋に欠陥がありたしたか 頭は私の抜象的なスパむクボヌルよりも䜕が起こっおいるのかをはるかに明癜にするかもしれたせんが、䟋党䜓はより倚くの地面を芆う圱で機胜したす。 どういうわけか重いですが、倚くの頂点でsin / cosが原因だず思いたす。

今あなたはそれに぀いお蚀及したす...ええ、ズヌムむンするず新しいMacBookProで10fpsで動䜜したす😮

圱ずランド、眪のコスなどだず思いたすが、ヒットが倚すぎるようです。

いずれにせよ、これを3行で実行したこずに驚いおいたす。私は、マテリアルパラメヌタがどのようにナニフォヌムに倉換され、そのパタヌンに埓うかに焊点を合わせすぎおいたした。 違いは、蟞曞のような代替のShaderLibを提䟛するため、 #include <>は異なるコヌドを取り蟌むこずです。 これが発生する前にむンクルヌドを削陀し、glslに眮き換えたす。 シェヌダヌの呚りにある皮のラッパヌを返す堎合、おそらくこの構文はよりクリヌンになる可胜性がありたす replace()代わりにチャンク名+ glslを指定するだけです。しかし、他の構文のように芋える可胜性がありたす。 。

これがあれば本圓にいいです。私はそれほど倚くの3D゚ンゞンを䜿ったこずがありたせんが、ナニティずシヌンキットにはこのようなものがあるようです。

@unconed

onBeforeCompile()利点の1぀は、材料特性が倉わらないこずだず思いたす。 そのため、組み蟌みのマテリアルを拡匵するような感じがしたす。

export class MyMeshPhongMaterial extends MeshPhongMaterial {
  constructor( parameters ) {
    super( parameters );
    this.onBeforeCompile = function ( shader ) {
      shader.vertexShader = shader.vertexShader.replace(
        '#include <begin_vertex>',
        'vec3 transformed = vec3( position.x + sin( position.y ) / 2.0, position.y, position.z );'
      );
    };
  }
}

var material = new MyMeshPhongMaterial();
material.color.setRGB( 1, 0, 0 ); // this still works

ShaderLibをいじるのは確かに泚意が必芁です。 ただし、氞遠に倉わらないフックを远加するこずは可胜です。

    #include <begin_vertex>
    % vertex %
    #include <morphtarget_vertex>
    #include <skinning_vertex>
    % transformed_vertex %
    #include <project_vertex>
    % projected_vertex %

眮換コヌドは次のようになりたす。

this.onBeforeCompile = function ( shader ) {
  shader.vertexShader = shader.vertexShader.replace(
    '% vertex %',
    'transformed.x += sin( position.y ) / 2.0;'
  );
);

もちろん、コンパむルする前に䜿甚されおいないフックはすべお削陀したす。

むンスタンスごずのShaderChunksず比范するず次のようになりたす

//given some material
var material = new THREE.MeshNormalMaterial();

//and some shader snippet
var myShader = [
    'float theta = sin( time + position.y ) / 2.0;',
    'float c = cos( theta );',
    'float s = sin( theta );',
    'mat3 m = mat3( c, 0, s, 0, 1, 0, -s, 0, c );',
    'vec3 transformed = vec3( position ) * m;', //and making assumptions about THREE's shader framework
    'vNormal = vNormal * m;'
].join( '\n' );

https://github.com/mrdoob/three.js/pull/10791 Material.definesアプロヌチず同じ

material.shaderIncludes = {

        begin_vertex: myShader,

    //uv_pars_vertex: [
    //  THREE.ShaderChunk['uv_pars_vertex'], //this doesn't have to be
    //  "uniform float time;",
    //].join('\n')
};

material.shaderUniforms = { time: { value: 0, type: 'f' || 'float' } }; //because this could just inject it in the right place (but needs type)

_これはチャンク名ずナニフォヌムオブゞェクトの蟞曞にすぎたせん。 ここでの文字列操䜜は、「このチャンクを再利甚しお、その䞊で䜕かを実行したい」ずいう方針に沿っおいたす。

このPR

material.onBeforeCompile = function ( shader ) {

    shader.uniforms.time = { value: 0 };

    shader.vertexShader = 'uniform float time;\n' + shader.vertexShader; //this feels hacky

    shader.vertexShader = shader.vertexShader.replace( //this is more verbose
        '#include <begin_vertex>',
        myShader
    );

};

onBeforeCompileの利点の1぀は、材料特性が倉曎されないこずだず思いたす。

他のPRでも同じように動䜜するので、どのように行っおもかたわないず思いたす。


私が考えるこずができるおそらく無関係な利点の1぀は、同じブロック内の同じレベルでマテリアルを操䜜するためのロゞックを維持できるこずです。 どこかに色を倉曎するコヌドがあり、埌でそのマテリアルにカスタムGLSLを远加する堎合は、コヌドを远加しお色のナニフォヌムを倉曎できたす。 テキストの壁をスキップ


uv_pars_vertexが玛らわしい堎合は、次の質問をするこずをお勧めしたす。

「 float rand( vec2)ようなカスタムGLSL関数をどこに挿入したすか」

次に、これは理にかなっおいるかもしれたせんhttps://github.com/mrdoob/three.js/pull/11050


もう1぀の議論は、GLSLを知っおいるず仮定し、THREEのシェヌダヌフレヌムワヌクを知っおいるず仮定するず、創造性を発揮し、どこに䜕を泚入するかを考える必芁がありたす。 uv_pars_vertexがマテリアルの拡匵を行うのに䟿利な堎所であるこずを理解するために、少し考えおほずんどのシェヌダヌを調べる必芁がありたした。

このようなものから抜象化に移行し、 lightingPhase 、 objectTransformation 、 perspectiveTransformationなどのフックを䜿甚するこずをお勧めしたす。 たたは、すべおのシェヌダヌプログラムに含たれおいる少なくずもguaranteedToBeAboveMainButBelowCommonsAndExtensionCallsダミヌチャンク。 % vertex %でそれを目指しおいるようですか しかし、私はその構文に慣れおいたせん。

このPRは、珟状では逆方向に進んでいるようです。 どこをタップする必芁があるかを知るこずに加えお、明瀺的に文字列を操䜜し、レンダラヌがすでに行っおいる䜜業の䞀郚を繰り返す必芁がありたす。 たた、最初の質問に加えお別の質問をする堎合

挿入しおいる関数内で、commonsチャンクで宣蚀されおいる関数を䜿甚するにはどうすればよいですか

シェヌダヌ党䜓にナニフォヌムを远加するだけでなく、より倚くの文字列操䜜を行っおいるこずに気付くかもしれたせん。

uv_pars_vertexがマテリアルの拡匵を行うのに䟿利な堎所であるこずを理解するために、少し考えおほずんどのシェヌダヌを調べる必芁がありたした。

私たちがオヌバヌ゚ンゞニアリングしない限り、それを回避する方法はないず思いたす。 % vertex %のアむデアは、フックに名前を付けお、コヌドを挿入しおいる状態を倚かれ少なかれ教えおくれるこずですが、どの倉数がどの時点で䜿甚可胜であるかを文曞化するのは難しいでしょう。 。

組み蟌みのマテリアルハッキングを蚱可するための扉を開いおいたすが、適切な「サポヌト」を提䟛できるずは思いたせん。 ナヌザヌは、物事が壊れる可胜性があるこずに泚意する必芁がありたす。

他のPRで取り組んでみたした。 少なくずも関数、バリ゚ヌション、属性、ナニフォヌム甚にダミヌフックを远加したした。 GLSLロゞックの倚くはすでに構造䜓で発生しおおり、シヌンキットは各倉数を文曞化しおいたすただし、同じ文曞を芋぀けるこずはできたせん。

私たちが進むに぀れお、おそらくリファクタリングする必芁がありたすが、これらの線に沿っお䜕かがありたす

#ifdef PHASE_FOO

#include <shader_foo> 
//someGlobalStruct.mvPosition = modelViewMatrix * myLogic( transformed );
//if there is glsl provided for phase "foo" document that it should operate on "transformed" 
//and that it should return "mvPosition" 
#end including <shader_foo>

#else 

  //default
  #ifdef USE_SKINNING

    vec4 mvPosition = modelViewMatrix * skinned;

  #else

    vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );

  #endif

#ifdef PHASE_BAR

#include <something_like_this>
//mvPosition = myPostDefaultTransformationLogic( mvPosition );

#endif

gl_Position = projectionMatrix * mvPosition;

#endif

もちろん、ifdefsずincludesはおそらくこのようには機胜したせん。 しかし、他のアプロヌチでは比范的簡単であるこずがわかりたす。 空の文字列を䜿甚しお、垞に#include <some_phase>远加できたす。 #ifdefを䜿甚しお、トリガヌされるものを管理するのに圹立぀可胜性がありたす。 したがっお、たずえば、「vertex_transformation」フェヌズのロゞックを提䟛する堎合、シェヌダヌは提䟛するものをすべお定矩したす。 各チャンクがGLSLで䜕をするかを文曞化するず、党䜓的に圹立ちたす。 抜象化をさらに進めるこずなく、チャンクが珟圚どのように構造化されおいるかに぀いお、このマップがあれば玠晎らしいず思いたす。

組み蟌みのマテリアルハッキングを蚱可するための扉を開いおいたすが、適切な「サポヌト」を提䟛できるずは思いたせん。 ナヌザヌは、物事が壊れる可胜性があるこずに泚意する必芁がありたす。

私たちはすでにすべおの玠材で利甚可胜な定矩のものを持っおいたす。 https://github.com/mrdoob/three.js/issues/10764は、 THREE.ShaderLibを倉曎しおから、 Materialむンスタンスで.definesプロパティを定矩するこずを提案したした。 確かに、私が゚ントリを曞くたでプロパティは文曞化されおいたせんでしたしかしあなたはそれを承認したした:)、そしおただ定矩されおいたせん。

しかし、これが珟圚機胜し、すべおのマテリアルに継承されおいる方法はサポヌトされおいたす。それに䜕かを入れるず、そのマテリアルのシェヌダヌに圱響したす。 さらに、すでにシェヌダヌラむブラリの䞀郚であるものを定矩するず、問題が発生する可胜性がありたす。

賢いお尻になろうずしおいるのではなく、䟋を考え出そうずしおいる。 私は䞻に定矩を䜿甚ShaderMaterialが、それはすべおの材料に圱響を䞎えない、どれだけのでWebGLRenderer䜜品。 次のようなロゞックはありたせん。

Phongようなマテリアルの抜象化のような、はるかに賢い衚面の堎合は、定矩を考慮しないでください。 3぀はシェヌダヌチャンクをオヌバヌラむドするように蚭蚈されおおらず、PhongテンプレヌトはGLSLが実行する必芁があるこずの最終的な暩限であり、これを䜿甚から隠すのに圹立぀ため、GLSL定矩がこれに干枉しないようにするこずは理にかなっおいたす。

それが壊れるかどうかは完党にはわかりたせんが、詊しおみる必芁がありたす。

そうは蚀っおも、それが倚くの利益をもたらすのであれば、私は物事を壊すオプションが欲しいです。 かなりカプセル化された小さなGLSLスニペットを䜿甚するず、3぀のバヌゞョンを簡単に倉曎しお、法線マップを異なる方法でレンダリングできたす。 法線を取り、それを別の法線に倉換するこずは非垞に簡単です。完党に異なる方法でコンピュヌタグラフィックスを始めない限り、これが壊れるのを芋るこずができたせん:)

むンスタンス化は別の䟋でした

ああ、ANGLE_INSTANCED_ARRAYSを䜿甚したいのですが、3぀はシャドりたたはPBRマテリアルではサポヌトされおいないようです。これらの2行を远加しお、機胜させおください。」

この機胜が぀いにthree.jsに登堎するのを芋おうれしいです:)。 はい、 yet another material modifier PRも䜜成したしたhttps://github.com/mrdoob/three.js/pull/7581叀すぎおコヌドはもう関係ありたせんが、基本的には@mrdoobのようなフックを
この機胜を䜿甚したいほずんどの人は、デフォルトのマテリアルを完党に曞き盎すのではなく、「わずかに」倉曎したいず思うので、倉曎内容を簡単に理解できるので、事前定矩されたフックのアむデアが奜きです。

私はこのPRのシンプルさが奜きですが、より構造化されたクリヌンな方法で物事を行う堎合は、コヌドに眮き換えるフックの蟞曞ず、ナニフォヌムやカスタムコヌドを远加する簡単な方法をすでに甚意しおおくこずをお勧めしたす。文字列を眮き換えるだけです。

@ fernandojsg 10791をチェックしおフィヌドバックを提䟛できる可胜性がありたす。メむンのすぐ倖偎に远加のフック「pre_vertex」などを配眮し、管理が少し増えおいるこずを陀けば、これは非垞によく䌌おいたす。

@fernandojsgあなたのPRを忘れおいたした😚。 あなたのPRは、私がこれが機胜しおいるのを芋始めた方法ず非垞によく䌌おいるず思いたす。 朜圚意識

賢いお尻になろうずしおいるのではなく、䟋を考え出そうずしおいる。 私は䞻に定矩を䜿甚ShaderMaterialが、それはすべおの材料に圱響を䞎えない、どれだけのでWebGLRenderer䜜品。

ラむブラリがそのようにハッキング可胜であるこずを嬉しく思いたすが、意図されおいないものに䞍正䜿甚機胜を内郚的に䜿甚するべきではありたせん。 そうすれば、壊れやすいコヌドになっおしたうのは簡単です。

7581をもう䞀床読んでいたす... % HOOKS %を远加しお、次のようなクラスを䜜成できたす。

THREE.ExtendedMaterial = function ( material, hooks ) {

    material.onBeforeCompile = function ( shader ) {
        var vertexShader = shader.vertexShader;
        var fragmentShader = parameters.fragmentShader;
        for ( var name in hooks ) {
           vertexShader = vertexShader.replace( '%' + name + '%', hooks[ name ] );
           fragmentShader = fragmentShader.replace( '%' + name + '%', hooks[ name ] );
        }
        shader.vertexShader = vertexShader;
        shader.fragmentShader = fragmentShader;
    };

    return material;

};

次に、これを行うこずができたす

`` `js
var material = new THREE.ExtendedMaterial
新しいTHREE.MeshBasicMaterial、
{頂点 'transformed.x + = sinposition.y/ 2.0;' }
;

だから問題は、どのフックが必芁かずいうこずです。

VERTEX
TRANSFORMED_VERTEX
PROJECTED_VERTEX

NORMAL
TRANSFORMED_NORMAL

FRAGMENT_UNIFORMS
INPUT_FRAGMENT
OUTPUT_FRAGMENT

@mrdoob䟋ずしお、MeshBasicMaterial頂点シェヌダヌに挿入する必芁がある堎所をこの芁点で確認できたす。

そしお、残りの資料に぀いおはここにありたす:)

https://github.com/mrdoob/three.js/pull/10750

VERTEX_UNIFORMSはあたりにも意芋が分かれおいるように聞こえたすが、関数、属性、たたは倉化をどこに远加する必芁がありたすか PRE_VERTEXか䜕か

NORMAL_MAPは間違いなく必芁です

vert:

PRE_VERTEX
VERTEX
TRANSFORMED_VERTEX
PROJECTED_VERTEX

NORMAL
TRANSFORMED_NORMAL

UV
fragment:

PRE_FRAGMENT
INPUT_FRAGMENT
LIGHT
NORMAL

OUTPUT_FRAGMENT

VERTEX_UNIFORMSはあたりにも意芋が分かれおいるように聞こえたすが、関数、属性、たたは倉化をどこに远加する必芁がありたすか PRE_VERTEXか䜕か

うヌん、意芋は どうしお

attribute vec4 aMyAttribute;はナニフォヌムではありたせん:)

float myRand( vec4 foo ) { /*logic*/ return vec4(bar,baz)}はナニフォヌムではありたせん

varying vec3 vMyVarying;もナニフォヌムではありたせん

耇数圢ではないか、ナニフォヌムではない

属性を「泚入」するためのナヌスケヌスは䜕ですか
代わりにgeometry.addAttribute( 'aMyAttribute', ... )を䜿甚するべきではありたせんか

あなたがそれを宣蚀する必芁がないこずを私は知りたせんでした。 ただ倉化ず機胜を残しおいたすか

ただ倉化ず機胜を残しおいたすか

いい芖点ね。

GLSLで属性を宣蚀する必芁はもうありたせんか ナニフォヌムのように機胜するず思いたした。GLSLで宣蚀したすが、JSで入力する必芁はありたせん。

このリストは、コヌドがかなり散らばっおしたう特定の事柄に関しおは、かなり急速に倧きくなる可胜性があるず思いたす。 法線マップを実行する1぀の方法には、vertずfragの䞡方での倉化ず倉換ロゞックずいう2぀の远加属性が含たれたす。

シンプルで゚レガントな最新の倉曎が気に入っおいたす。 私は@pailheadに同意し、グロヌバルスコヌプにコヌドを配眮する堎所が必芁です。 https://github.com/mrdoob/three.js/pull/7581で、 preMainVertex preMainFragmentをグロヌバルに泚入しお、さたざたな機胜に䜿甚できるようにしたした。 おそらくglobalVertex/Fragmentなどの名前の方が良いでしょう。

GLOBAL_VERTEXずGLOBAL_FRAGMENTいいですね👌

正確に私が他のPRでそれらに名前を付けた方法😆👍

@pailheadしかし、コヌドをマヌゞする秘蚣はわかっおいたす@ mrdoobが最終的に同様のこずを行うこずを

image

今、私もその名前が奜きで、それで私たちは行く準備ができおいるず信じおいたすか、それずも䜕かが足りたせんか 䟋をPRからこの新しいコヌドに倉換しおみたす;

コヌドが入る郚分は問題ありたせん。タむムラむンは少しずれおいたす。 7581はほが2幎前に提案されたした。 https://github.com/mrdoob/three.js/issues/10789で参照されおいなかったため、おそらくレヌダヌから倖れたした。 私はそれをぶ぀けたり、フォヌクしたりしたでしょう。

モゞュヌルをむンポヌトしお自分の3぀を遞んだずしおも、非公匏のコアモゞュヌルを䜿甚するこずにあたり満足しおいたせん。 「ねえ、fooを凊理するnpmパッケヌゞがありたす」ず蚀うのははるかに簡単です。 そのため、このようなPRは重芁だず感じおいたすが、3぀では十分な柔軟性がありたせん。

利益

どのような利益がありたすか 😆

コヌドが入る郚分は問題ありたせん。タむムラむンは少しずれおいたす。 7581はほが2幎前に提案されたした。 https://github.com/mrdoob/three.js/issues/10789で参照されおいなかったため、おそらくレヌダヌから倖れたした。 私はそれをぶ぀けたり、フォヌクしたりしたでしょう。

䜕 新しいPRを䜜成する前に、開いおいるすべおのPRをチェックしおいたせんか #trololol

NS 

リストにダむダルしお、できるだけ早くD

このシェヌダヌはたずえば

#include <shadowmap_pars_vertex>

void main() {

    #include <begin_vertex>
    #include <project_vertex>
    #include <worldpos_vertex>
    #include <shadowmap_vertex>

}

こんな颚に芋える

#include <shadowmap_pars_vertex>

void main() {

    % begin_vertex %
    % project_vertex %
    % worldpos_vertex %
    % shadowmap_vertex %

}

うヌん、それらすべおを眮き換えるのか、それずも珟圚の動䜜の䞀郚を残しおコヌドを挿入するだけなのかはわかりたせん。

#include <shadowmap_pars_vertex>

%GLOBAL_VERTEX% 
void main() {
       %PRE_VERTEX% 
    #include <begin_vertex>
...
}

私の最初のアプロヌチは、むンクルヌドの残りの郚分をそのたたにしお、䜙分なコヌドを挿入するこずでした。

したがっお、 % hook %は実際のフック専甚です。 <begin_vertex>を眮き換えたい堎合でも、文字列でそれを探す必芁がありたす。 begin_vertexフックはありたせんか

私のPRでは、マテリアルの動䜜を少し倉曎したかっただけです。通垞、fsが完党に実行された埌、たたは@mrdoobが圌の䟋で瀺したものず同様の倉換に察しお、いく぀かの色補正を行いたす。
ただし、各むンクルヌドを完党に眮き換えたい堎合は、むンクルヌドの代わりにフックを䜿甚し、フックをバむンドしなかった堎合に備えお、むンクルヌド自䜓を挿入するロゞックを远加する必芁がありたす。

法線に察しおこれを実行したいず思いたす導関数を䜿甚せず、3ds maxたたはmaya、たたは法線マップが生成されおいる堎所からの実際のTBN情報を䜿甚したす。 MeshPhongMaterialをむンスタンスで機胜するように適合させるには、いく぀かのチャンクを完党に眮き換える必芁もありたしたが、これはそのような゚ッゞケヌスのように感じたす。

これらは私が考えるこずができる2぀です、私はもっずあるのだろうかず思いたす。

したがっお、 % hook %は実際のフック専甚です。 <begin_vertex>を眮き換えたい堎合でも、文字列でそれを探す必芁がありたす。 begin_vertexフックはありたせんか

䞡方を亀換できたす。 珟圚のコヌドでは、すでに䜕でも眮き換えるこずができたす。 %HOOK%ものは䟿宜䞊のものです。

11562で述べたように、亀換可胜なシェヌダヌチャンクの抂念はどうですか

䟋

const material = new THREE.MeshPhongMaterial({
  color: 0xffffff,
  map: texture,

  parts: {
    frag: {
      map_pars_fragment: `
        uniform sampler2D map;
        uniform sampler2D map2;
     `,

      map_fragment: `
        vec4 texelColor = texture2D( map, vUv );
        vec4 texelColor2 = texture2D( map2, vUv );

    texelColor = mapTexelToLinear( 
          mix( texelColor, texelColor2, progress)
        );

    diffuseColor *= texelColor;
      `
    }
  }
});

material.uniforms.progress = {value: 1};
material.uniforms.map2 = {value: texture2};

これは、1぀のマテリアル䞊の耇数のテクスチャ間の遷移のコヌドがいかに簡単であるかを瀺しおいたす。

簡単に実装でき、䞍芁なコヌドを䜜成する必芁がありたせん。

@ sasha240100

https://github.com/mrdoob/three.js/pull/10791は、 partsがshaderChunksず呌ばれ、それを口論。
roll_eyes😆

チャンクはすでにマヌクされおいるので、 frag{}蟞曞も必芁ありたせん。 それらはすべお_fragmentず_vertex持っおいたす。

これは、文字列を怜玢しお眮き換える必芁があるものを芋぀ける必芁があるこずを陀いお、同じこずを行いたす。

@pailheadはい、 frag: {}削陀したしょう。 マテリアルシェヌダヌを連結する前に枡す必芁があるため、匕数ずしお䜿甚したした。 この堎合、連結埌に既存のパヌツを亀換するこずを簡単に回避できたす。

実際には、匕数ずプロパティの䞡方を远加できたす。 colorように

これは今どこにありたすか 䟋が.replace()を実行しおいるのがわかりたすが、フック/亀換可胜なチャンクが衚瀺されたせんか @mrdoob

ただこれに戻るこずができおいたせん。

% hook % PRをしたいですか

䞊蚘のコメントから、拡匵された資料が必芁ですか

THREE.ExtendedMaterial = function ( material, hooks ) {

    material.onBeforeCompile = function ( shader ) {
        var vertexShader = shader.vertexShader;
        var fragmentShader = parameters.fragmentShader;
        for ( var name in hooks ) {
           vertexShader = vertexShader.replace( '%' + name + '%', hooks[ name ] );
           fragmentShader = fragmentShader.replace( '%' + name + '%', hooks[ name ] );
        }
        shader.vertexShader = vertexShader;
        shader.fragmentShader = fragmentShader;
    };

    return material;

};

フックの堎所を遞択しお文曞化するこずは、実際にはそれほど簡単ではないかもしれたせんか 枡されたhooksをchunks眮き換えお、今のずころglobal_vertずglobal_fragを远加しお、むンクルヌドを探したすか 私が曞いた今、それは3人の責任でさえあるべきではないように思えたすが、䞀方で、将来的にはTHREE.ExtendedMaterialを% hook %スタブするでしょうか

あなたがTHREE.BAS拡匵子を知っおいるかどうかはわかりたせん。 次のように、カスタマむズされたマテリアルから配列ずしおアクセスできる元のマテリアルのプレヌスホルダヌを䜿甚したす。

  var material = new BAS.PhongAnimationMaterial({
    flatShading: true,
    vertexColors: THREE.VertexColors,
    side: THREE.DoubleSide,
    uniforms: {
      uTime: {type: 'f', value: 0}
    },
    vertexFunctions: [
      // cubic_bezier defines the cubicBezier function used in the vertexPosition chunk
      BAS.ShaderChunk['cubic_bezier'],
      BAS.ShaderChunk['quaternion_rotation']
    ],
    vertexParameters: [
      'uniform float uTime;',
      'attribute vec2 aDelayDuration;',
      'attribute vec3 aStartPosition;',
      'attribute vec3 aEndPosition;',
      'attribute vec3 aControl0;',
      'attribute vec3 aControl1;',
      'attribute vec4 aAxisAngle;'
    ],
    vertexInit: [
      'float tProgress = mod((uTime + aDelayDuration.x), aDelayDuration.y) / aDelayDuration.y;',
      'vec4 tQuat = quatFromAxisAngle(aAxisAngle.xyz, aAxisAngle.w * tProgress);'
    ],
    vertexPosition: [
      'transformed = rotateVector(tQuat, transformed);',
      'transformed += cubicBezier(aStartPosition, aControl0, aControl1, aEndPosition, tProgress);'
    ]
  });

単玔な芏則に基づいおいるずいう事実が気に入っおいたす。たずえば、 vertexInitずfragmentInitはmain関数の先頭にありたす。 vertexParametersずfragmentParametersはシェヌダヌの䞊郚にあり、ナニフォヌムたたは属性を定矩したす。 vertexFunctionsずfragmentFunctionsは、main関数の前にありたす。 法線、䜍眮などに぀いおは、以䞋同様です。

䜍眮でわかるように、倉数transformedを倉曎しお、最終的な䜍眮を倉曎したす。 たずえば、フラグメントシェヌダヌの法線 objectNormal たたは色 diffuseColor に぀いおも同様です。

これはPhongマテリアルがどのように芋えるかであり、プレヌスホルダヌのみを远加したす //github.com/zadvorsky/three.bas/blob/master/src/materials/PhongAnimationMaterial.js

こんにちはみんな、私はコンボをフォロヌしようずしおいたしたが、正盎なずころ、私はゲヌム開発者ではなくフロント゚ンドから来たので、私は負けたした。

MTLをロヌドしようずするず、次のようになりたす。

material.onBeforeCompile.toStringは未定矩です。

私のMTLファむルは元々.psdファむルを指しおいお、同じフォルダヌを含む数少ないpngの1぀に倉曎したした通垞psdをロヌドするこずはできないず思いたすが、ずにかくpsdでも倱敗したす。

# Blender MTL File: 'goblin.blend'
# Material Count: 1

newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.001617 0.005682 0.002517
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd Normal.png

コン゜ヌル出力は次のずおりです。

THREE.WebGLRenderer 87
bundle.js:54570 OBJLoader: 29.447998046875ms
bundle.js:28429 Uncaught TypeError: Cannot read property 'toString' of undefined
    at WebGLPrograms.getProgramCode (bundle.js:28429)
    at initMaterial (bundle.js:32350)
    at setProgram (bundle.js:32542)
    at WebGLRenderer.renderBufferDirect (bundle.js:31605)
    at renderObject (bundle.js:32335)
    at renderObjects (bundle.js:32308)
    at WebGLRenderer.render (bundle.js:32072)
    at bundle.js:9658
    at bundle.js:53976
    at XMLHttpRequest.<anonymous> (bundle.js:40153)

䜿甚しおいるコヌドは䞻に次のずおりです。

OBJLoader(THREE);

const modelLoader = new THREE.OBJLoader();
const textureLoader = new MTLLoader();
textureLoader.setTexturePath( 'models/' );
    textureLoader.load('models/goblin.mtl', function( materials ) {

            materials.preload();

            modelLoader.setMaterials( materials );
            modelLoader.load('models/goblin.obj', function ( obj ) {
                 scene.add( obj );
                renderer.render( scene, camera );


            });

        }); 


    renderer.render( scene, camera );

}

これはモデルの問題ですか スリヌで mtlロヌダヌで 解決策はありたすか

どんな助けでもいただければ幞いです。
ありがずう。

material.shader = shaderでmaterial.onBeforeCompile(shader=>...) material.shader = shaderようなこずをする必芁がありたすか

私はそれがやや䞍栌奜に感じるず思いたす、ある時点で他の提案を再怜蚎する䟡倀があるかもしれたせん:)

@jjalonso

これはバグのようです

https://stackoverflow.com/questions/46787166/react-and-three-js-mtlloader-material-onbeforecompile-is-undefined

これが原因ですが、 Materialにこの機胜がない原因は䜕ですか
https://github.com/mrdoob/three.js/blob/35a26f178c523514673d992da1aece23c1cfca6e/src/renderers/webgl/WebGLPrograms.js#L244

@mrdoob

これらの拡匵シェヌダヌが正しくキャッシュされおいない可胜性はありたすか 2぀の異なるマテリアルを䜿甚しようずしおいたす。1぀はdithering_fragment倉曎されおおり、もう1぀は倉曎されおいdithering_fragmentチャンクのないものだけが䜿甚されおいるように芋えたす。

私はこのフィドルでそれを再珟するこずができたせんでした
https://codepen.io/anon/pen/KQPBjd

しかし、私の䟋ではこのコヌドを䜿甚したす

const dithering_fragment = 
`
gl_FragColor.xyz *= foobar
`
// in onBeforeCompile
console.log(shader.fragmentShader)



md5-0f1a3ac67268b230968df20abdbd03d1



/**
#if defined( DITHERING )
  gl_FragColor.rgb = dithering( gl_FragColor.rgb );
#endif

gl_FragColor.xyz *= foobar

}
*/

しかし、他のむンクルヌドず定矩を共有するシヌンに別のマテリアルを远加しおも゚ラヌは発生したせん。

これが原因です

https://github.com/mrdoob/three.js/blob/35a26f178c523514673d992da1aece23c1cfca6e/src/renderers/webgl/WebGLPrograms.js#L244

䞡方のマテリアルにいく぀かのロゞックが提䟛されおいる同じ関数があり、ロゞックの倉数がコヌルバックの範囲倖であるため、䞡方のマテリアルが同じハッシュを取埗したすか

array.push( material.onBeforeCompile( obtainShaderSomehow ) )

https://github.com/mrdoob/three.js/pull/10791は次のように解決したした

https://github.com/pailhead/three.js/blob/879d52349bd5ef72c64fc962d8ca26bacaf489bf/src/renderers/webgl/WebGLPrograms.js#L242

global_vertexずglobal_fragmentプレヌスホルダヌ/フックを削陀した堎合、他のプルリク゚ストを再怜蚎したすか それらがあれば、倚くのファむルに觊れたしたが、それらがなければ、コヌドは少なくなりたす。 3行ではありたせんが、正しくハッシュされたす:)

このフィドルで#41にコメントするhttps://codepen.io/anon/pen/KQPBjd
シヌン内の他のメッシュのマテリアルが倉曎されたす。

これは最近のリリヌスに含たれおいたすか、それずもすべおただ開発䞭ですか

@mrdoob .onBeforeCompile()ハッキングされたマテリアルをシリアル化するのは難しいたたは䞍可胜ず思いたす。 完党に機胜するレンダリング、コピヌ、クロヌン、シリアル化など倉曎された組み蟌みマテリアルが必芁な堎合、ナヌザヌはShaderMaterialを䜿甚する必芁があるず思いたすか

_以䞋を可胜な限り玠晎らしく、建蚭的で、察立のない方法で読んでください_ :)

@takahiroxなぜこれが䞻匵され続けるのですか

ハッキングされたマテリアルをシリアル化するのは難しいたたは䞍可胜ず思いたす

あなたが持぀玠材「ハック」するずonBeforeCompileあなただけの任意の他の材料ず同じであるナニフォヌムを远加したす。 違いはありたせん。 material.colorをシリアル化できるのなら、なぜmaterial.userData.myColorをシリアル化できないのですか

私は戊い、テキストの壁などを始めようずはしおいたせん。 最短で簡単に説明しおいただけたすか、それずも䞍可胜たたは困難な理由に぀いお、少なくずも正しい方向に向けおください。 私は明らかな䜕かを芋逃しおいる可胜性を受け入れおいたすが、私がそうであれば、それが䜕であるかを理解したいず思いたす:)

蚘事によっお生成された非垞に小さなサンプルから、この実隓では、人々がShaderMaterialアプロヌチを䜿甚したいずは思わないようです。


これはちょうど頭に浮かんだ これが難しいか䞍可胜であるこずを蚌明するある皮のテストはありたすか お気に入り

runSerializationTest( someMaterialWithOnBeforeCompile ).expect( something )

onBeforeCompileメ゜ッドには非垞に任意のコヌドが含たれおいる可胜性があるため、そのコヌルバックを堅牢にシリアル化するこずは確かに䞍可胜です。 たずえば、メ゜ッドは同期XMLHttpRequestを䜜成し、その結果を凊理するこずができたす。 😅

ただし...実際に䜿甚されおいる方法シェヌダヌにパッチを適甚するために぀いおは、䞍可胜ではないこずに同意したす。 しかし、簡単なAPI fn.toString() はハッキヌであり、堅牢なAPIはより耇雑です。

私はただ問題を理解しおいたせん。 この芳点はどうですか

MeshPhongMaterialあり、 MeshStandardMaterialがないrNを取りたす。

MeshPhongMaterialをシリアル化できたす。 次のようなJSONを蚘述したす。

{
  color: 'red',
  specular: 'very',
  glossy: 'not much'
}

䞡方の材料を持぀rN + 1を取りたす。

䞡方を同じ方法でシリアル化するこずもできたす。

//phong
{
  color: 'red',
  specular: 'very',
  glossy: 'not much'
}

//standard
{
  color:'red',
  shininess: 'shiny',
  metalness: 'not much'
}

MeshStandardMaterialからGLSLをシリアル化した堎所はどこにもありたせん。

同じように、拡匵された玠材をシリアル化したす。

//extended PhongMaterial
{
   color: 'red',
   specular: 'very',
   glossy: 'not much',
   hamburger: 'medium rare'
}

デシリアラむズ

if ( data.userData.hamburger && HamburgerPhongMaterial )
   mat = new HamburgerPhongMaterial( data ) 
else{ 
   console.warn(`I'm terribly sorry, but you don't have the HamburgerPhongMaterial extension, using default fallback`)
   mat = new PhongMaterial( data ) 
}

ここで䜕が欠けおいたすか


onBeforeCompileずしお...そのコヌルバックをシリアル化したす。

なぜ、なぜあなたはそれを考えるのですか:)これが私の混乱の栞心だず思いたす、なぜこのフックに䜕か考えが䞎えられおいるのですか、それは材料の定矩、説明、䜕の䞀郚でもありたせん。 デヌタではなく、゚ンゞン、プラグむン、アプリなどず関係がありたす。

䞊蚘の䟋は私には問題ないように芋えたす。マテリアルを逆シリアル化するナヌザヌコヌドがHamburgerPhongMaterialの存圚を知っおいる必芁がありたすか 私はそれで問題はありたせん。14099ず同様のアプロヌチを取り、toJSONずfromJSONをオヌバヌラむドする堎合、必ずしもAPIの倉曎は必芁ありたせん。

ここで@takahiroxの質問を別の方法で解釈したのではないでしょうか。

... .onBeforeCompileでハッキングされたマテリアルをシリアル化するこずは困難たたは䞍可胜です。 完党に機胜するレンダリング、コピヌ、クロヌン、シリアル化など倉曎された組み蟌みマテリアルが必芁な堎合、ナヌザヌはShaderMaterialを䜿甚する必芁があるず思いたすか

私はそれを分割しようずしたす

  • ナヌザヌがプレヌンなMeshStandardMaterialでtoJSONを呌び出した堎合、そのonBeforeCompileによっお倉曎されたGLSLは、GLSLぞの倉曎が自動的にシリアル化されたせん。
  • ナヌザヌがGLSLぞの倉曎を瀺すいく぀かの远加のプロパティを䜿甚しおMeshStandardMaterialをシリアル化し、それらの远加のプロパティをどう凊理するかを知っおいるカスタムコヌドをロヌドする堎合、それは確かに問題ありたせん。
  • 他のさたざたなオプションShaderMaterial、NodeMaterial、glTFのKHR_techniques_webgl 、...を䜿甚しお、任意のカスタムマテリアルをシリアル化できたす。

私たちが話しおいるケヌスがそれらの1぀ではない堎合、私はここで誀解しおいるず思いたす。 これが玄14099の堎合、私はただそれをマヌゞするこずに賛成です。

うヌん、私は実際には最初の2぀を区別しおいたせんでした。 私はナニフォヌムを必芁ずしない䜕かを考えようずしおいたす、それは䟋えばgl_FragColor.xyz /= gl_FragColor.a;かもしれたせん。 しかし、私はあなたがこのようなものを資料ず䞀緒に シリアル化したいシナリオを想像するこずはできたせん。 マテリアルデヌタではなく、゚フェクトレンダラヌなどの範囲に含たれるようです。

materials = loadSerializedMaterials()

effect = new Effect()

effect.load( 'alphaDivide').then(()=>materials.forEach(mat.onBeforeCompile = effect.getOnBeforeCompile('alphaDivide')))

2番目の䟋は私がずっず考えおいたものです。 さたざたな入力ずずもに、それらをどう凊理するかに぀いおのヒントをシリアル化したすuserData.extension === 'hamburger' 。

私は䞋手に曞いたず思いたす。 私が蚀いたかったのは

  • .onBeforeCompile()ハッキングされた組み蟌みマテリアルは、組み蟌みマテリアルず同じAPIで正しくコピヌ、耇補、シリアル化されたせん。 ハッキングされおいない玠材ずしお扱われたす。
  • ナヌザヌが正しい結果を求めおいる堎合は、ナヌザヌ偎で远加の䜜業が必芁です。
  • ナヌザヌ偎の远加䜜業なしでThree.jsコアAPIを䜿甚しおハッキングされた組み蟌みマテリアルが必芁な堎合は、 ShaderMaterialなどの他のオプションを怜蚎する必芁がありたす。

私の質問は、特定のケヌスではなく、 .onBeforeCompile()のポリシヌに関するものです。 制限を明確にしお、ドキュメントにメモを远加したいず思いたした。

three.jsずレンダリングシステム党䜓を忘れた堎合、私はその芁点を理解しおいるず思いたす。 汎甚オブゞェクトずしお、 .clone()堎合は、クロヌンを䜜成しお䞀貫した期埅を持たせる必芁がありたす。 問題は、䞡方の解決策これを耇補するのではなく耇補するに有効な匕数があるように芋えるこずです。 リスナヌのクロヌンを䜜成したせんが、描画に圱響を䞎える䜕かが䞀貫しおいるこずもある皋床期埅したす。

他の領域でも同じ問題が発生したため、䞊蚘の提案はこれを行うための有効な方法だず思いたすたずえば、タヌゲット間で深床バッファヌを共有するこずもownThing || outsideThingで解決できたす。

機胜しない関数をキャッシュする代わりに、基本的にuserDataキャッシュしたすが、そのサブセットをキャッシュしたす。 userData.hamburger: 'rare'をキャッシュするこずは意味がありたせんが、 userData.effectOn: true". Theキャッシュしたす。 ownChunks | ownWhatever`はこの問題を解決したす。

たた、次の問題も解決したす。

onBeforeCompileメ゜ッドには非垞に任意のコヌドが含たれおいる可胜性があるため、そのコヌルバックを堅牢にシリアル化するこずは確かに䞍可胜です。

長い間、人々はonBeforeCompileを䜿甚しおきたしたが、そこにはどのような任意のコヌドが含たれおいるのかを知る必芁がありたす。 枡されたshaderオブゞェクトでのみ動䜜するず思いたす。そのオブゞェクトを倉曎したすが、ずにかくShaderMaterial意味のある倉曎のみが圱響したす。 自分でglものを蚭定するず、おそらくオヌバヌラむドされたす。それが私の頭に浮かぶ唯䞀のこずです。

これは基本的にpre three parseステップであり、 Material  defines:{}で䜿甚できないため、必須のuniforms:{}むンタヌフェむスずずもにシェヌダヌを自分で解析する機䌚が埗られたす。䞀方、 defines:{}を実行するず、どちらもShaderMaterial兄匟になりたす。

それをどのように行うか、぀たり任意のコヌドが䜕であれ、問題ではありたせん。 䜕も返したせんが、 shader:{} 、レンダラヌがそれを䜿甚したす。

私が提案するアプロヌチ

  1. さたざたなクラスにownThingを远加したす。 THREE.WebGLRenderTargetは.ownStencilDepthBuffer持぀こずができたす。 ここで、私が䞊で提案したように、それはownGLSL:{} ownInput | ownUniformsいく぀かのバヌゞョンになりたす。 shader:{}オブゞェクトを倉曎するための任意のコヌドの必芁性を排陀したす。

WebGLRenderer スヌパヌプラむベヌトの内郚から発生するこのような入力が䞎えられた堎合

const shader = {
  uniforms: buildFromMaterial(mat),
  vs: getVSTemplate(key),
  fs: getFSTemplate(key)
}

これを栞兵噚

shader = onBeforeCompile( shader )

shader.vs //invalid GLSL
shader.uniforms //you got some extra ones that onBeforeCompile may have mutated, maybe removed some others

shader = ___parse(shader) //private step

shader.vs //valid glsl, (not a template)

compile(shader)

これを䜿っお

function parseShader(shader){
   return {
     uniforms: shader.uniforms,
     vs: parseChunks(shader.vs)
     fs: parseChunks(shader.fs)
   }
}
//FIX FOR HASHING BUG
function parseChunk( material, chunkName ){
  return material.ownChunks[chunkName] || THREE.ShaderChunks[chunkName]
}

//do whatever you want with the templates, maybe remove an `#include <>`
shader = onBeforeParse(shader)

shader.vs //template || valid glsl

shader = parseShader(shader) //sample OWN || PRIVATE 

shader.vs //valid GLSL 

//if you want to apply a regex on the entire valid glsl, or compile node material or something else
shader = onBeforeCompile( shader )

compile(shader)
  1. WebGLRenderer ShaderMaterial以倖のこずを知らないようにしたす。

どこにでも

const mat = new THREE.MeshBasicMaterial()
const sm = new THREE.ShaderMaterial()

も぀

const mat = nodeMaterial.compile() //returns ShaderMaterial, with a friendly interface (same as StandardMaterial for example)

const mat = chunkMaterial.compile()

TLもののDRは、䞊蚘の「コンパむル」パヌスが発生したずきに、特定の時点気にしないナヌザヌです。 圌らは䜕が起こるかをもっず気にかけおいるず思いたす。そしお、䜕が起こるかは、単䞀のナヌスケヌスではないにしおも、ほんの䞀握りに分離するこずができたすin: shaderString, out: shaderString 。 パむプラむンの特定のポむントで実行する必芁がある理由は、調査しお理解する䟡倀があるず思いたす。 それはその助け以䞊に物事の邪魔をしおいるようです。

@mrdoob .onBeforeCompile()ハッキングされたマテリアルをシリアル化するのは難しいたたは䞍可胜ず思いたす。 完党に機胜するレンダリング、コピヌ、クロヌン、シリアル化など倉曎された組み蟌みマテリアルが必芁な堎合、ナヌザヌはShaderMaterialを䜿甚する必芁があるず思いたすか

onBeforeCompile()の䜿甚がシリアル化されるずは思っおいたせんでした...

onBeforeCompileを䜿甚しお激しく噛たれたした。 組み蟌みのシェヌダヌを定矩された方法で倉曎できるシェヌダヌヘルパヌクラスがありたす。 これを行うには、onBeforeCompileメ゜ッドを䜿甚したす。 どうやら、最初のコメントで述べたように、WebGLProgramはonBeforeCompile.toStringをハッシュずしお䜿甚したす。 しかし、私の関数はゞェネリックであるため頂点シェヌダヌずフラグメントシェヌダヌの䞀郚を倉数に眮き換えたす、onBeforeCompile.toStringはシェヌダヌごずに異なっお芋えたせん。 これは、私の異なるシェヌダヌがすべお同じプログラムずしおキャッシュされるこずを意味したした。 eval呌び出しずuuid、そしお今では私の関数はすべお異なっお芋えたす。 これを理解するために氞遠にかかりたした。

@donaldrhttps  //github.com/mrdoob/three.js/issues/13192を参照しおください。 これらの制限を文曞化するずよいず思いたす。

evalの䜿甚方法を教えおください。 ずっず考えおいたのですが、汚れすぎたようです。 基本的に、ボディの䞊郚にconst fdscxnmdrek435rkjlを远加しおから、評䟡するこずができたすか

これは、私の異なるシェヌダヌがすべお同じプログラムずしおキャッシュされるこずを意味したした。 eval呌び出しずuuid、そしお今では私の関数はすべお異なっお芋えたす。 これを理解するために氞遠にかかりたした。

それは非垞にむラむラするように聞こえたす、ごめんなさい。 😞必芁な倉曎がラむブラリ自䜓で意味があるように思われる堎合は、未解決の問題も歓迎したす。

未解決の問題も歓迎したす。

既存のものを再開するこずを怜蚎したすか 13192は同じように芋えたすが、閉じられたしたcrying_cat_face機胜ず芋なされた堎合、回避策がそこに投皿されおいれば本圓にいいでしょう。

うヌん...

const _obc = shader => {...}
const obc = `
function (shader){
  const _${ hash() }
  ${ _obc.toString() }
  _obc(shader)
}
`
material.onBeforeCompile = eval(obc)

^これは機胜したすか eval䜿甚したこずはありたせん。

17567を介したMaterial.customProgramCacheKeyの導入により、開発者は、条件ステヌトメントを䜿甚しおonBeforeCompile()を介しお倉曎されたマテリアルに察しおシェヌダヌプログラムが共有されない可胜性がありたす。

新しいスレッド13446などのonBeforeCompile()コンテキストで、他の既存の問題たたは拡匵機胜に぀いお説明しおください。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡