سؤال

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

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

عندما يتم أخذ عدد n من العينات، أحسب نسبة الأشعة التي تصادمت وأضرب لون الضوء بهذه النسبة (وبالتالي فإن الضوء الذي لونه 1000,1000,1000 سيصبح 500,500,500 بنسبة 0.5، حيث نصف الأشعة لقد اصطدمت).ثم أقوم بحساب متوسط ​​المسافة إلى مصدر الضوء عن طريق قسمة متغير المسافة السابق على كمية الأشعة غير المتصادمة.أرجع هذا المتغير وتخرج الوظيفة.

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

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

هذا هو الضوء الفعلي لفئة الظلال الناعمة:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyFirstRayTracer
{
  public class AreaLight : ILight
  {
    private const int _radius = 5;
    private const int _samples = 16;
    public Color Color { get; set; }
    public Vector Location { get; set; }
    #region ILight Members

    public float GetLightingInformation(Vector point, ISceneObject[] scene, out Color color)
    {
      int intersectCount = 0;
      float distance = -1;
      for(int i = 0; i < _samples; i++)
      {
    bool intersects = false;
    float rand = 0;
    rand = _radius - (float)(new Random().NextDouble()*(2*_radius));
    foreach (ISceneObject obj in scene)
    {
      Vector iPoint;

      Vector loc = new Vector(Location.X + rand, Location.Y + rand, Location.Z + rand);

      if (!obj.Intersect(new Ray(point, loc), out iPoint))
      {
        distance += (Location - point).SqLength;

      }
      else
      {
        intersects = true;
        distance -= (Location - point).SqLength;
      }
    }
    if (intersects)
      intersectCount++;
      }
      float factor = 1-((float)intersectCount/_samples);

      color = new Color(factor*Color.R, factor*Color.G, factor*Color.B);

      return (float)Math.Sqrt(distance / (_samples - intersectCount));
    }


    #endregion
  }
}
هل كانت مفيدة؟

المحلول

حاول إنشاء "راند" مختلف لكل مكون من مكونات "loc".وكما هو الحال، فإن نقاطك المتوترة كلها تقع على خط واحد.

نصائح أخرى

نقطة ثانوية ولكن هل هذا هو أفضل استخدام للفئة العشوائية ..

 for(int i = 0; i < _samples; i++)
      {
        bool intersects = false;
        float rand = 0;
        rand = _radius - (float)(new Random().NextDouble()*(2*_radius));

ألا ينبغي أن يكون هذا ..

    var rnd = new Random()    
    for(int i = 0; i < _samples; i++)
              {
                bool intersects = false;
                float rand = 0;
                rand = _radius - (float)(rnd.NextDouble()*(2*_radius));

أنت في الواقع تولد النقطة على الخط على خط ذو اتجاه (1، 1، 1).هل مصدر الضوء خطي حقًا؟

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

ترى، هذا هو السبب في أنني أتيت إلى هذا الموقع :)

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

هل تعرف طريقة أكثر فعالية لتقليل تكوين الأنماط؟

أكبر مساعدة على الرغم من:لا يتم إنشاء مثيل عشوائي لكل عينة.لقد تضاعفت سرعة العرض ثلاث مرات بشكل خطير مع الظلال الناعمة!لم أكن أعلم أبدًا أن إنشاء Random كان مكلفًا جدًا.رائع.

شكرًا جزيلاً.

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top