Сегодня, при помощи горстки конфет, полтора часа и музыки от Pendulum запилил свои пост-эффект для Unity, не без с помощи сторонних примеров правда. Немного взбесило, что все примеры шейдера пост-эффекта имеются только на cg/glsl, ну да ладно, я его тоже хотел изучить. В принципе там только uniform'ы надо прописать и помнить некоторые отличия по инструкциям и функциям.
Все пост-эффект скрипты должны находится в камере и каждый шейдер пост-эффекта должен иметь кое-какой постоянный код (ну типа, поддерживаются ли пост-эффекты, есть ли шейдер в сокете, есть ли материал и т.д.).
Настоящий код начинается вот с этого:
Кстати, рендертекстуры source и destination заранее не объявляются, Юнити их видимо знает по лицу :D . Обычно эта строка не меняется, но если эффект состоит из нескольких "пассов", то необходимо обьявить о новой рендертекстуре (скажем passTwo) и соответственно прописать
Самый важный код во всем скрипте это вот:
Собственно График.Блит и делает пост-обработку по материалу. А материал требует шейдер (который, как напоминает КЭП, нужно еще написать), и параметры получаемые с скрипта. Насчет имени материала можно не волноваться, хотя странно, я думал ему в скрипте можно имя дать, а вот нифига... Теоретически скрипт способен менять шейдерыкак перчатки прямо в игре, я так понимаю, чтобы эффекты менялись, при тех же параметрах.
А вот и мой эффект -
На значения не смотрите, это я их пабликами сделал, чтоб посмотреть. Имена тоже не несут здесь правды - это просто косинус и синус времени. Шейдер принимает эти параметры и умножает на красный и зеленый канал текстуры.
Отдельно надо сказать о шейдере.
В шейдере присутствует вертексная часть, и это не просто так, суть вот в этой строчке:
В заключений я приведу код своего шейдера и скрипта. Незнаю, может кому понадобится...
Скрипт:
Все пост-эффект скрипты должны находится в камере и каждый шейдер пост-эффекта должен иметь кое-какой постоянный код (ну типа, поддерживаются ли пост-эффекты, есть ли шейдер в сокете, есть ли материал и т.д.).
Настоящий код начинается вот с этого:
void OnRenderImage (RenderTexture source, RenderTexture destination)
Кстати, рендертекстуры source и destination заранее не объявляются, Юнити их видимо знает по лицу :D . Обычно эта строка не меняется, но если эффект состоит из нескольких "пассов", то необходимо обьявить о новой рендертекстуре (скажем passTwo) и соответственно прописать
void OnRenderImage (RenderTexture source, RenderTexture passTwo)И так далее, правда в итоге все равно в конце должна быть RenderTexture destination, которая идет по следующим скриптам пост-обработки, ну или уже на экран.
Самый важный код во всем скрипте это вот:
material.SetFloat("_amplitude", amplitude);
material.SetFloat("_Waves", waves);
Graphics.Blit (source, destination, material);
Собственно График.Блит и делает пост-обработку по материалу. А материал требует шейдер (который, как напоминает КЭП, нужно еще написать), и параметры получаемые с скрипта. Насчет имени материала можно не волноваться, хотя странно, я думал ему в скрипте можно имя дать, а вот нифига... Теоретически скрипт способен менять шейдеры
А вот и мой эффект -
На значения не смотрите, это я их пабликами сделал, чтоб посмотреть. Имена тоже не несут здесь правды - это просто косинус и синус времени. Шейдер принимает эти параметры и умножает на красный и зеленый канал текстуры.
Отдельно надо сказать о шейдере.
В шейдере присутствует вертексная часть, и это не просто так, суть вот в этой строчке:
v2f vert (appdata_img v) {А точнее в appdata_img. Точнее - вертексная информация (позиция, текстурные координаты) экрана. Поскольку модели у нас нет, а уточнить что у нас экран надо. appdata_img входит в UnityCG.cginc, поэтому он нужен для всех пост-эффектов, вот так вот.....
В заключений я приведу код своего шейдера и скрипта. Незнаю, может кому понадобится...
Shader "Hidden/Post_Shader" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_Waves ("Waves", Float) = 0.5
_amplitude ("amplitude", Float) = 1.0
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off Fog { Mode off }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
#pragma target 3.0
struct v2f {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
uniform sampler2D _MainTex;
uniform float _Waves;
uniform float _amplitude;
v2f vert (appdata_img v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = MultiplyUV (UNITY_MATRIX_TEXTURE0, v.texcoord);
return o;
}
half4 frag (v2f i) : COLOR
{
float4 finalColor = tex2D (_MainTex, i.uv);
finalColor.r *= _amplitude;
finalColor.g *= _Waves;
return finalColor;
}
ENDCG
}
}
Fallback off
}
Скрипт:
using UnityEngine;
[RequireComponent (typeof(Camera))]
[AddComponentMenu("Image Effects/Post Effect TEST")]
public class post_effect_1 : MonoBehaviour {
// Определяем параметры
public float amplitude = 0.5f;
public float waves = 1.0f;
public Shader shaderRGB;
//обязательный параметр
private Material m_MaterialRGB;
//техническая часть
protected void Start ()
{
// Disable if we don't support image effects
if (!SystemInfo.supportsImageEffects) {
enabled = false;
return;
}
if( shaderRGB == null)
{
Debug.Log( "Noise shaders are not set up! Disabling noise effect." );
enabled = false;
}
else
{
if( !shaderRGB.isSupported ) // disable effect if RGB shader is not supported
enabled = false;
//else if( !shaderYUV.isSupported ) // fallback to RGB if YUV is not supported
// rgbFallback = true;
}
}
protected Material material {
get {
if( m_MaterialRGB == null ) {
m_MaterialRGB = new Material( shaderRGB );
m_MaterialRGB.hideFlags = HideFlags.HideAndDontSave;
}
return m_MaterialRGB;
}
}
protected void OnDisable() {
if( m_MaterialRGB )
DestroyImmediate( m_MaterialRGB );
}
// а вот творческая часть, лол
void OnRenderImage (RenderTexture source, RenderTexture destination)
{
amplitude = Mathf.Cos (Time.fixedTime); //А вообще где-то там есть конкретный косинус времени, но я ленивая задница
waves = Mathf.Sin (Time.fixedTime);
material.SetFloat("_amplitude", amplitude);
material.SetFloat("_Waves", waves);
Graphics.Blit (source, destination, material);
}
}
Комментариев нет:
Отправить комментарий