Three.js: إضاءة انتقائية

تم إنشاؤها على ١٠ أغسطس ٢٠١٤  ·  101تعليقات  ·  مصدر: mrdoob/three.js

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

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

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

لذلك أعتقد أنني بحاجة إلى نوع من المجموعات أو القنوات للإضاءة ، حتى أتمكن من ضبط الأشياء التي تتأثر بمصدر ضوء واحد والأشياء التي تتأثر بآخر.

لم أجد أي شيء من هذا القبيل في الأضواء أو الأشياء ، لذلك اعتقدت أنه قد يكون ميزة جيدة.

وبالمناسبة ، إذا لم يتم تنفيذها بعد ، ما هو النهج الموصى به لحل مثل هذه المهام باستخدام الحالة الحالية لـ three.js؟

Enhancement

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

هل لديك رابط لمثال لشيء كهذا؟

هنا ، صنعت واحدًا من أجلك فقط: https://jsfiddle.net/f2Lommf5/524/

ال 101 كومينتر

ما أقوله هو وجود حقل channel في حقل THREE.Light و lightChannel في THREE.Mesh أو شيء من هذا القبيل. إذا كان الأخير فارغًا ، فإنه يتأثر بجميع مصادر الضوء. إذا لم يكن الأخير فارغًا ، فإنه يتأثر فقط بالقنوات الضوئية ذات القيمة نفسها.

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

يبدو أنك تريد استخدام الظلال؟

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

ما أحتاجه هو أن مصدر ضوء معين لا يؤثر على مجموعة واحدة من الشبكات ، ولكنه يؤثر على المجموعة الأخرى.

عادةً ما أفعل ذلك باستخدام أسلوب مثل هذا: مثال على سلسلة مناقشة :

glEnable(GL_LIGHT0);
//...
glEnable(GL_LIGHTn);

// Draw the walls to room 1
DrawWalls(room[0]);

// Draw the contents of room 1
DrawContents(room[0]);

glDisable(GL_LIGHT0);
//...
glDisable(GL_LIGHTn);

// Draw the walls to room 2
DrawWalls(room[1]);

// Draw the contents of room 2
DrawContents(room[1]);

لذلك يبدو وكأنه ميزة مختلفة عن مجرد الظلال. أم هل فاتني شيء؟

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

ربما يكون الحل الأكثر بساطة هو الأكثر فعالية هنا:

  1. أضف channel (أو group ) إلى THREE.Light
  2. أضف affectedByLightChannel (أو affectedByLightGroup ) إلى THREE.Mesh (أو ربما حتى إلى وجه في الهندسة)

ما رأيك؟

ربما تكون "القناة المُؤثرة" طويلة جدًا ويمكن أن تفعل شيئًا مثل "lightChannel" ، لكنني أعتقد أنه سيكون مناسبًا: فقط أرقام القنوات على مصدر الضوء وأجهزة الاستقبال.

مثل هذا:

    light = new THREE.PointLight(0xFFF7D6, 1.0, 15)
    light.channel = 123
    testScene.add(light)

    testScene = new THREE.Scene
    geometry = new THREE.BoxGeometry(2,2,2)
    material = new THREE.MeshLambertMaterial 
        color: 0xffffff

    cube = new THREE.Mesh(geometry, material)
    cube.lightChannel = 123
    testScene.add(cube)

إذا كان lightChannel يساوي 0 ، فإنه يتأثر بكل القنوات. إذا كان channel يساوي 0 ، فإنه يؤثر على جميع الشبكات.

لذلك سيكون متوافقًا تمامًا مع السلوك الحالي.

قد يكون من الصعب جدًا فهم ذلك ... ربما يكون من الأفضل شيئًا كهذا:

cube.lightInfluences = [ light1, light2 ];

يبدو جيدا بالنسبة لي.

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

ماذا عن خاصية قناع عدد صحيح بسيط للشبكات والأضواء؟

light = new THREE.PointLight(0xFFF7D6, 1.0, 15)
light.mask = 0xffffffff; // default mask
testScene.add(light);

cube = new THREE.Mesh(geometry, material)
cube.mask = 0xffffffff; // default
testScene.add(cube);

لا تضيء الأشياء بعد ذلك إلا بواسطة الأضواء إذا كانت قيمة AND المنطقية لأقنعةها غير صفرية.
سيسمح هذا للأضواء بالتأثر بأكثر من قناة واحدة ، بدون طرق إضافية على الأشياء.

لن يؤثر القناع الافتراضي لـ 0xffffffff على الكود الموجود.

ماذا قال @ satori99 .

على الرغم من أنني أعتقد أن mask يجب أن يكون ملكية Light و Mesh*Material ، بدلاً من ذلك. (فقط تلك المواد التي تتأثر بالأضواء.)

أيضًا ، يمكن بدلاً من ذلك تسمية الخاصية lightMask أو lightChannel أو channel .

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

