Пользователи · Новые посты · Правила форума · Поиск по форуму · · · Регистрация
Страница 1 из 11
Форум о визуальных новеллах » Для разработчиков » Ren'Py » Подскажите как в renpy сделать коректирующий слой -Sepia.
Подскажите как в renpy сделать коректирующий слой -Sepia.

stop_control
Дата: Четверг, 14 Сентября 2017, 08:59 | Сообщение # 1
Проверенный
Сообщений: 35
Награды: 0
Репутация: 5
Замечания: 0%
Если посмотреть в "Бесконечном Лето" настройки, то в самом низу можно выбрать фильтры.
Фильтры - оттенки серого, сепия и 27 цветов воздействуют только на графику, "диалоговое окно" выше слоя "фильтра".
Видел в описании к renpy операторы сепии и оттенков серого - im.Grayscale, im.Sepia

Как сделать корректирующий слой?
Прикрепления: 8016442.jpg(288Kb)

mrWebster
Дата: Четверг, 14 Сентября 2017, 11:28 | Сообщение # 2
Проверенный
Сообщений: 162
Награды: 0
Репутация: 23
Замечания: 20%
Прочти вот это: http://anivisual.net/forum/4-95-19760-16-1501941002
Тут объясняется сходная тема.


Добро пожаловать во Мрак!

stop_control
Дата: Четверг, 14 Сентября 2017, 21:29 | Сообщение # 3
Проверенный
Сообщений: 35
Награды: 0
Репутация: 5
Замечания: 0%
По ссылке идет обсуждение модификации одной картинки.

В моей ситуации есть слой фона.
Над ним слой спрайтов предметов.
Над ним спрайт персонажа.
Над ним слой предметов переднего плана - перекрывающих персонажа.
Над ним например слой с анимайией дождя...

И выше как раз должен быть корректирующий слой, дающий обработку все обьектам находящимся ниже - например делающий их черно белыми.

Выше окно вывода диалогов - и оно идет без изменений

Вопрос как в renpy создать этот корректирующий слой.
Судя по "Бесконечному лету" - проблема решена. В зввисимости от выбора фильтра - меняется выдод общей картинки на экран.
Поставил галочку - черно белый. Поставил другую - сепия.

mrWebster
Дата: Четверг, 14 Сентября 2017, 22:04 | Сообщение # 4
Проверенный
Сообщений: 162
Награды: 0
Репутация: 23
Замечания: 20%
Если мы можем модифицировать одно изображение, то мы можем модифицировать все. Ладно, можно еще сделать так, но я не уверен, что сработает: делаем полупрозрачное изображение характерного оттенка и накладываем поверх всех спрайтов и прочего. Более того, имея этот "экран", его тоже можно модифицировать.
UPD
На примере, приложенном к тему, видно, что модифицировано лишь одно изображение.


Добро пожаловать во Мрак!

Сообщение отредактировал mrWebster - Четверг, 14 Сентября 2017, 22:04

stop_control
Дата: Четверг, 14 Сентября 2017, 22:10 | Сообщение # 5
Проверенный
Сообщений: 35
Награды: 0
Репутация: 5
Замечания: 0%
Вот как раз как модифицировать ВСЕ я и спрашиваю.
Написанное внятно руководство пока не попадалось...

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

Ikuku
Дата: Четверг, 14 Сентября 2017, 23:04 | Сообщение # 6
Проверенный
Сообщений: 19
Награды: 1
Репутация: 49
Замечания: 0%
Не знаю, как там в БЛ, упоминания фильтров во вскрытых исходниках не вижу. Могу посоветовать полистать исходники той сборки, в которой эти фильтры вы точно видите, и по ключевым словам поиском пройтись, поискать, как они это реализовали.

В кач-ве альтернативы могу предложить следующий вариант (слегка топорный с точки зрения кода, правда, но по большей части автоматизированный):
Код
init -2 python:
    def filter_img(url):
        # завели матричный объект; пока что, если его применить к картинке, он только создаст идентичный дисплейабл
        im_custom = im.matrix.identity()
                
        # если параметр ч/б фильтра включен, доливаем к трансформациям уход в ч/б путем перемножения матричных объектов (того, что было и того, что обращает в ч/б)
        if is_blacknwhite:
            im_custom *= im.matrix.saturation(0)
            
        # если параметр фильтра "сепия" включен, аналогично:
        # (функция im.Sepia раскладывается на im.tint и im.saturation (с desat) с соответствующими ниже значениями, поскольку у нас все идет через im.MatrixColor, я беру как раз "разложенную" версию, а не сокращенную)
        if is_sepia:
            im_custom *= im.matrix.saturation(.5, desat=(0.2126, 0.7152, 0.0722)) * im.matrix.tint(1.0, .94, .76)

        # ну и еще уклон в голубой оттенок для примера
        if is_blue:
            im_custom *= im.matrix.tint(.8, .8, 1)
        
        # превратили урл картинки в дисплейабл с помощью получившегося в результате всех трансформаций матричного объекта, вернули его
        return im.MatrixColor(url, im_custom)

