Страница 1 из 1
Чернобелый пост-эффект
Добавлено:
07 апр 2013, 14:52
Riddik
Привет.
С шейдерами не сталкивался, так что не обессудьте)
Иногда нужно показывать всю картинку на экране в чёрно-белом цвете, кроме одного объекта на переднем плане.
Взял чёрно-белый шейдер:
Используется glsl
Shader "GrayScaleAlpha"
{
Properties
{
_MainTex ("Texture", 2D) = "white" { }
}
SubShader
{
Tags { "RenderType" = "Opaque" }
CGPROGRAM
#pragma surface surf Lambert alpha
struct Input
{
float2 uv_MainTex;
};
sampler2D _MainTex;
void surf (Input IN, inout SurfaceOutput o)
{
half4 tex = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = 0.299 * tex.r + 0.587 * tex.g + 0.184 * tex.b;
o.Alpha = tex.a;
}
ENDCG
}
Fallback "Diffuse"
}
В нужные моменты юзаю:
Используется csharp
Camera.mainCamera.SetReplacementShader(Shader.Find("GrayScaleAlpha"), "");
1. Первая проблема - все объекты теперь рендерятся в обратной последовательности - ближайший объект теперь позади всех, а самый далёкий - поверх всех. (камера в ортографической проекции).
2. Как применить это ко всем, кроме одного объекта? Если заюзать второй параметр (пробовал указывать тег объекта) - то вообще черный экран.
Помогите разобраться в их решении.
Re: Чернобелый пост-эффект
Добавлено:
08 апр 2013, 04:57
LightWorld
Вроде можно через слой исключить, или я что-то путаю?
Re: Чернобелый пост-эффект
Добавлено:
08 апр 2013, 09:06
Riddik
Каким образом?
И главная проблема - все рисуется в обратном порядке при включении чёрно-белого шейдера. Откуда такие грабли?
Re: Чернобелый пост-эффект
Добавлено:
08 апр 2013, 11:51
waruiyume
В шейдере объекта, на который не должен воздействовать эффект, нужно написать: Tags { "RenderType"="GrayscaleMask" }
На камеру.
Используется csharp
using UnityEngine;
[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
[AddComponentMenu("Image Effects/GrayscaleMasked")]
public class GrayscaleMasked: MonoBehaviour
{
public Shader shader;
private Material material;
public Texture textureRamp;
//public Texture mask;
public Shader maskShader;
public float rampOffset;
private Camera maskCamera;
private RenderTexture renderTexture;
void Start()
{
shader = Shader.Find("Hidden/GrayscaleMasked Effect");
maskShader = Shader.Find("Hidden/RenderGrayscaleMask");
// Disable if we don't support image effects
if (!SystemInfo.supportsImageEffects)
{
enabled = false;
return;
}
// Disable the image effect if the shader can't
// run on the users graphics card
if (!shader || !shader.isSupported)
enabled = false;
}
// Called by camera to apply image effect
void OnRenderImage (RenderTexture source, RenderTexture destination)
{
if (material == null)
{
if(shader==null)return;
material = new Material(shader);
material.hideFlags = HideFlags.HideAndDontSave;
}
if (maskCamera == null)
{
maskCamera = new GameObject("maskCamera").AddComponent<Camera>();
maskCamera.enabled = false;
maskCamera.gameObject.hideFlags = HideFlags.HideAndDontSave;
}
maskCamera.CopyFrom(camera);
maskCamera.clearFlags = CameraClearFlags.SolidColor;
maskCamera.backgroundColor = new Color32(0, 0, 0, 0);
renderTexture = RenderTexture.GetTemporary((int)maskCamera.pixelWidth, (int)maskCamera.pixelHeight, 8, RenderTextureFormat.RGB565);
maskCamera.targetTexture = renderTexture;
maskCamera.RenderWithShader(maskShader, "RenderType");
material.SetTexture("_RampTex", textureRamp);
material.SetTexture("_Mask", renderTexture);
material.SetFloat("_RampOffset", rampOffset);
Graphics.Blit (source, destination, material);
RenderTexture.ReleaseTemporary(renderTexture);
}
void OnDisable()
{
if (material)
{
DestroyImmediate(material);
}
if (renderTexture != null)
{
renderTexture.Release();
renderTexture = null;
}
if(maskCamera!=null)
{
DestroyImmediate(maskCamera.gameObject);
}
}
}
Эффект
Используется glsl
Shader "Hidden/GrayscaleMasked Effect"
{
Properties {
_MainTex ("Base (RGB)", Rect) = "white" {}
_Mask ("Mask (a)", Rect) = "white" {}
_RampTex ("Base (RGB)", 2D) = "grayscaleRamp" {}
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
Fog { Mode off }
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform sampler2D _Mask;
uniform sampler2D _RampTex;
uniform half _RampOffset;
fixed4 frag (v2f_img i) : COLOR
{
fixed4 original = tex2D(_MainTex, i.uv);
fixed grayscale = Luminance(original.rgb);
half2 remap = half2 (grayscale + _RampOffset, .5);
fixed4 output = tex2D(_RampTex, remap);
fixed4 maskR = tex2D(_Mask, i.uv).r;
output = lerp(output, original, maskR);
//output = maskA;
output.a = original.a;
return output;
}
ENDCG
}
}
Fallback off
}
Маска.
Используется glsl
Shader "Hidden/RenderGrayscaleMask"
{
Category
{
Fog { Mode Off }
SubShader
{
Tags { "RenderType"="GrayscaleMask" }
Pass
{
Color (1.0,0.0,0.0,1.0)
}
}
SubShader
{
Tags { "RenderType"="Opaque" }
Pass
{
Fog { Mode Off }
Color (0.0,0.0,0.0,1.0)
}
}
SubShader
{
Tags { "RenderType"="Transparent" }
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
uniform sampler2D _MainTex;
uniform half4 _MainTex_ST;
struct vertexInput {
float4 vertex : POSITION;
half4 texcoord : TEXCOORD0;
};
struct vertexOutput {
half4 pos : SV_POSITION;
half4 tex : TEXCOORD0;
};
vertexOutput vert(vertexInput input)
{
vertexOutput output;
output.tex = input.texcoord;
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
return output;
}
float4 frag(vertexOutput input) : COLOR
{
fixed4 col = tex2D(_MainTex,
_MainTex_ST.xy * input.tex.xy + _MainTex_ST.zw);
return fixed4(1.0-col.a, 0.0, 0.0, col.a);
}
ENDCG
}
}
SubShader
{
Tags { "RenderType"="TransparentCutout" }
Pass
{
AlphaTest Greater [_Cutoff]
SetTexture[_MainTex] { constantColor(0.0,0.0,0.0,1.0) combine constant, texture }
}
}
}
}
Если нужно что бы работало и для земли, курите:
http://u3d.as/content/unity-technologie ... cement/3zx - там много букафф копировать.
P.S. Впервые пробую, т.ч. если что через
, я не виноват
Кто нибудь, может подсказать, какой формат и глубину использовать в данном случае.
Версия с фиксами для пятёрки
https://yadi.sk/d/JM9y_Jr3sAyu3
Re: Чернобелый пост-эффект
Добавлено:
08 апр 2013, 12:39
Riddik
Спасибо! Уже есть с чем работать, что пробовать и от чего отталкиваться.
С другой стороны, мне уже кажется, что проще сделать задуманное наложением текстуры поверх всех объектов (кроме того, на который эффект не должен распространяться - этот объект останется перед текстурой, остальные - позади неё). Требования не обязательно сделать чёрно-белое изображение, а сделать его просто менее заметным, серым, добавить серости, в общем как бы показать, что оно неактивно.
Может ради этого не стоит заморачиваться с шейдерами, тем более не везде гарантируется их работа?
Re: Чернобелый пост-эффект
Добавлено:
08 апр 2013, 13:09
waruiyume
ХЗ, можно нарисовать планку перед камерой, а выделенный объект, вывести второй камерой; или изменить материалы на всех объектах, коме выделенного; или не делать постэффект, а просто, отрисовать шейдерреплейсментом, и во всех тэгах, кроме нужного сделать серый цвет.
P.S. Подправил маску.
Re: Чернобелый пост-эффект
Добавлено:
10 апр 2013, 19:23
gturk
Я делал так: Объект, который нужно подсветить клал в отдельный слой newLayer, создавал дополнительную камеру cam2, которая совпадает с основной, но рендерит только newLayer, основная камера показывает все, кроме newLayer. На основную камеру вешается постэффект "цветокоррекция" с выкрученным в 0 значением saturation.
cam1.Depth = 0;
cam2.Depth = 1;
cam2.clear = DepthOnly;
Re: Чернобелый пост-эффект
Добавлено:
10 апр 2013, 20:02
Woolf
gturk писал(а):Я делал так: Объект, который нужно подсветить клал в отдельный слой newLayer, создавал дополнительную камеру cam2, которая совпадает с основной, но рендерит только newLayer, основная камера показывает все, кроме newLayer. На основную камеру вешается постэффект "цветокоррекция" с выкрученным в 0 значением saturation.
cam1.Depth = 0;
cam2.Depth = 1;
cam2.clear = DepthOnly;
И это и есть самое идеологически верное решение )
Re: Чернобелый пост-эффект
Добавлено:
12 апр 2013, 00:27
Riddik
Спасибо большое!!!