ما هو الشيء الذي يمكنك فعله بالأقنعة ولا يمكنك فعله باستخدام نهج المصفوفة؟

يمكنني إعطاء مثال من المهمة مع غرفتين أعلاه.

تتمثل النقطة الرئيسية لاستخدام نهج القناة على نهج المصفوفة في أن العمليات البسيطة مثل "نقل الضوء 1 من الغرفة 1 إلى الغرفة 2" تصبح أكثر تعقيدًا إذا كنت تستخدم المصفوفات.

بدلا من مجرد الإعداد

light1.channel = 2

(تم ضبطه سابقًا على 1)

سيتعين عليك العثور على جميع العناصر الموجودة في الغرفة 1 التي تحتوي على light1 في مجموعة lightInfluences مسبقًا ، ثم إزالة الضوء من المصفوفات الخاصة بهم ، ثم إضافته إلى جميع الكائنات في الغرفة 2.

نفس القصة مع عملية بسيطة مثل "نقل الكائن 1 من الغرفة 1 إلى الغرفة 2". بدلاً من ضبط تأثير القناة من 1 إلى 2 ، ستحتاج إلى العثور على جميع الأضواء في تلك الغرفة ، ثم إزالتها من مجموعة تأثيرها ، ثم البحث عن جميع الأضواء في الغرفة الثانية وإضافتها.

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

أعتقد أنه ينبغي تنفيذه كقناع. (سواء تم تنفيذه على وحدة المعالجة المركزية أو وحدة معالجة الرسومات ، فهذه مشكلة للمناقشة لاحقًا.)

يمكننا أن نوضح عبر الأمثلة كيفية ضبطه ، ويمكن للمستخدمين متابعة النمط.

إذا كنت تعتقد أن هذا لا يزال معقدًا للغاية ، فيمكننا إنشاء واجهة برمجة تطبيقات THREE.Channels له.

light.channels = new THREE.Channels();
...
light.channels.clear();
light.channels.add( channel );
light.channels.remove( channel );
light.channels.all();

نفس الطرق لـ Mesh*Material .

أنا أحب واجهة برمجة التطبيقات تلك :)
أستطيع أن أرى هذا يعمل للأشياء والأضواء ، لكن كيف تراه يعمل مع المواد؟

المواد فقط هي التي تستجيب للأضواء. أعتقد أن هذا يجب أن يكون خاصية للمادة.

أوافق على هذا معwestlangley. تعتمد الأضواء على المواد.

نفس القصة مع عملية بسيطة مثل "نقل الكائن 1 من الغرفة 1 إلى الغرفة 2".

حسنًا ، هذه مشكلة. لن يكون Channels مستندًا إلى الكائن.

حسنًا ، هذه مشكلة. القنوات لن تكون قائمة على الكائن.

لكن لماذا؟ هل هو قيد تقني؟

لأنه نوع من يبطل فكرة كل ذلك. لأنه يمكن أن يكون هناك كائنات مختلفة ، والتي تعيد استخدام نفس المادة ، ولكن يجب أن يضيء أحدهما والآخر - لا ينبغي.

لكن لماذا؟ هل هو قيد تقني؟

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

لأنه يمكن أن يكون هناك كائنات مختلفة ، والتي تعيد استخدام نفس المادة ، ولكن يجب أن يضيء أحدهما والآخر - لا ينبغي.

يمكنك استخدام نفس المادة لجميع الكائنات في المشهد - فقط clone مادة الكائنات التي تتطلب مادتها قيمًا موحدة مختلفة. يجب أن يكون هناك برنامج تظليل واحد فقط يتقاسمه الجميع.

أعتقد أنه ينبغي تنفيذه كقناع. (سواء تم تنفيذه على وحدة المعالجة المركزية أو وحدة معالجة الرسومات ، فهذه مشكلة للمناقشة لاحقًا.)

هل يمكن التعامل مع هذا بسهولة إلى حد ما في وحدة معالجة الرسومات مباشرة؟

هل يمكن التعامل مع هذا بسهولة إلى حد ما في وحدة معالجة الرسومات مباشرة؟

نعم ، سوف تحتاج إلى تمرير زي إضافي channels للأضواء والمواد.

ماذا عن نظام إدارة الطبقة؟ كنت أقوم بتجميع الشبكات في طبقات وتطبيق الأقنعة من هناك (يمكن أن تؤثر على الأضواء والظلال والرؤية وما إلى ذلك) ، هل ستكون الوحدة مثالًا جيدًا؟

الظلال هي أيضا موضوع ذو صلة. أعتقد أنه يجب أن يكون هناك أيضًا شيء مثل إلقاء الظل الانتقائي. مثل "ReceiveShadowFrom = ..." (وقائمة المصادر) بدلًا من "getShadow = true" فقط.

لأنه عندما تقوم بتعيين الأضواء التي تؤثر فقط على غرفة معينة (في المثال الخاص بي) ، فأنت تريد أيضًا على الفور أن تلقي تلك الأضواء بظلالها فقط على كائنات هذه الغرفة.

يجب أن تكون سمات الظلال على المواد وليس الكائنات لنفس الأسباب المذكورة أعلاه في هذا الموضوع.

يجب أن تكون سمات الظلال على المواد وليس الكائنات لنفس الأسباب المذكورة أعلاه في هذا الموضوع.

نعم ، هذا منطقي!

هل هناك أي خطط لتضمين هذه الميزة (مثل إصدار مستهدف مخطط للمسودة الأولى)؟

كحل بديل ، هل يمكنك تحقيق معظم متطلباتك من خلال وجود مشهد منفصل لكل غرفة (وأضوائها)؟

renderer.autoClear = false;
...
renderer.render( scene1, camera );
renderer.render( scene2, camera );

حسنًا ، سأحاول هذا النهج!

الإضاءة / الظلال الانتقائية أمر لا بد منه للإصدارات المستقبلية IMO.

+9999 كبير لهذا ، أود أن أكون قادرًا على تحديد ما إذا كانت المادة تلقي بظلالها من مصدر الضوء أ أو من مصدر الضوء ب. هل حصل أي شخص على حل حاليًا بخلاف مشهدين؟ هذا سيجعل الأمور مؤلمة جدًا بالنسبة لي ...

حماقة مقدسة كيف هذا لا يزال غير مطبق؟ بعد +9999 من روهان)

هاها تخميني أنه من الصعب تنفيذ tsone ، هل يمكنك تقديم بعض المعلومات حول هذا الالتزام؟ التصفح على عميل الهاتف الآن

كيف يكون من الصعب تنفيذها إذا كانت هذه مجرد زي موحد ينتقلون إلى المواد. كل ما يتعين عليهم فعله هو القائمة العالمية للأضواء البديلة مع القائمة المحددة في المادة ، إذا كانت موجودة ، في مكان ما عميق في عارض webgl.

إليك JSFiddle بسيط يختبر تنفيذ طبقات فرع Dev:
https://jsfiddle.net/Angrypickle/t8f7q3vo/4/
لسوء الحظ ، اعتبارًا من هذه اللحظة ، لا يبدو أنه يعمل بشكل صحيح. أم أنني أفعل شيئًا خاطئًا؟

نعم. لا تعمل الطبقات مع الأضواء حتى الآن. إنهم يعملون مع الكاميرا / الكائن رغم ذلك! 😊

روجر أن سيدي! إليك JSFiddle محدث يستخدم كاميرات متداخلة لتحقيق إضاءة انتقائية بطبقات:
https://jsfiddle.net/Angrypickle/t4a1eusL/
يبدو أنه يعمل بشكل صحيح على سطح المكتب والجوال. أي شخص يرى أي شيء سيء للغاية مع هذا النهج؟ على الأقل حتى يتم ربط الأضواء بوظيفة الطبقات؟

أي شخص يرى أي شيء سيء للغاية مع هذا النهج؟

بالطبع إنه أمر سيء. بدلاً من وجود كاميرا واحدة تتنقل في المشهد ، سيتعين على الأشخاص الآن القيام بأشياء camera1.add( camera2 ); أعني أن هذا هو WTF عندما أنظر إليه. مثل ماذا؟ الكاميرا في كاميرتي؟ ماذا لو كان لدي عشرات الغرف التي يجب أن تكون مضاءة بشكل فردي؟ كم عدد الكاميرات التي أحتاجها؟ وطبقات ... لم تكن هناك طبقات أمس، والحق، والآن لدي للتعرف عليهم.

انتهى التشدق ، كي لا نقول أن لدي الحل الأمثل لهذا. على سبيل المثال ، اعتاد الأشخاص alternativa3d على إلقاء الضوء على الأشياء الموجودة في الصناديق المحيطة بالضوء. كان لهذا ميزة إعداد next-to-0 للمستخدمين النهائيين ، لكنه كان ينهار عندما كان يجب أن تكون الحدود بين الأضواء في الزاوية. ولكن مع ذلك ، إذا اضطررت إلى حل هذه المشكلة في مشروع فعلي في الوقت الحالي ، فسأقرر على الأرجح تجريف المواد القياسية المستخدمة في ShaderMaterial-s وتمرير الأضواء التي أريدها يدويًا هناك.

إن طبقات
نهج @ Zob1 ليس بالتأكيد هو النهج الصحيح. نأمل ألا يستغرق الأمر وقتًا طويلاً حتى تعمل الطبقات أيضًا مع الأضواء.

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

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

ما يمكننا فعله في الوقت الحالي هو إظهار / إخفاء الأشياء من الكاميرا:

