puksus | Дата: Воскресенье, 30 Июля 2017, 13:18 | Сообщение # 1 |
Пчёлка Зоя
Сейчас нет на сайте
| Напоролся на проблемку, думаю-думаю, и никак не придумаю, как её решить. Вид сбоку, мы видим стену. Стена состоит из анимированных тайлов, причём нету строгого ограничения в том чтобы текстура тайла умещалась конкретно в свой квадратик - то есть, тайлы частично налазят друг на друга. В тайлах могут быть дырки, сквозь который виден фон. Кроме того, тайлы могут быть пустыми - то есть иногда на месте тайла ничего не рисуется (то есть в этом месте виден только фон). В идеале, тайлы могут быть даже полупрозрачными. Кроме того, поверх тайлов ещё рисуется текстура, содержащая всякого рода следы, кровь и т.д. В самом начале наши стены ничто не пачкает, однако если, например, замочить врага, то его кровь забрызгает стены, и эти брызги, собственно, будут нарисованы как раз в эту текстуру, которая рисуется поверх тайлов. Причём, текстуры этих брызгов могут быть произвольно смещены и повёрнуты.
А теперь собственно проблема: Нужно отрисовать в эту текстуру(которая рисуется поверх тайлов) кровь таким образом, чтобы отрисовка была произведена ТОЛЬКО в те пиксели, через которые не проступает фон. То есть, чтобы фрагменты крови не висели в воздухе, а рисовались ТОЛЬКО поверх стены. То есть, обычная рисовка в текстуру не прокатывает т.к. НЕ ВСЕ пиксели нужно отрисовать.
Как я думал решить проблему: сначала в промежуточную текстуру(равную по размерам той текстуре, в которой хранится кровь\следы) отрисовать все тайлы, которые теоретически могут быть заляпаны кровью, а затем 1 вариант) как-нибудь с помощью блендинга отрисовать туда же кровь так, чтобы были видны только те пиксели, где непрозрачен И тайл И кровь(Но как это сделать - непонятно), после чего отрисовать результат в исходную текстуру. Если делать так - то каково уравнение блендинга? А то сижу в 3 ночи, уже мозги кипят. Желательно чтобы осталась поддержка полупрозрачности и тайлов и крови при всём этом. (но необязательно)
2 вариант) написать GLSL шейдер, который будет принимать наше промежуточное изображение, изображение крови, как-то выдирать из обеих соответствующие пиксели и записывать кровь только там, где оба цвета непрозрачны. Но я с шейдерами особо не дружу, и опять же не совсем понимаю как это сделать.
Что можете посоветовать?Добавлено (30 июля 2017, 13:18) --------------------------------------------- Проблема решена, вопрос закрыт. Завёл 2 промежуточные текстуры, равные по размеру текстуре, на котрой помещается кровь и следы. В первую текстуру рендерю только те тайлы, которые могут быть затронуты (берём центр рисуемого объекта, строим прямоугольник с центром в этой точке со сторонами, равными размеру текстуры объекта, умноженными на корень из двух на случай поворота), рендерим все тайлы, которые помещаются в данный прямоугольник Во вторую рендерим кровь Делаем шейдер, пихаем в него обе текстуры, внутри него проверяем, если в конкретно данной точке нету пикселя крови ИЛИ пикселя тайлов - discard; иначе - смешиваем цвета как нам надо. Поскольку размеры обеих текстур равны размеру текстуры с кровью, то между пикселями взаимооднозначное соответствие, и не нужно делать хитрые преобразования координат.
На самом деле, у меня несколько текстур с кровью, размером по 2048х2048 пикселей, которые покрывают уровень, на тот случай если видюха не поддерживает больший размер текстур, поэтому танцев с бубном на самом деле больше, но суть от этого не меняется.
Плюсы - банальность и простота Минусы - быстродействие. Смена рендер таргета происходит долго, и у меня происходит минимум 3 раза за операцию. Если сделать более хитрый шейдер, то можно сократить количество смен рендер таргетов до 2-х. Кроме того, одна из оперируемых текстур была бы намного меньшего размера и если вызывать шейдер для объекта с меньшим размером - то и количество расчитываемых пикселей колоссально уменьшается (хотя, для каждого пикселя были бы более тяжёлые вычисления).
К счастью, подобные операции происходят очень редко по сравнению с рисовкой тайлов и остальных объектов, поэтому потеря производительности в данном вопросе, скорее всего, будет незаметной, если нам не нужно каждый кадр рисовать сотни текстур в уровень.
https://vk.com/beezoya
|
|
| |