Войти
ПрограммированиеФорумГрафика

В шейдере затемняю пиксели, но кажется что некоторые наоборот становятся светлее.

Страницы: 1 2 Следующая »
#0
12:31, 4 апр. 2017

Всем доброго дня!

Вожусь с шейдерами. Накидал простую программу где персонаж в виде прямоугольника бегает и прыгает по уровню, составленному из квадратиков. Без шейдеров это выглядит так:

+ Показать

Решил поупражняться в шейдерах. Использую HLSL 11. Поставил себе задачу поиграться с цветом. Решил определить от персонажа два радиуса:

+ Показать

Все пиксели, которые имеют дистанцию до персонажа меньше r1, я не буду трогать. Все пиксели, которые от персонажа дальше r2, я хочу сделать чёрными. А промежуточное расстояние, от r1 до r2, я хочу там пиксели плавно менять от цвета оригинала до чёрного.

Пишу код пиксельного шейдера:

+ Показать

Результат:

+ Показать

На картинке видно, что около радиуса r1 имеются какие-то осветления. Ощущение такое, будто эту область я наоборот делаю светлее чем те пиксели, что лежат ближе радиуса r1. Почему так происходит? Что я делаю не так?


#1
12:40, 4 апр. 2017

> кажется
Ты сам ответил на свой вопрос. Это из-за линейной интерполяции, попробуй smoothstep.

#2
13:00, 4 апр. 2017

mahrizh
> Ты сам ответил на свой вопрос. Это из-за линейной интерполяции, попробуй smoothstep.
Спасибо за функцию. Думаю она мне точно ещё пригодится.

Переписал:

+ Показать

Результат:

+ Показать

Если перенести новый результат и старый результат в одну папку и открыть какой-нибудь программой, которая позволит быстро между ними переключаться, то сразу видно разницу. Вариант с smoothstep() красиво смотрится. Однако всё равно кажется что есть осветлённые места. Видимо это только кажется и ничего не поделать?

#3
13:07, 4 апр. 2017

Это оптическая иллюзия подобная этой:
Изображение
Цвета А и В идентичны.

#4
13:16, 4 апр. 2017

Просто я сначала смотрел на картинку. А теперь решил подвигаться и смотреться стало не очень:

+ Показать

Очень хорошо видно как персонажа окружает это кольцо. Разве так должно быть? Я не этого добивался.

#5
13:28, 4 апр. 2017
    // Рассчитываем затемнение
    float c=1.0-smoothstep(0.0f,radius2,dist);

А так ?

#6
13:33, 4 апр. 2017

s3dworld
> Разве так должно быть? Я не этого добивался.
Откажись от внутреннего радиуса.

float c = 1 - pow(dist / radius2, 7);
#7
13:54, 4 апр. 2017

bykabak
> float c=1.0-smoothstep(0.0f,radius2,dist);
Получается так:

+ Показать

То есть очень плохо.

mahrizh
> float c = 1 - pow(dist / radius2, 7);
Получается так:

+ Показать

То есть пока самый лучший вариант. Правда если попытаться поиграться со значениями и заменить 7 на что-то меньшее (чтобы затемнения начинали раньше действовать), снова начинает всё возвращаться к появлению кругов.

#8
14:09, 4 апр. 2017

s3dworld
Хочешь затенения раньше, оставь 7 и возьми r2 ближе к r1

#9
14:14, 4 апр. 2017

Просто поиграйтесь с формулой, и добейтесь результата который вас устроит. Нужно более плавную математическую зависимость яркости пикселя от расстояния до центра объекта вокруг которого вы хотите получить "ауру". ;)

#10
16:09, 4 апр. 2017

AMM1AK
> Хочешь затенения раньше, оставь 7 и возьми r2 ближе к r1
Таки образом получается не совсем то что я хотел:

+ Показать

Всё равно видно черту разделения.

bykabak
> Просто поиграйтесь с формулой, и добейтесь результата который вас устроит. Нужно более плавную математическую зависимость яркости пикселя от расстояния до центра объекта вокруг которого вы хотите получить "ауру". ;)
Придётся поиграться. Только мне всё равно не понятно почему вообще так всё отображается. К примеру я взял и переделал затемнение. Было вокруг персонажа, а теперь на определённом расстоянии по горизонтали от персонажа (чисто ради теста). И всё равно светлая область:

+ Показать

Это ещё по моей формуле:

float c=1.0-smoothstep(radius1,radius2,dist);

Если использовать эту:

float c=1.0f-pow(dist/radius2,7.0f);

То полосы ещё сильнее видно.

#11
16:24, 4 апр. 2017

Пока что вот такой ерунды смог добиться:

+ Показать

Это так, повозиться. Но как сделать освещение по интереснее, скажем чтобы светлее было только там, где главный персонаж может "видеть"? То что придумал я, но не знаю на сколько так делают и вообще правильно ли в шейдере такие алгоритмы использовать.

Рендерю стены в отдельную текстуру и заливаю их все белым цветом (лучше без всяких сглаживаний). Затем рендерю уже нормальный уровень. Затем передаю в шейдер две текстуры. Одна текстура, та что мы будем изменять, а вторая маска стен. Для каждого пикселя я буду брать вектор направления к персонажу (нормализую его) и начну шагать к персонажу. Если по пути встречу белый пиксель из текстуры масок стен, то эту точку я сделаю темнее. Если до персонажа дошагали, то точка будет стандартного цвета. Знаю что получится не красиво, так как всё будет иметь всего два состояния: нормальный и тёмный. Но это так, пробы. Меня больше интересует вообще так делают, в плане шагать так вот по точкам до источника?

Ну или какой вариант для придания интересной картинке данному примеру Вы приведёте?

#12
16:43, 4 апр. 2017

s3dworld
Я вообще-то нуб в шейдерах, но, может, мой совет поможет со светлым кольцом:

+ Совет
#13
16:56, 4 апр. 2017

fent
> Что, если заменить всю "if" логику

+ Показать
#14
18:52, 4 апр. 2017

s3dworld,
Вам тут столько идей накидали.  Просто посмотрите HLSL функции и поиграйтесь с ними. Включите воображение и поймите как именно вы хотите чтобы работала засветка. Нет понятия "правильно ли в шейдере такие алгоритмы использовать", есть понятие - я хочу чтобы выглядело так. ;) Потом сделаете код оптимальным по скорости.  Вы сейчас учитесь, это нормально экспериментировать. ;)

Страницы: 1 2 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.