لنفترض أنك تقوم بلعبة ، وفي المحرر ، تستخدم المجالات لعرض المصادمات. يمكن ضبط هذه المجالات على الطبقة 1 ، ويمكن لمحرر الكاميرا تمكين الطبقات 0 و 1 ، ولكن يمكن ضبط كاميرا اللعبة على الطبقة 0. وبهذه الطريقة ، سترى جميع الدمى في المحرر الخاص بك ، ولكن في اللعبة هم إعادة ذهب.

أعتقد أن هذا سيكون أكثر منطقية كلما أضفت الوظيفة إلى المحرر نفسه. ربما ينبغي علينا القيام ببعض الأمثلة أيضًا.

حق! إذن ما أريد فعله هو أن لدي شخصيات ثنائية الأبعاد في عالم Three JS الخاص بي. تحتاج هذه الشخصيات إلى ظلال "موضعية" لجعلها تبدو وكأنها جزء من البيئة. أقوم حاليًا بتحقيق ذلك باستخدام أشكال هندسية شفافة لدائرة سوداء موضوعة عند أقدامهم وبعض الأشياء المبتذلة إلى حد ما لجعلها تعمل في زوايا. حتى مع ذلك ، فإنه لا يعمل بشكل جيد على الإطلاق على الأسطح المعقدة.

كانت فكرتي الأصلية هي أن يكون هناك أماكن هندسية غير مرئية على شكل "هالات" فوق كل حرف وإنشاء ضوء يشير مباشرة إلى الأسفل ، ويغطي المشهد بأكمله. ستلقي هذه الهالات بظلالها من مصدر الضوء هذا فقط بينما يلقي كل شيء آخر في المشهد بظلاله من مصدر الضوء "الرئيسي".

أعتقد لكي تنجح هذه الفكرة ، نحتاج إلى طبقات ، أليس كذلك؟

ستلقي هذه الهالات بظلالها من مصدر الضوء هذا فقط بينما يلقي كل شيء آخر في المشهد بظلاله من مصدر الضوء "الرئيسي".

اعتدنا أن يكون لدينا خيار shadowOnly ، لكن تمت إزالته.

FWIW ، هناك هذا النهج لإنشاء الظلال ...

آه لكن الظل فقط لن يعمل حقًا لأن الهالات ستلقي بظلالها من كلا مصدري الضوء ، أريد فقط أن تلقي بظلالها من أحدهما.

سوف أتحقق من هذا المثال ، على الهاتف الآن ولكن يبدو واعدًا.

قم بتحرير Hmm ولكن إذا غيرت هذه الكرة موقعها في المشهد وكان لشبكة الأرض ارتفاعات متفاوتة ، فهل يتطابق ظلها مع معايير سطح الأرض بشكل صحيح؟

لا...

نعم اعتقد ذلك. تحتاج طبقات! هيهي

مرحبًا @ rohan-deshpande ،

نعم لحالة الاستخدام الخاصة بك ، ستحتاج إلى طبقات من نوع ما. كنت أنا من نفذ ميزة shadowmesh منذ فترة. كان من المفترض استخدامها في مشهد يحتوي على أرضية مسطحة أو أرضية ، لأنها ظلال أحادية المستوى. ومع ذلك ، إذا احتجت في أي وقت إلى ظلال طائرة واحدة سريعة ورخيصة (ولكنها صحيحة) ، فمن الصعب التغلب عليها من حيث الأداء. كان السبب في أنني أضفت ذلك هو أنه حتى بالنسبة إلى المشاهد التجريبية البسيطة ، فإن خرائط الظل أسقطت معدل الإطارات بشكل كبير. من ناحية أخرى ، تعمل Shadowmeshes بسرعة حتى على هاتفي.

يمكنك التحقق من لعبتي التي تستخدمها هنا:
https://github.com/erichlof/3dLightCycles

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

+1 هنا للطبقات في المستقبل :)

لعبة erichlof تبدو وتعمل بشكل رائع على iPhone6 ​​man.

حسنًا ، أعتقد أنني سأنتظر الطبقات. حتى ذلك الحين ، يجب أن يكون الحل المبتكر الخاص بي كافياً.

لا لم يتم تنفيذه بعد. سيتعين عليك انتظار الطبقات أو تجربة أحد الحلول المدرجة في ITT (مشاهد منفصلة على سبيل المثال).

+99999 مرة أخرى

هذا سيكون بالتأكيد مفيد جدا ولدينا الآن طبقات تعمل ، وهو ما يبدو أنه ما كان يعيق هذا. إذن ، ها هي النتوء الودية. ؛-)

@ manthrax تحقق من هذا!

+99999 مرة أخرى

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

