Three.js: [EffectComposer] مشكلة في 2 RenderPass متتاليين

تم إنشاؤها على ١ فبراير ٢٠١٢  ·  18تعليقات  ·  مصدر: mrdoob/three.js

الرابط

http://demo.bkcore.com/threejs/webgl_tron_glow.html

الرمز

glowcomposer = new THREE.EffectComposer( renderer, renderTarget );

glowcomposer.addPass( renderModelGlow ); // RenderPass
glowcomposer.addPass( hblur ); // ShaderPass
glowcomposer.addPass( vblur ); // ShaderPass
glowcomposer.addPass( effectSave ); // SavePass

glowcomposer.addPass( renderModel ); // RenderPass
glowcomposer.addPass( finalPass ); // ShaderPass

السياق

حصلت على مشهدين بنفس الشيء / الكاميرا / الضوء. واحد مع نسيج منتشر (http://demo.bkcore.com/threejs/webgl_tron.html) والآخر بنسيج متوهج (المناطق المتوهجة بيضاء على أسود).

خط أنابيب العرض الخاص بي هو كما يلي:
أقوم أولاً بعرض مشهد التوهج وتطبيق H / V blur عليه ، ثم تخزين الإخراج في frameBuffer باستخدام SavePass.
ثم أريد أن أجعل المشهد منتشر.
وأخيرًا امزج ذلك مع المخزن المؤقت للإطار المتوهج

المشكلة

تمرر عينات التوهج 2D الخاصة بي بشكل جيد إلى أداة التظليل النهائية الخاصة بي ، ولكن كما ترون في العرض التوضيحي ، فإن استدعاء RenderPass الثاني للمشهد المنتشر لا يعمل جيدًا. ينتج اللون الأسود فقط.

حاولت أن أجعل المشهد المنتشر في تمريرة عرض واحدة وهذا يعمل. عندما أستخدمه كبرنامج RenderPass ثانٍ لا يعمل.

أيه أفكار ؟

شكرا لك.
تيبوت د.

Question

التعليق الأكثر فائدة

يبدو أن العرض الأصلي لم يعد يعمل:

FWIW لقد قمت بعمل عرض تجريبي لتطبيق FX بشكل انتقائي والتأليف عبر Additive Blend (باستخدام Three.js v79) هنا: https://www.airtightinteractive.com/demos/selective-fx/

ال 18 كومينتر

أعتقد أنه بسبب تدمير المخزن المؤقت للعمق ، انظر # 1017.

بالنسبة لحالة الاستخدام الخاصة بك ، ما قد ينجح بدلاً من ذلك هو استخدام مؤلفين (وبالتالي هدفان منفصلان تمامًا للعرض ، ولكل منهما مخزن مؤقت للعمق).

شيء من هذا القبيل:

glowComposer = new THREE.EffectComposer( renderer, renderTargetGlow );

glowComposer.addPass( renderModelGlow ); // RenderPass
glowComposer.addPass( hblur ); // ShaderPass
glowComposer.addPass( vblur ); // ShaderPass

finalComposer = new THREE.EffectComposer( renderer, renderTargetFinal );
finalComposer.addPass( renderModel ); // RenderPass
finalComposer.addPass( finalPass ); // ShaderPass

ستكون الطبقة المنتشرة متاحة الآن كعينة عينة نسيج عادية tDiffuse في finalComposer وطبقة الوهج التي ستوفرها من glowComposer .

سيكون إما glowComposer.renderTarget1 أو glowComposer.renderTarget2 اعتمادًا على عدد معين من التمريرات وما إذا كانت الممرات تبديل المخازن المؤقتة الأمامية والخلفية ، أبسطها هو تجربة الاثنين ومعرفة أيهما يعمل.

finalshader.uniforms[ 'tGlow' ].texture = glowComposer.renderTarget1;

لقد حاولت ذلك ، لكنني حصلت على نتيجة غير متوقعة.

هذا هو الكود الذي اقترحته:
http://demo.bkcore.com/threejs/webgl_tron_glow_swap.html
لا يزال tDiffuse من نموذج العرض أسود.

وهذا هو نفس الكود بالضبط ، مع تبديل ممري التجسيد فقط (المشهد المنتشر في مؤلف التوهج ، ومشهد التوهج في الملحن النهائي):
http://demo.bkcore.com/threejs/webgl_tron_glow_swap2.html
إنه بالطبع ليس التأثير الذي أبحث عنه لأن الانتشار غير واضح وليس التوهج ، ولكن كما ترون ، تعمل كل من عينات tGlow و tDiffuse ...

وكل ما فعلته هو المبادلة (السطر 130 و 175):
ثلاثة جديدة RenderPass (المشهد ، الكاميرا) ؛
مع
ثلاثة جديدة. RenderPass (glowscene ، glowcamera) ؛

إنه أمر مذهل للغاية.

تحتاج إلى استخدام تنسيق RGBA لأهداف العرض إذا كنت تستخدم الشفافية.

حسنًا ، أوافق ، لكنني لا أستخدم أي شفافية لأن ممر التوهج الخاص بي يجعل اللون الأبيض على الأسود ويمر منتشر جيدًا ... منتشر على الأسود. ثم أقوم بتكوينها مع إضافة حتى لا تكون هناك حاجة إلى الشفافية.

ومع ذلك ، وللتأكد فقط ، قمت بتغيير تنسيق RT إلى RGBA ، لكن هذا لم يغير شيئًا.

المشكلة الغريبة هنا ، هي أن القيام بالمشهد / الكاميرا RenderPass الخاص بي بعد المشهد المتوهج / الكاميرا المتوهجة لا يعمل RenderPass ، أثناء القيام بالمشهد / الكاميرا RenderPass قبل أن يعمل RenderPass المتوهج / glowcamera.

هممم ، تبدو مشكلة مشاركة الهندسة للمواد المختلفة (انظر # 1211).

جرب هذا:

function createScene( geometry, x, y, z, b ) {

    zmesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial() );

    // ...

    var geometryClone = THREE.GeometryUtils.clone( geometry );
    var gmat = new THREE.MeshBasicMaterial( { map: gtex } );
    var gmesh = new THREE.Mesh( geometryClone, gmat );

    // ...
}

نعم ! هذا كان هو.

الآن تم ملء اثنين من العينات الخاصة بي بشكل صحيح. شكرا لك :)

تعديل

همهمة ... بعد سلوك غريب آخر ، عيّناتي جيدتان عندما أفعل

gl_FragColor = texel;

أحصل على الانتشار بشكل صحيح (http://demo.bkcore.com/threejs/webgl_tron_glow_swap2.html)

عندما أفعل

gl_FragColor = glow;

أحصل على التوهج بشكل صحيح.

ولكن عندما أحاول عمل مزيج مضاف بسيط على كليهما
gl_FragColor = تيكسل + توهج ؛
أحصل على التوهج فقط (http://demo.bkcore.com/threejs/webgl_tron_glow_swap.html).

آسف لطرح الكثير من الأسئلة ، كنت أحاول تشغيل هذا ولكن دون جدوى ..

EDIT2

في الحقيقة يبدو أن العمل

gl_FragColor = texel + glow;

يبدو مثل هذا فيما يتعلق بإخراج الإخراج:

gl_FragColor = glow + glow;

إنه مثل texel vec4 يتم استبداله بشكل غير مفهوم بـ glow vec4. يبدو جنونيًا.

تحتاج إلى وضع الزخارف في وحدات نسيج مختلفة:

uniforms: {
    tDiffuse: { type: "t", value: 0, texture: null },
    tGlow:    { type: "t", value: 1, texture: null }
},

في احسن الاحوال!
http://demo.bkcore.com/threejs/webgl_tron_glow.html

شكرا مرة اخرى :)

الصيف!

في حالة اهتمام أي شخص بعرض التوهج الانتقائي باستخدام Three.js ، فقد قمت للتو بنشر مقال صغير حول هذا الموضوع: http://bkcore.com/blog/3d/webgl-three-js-animated-selective-glow.html

آمل أن يساعد.

لطيف ؛)