label start:
    $ is_blacknwhite = False
    $ is_sepia = False
    $ is_blue = False
    
    show expression filter_img("lorraine.jpg")
    "Картинка без изменений. Установим ч/б фильтр..."
    
    $ is_blacknwhite = True
    show expression filter_img("lorraine.jpg")
    "Черно-белое изображение. Уберем ч/б и поставим сепию..."
    
    $ is_blacknwhite = False
    $ is_sepia = True
    show expression filter_img("lorraine.jpg")
    "Сепия. поставим сепию и оттенок голубого одновременно..."
    
    $ is_blue = True
    show expression filter_img("lorraine.jpg")
    "А теперь отключим сепию..."
    
    $ is_sepia = False
    show expression filter_img("lorraine.jpg")
    "Примерно так оно и выглядит."

Суть в том, чтобы не писать для каждой картинки сто тысяч if-ов на каждый вывод, а при выводе картинки пропускать ее сквозь функцию-фильтр. Если переменные чекнуты, картинка (переданная параметром) трансформируется и возвращается в вывод уже по итогу всех трансформаций.
Вполне возможно, можно обойтись и без show expression, просто show, но навскидку я не могу назвать способ это сделать.

Вариант с единым корректирующим слоем не пойдет, к сожалению. Кроме этого, если элементы должны быть отдельны/подвижны, то каждому нужен свой корректирующий слой.

stop_control
Дата: Четверг, 14 Сентября 2017, 23:36 | Сообщение # 7
Проверенный
Сообщений: 35
Награды: 0
Репутация: 5
Замечания: 0%
Ikuku, Спасибо, на следующей неделе до нормального компа доеду - попробую...

Вектор задан - буду копать потихоньку...

dmit
Дата: Пятница, 15 Сентября 2017, 00:14 | Сообщение # 8
Проверенный
Сообщений: 101
Награды: 0
Репутация: 15
Замечания: 0%
img_filters.rpy мод БЛ
Доступно только для пользователей


планета FOREVER!!!

stop_control
Дата: Пятница, 15 Сентября 2017, 06:55 | Сообщение # 9
Проверенный
Сообщений: 35
Награды: 0
Репутация: 5
Замечания: 0%
dmit, Спасибо.

stop_control
Дата: Среда, 20 Сентября 2017, 08:24 | Сообщение # 10
Проверенный
Сообщений: 35
Награды: 0
Репутация: 5
Замечания: 0%
В продолжение темы...

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

Отсюда возникает вопрос:

Как слою "master" назначить матричный объект im.matrix.colorize или функцию im.Sepia?

Ikuku
Дата: Среда, 20 Сентября 2017, 11:46 | Сообщение # 11
Проверенный
Сообщений: 19
Награды: 1
Репутация: 49
Замечания: 0%
Интересный вопрос, применение трансформации к слоям прошло мимо меня как-то, спасибо за наводку.
Но все равно не сработало.

Факты:
1. К слоям можно применять трансформации (at something): https://www.renpy.org/doc/html/displaying_images.html#show-statement
2. Внутри трансформации можно использовать те самые заветные манипуляторы: https://lemmasoft.renai.us/forums/viewtopic.php?f=8&t=40667 (тут у юзера, кстати, сходная с вашей задача)

В теории из этого следует, что можно создать трансформацию с манипуляторами (im.Sepia), которую мы применим к слою, и все будет зашибись. Однако код:
Код
image img = "test.jpg"
image img2 = "test.jpg"

transform sepia(child):
    contains:
        im.MatrixColor(child, im.matrix.saturation(.5, desat=(0.2126, 0.7152, 0.0722)) * im.matrix.tint(1.0, .94, .76))
        
transform pos(xa):
    xalign xa
    
label start:
    show img at pos(.3)
    show img2 at pos(.6)
    show layer master at sepia
    
    "test"
    pause