مرحبا!
سأحتاج إلى هذه الميزة ، وفكرت في تنفيذها ، لأنني أعتقد أنني حددت المكان الذي يمكن أن يتم فيه ذلك ( initMaterial في WebGLRenderer ) ويجب أن يكون الأمر بسيطًا جدًا باستخدام الطبقات الموجودة.

أفكر في إنشاء قناع بت خاص بالضوء (ككائن Layers ) لتحديد الطبقات التي تتأثر بكائن ضوء معين (بغض النظر عن طبقة الكائن الخاصة بالضوء) ، ثم تصفية الأضواء / خرائط الظل التي كزي موحد لكل كائن في الوظيفة المذكورة أعلاه.

هل سيكون ذلك ذا صلة؟

سأحاول ذلك وأرسل طلب سحب بمجرد أن أنجز هذا إلا إذا قمت بإعادة توجيهي إلى طريقة أخرى قبل ذلك.

تحديث:

https://github.com/tiesselune/three.js/tree/selective-lighting

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

لا يزال يتعين علي اختبار المزيد ، وتقديم مثال ذي صلة قبل إرسال طلب سحب.

تحديث:

لقد أجريت بعض الاختبارات الإضافية ، ووجود نفس المادة على كائنين في طبقات مختلفة (ولهما إعدادات إضاءة مختلفة) يتسبب في قيام العارض بتحديث المادة باستمرار (عبر needsUpdate ) منذ إعدادات الإضاءة على التغييرات المادية بين شيئين ، وهو ما كان مستحيلًا من قبل. هذا يعني انخفاضًا كبيرًا في الأداء وشذوذًا بصريًا (نظرًا لأن تحميل المواد الأخير يفوز في وقت العرض)

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

إليك حلين يمكنني استخدامهما:

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

  2. يمكنني إضافة طبقات على مستوى المواد بدلاً من مستوى الكائن (وإنشاء نظام طبقات متوازية للأضواء) بحيث يكون استخدام مواد مختلفة إلزاميًا لتحقيق إعدادات إضاءة مختلفة. هذا يعني أنه سيكون هناك نظام طبقة حالي للرؤية (على الأشياء والكاميرات) ونظام مختلف للإضاءة (على المواد والأضواء).

ماذا تظنون يا جماعة؟

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

فقط للتوضيح ، عند تعيين needsUpdate ، في هذه الحالة ، يقوم فقط بإعادة حساب القيم الموحدة ، أليس كذلك؟ لا ينبغي أن تضطر إلى إعادة تجميع تظليل لأن التظليل المختلفة يجب تخزينها مؤقتًا. ما نوع الأداء الذي تراه؟ هل استخدمت ملف تعريف لمعرفة مكان إجراء الحسابات الإضافية بالضبط؟

بالمناسبة ، يجب أن يكون filterAmbientLights filterAmbiantLights filterAmbientLights .

أنت محق بشأن الخطأ الإملائي. لقد كتبت في الواقع كل شيء باستخدام كلمة "ambiant" قبل أن ألاحظ أنها خطأ ونسيت حدوث ما. 😇

أعتقد أنني سأقوم بتحريك معلومات الطبقة على المادة بعد ذلك. يبدو أكثر ملاءمة وتوافقًا مع الطريقة التي يعمل بها.

جاء انخفاض الأداء (ولا يزال) من initMaterial (ثم acquireProgram و getShaderParameter وهو بطيء للغاية لسبب ما) يتم استدعاء كل إطار عدة مرات لأن lightHash مختلفًا في كل مرة ، حيث يتم تعيين material.needsUpdate إلى true .

راجع للشغل أنا أستخدم أدوات التنميط في Chrome. (الجداول الزمنية وملف التعريف).

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

أنا لا أحصل عليه سواء؛

ها هي مجموعة المكالمات (في كل إطار) والتسرب الرهيب للذاكرة الذي يلي ذلك ، إذا كنت معتادًا على هذه الأشياء ، فقد يساعدني ذلك في فهم الخطأ الذي يحدث. يبدو أنه ينشئ WebGLProgram s كل إطار ...

threejscalltree

ربما يكون replaceLightNums الذي يقوم بتحديث كود تظليل الرأس / الجزء أثناء إنشاء WebGLProgram ، مما يتسبب في إعادة تجميعه ، أو اعتباره تظليلًا مختلفًا ...؟

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

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

لا أعرف WebGLPrograms جيدًا بما يكفي لأقول ما يحدث ، ولكن يبدو أنه يجب تخزين هذه المظلات مؤقتًا نيابة عنك.

