Динамические 2d тени — проблема со смешиванием

#c #opengl

#c #opengl

Вопрос:

Добрый день, мое дорогое сообщество.

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

Вот где я сейчас нахожусь:введите описание изображения здесь

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

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

Вот как я визуализирую свой свет:

     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);
  

Вот и все. Если я недостаточно ясно выразился или пропустил публикацию соответствующего кода, пожалуйста, скажите об этом и не снижайте голос.

Комментарии:

1. Если вы хотите придерживаться конвейера с фиксированной функцией, как насчет использования параметров ослабления света? (см. Руководство glLightf).

Ответ №1:

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

 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. Я должен был это знать. Большое вам спасибо.

Ответ №2:

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

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