بدلاً من ذلك ، بدلاً من الاستنساخ الهندسي ، هناك خيار آخر أرخص وهو استخدام المزيد من المواد المتشابهة (بحيث تحتاج الهندسة في كلا المسارين إلى نفس المخازن المؤقتة).

في هذه الحالة ، بدلاً من استخدام مادة أساسية لتمرير التوهج ، يمكنك تجربة مادة لامبرت بدون إضاءة منتشرة ، فقط مع الإضاءة المحيطة.

شيء من هذا القبيل:

glowScene.add( new THREE.AmbientLight( 0xffffff ) );

// ...

var gmat = new THREE.MeshLambertMaterial( { map: gtex, ambient: 0xffffff, color: 0x000000 } );
var gmesh = new THREE.Mesh( geometry, gmat );

في الواقع ، هذا يعمل بشكل مثالي.

http://demo.bkcore.com/threejs/webgl_tron_glow_seq.html

سوف أقوم بتحديث مقالتي بخصوص هذا الحل. شكرا لك !

أنا أقوم بنقل هذا الكود إلى r60 وأواجه نفس المشكلة بشكل غريب مع ربط مؤلفي التأثير. لدي ممر godray يعمل إذا عرضته على الشاشة. لكن التمريرة النهائية تنتج النموذج فقط. يبدو أن إخراج oclcomposer إلى قناة النسيج "tadd" يأتي على ما يرام عندما لا أستخدم مؤلف تأثير منفصل !! لقد حاولت مع Renderer.PreserveDrawingBuffer = صحيح ولكن هذا لم ينجح أيضًا. لقد حاولت ضبط التصفية التلقائية على خطأ ولكن لم يكن الأمر كذلك.

إذا عرضتُ oclcomposer بعد الملحن النهائي وجعلت إخراج godray يمر إلى الشاشة ، يمكنني رؤية Godrays ولكن بدون نماذج.

بدلاً من توجيه إخراج oclcomposer إلى قناة tadd في التمرير النهائي ، إذا قمت بتوجيهها إلى MeshBasicMaterial وأنشأت رباعيًا محكمًا وأضفته إلى المشهد الرئيسي ، يمكنني الآن رؤية النموذج و Godrays (على متن طائرة) ، لا التأثير الذي أريده ولكنه يخبرني أن أنابيب النسيج تعمل.

// COMPOSERS
//-------------------
var renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, stencilBufer: false };

renderTargetOcl = new THREE.WebGLRenderTarget( SCREEN_WIDTH/2, SCREEN_HEIGHT/2, renderTargetParameters );

hblur = new THREE.ShaderPass( THREE.ShaderExtras[ "horizontalBlur" ] );
vblur = new THREE.ShaderPass( THREE.ShaderExtras[ "verticalBlur" ] );
var bluriness = 2;

hblur.uniforms[ 'h' ].value = bluriness / SCREEN_WIDTH*2;
vblur.uniforms[ 'v' ].value = bluriness / SCREEN_HEIGHT*2;

var renderModel = new THREE.RenderPass( scene, camera );
var renderModelOcl = new THREE.RenderPass( oclscene, oclcamera );

grPass = new THREE.ShaderPass( THREE.Extras.Shaders.Godrays );
grPass.needsSwap = true;
grPass.renderToScreen = false;

oclcomposer = new THREE.EffectComposer( renderer, renderTargetOcl );

oclcomposer.addPass( renderModelOcl );
oclcomposer.addPass( hblur );
oclcomposer.addPass( vblur );
oclcomposer.addPass( grPass );

var finalPass = new THREE.ShaderPass( THREE.Extras.Shaders.Additive );
finalPass.needsSwap = true;
finalPass.renderToScreen = true;
finalPass.uniforms[ 'tAdd' ].texture = oclcomposer.renderTarget1;