الأمر بسيط للغاية ، في الواقع:

  • لتعرف أو لا تتصل acquireProgram ، يحصل initMaterial على "كود" التظليل من ذاكرة التخزين المؤقت (إنه أكثر من تجزئة ، في الواقع ، تم إنشاؤه في getProgramCode ) ويقارن إلى "رمز" برنامج المادة الحالي.
  • نظرًا لأن هذه الوظيفة تنشئ "الرمز" من المعلمات بما في ذلك عدد كل نوع من الضوء ، والذي يتم تصفيته وعلى الرغم من اختلافه بين الكائنات ، يمكن أن يكون الرمز مختلفًا للمادة نفسها (على سبيل المثال ، نفس البرنامج) من كائن إلى آخر.
  • نظرًا لأن هذه العملية يتم تكرارها لكل كائن ، فإن "الكود" يتغير عدة مرات لكل إطار ، مما يتسبب في إعادة تجميعه عدة مرات في إطار واحد: مما يتسبب في انخفاض الأداء.
  • ومع ذلك ، نظرًا لأن العديد من الكائنات تحتوي على نفس المادة ، وبالتالي ، فإن نفس البرنامج ، فقد تم تكرار الكائن الأخير من خلال فرض معلماته على البرنامج ، مما تسبب في إضاءة كلا الكائنين بنفس إعداد الإضاءة ولكن ليس بالضرورة نفس خرائط الظل (التي يمكن حسابها للأشياء بترتيب مختلف ، ولكنها تعاني من نفس مشكلة "آخر كائن يفوز") ، مما يسبب لي الشذوذ البصري.

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

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

آمل أن يكون التفسير مفهومًا بدرجة كافية

أتساءل عما إذا كان بإمكاننا تمرير قناع الطبقة إلى التظليل (واحد موحد لكل كائن وآخر موحد لكل ضوء). ثم يمكننا إضافة شيء مثل هذا هنا .

شيء مثل...

for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {

    pointLight = pointLights[ i ];
    pointLight.distance *= float( object.mask & pointlight.mask > 0.0 );

    ...

}

مه ، لا أعتقد أنه يمكننا القيام بعمليات ثنائية في glsl ...

نعم ، يبدو أن العمليات على مستوى البت تبدأ في GLSL 1.30 وأن WebGL القياسي يستخدم 1.00. 😕

مرحبًا mrdoob و tiesselune ،

وصل كل من Chrome 56 و Firefox 51 للتو ، مما يعني أن WebGL 2.0 ممكّن افتراضيًا (يتبع WebGL2 مواصفات OpenGL ES 3.0). هذا يعني أن عمليات البت (وغيرها من الأشياء الرائعة مثل الزخارف ثلاثية الأبعاد) متاحة الآن. لا أعرف ما إذا كان Three يستعدون ببطء للانتقال إلى WebGL 2.0 ، لكنني أجريت بعض التغييرات الإلزامية على نسختي المكونة من ثلاثة 84.js وقمت بتمكين WebGL 2.0 ، وقمت بإجراء عملية بسيطة في تظليل فقط للتأكد من ذلك عملت ، وفعلت!
https://developers.google.com/web/updates/2017/01/nic56
https://developer.mozilla.org/en-US/Firefox/Releases/51

فقط أردت أن أخبرك. +1 لفكرة التقنيع :-)

مرحبًا erichlof ! هذه أخبار رائعة لـ WebGL2 ؛ هذا يعني أن عارض WebGL2 سيكون على الأرجح قادرًا على التعامل مع مشاكل التقنيع بطريقة أكثر فاعلية.

على أي حال ، نظرًا للاستخدام المحدود للغاية للمتصفحات التي تدعم WebGL2 حتى الآن ، لا أعتقد أنه يمكننا تجاهل الجهود لجعلها تعمل في WebGL 1: لقد استغرق الأمر وقتًا طويلاً حتى تتمكن جميع المتصفحات تقريبًا من تشغيل تطبيقات WebGL ، لذلك من المحتمل أن يكون أطول قليلاً حتى يصبح WebGL 2 قابلاً للاستخدام حقًا على نطاق واسع ... 😕 لكن شكرًا للتلميح!

أهلا مرة أخرى!

تحديث جديد: لقد فعلت ما اعتقدت أنه ضروري لإدارة الذاكرة ، ولكن يبدو أن مجموعة البيانات المهملة لـ JS لها علاقة كبيرة بتكوين البرنامج (البرامج قيد التشغيل ، وعلامات التبويب المفتوحة ، والإضافات) في الوقت الذي أقوم فيه بتشغيل ملفات التعريف. هل يمكن لشخص لديه خبرة أكبر قليلاً في ذلك أن يؤكد أن الكود الخاص بي ليس ذاكرتي الجائعة مقارنة بالإصدار الحالي من threejs؟

على أي حال ، لقد قدمت مثالاً في الأمثلة / webgl_lights_selective_lighting.html . الشيء هو أنني حصلت على عناصر بصرية مرتبطة بخريطة الظل عند استخدام ضوءين موضعيين (على نفس الطبقات) في وقت واحد على الأشياء المصقولة في المشهد. الكائنات الثابتة تتصرف كما هو متوقع. لقد أجريت اختبارات وتحدث ذلك على فرع dev أيضًا ، دون التفكير في طبقات الضوء الانتقائية على الإطلاق (في الواقع ، لقد أضفت للتو ضوءًا موضعيًا في مثال خريطة الظل ، في فرع dev). هل يعرف أحد من أين يأتي ذلك؟

