Отображение красного света на зеленых поверхностях LWJGL - PullRequest
0 голосов
/ 28 октября 2018

Привет всем, я работаю с освещением в игре 2D Tile Based, и у меня возникли проблемы с моими расчетами освещения, в моей игре я беру полутоновые изображения, а затем окрашиваю их с помощью шейдеров в любой цвет, какой мне нравится, будь то зеленый (rgb = (0,1,0)) или красный (rgb = (1,0,0)) или любой цвет. Затем я применяю свои расчеты освещения к этому текстурированному и цветному пикселю. Освещение работает хорошо, когда свет белый (rgb = (1,1,1)), но когда он, скажем, красный или зеленый, он не будет отображаться так, как я хочу. Я знаю, почему это происходит, конечно, потому что реалистично чистый красный свет в чисто зеленой комнате не будет отражать красный свет, поэтому комната останется темной. Что я действительно хочу, так это увидеть красный свет над зеленой поверхностью. Итак, мой вопрос: как я могу четко показать красный свет на зеленой поверхности? (Или действительно любой другой цвет на любой поверхности)

Это код для моего фрагментного шейдера, где ослабление - это просто ослабление для света, lightColor - это, очевидно, значение rgb источников света, расстояние - это расстояние от данного вектора до этого источника света (рассчитывается в вершинном шейдере) и, наконец, color - это значение rgb, которое применяется к текстуре.

Заранее спасибо за помощь!

vec3 totalDiffuse = vec3(0.0);

for(int i = 0; i < 4; i++)
{
    float attFactor = attenuation[i].x + (attenuation[i].y * distance[i]) + (attenuation[i].z * distance[i] * distance[i]);
    totalDiffuse = totalDiffuse + (lightColor[i])/attFactor;
}
totalDiffuse = max(totalDiffuse,0.2);

out_Color = texture(textureSampler, pass_textureCoords)*vec4(color,alpha)*vec4(totalDiffuse,1);

А вот изображение того, как чистый красный свет выглядит на поверхности в настоящее время, он должен быть внутри белого круга, и вы можете увидеть, что он немного влияет на воду, потому что я даю воде маленький красный компонент- Light Demo Image

1 Ответ

0 голосов
/ 28 октября 2018

Одной из возможностей может быть изменение расчета освещенности.

Вычисление серой шкалы цвета освещения и цвета поверхности.Умножьте цвет поверхности на серую шкалу светлого цвета и умножьте светлый цвет на серую шкалу цвета поверхности, и, наконец, суммируйте их:

vec4  texCol  = texture(textureSampler, pass_textureCoords);
float grayTex = dot(texCol.rgb,  vec3(0.2126, 0.7152, 0.0722));
float grayCol = dot(colGray.rgb, vec3(0.2126, 0.7152, 0.0722));

vec3  mixCol  = texCol.rgb * grayCol + color.rgb * grayTex;

out_Color     = vec4(mixCol * totalDiffuse, texCol.a * alpha); 

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

Если вам нужны источники света с эффектом, описанным выше, другие источники, но с оригинальным эффектом вопроса, тогда я рекомендую ввести параметркоторый смешивает два эффекта:

uniform float u_lightTint;

void main()
{
    .....

    vec3 mixCol = texCol.rgb * grayCol + color.rgb * grayTex;

    mixCol      = mix(texCol.rgb * color.rgb, mixCol.rgb, u_lightTint);

    out_Color   = vec4(mixCol * totalDiffuse, texCol.a * alpha); 
} 

Если u_lightTint установлен на 1,0, то используется «новый» расчет освещения, если он установлен на 0,0, то используется исходный расчет освещения.Оба алгоритма могут быть линейно интерполированы с помощью u_lightTint.
В качестве альтернативы параметр u_lightTint может быть закодирован в альфа-канале светлого цвета:

mixCol = mix(texCol.rgb * color.rgb, mixCol.rgb, color.a);
...