renderTarget = new THREE.WebGLRenderTarget( SCREEN_WIDTH, SCREEN_HEIGHT, renderTargetParameters );
finalcomposer = new THREE.EffectComposer( renderer, renderTarget );

finalcomposer.addPass( renderModel );
finalcomposer.addPass( finalPass );

//RENDER
//-----------
oclcomposer.render(0.1);
finalcomposer.render( 0.1 );

bbiswas لدي نفس المشكلة مع أحدث إصدار. هل وجدت أي شيء؟

نعم ، لقد نجحت - ها هو الرمز

var renderTargetOcl = new THREE.WebGLRenderTarget( webGL_window_width/4, webGL_window_height/4, renderTargetParameters );

            hblur = new THREE.ShaderPass( THREE.ShaderExtras[ "horizontalBlur" ] );
            vblur = new THREE.ShaderPass( THREE.ShaderExtras[ "verticalBlur" ] );

            var bluriness = 3;

            hblur.uniforms[ 'h' ].value = bluriness / webGL_window_width*2;
            vblur.uniforms[ 'v' ].value = bluriness / webGL_window_height*2;

            var renderModel = new THREE.RenderPass( scene, camera );
            var renderModelOcl = new THREE.RenderPass( g_occlusion_buffer, g_occlusion_camera );

            grPass = new THREE.ShaderPass( THREE.Extras.Shaders.Godrays );
            grPass.needsSwap = true;
            grPass.renderToScreen = false;

            g_volumetric_light_composer = new THREE.EffectComposer( webGLRenderer, renderTargetOcl );

            g_volumetric_light_composer.addPass( renderModelOcl );
            g_volumetric_light_composer.addPass( hblur );
            g_volumetric_light_composer.addPass( vblur );
            g_volumetric_light_composer.addPass( hblur );
            g_volumetric_light_composer.addPass( vblur );
            g_volumetric_light_composer.addPass( grPass );

            var finalPass = new THREE.ShaderPass( THREE.Extras.Shaders.Additive );
            finalPass.needsSwap = true;
            finalPass.renderToScreen = true;
            finalPass.uniforms[ 'tAdd' ].value = g_volumetric_light_composer.renderTarget1;

            finalcomposer.addPass( renderModel );
            finalcomposer.addPass( finalPass );

//in Render Loop



                g_occlusion_camera.position = camera.position;

                g_occlusion_camera.lookAt( new THREE.Vector3(0,0,0) );
                camera.lookAt( new THREE.Vector3(0,0,0)  );

                vlight.position = pointLight1.position;
                vlight.updateMatrixWorld();

                var lPos = THREE.Extras.Utils.projectOnScreen(pointLight1, camera);
                grPass.uniforms["fX"].value = lPos.x;
                grPass.uniforms["fY"].value = lPos.y;

                g_volumetric_light_composer.render(0.1);
                finalcomposer.render( 0.1 );

شكرا جزيلا!
كان الخط مع finalPass.uniforms[ 'tAdd' ].value . كان لدي finalPass.uniforms[ 'tAdd' ].texture قبل.

مرحبًا يا حبيبي ، هل يمكنك إضافة المكان الذي أنشأت فيه g_occlusion_buffer لهذا الجزء:

var renderModelOcl = جديد THREE.RenderPass (g_occlusion_buffer، g_occlusion_camera) ؛

يبدو أن العرض الأصلي لم يعد يعمل:

FWIW لقد قمت بعمل عرض تجريبي لتطبيق FX بشكل انتقائي والتأليف عبر Additive Blend (باستخدام Three.js v79) هنا: https://www.airtightinteractive.com/demos/selective-fx/

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

lmcd picture lmcd  ·  74تعليقات

ghost picture ghost  ·  81تعليقات

QuaziKb picture QuaziKb  ·  73تعليقات

sunag picture sunag  ·  161تعليقات

kdilayer picture kdilayer  ·  62تعليقات