هذه لقطة شاشة:
shadowmap

يجب أن يكون من الممكن مشاهدة المثال مباشرة هنا:

https://rawgit.com/tiesselune/three.js/selective-lighting/examples/webgl_lights_selective_lights.html

أتلقى خطأ بالرغم من:

Uncaught TypeError: Cannot read property 'set' of undefined
    at init (webgl_lights_selective_lights.html:117)
    at webgl_lights_selective_lights.html:67

looeee : عليك تشغيل npm run build-uglify على مضيف محلي. طواعية لم أقم بتضمين البنيات في ارتباطاتي لأغراض الاندماج ...

او يجب ان؟

تحرير: إليك ارتباط عمل على فرع مختلف لأغراض الاختبار: https://rawgit.com/tiesselune/three.js/selective-lights-test/examples/webgl_lights_selective_lights.html

مرحبًا ، +999999 مني. يجب تنفيذ ذلك (على الأقل مع THREE.Layers )

$$('.comment-body').reduce((acc, el) => {
  let mat = el.textContent.match(/\+(\d+)/)
  let num = +(mat && mat[1] || 0)
  return acc + num
}, 0)
>> 1219997

🤔

mrdoob قام بحساب + Ns في هذا الموضوع

راجع للشغل ، +14570 للأضواء الانتقائية

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

على سبيل المثال ، في القلم التالي ، أود أن تعمل الإضاءة بطريقة واحدة لعناصر DOM مقابل طريقة أخرى لـ Sphere لكي تكون الإضاءة أكثر واقعية:

https://codepen.io/trusktr/pen/RjzKJx

يمكن تحقيق تأثيرات معينة تبدو وكأنها نقطة ضوء واحدة من خلال الجمع بين مصباحين أو أكثر تؤثر بشكل انتقائي على عناصر معينة فقط.

على سبيل المثال ، في المثال السابق ، يمكنني زيادة شدة الضوء للحصول على ظل جميل المظهر على "عنصر DOM" ، ولكن بعد ذلك سيبدو Sphere شديد اللمعان والسطوع. إذا تمكنت من الحصول على ضوء خافت للكرة ، وضوء أكثر سطوعًا لـ "عنصر DOM" ، عندها يمكنني تحقيق شيء أكثر واقعية بهذه الطريقة ، حيث يبدو للمشاهد أنه لا يزال هناك ضوء واحد فقط. يمكن بعد ذلك تجريد هذا النوع من الأشياء بعيدًا في واجهة برمجة تطبيقات ذات مستوى أعلى مما يجعل الأمر يبدو وكأن هناك ضوءًا واحدًا يتم التلاعب به عندما يكون خلف الكواليس مصباحان من نوع Three.js قيد التشغيل بالفعل.

تضمين التغريدة

كحل بديل ، هل يمكنك تحقيق معظم متطلباتك من خلال وجود مشهد منفصل لكل غرفة (وأضوائها)؟

هل لديك رابط لمثال لشيء كهذا؟ هل يمكن أن يكون لها تأثيرات عرض غير متوقعة أخرى على النتيجة؟

تأثيرات عرض أخرى غير متوقعة على النتيجة؟

ترتيب عرض الكائنات الشفافة ، على سبيل المثال - سيتم عرض الكائنات الشفافة في المشهد 1 قبل الكائنات المعتمة في المشهد 2.

هل لديك رابط لمثال لشيء كهذا؟

هنا ، صنعت واحدًا من أجلك فقط: https://jsfiddle.net/f2Lommf5/524/

ترتيب عرض الكائنات الشفافة ، على سبيل المثال - سيتم عرض الكائنات الشفافة في المشهد 1 قبل الكائنات المعتمة في المشهد 2.

هذا ما كنت أفكر؛ فإنه يجعل الحل البديل فقط حلاً لحالات محدودة للغاية. نتطلع إلى الحل الحقيقي!

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

makc هذا مثال على المشكلة التي أحاول حلها:

https://discourse.threejs.org/t/how-to-make-shadows-darker-on-transparent-objects/1389

أعتقد أن الإضاءة الانتقائية ستساعد حقًا في ذلك.

trusktr أعتقد أنه يمكنك حل ذلك عن طريق تغيير مادة ظل mrdoob. يظهر فقط نسيج الظل الأبيض والأسود ، ويمكنك تعديله ليكون شفافًا حسب الضرورة

تبدو الأقنعة في PlayCanvas سهلة الاستخدام حقًا للإضاءة الانتقائية: https://forum.playcanvas.com/t/set-certain-object-to-not-receive-light/785.

