В этой статье мы рассмотрим:
- порядок создания простого пост эффекта;
- некоторые нюансы приведения размеров.
Для
наших экспериментов нам потребуется сцена, с объектами или картинками, не
важно, главное по пестрее. Я набросал такую:
На этой
сцене отлаживался не один пост эффект, поэтому все что на ней присутствует –
закономерно и не лишнее.
Подготовим
файлы. Мы будем работать с файлом шейдера и скриптом.
Начнем
с шейдера.
В папке Assets кликаем правой кнопкой мыши и выбираем:
Create->Shader-> NewImageEffectShader.
Нам
будет предложено на выбор несколько типов шейдеров, но это не так важно,
внутренности мы перепишем. Я переименовал созданный файл в «Pixelation».
Открываем и зачищаем от всего лишнего до такого вида:
Shader "Hidden/Pixelation Effect" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Pass { CGPROGRAM #pragma vertex vert_img #pragma fragment frag #include "UnityCG.cginc" fixed4 frag (v2f_img i) : SV_Target { } ENDCG } } }
Обратите внимание на то, что входные данные пиксельного
(фрагментного, привык я к терминологии HLSL) шейдера описывает структура
v2f_img. Ее вполне достаточно для нас.
Далее добавляем входные параметры шейдера и необходимый код
как в примере:
Shader "Hidden/Pixelation Effect" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Pass { CGPROGRAM #pragma vertex vert_img #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; float2 BlockCount; float2 BlockSize; fixed4 frag (v2f_img i) : SV_Target { float2 blockPos = floor(i.uv * BlockCount); float2 blockCenter = blockPos * BlockSize + BlockSize * 0.5; float4 tex = tex2D(_MainTex, blockCenter); return tex; } ENDCG } } }
sampler2D _MainTex – буфер экрана как текстура;
float2 BlockCount – количество кирпичиков на экране (псевдопикселей)
по X и Y;
float2 BlockSize – размеры кирпичиков тоже по X и Y;
Шейдер простой, вся суть в
функции floor. Из справки:
floor(x) - возвращает самое большое целое число, которое
является меньше чем или равным x.
Назначение и подготовку BlockCount и BlockSize рассмотрим в
скрипте эффекта.
Как создать новый скрипт я писать не буду, но стоит уточнить
вот что.
Нам потребуется импортировать некоторые стандартные ассеты,
а именно:
Assets->Import package->Effects
С точки зрения изучения пост эффектов нам интересен весь
пакет, в дальнейшем можно самостоятельно почитать типовые эффекты, входящие в
него. Но пока на нужен только ImageEffectBase.cs что бы наследовать от него
класс нашего скрипта.
В результате у нас должен
получиться вот такой код:
using UnityEngine; using UnityStandardAssets.ImageEffects; namespace Assets.Scripts.PostEffects { [ExecuteInEditMode] [AddComponentMenu("Image Effects/Color Adjustments/Pixelation")] public class Pixelation : ImageEffectBase { [Range(64.0f, 512.0f)] public float BlockCount = 256; private void OnRenderImage(RenderTexture source, RenderTexture destination) { float k = Camera.main.aspect; Vector2 count = new Vector2(BlockCount, BlockCount/k); Vector2 size = new Vector2(1.0f/count.x, 1.0f/count.y); // material.SetVector("BlockCount", count); material.SetVector("BlockSize", size); Graphics.Blit(source, destination, material); } } }
Где:
BlockCount – исходное количество блоков по горизонтали;
k – понятно из определения, коэффициент соотношения сторон
экрана;
count – вектор в который складываем расчетные значения
количества кирпичиков по горизонтали и вертикали;
size – расчетное значение размеров кирпичиков, основанное на
их количестве и коэффициенте соотношения сторон экрана.
Может
быть лишнее, но я хотел бы пояснить то, что в шейдере мы имеем дело с
текстурами размером (1f, 1f) не зависимо от их реальных размеров в пикселях. И
т.к. текстурные координаты носят относительный характер, то эту самую
относительность мы и выражаем в size. Для пущей очевидности замечу, что size
делает условные пикселы квадратными на всех разрешениях мониторов с разным
соотношением сторон.
Далее
файл скрипта перетаскиваем на объект нашей сцены - камеру, в поле скрипта
Shader перетаскиваем наш шейдер. Итог:
Готово.
Запускаем.
Не ужели на Unity перебрался?)
ОтветитьУдалитьПривет. Да :). Как с тобой связаться? Можешь мне на почту свой скайп выслать?
ОтветитьУдалить