Для понимания материала изложенного здесь полезно иметь навыки программирования в Unity3D на языке C# и разработки шейдеров. Использовать мы будем так называемые сурфейс шейдеры.
Как это работает
Я из тех людей которые со временем полностью проникают в среду разработки и пытаются узнать о всех, даже почти не используемых вещах. Не то чтобы пост эффекты почти не используются, но практических задач по их написанию у меня было очень мало. Я честно, не смог найти в документации исчерпывающего описания данной темы и мне пришлось руководствоваться благо опенсурсными скриптами и шейдерами из стандартного набора а так-же кое-какими знаниями которые я получил во время чтения книги по шейдерам.
Абстрагируясь от кода, мы получим примерно такую картину:
- Рендеринг сцены в растр (текстуру).
- Создание плоскости прямо перед камерой которая бы заполнила всю видимую область.
- Рендеринг этой плоскости с нашим шейдером в который передаётся предварительно отрендеренная сцена.
Во всяком случае так в RenderMonkey (да я динозавр).
Но вернёмся к коду:
Для этого в событие рендеринга нам нужно вклинится и сделать всё по своему. Код который я предоставляю дедуктивный и лишён мишуры, всякие проверки можно посмотреть в стандартных компонентах.
using UnityEngine; using System.Collections; public class ImageEffect001 : ImageEffectBase { public Material Mat; void OnRenderImage(RenderTexture source, RenderTexture destination) { Graphics.Blit(source, destination, Mat); } }
В данном случае мы переносим одну текстуру в другую с проходам по ней шейдером. Материал нужен для логичного интерфейса передачи параметров в шейдер.
Далее нам нужен шейдер:
Shader "Custom/NewShader" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Lambert sampler2D _MainTex; struct Input { float2 uv_MainTex; float3 worldPos; }; void surf (Input IN, inout SurfaceOutput o) { half4 c = tex2D (_MainTex, IN.uv_MainTex); o.Albedo = dot(c.rgb, float3(0.3, 0.59, 0.11)); o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
Он тоже не пестрит хитростями. У него есть одно поле для текстуры которая передастся нашим фреймворком. В данном случае в сурфейс блоке мы переводим цвета текстуры в оттенки серого.
Посмотрим в коробку
А вот сейчас я хочу не много рассмотреть то что содержат в себе стандартные имэдж эффекты (я знаю что вам возможно порежит глаза моё написание данного словосочетания, если есть более приятные варианты, пишите в комментариях)
- Просчёт не только в шейдере — Стандартным подходом является распределение просчётов, так-как непосредственно некоторые данные можно(а даже иногда только там и нужно) просчитать только один раз нежели при рендеринге каждого пикселя
- Наследование от ImageEffectBase — В Unity3D мы не только MonoBehaivor едины. В простых эффектах хватит и нашего старого товарища MB но во всех стандартных используется ImageEffectBase. Причём он не поставляется конкретно и движком а идёт отдельно вместе с пакетом стандартных эффектов
- Проверка на поддержку эффектов — Фреймворк пост обработки достаточно требовательная штука и его вполне вероятно видеокарта пользователя может не поддерживать. Для этого в стандартных эффектах используется следующий код
// Disable if we don't support image effects if (!SystemInfo.supportsImageEffects) { enabled = false; return; }
Заключение
В данной статье я постарался собрать обрывками информацию которую приобрёл методом научного тыка. Возможно таким-же как и я эта статья поможет побыстрей разобраться со всем этим делом!
ссылка на оригинал статьи http://habrahabr.ru/post/216847/
Добавить комментарий