هل يمكننا دمج هذا؟ أعتقد أن مشاكل الظل كانت بسبب عدم علاقة لامبرت شادر بالتغيير في الكود. تضمين التغريدة

ErikBehar كنت أبحث بالفعل عن شيء أفعله بعد ظهر هذا اليوم ، سأحاول تحديث الكود إلى أحدث ثلاثة جي إس وإرسال طلب سحب ربما؟ سأستمتع حقًا بمعرفة أنني قدمت مساهمة حقيقية في مثل هذا المشروع الكبير. (ومن الجيد الحصول على تأكيد بأن هذا الخطأ ليس له علاقة بتغييراتي)

تحرير: اكتشفت للتو أن هذا الجزء من الكود قد تغير كثيرًا. سأحتاج إلى بعض الوقت على ما أظن لأن الحالات التي كنت أستخدمها سابقًا انتقلت من WebGLRenderer إلى WebGLLights.

tiesselune كنت بحاجة إلى إدخال هذا في مشروع لذا تقدمت وقمت بنقل الكود الخاص بك إلى الإصدار 93 انظر: https://github.com/ErikBehar/three.js/tree/selectiveLights

يمكنني القيام بالعلاقات العامة إذا كنت ترغب في ذلك يا رفاق؟ تضمين التغريدة

ErikBehar حسنًا ، يبدو الأمر كما كنت أهدف إليه ولكن لم يكن لدي الوقت الكافي للقيام بذلك بالكامل. أعتقد أنني كنت سأقوم بنقل وظائف التصفية / التجزئة خارج WebGLRenderer وإضافتها إلى كائن حالة WebGLLights بالرغم من ذلك. أشعر أنهم ينتمون إلى هناك الآن ، نظام الطبقات هو جزء من الحالة وليس جزءًا من العارض.

ErikBehar العلاقات العامة ستكون رائعة!

tiesselune سأفكر في نقله كما تقترح ، أو لا تتردد في دفع العلاقات العامة على مفترقتي lol =] mrdoob

ما هو الوضع على هذا؟ لقد قمت بدمج كود r94dev من ErikBehar في r94 ، ثم قمت بدمج r97 فيه ، فقط زوجان من التعارضات المباشرة (تغيير الإصدار ، بعض المتغيرات للإضاءة الانتقائية ، وإنشاء التجزئة في العارضين / WebGLRenderer.js ؛ أود كن سعيدًا بوضع العلاقات العامة. tiesselune إذا كان بإمكانك إعطائي فكرة عن المكان الذي كنت تنوي أن تنتقل فيه حالة الإضاءة الانتقائية ،

تعديل:
بعد ذلك بقليل: أرى أن هذا يحتاج إلى بعض العمل ليعمل ، الآن ، مع lighthash الجديدة.

VaelynPhi أعتقد أنه بغض النظر عما إذا كانوا على استعداد لقبول رمز ErikBehar أم لا ، فمن الجيد إرسال العلاقات العامة ، فقط لاستبدال الرمز القديم في حال أراد الآخرون ذلك ، مثلك أنت فعلت

آسف لإسقاط الكرة على هؤلاء الرجال = / ... VaelynPhi هل يمكنك إرسال شوكة / فرعك؟

لا قلق؛ أتفهم كونك مشغولاً. للأسف ، لم أستطع حتى الحصول على الفرع الذي كنت تعمل فيه ،ErikBehar ؛ لقد استقرت على قراءة الكود لمحاولة تقسيمه حتى أتمكن من نقل الحالة إلى الموقع المناسب ونأمل في إصلاح أي أخطاء. لا يزال يتعين علي الوصول إلى حالة منفذ عاملة حتى في الإصدار 94. ربما يمكنني تنظيفه ووضعه في العلاقات العامة فقط لتحديثه كما يقترح makc . أعطني قليلا أنا مشغول للغاية. :) على الأقل ، قد يساعد ذلك في إبراز التغييرات التي يجب إجراؤها لجذب الإضاءة الانتقائية إلى الإصدار الأخير.

أضاف علاقات عامة على أساس:
https://github.com/ErikBehar/three.js/commit/ac0499b70b82bc7bb780100a8372fcdf318d1424#diff -5e43a0b5002eb2c419def3baf67d4e67
بقلمErikBehar
يمكن لأي شخص أن يقدم يد المساعدة مع بعض الاستعراض والمثال؟

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

مرحبًا يا شباب ، ما هو الوضع في هذا؟ TiesseluneErikBehar هل يمكنني مساعدتك بشيء؟ سيكون من الجيد تنفيذه أخيرًا بعد 4 سنوات 😄💯

flyrell أعتقد أنه يمكننا إغلاق هذه المشكلة لأنه يبدو أنه أقرب إلى الانتهاء في # 15223 ربما؟

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