Динамические 2d тени - проблема смешивания - PullRequest
2 голосов
/ 11 мая 2011

Добрый день, моя дорогая община.

Я работаю над динамическими тенями для игры, над которой я буду работать, но, как это обычно бывает, я доставляю вам проблему в надежде (я уверен, на самом деле), что кто-то поможет.

Вот где я сейчас нахожусь: enter image description here

Обратите внимание на красный квадрат, я хочу, чтобы он постепенно угасал, когда источник света исчезает из поля зрения. Я проверяю, находится ли точка многоугольника внутри радиуса круга, но это, конечно, не решает; как я уже сказал, я хочу, чтобы он постепенно угасал, пока не погас полностью, если свет слишком далеко.

В моей голове есть одна идея, но я надеюсь на лучшую. Я не буду говорить об этом, так как это действительно последний вариант, и я считаю, что это техника "грубой силы".

Вот как я передаю свой свет:

    glBegin(GL_TRIANGLE_FAN);
    {
        Graphics::Instance()->SetColor(r_,g_,b_,intensity_);
        glVertex2f(posX_,posY_);

        glColor4f(0.f, 0.f, 0.f, 0.0f);

        for (angle_=0.0; angle_<=3.14159265*2; angle_+=((3.14159265*2)/64.0f) )
        {
            glVertex2f(range_*(float)cos(angle_) + posX_,
                       range_*(float)sin(angle_) + posY_);
        }

        glVertex2f(posX_+range_, posY_);
    }

И вот как я это смешал:

glBlendFunc(GL_SRC_ALPHA, GL_ONE);
l0->Render();

glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
l0->ProjectShadow(*mmm);
l0->ProjectShadow(*bb);

Это все. Если я не прояснил себя или если я пропустил опубликовать соответствующий код, пожалуйста, скажите об этом и не понижайте голос.

Ответы [ 2 ]

3 голосов
/ 11 мая 2011

Как насчет вычисления расстояния до центра вашего красного квадрата от центра источников света?Нормализовать это значение до подходящего диапазона и настроить прозрачность или цвет красного квадрата?Примерно так:

double Range(double x1, double y1, double x2, double y2)
{
    double xDist = x1-x2;
    double yDist = y1-y2;
    return math::sqrt(xDist*xDist+yDist*yDist);
}

double CalcIntensity(double lightX, double lightY, double lightRadius, double objectX, double objectY)
{
    double range = Range(lightX, lightY, objectX, objectY);
    double intensity;
    if( range > lightRadius )
    {
        intensity = 0.0;
    }
    else
    {
        intensity = range/lightRadius;
    }
    return intensity;
}

Тогда просто позвоните CalcIntensity и введите соответствующие позиции света, квадрата и радиуса света.

[Редактировать] ... или это будет немного более оптимистичная версия, если вы предварительно не проверяете, что она находится в радиусе освещения:

double CalcIntensity(double lightX, double lightY, double lightRadius, double objectX, double objectY)
{
    double intensity = 0.0;
    double xDist = lightX-objectX;
    if( xDist < lightRadius )
    {
        yDist = lightY-objectY;
        if( yDist < lightRadius )
        {
            double range = math::sqrt(xDist*xDist+yDist*yDist);
            intensity = range/lightRadius;
        }
    }

    return intensity;
}
1 голос
/ 11 мая 2011

Хорошо, свет на полной яркости на posX,posY и полностью "истощен" (то есть черный) на range.Значения между интерполируются линейно.Поэтому точка в любом положении на расстоянии d от источника света освещается на rgb * (d/range).

Если вы теперь вычисляете расстояния d_i каждой вершины v_i вашего красного квадрата, вы можетеприменить затенение к каждому цвету вершины c_i, умножив на него (d_i/range).Если вы хотите, чтобы весь квадрат отображался в одном и том же цвете независимо от удаленных вершин, просто используйте расстояние от его центра для каждой вершины, то есть цвет задается только один раз, прежде чем вы начнете рисовать квадрат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...