Волшебное затухание

В игродеве частенько бывает нужно, что нибудь плавно растворить или сфейдить. Тот-же звук к примеру или объекты какие нибудь по альфе, обычно не задумываясь пишут getDistance() до объекта и потом считают коэфицент фейдинга, но getDistance() не менее класически содержит в себе sqrt, а если объектов много ?

Некоторое время назад, оптимизируя код для xbox360 этот корень вылез в одном из модулей игры, немного времени на раздумье и вот оно решение, без корней:

//Где нибудь вначале, считаем константы...
//Дистанция (в квадрате) на которой объект начинает растворяться 
float startFadeDistSq = startFadeDist * startFadeDist;
//Дистанция растворения (в квадрате) объекта 
float magicFadeLenK = 1.0 / ((endFadeDist * endFadeDist) - startFadeDistSq);
_Winnie C++ Colorizer

//Считаем коэфицент прозрачности объекта в зависимости
//от дистанции до камеры
vector dist = objectPosition - cameraPosition;
float distSquared = dot (dist, dist);
float transparencyK = clamp(1.0 - ((distSquared - startFadeDistSq) * magicFadeLenK), 0.0, 1.0);
_Winnie C++ Colorizer

результат функции красивый практически линейный, идеально ложиться в HLSL, на PowerPC обрезаем через fsel, что бы избежать float compare и branch

результаты так же можно возводить в квадрат и в куб, для более интересной функции затухания, в результате практически все объекты движка, которым нужно плавное растворение/затухание теперь работают через эту функцию. А это: attenuation звуков, лоды источников света, лоды геометрии, 3d текст и еще куча всякого.

График функции:

Leave a comment

Your comment