роняет эксепшен "Expected an image, but got a general displayable." На одиночных картинках все работает, проверено (show img at sepia, я имею в виду). Дело как раз в том, что мы изначально пытались обойти - манипулятор принимает в качестве параметра только объект типа image (или image manipulator), а с другими типами дисплейаблов не работает. Т.е. применить манипулятор к объекту типа layer, который. в свою очередь, является набором дисплейаблов (даже если все дисплейаблы на нем будут только Image), не выходит. Как-то так, могу ошибаться, может, есть еще интересные способы автоматизировать процесс.

stop_control
Дата: Среда, 20 Сентября 2017, 12:41 | Сообщение # 12
Проверенный
Сообщений: 35
Награды: 0
Репутация: 5
Замечания: 0%
Ikuku, Спасибо, буду разбираться...

renpy ковыряю всего месяц активно - что и как не понимаю совсем...

СОНЦЕ
Дата: Четверг, 21 Сентября 2017, 15:43 | Сообщение # 13
Разработчик
Сообщений: 79
Награды: 16
Репутация: 49
Замечания: 0%
Вот пост от RenPy авторитета Asceai.
Попробую его вкратце перевести, но я знаю английский еще хуже чем руский, потому, если знаешь, лучше читай оригинал.

На данный момент (август 2014) РенПи не может это делать сколь угодно пристойным образом. Операции matrix color доступны только для отдельных картинок. Их нельзя применить "на лету" потому, например, нельзя использовать transform чтобы все стало серым.

Теперь, как сделать чтоб не определять все картинки отдельно. Вот костыль, который я (Asceai) написал. Это костыль по определению, поскольку использует незадокументированный внутренний функционал движка. (вчастности каталог images со списком картинок) Тем не менее он создает черно-белую версию каждой картинки.
Код

init 999 python:
  grey_images = {}
  for i in renpy.display.image.images:
    try:
      grey_im_name = i + ('greyscale',)
      grey_images[grey_im_name] = im.Grayscale(renpy.display.image.images[i])
    except:
      pass
  for i in grey_images:
    renpy.image(i, grey_images[i])


Теперь вместо show picture пишешь show picture greyscale, вместо scene background - scene background greyscale итп
Оно будет работать только с простыми картинками. Если картинка будет анимированной, работать не будет - хоть и будет создана черно-белая версия каждого кадра, движок не будет знать что с ним делать.

Так же я не знаю хорошего пути чтобы все ставало черно-белым автоматически. Самый простой способ это перезадать config.show чтобы он проверил флаг (например "greyscale") и если он поднят применять атрибут "черно-белый" к показываемым картинкам. (я использовал getattr для проверки, чтоб оно не отвалилось если мы еще не назначили флаг greyscale)
Код

init python:
  def replacement_show(name, *args, **kwargs):
    if getattr(renpy.store, 'greyscale', False):
      renpy.show(name + ('greyscale',), *args, **kwargs)
    else:
      renpy.show(name, *args, **kwargs)
  config.show = replacement_show


И теперь ты можешь просто поднять флаг и все нижеследующие команды будут выполняться в чб варианте

Код

label start:
  scene forest_bg
  show girl
  girl "Привет!"
  $greyscale = True
  scene forest_bg
  show girl
  "Я помнил это место с моего детства..."
  return


Есть у этого некоторые недостатки. Во первых - оно не будет работать с renpy.show() - только со scene и show. Кроме того оно не будет работать с анимациями (вероятно придется сделать отдельные чб версии для каждой анимированной сцены). И еще просто переназначение флага не сделает все изображенное черно-белым, потому после назначения нужно перерисовать все что есть на экране.

(на месте im.Grayscale() может быть и im.Sepia() и любой матрикс-колор)

(UPD:Возникли некоторые проблемы с данным костылем в последней версии, работает с актуальной на время публикации поста 6.17 . Расследование продолжается ^^)
(UPD2: похоже суть проблемы в том что не поддерживаются картинки которые не объявлены в начале через image, а показываются напрямую из папки images (похоже модерновый ренпи их объявляет автоматически и через другие переменные))


Сообщение отредактировал СОНЦЕ - Четверг, 21 Сентября 2017, 17:12

stop_control
Дата: Четверг, 21 Сентября 2017, 21:27 | Сообщение # 14
Проверенный
Сообщений: 35
Награды: 0
Репутация: 5
Замечания: 0%
СОНЦЕ, Спасибо.))
Форум о визуальных новеллах » Для разработчиков » Ren'Py » Подскажите как в renpy сделать коректирующий слой -Sepia.
Страница 1 из 11
Поиск: