Lerping ফাংশনগুলিতে কেন সময়.ডেলটাটাইম ব্যবহার করবেন?


12

আমার বোঝার, দুই মান (মধ্যে একটি Lerp ফাংশন interpolates করার aএবং b) একটি তৃতীয় মান (ব্যবহার tমধ্যে) 0এবং 1। এ t = 0, মানটি প্রত্যাবর্তিত হয়, এ t = 1, মান bফিরে আসে। 0.5 এর অর্ধেকের মধ্যে মানটি ফিরে আসে aএবং bফিরে আসে।

(নীচের ছবিটি একটি স্মুথ স্টিপ, সাধারণত কিউবিক ইন্টারপোলেশন হয়)

এখানে চিত্র বর্ণনা লিখুন

আমি ফোরামগুলি ব্রাউজ করছি এবং এই উত্তরে আমি নিম্নলিখিত কোডের লাইনটি পেয়েছি:transform.rotation = Quaternion.Slerp(transform.rotation, _lookRotation, Time.deltaTime);

আমি নিজেকে ভেবেছিলাম, "কী বোকা, তার কোনও ধারণা নেই" তবে যেহেতু এটির 40++ উর্ধ্বতন রয়েছে আমি এটি চেষ্টা করেছিলাম এবং যথেষ্ট নিশ্চিত, এটি কার্যকর হয়েছে!

float t = Time.deltaTime;
transform.rotation = Quaternion.Slerp(transform.rotation, toRotation, t);
Debug.Log(t);

আমি মধ্যে র্যান্ডম মান পেয়েছিলাম 0.01এবং 0.02জন্য t। সেই অনুযায়ী ফাংশনটি বিভক্ত হওয়া উচিত নয়? কেন এই মানগুলি স্ট্যাক করে? আমি বুঝতে পারি না এমন লিরপ কী?


1
এ সাধারণত অবস্থান হয়, যা পরিবর্তিত হয় এবং এর জন্য 1/60 (60 fps) এ স্যাম্পলিং কেবলমাত্র 0.16 এর বিভাজন দ্বারা বস্তুটিকে অবিচ্ছিন্নভাবে এ এবং বি এর মধ্যকার দূরত্বকে সংকীর্ণ করে তোলে (এভাবে প্রতিটি সময় নমুনাটি ছোট এবং ছোট হয়)।
সিডার

আপনি টি লগ ইন করেছেন এবং টিটি দিয়ে লার্পড করেছেন those এগুলি হ'ল ডিফেরেন্ট ভেরিয়েবল।
ব্যবহারকারী 253751

উত্তর:


18

এই উত্তরটি দেখুন

ব্যবহারের দুটি সাধারণ উপায় রয়েছে Lerp:

1. একটি শুরু এবং শেষের মধ্যে রৈখিক মিশ্রণ

progress = Mathf.Clamp01(progress + speedPerTick);
current = Mathf.Lerp(start, end, progress);

এটি সম্ভবত আপনি সবচেয়ে পরিচিত সংস্করণ।

২. লক্ষ্যের দিকে ক্ষতিকারক স্বাচ্ছন্দ্য

current = Mathf.Lerp(current, target, sharpnessPerTick);

নোট করুন যে এই সংস্করণে currentমান আউটপুট এবং একটি ইনপুট উভয় হিসাবে প্রদর্শিত হবে । এটি startভেরিয়েবলটি স্থানান্তর করে , তাই সর্বদা আমরা সর্বশেষ আপডেটে যেখানেই চলেছি সেখান থেকে শুরু করি। এটি Lerpএকটি ফ্রেম থেকে পরের মেমরির এই সংস্করণটি দেয় । এই চলমান সূচনা বিন্দু থেকে আমরা তারপরে targetএকটি sharpnessপরামিতি দ্বারা নির্ধারিত দূরত্বের একটি ভগ্নাংশটি সরিয়ে নিই ।

এই প্যারামিটারটি আর কোনও "গতি" নয়, কারণ আমরা একটি জেনোর মতো ফ্যাশনে লক্ষ্যটির কাছে যাই । তাহলে sharpnessPerTickছিল 0.5, তারপর প্রথম আপডেটে আমরা halfway আমাদের লক্ষ্য থেকে সরানো চাই। তারপরে পরবর্তী আপডেটে আমরা বাকি দূরত্বের অর্ধেক (আমাদের প্রাথমিক দূরত্বের এক চতুর্থাংশ) সরিয়ে নিয়ে যাব। তার পরের দিকে আমরা আবার অর্ধেক স্থানান্তর করব ...

এটি একটি "তাত্পর্যপূর্ণ স্বাচ্ছন্দ্য" দেয় যেখানে লক্ষ্য থেকে দূরে যখন আন্দোলনটি দ্রুত হয় এবং ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে বেড়ে যায় y যথেষ্ট কাছাকাছি পায়)। এটা একটা চলন্ত লক্ষ্য মান পশ্চাদ্ধাবন, অথবা ব্যবহার করে একটি সশব্দ ইনপুট মসৃণকরণ জন্য দারুণ একটি " গড় চলন্ত সূচকীয় সাধারণত একটি খুব ছোট ব্যবহার করে," sharpnessPerTickমত পরামিতি 0.1বা ছোট করা হয়েছে।


তবে আপনি ঠিক বলেছেন, আপনার লিঙ্কিত উত্তোলিত উত্তরের একটি ত্রুটি রয়েছে। এটি deltaTimeসঠিক উপায়ে সংশোধন করছে না । এই স্টাইলটি ব্যবহার করার সময় এটি একটি খুব সাধারণ ভুল Lerp

প্রথম স্টাইলটি Lerpরৈখিক, সুতরাং আমরা গুনাগুণ দ্বারা গতি রৈখিকভাবে সামঞ্জস্য করতে পারি deltaTime:

progress = Mathf.Clamp01(progress + speedPerSecond * Time.deltaTime);
// or progress = Mathf.Clamp01(progress + Time.deltaTime / durationSeconds);
current = Mathf.Lerp(start, end, progress);

তবে আমাদের ক্ষতিকারক সহজকরণটি অ-রৈখিক , সুতরাং কেবলমাত্র আমাদের sharpnessপরামিতিগুলি দ্বারা গুণ করা deltaTimeসঠিক সময় সংশোধন দেয় না। এটি যদি আমাদের ফ্রেমরেট ওঠানামা করে তবে আপনি যদি ধারাবাহিকভাবে 30 থেকে 60 এ যান তবে হালকা তীক্ষ্ণতায় পরিবর্তন হলে আন্দোলনে বিচারক হিসাবে এটি প্রদর্শিত হবে।

পরিবর্তে আমাদের তাত্পর্যপূর্ণ স্বাচ্ছন্দ্যের জন্য আমাদের একটি সূচকীয় সংশোধন প্রয়োগ করতে হবে:

blend = 1f - Mathf.Pow(1f - sharpness, Time.deltaTime * referenceFramerate);
current = Mathf.Lerp(current, target, blend);

এখানে সময় referenceFramerateঠিক করার আগে আমরা যেমন 30ইউনিটগুলি ব্যবহার sharpnessকরেছিলাম ঠিক তেমনই তার জন্য ইউনিট রাখার মত এখানে একটি ধ্রুবক ।


এই কোডটিতে অন্য একটি তর্কযোগ্য ত্রুটি রয়েছে, যা ব্যবহার করছে Slerp- যখন আমরা পুরো আন্দোলনের মধ্য দিয়ে ঘূর্ণনটির যথাযথ ধারাবাহিক হার চাই তখন গোলাকার লিনিয়ার আন্তঃসম্পাদন কার্যকর হয়। তবে যদি আমরা যাইহোক কোনও অ-রৈখিক তাত্পর্যপূর্ণ স্বাচ্ছন্দ্য ব্যবহার করতে চলেছি তবে Lerpএকটি প্রায় অবিসংবাদিত ফলাফল দেবে এবং এটি সস্তা। ;) ম্যাট্রিকেসের চেয়ে কোয়ার্টারিয়নগুলি আরও ভাল লিটার হয়, তাই এটি সাধারণত একটি নিরাপদ প্রতিস্থাপন।


1

আমি মনে করি যে মূল ধারণাটি অনুপস্থিত এটি এই দৃশ্যে থাকবে তা স্থির নয়। টাইম.ডেলটাটাইম যে দ্বিখণ্ডিত প্রবাহের সাথে রয়েছে তাতে প্রতিটি পদক্ষেপের সাথে একটি আপডেট হয়।

সুতরাং, প্রতিটি পদক্ষেপের সাথে বি এর আরও কাছাকাছি আসার সাথে সাথে প্রতিটি লার্প / স্টার্প কলের সাথে আন্তঃবিভাজনের মোট স্থান পরিবর্তন হয়। প্রকৃত গণিত না করেই, আমি সন্দেহ করব যে প্রভাবটি আপনার স্মুথস্টেপ গ্রাফের মতো নয়, তবে এ বি এর কাছাকাছি যাওয়ার সাথে সাথে হ্রাস প্রায় অনুমান করার একটি সহজ উপায়

এছাড়াও, এটি প্রায়শই ব্যবহৃত হয় কারণ বি কোনও স্থির নাও হতে পারে। সাধারণ ক্ষেত্রে কোনও প্লেয়ার অনুসরণকারী একটি ক্যামেরা হতে পারে। আপনি কোনও অবস্থান বা রোটেশনে ক্যামেরার ঝাঁপিয়ে পড়ে ঝাঁকুনি এড়াতে চান।


1

আপনি ঠিক বলেছেন, পদ্ধতিটি পরিমাণের Quaternion Slerp(Quaternion a, Quaternion b, float t)মধ্যে aএবং বিভক্ত bকরে t। তবে প্রথম মানটি দেখুন, এটি শুরুর মান নয়।

এখানে পদ্ধতিতে প্রদত্ত প্রথম মানটি হ'ল বর্তমান বস্তুর ঘূর্ণন transform.rotation। সুতরাং প্রতিটি ফ্রেমের জন্য এটি বর্তমান ঘূর্ণন এবং _lookRotationপরিমাণ দ্বারা লক্ষ্য ঘূর্ণনের মধ্যে বিভক্ত হয় Time.deltaTime

এজন্য এটি একটি মসৃণ ঘূর্ণন উত্পাদন করে।


2
এখন আমি নির্বোধের মতো অনুভব করছি
AzulShiva

@ আজুলশিবা সবার সাথে এটি হওয়ার চিন্তা করবেন না;)
লুডোভিচ ফেল্টজ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.