193 lines
6.8 KiB
C#
193 lines
6.8 KiB
C#
using UnityEngine;
|
|
|
|
/// Blending modes use by the ImageEffects.Blit functions.
|
|
public enum BlendMode
|
|
{
|
|
Copy,
|
|
Multiply,
|
|
MultiplyDouble,
|
|
Add,
|
|
AddSmoooth,
|
|
Blend
|
|
}
|
|
|
|
/// A Utility class for performing various image based rendering tasks.
|
|
[AddComponentMenu("")]
|
|
public class ImageEffects
|
|
{
|
|
static Material[] m_BlitMaterials = { null, null, null, null, null, null };
|
|
|
|
static public Material GetBlitMaterial(BlendMode mode)
|
|
{
|
|
int index = (int)mode;
|
|
|
|
if (m_BlitMaterials[index] != null)
|
|
return m_BlitMaterials[index];
|
|
|
|
// Blit Copy Material
|
|
m_BlitMaterials[0] = new Material(
|
|
"Shader \"BlitCopy\" {\n" +
|
|
" SubShader { Pass {\n" +
|
|
" ZTest Always Cull Off ZWrite Off Fog { Mode Off }\n" +
|
|
" SetTexture [__RenderTex] { combine texture}" +
|
|
" }}\n" +
|
|
"Fallback Off }"
|
|
);
|
|
// Blit Multiply
|
|
m_BlitMaterials[1] = new Material(
|
|
"Shader \"BlitMultiply\" {\n" +
|
|
" SubShader { Pass {\n" +
|
|
" Blend DstColor Zero\n" +
|
|
" ZTest Always Cull Off ZWrite Off Fog { Mode Off }\n" +
|
|
" SetTexture [__RenderTex] { combine texture }" +
|
|
" }}\n" +
|
|
"Fallback Off }"
|
|
);
|
|
// Blit Multiply 2X
|
|
m_BlitMaterials[2] = new Material(
|
|
"Shader \"BlitMultiplyDouble\" {\n" +
|
|
" SubShader { Pass {\n" +
|
|
" Blend DstColor SrcColor\n" +
|
|
" ZTest Always Cull Off ZWrite Off Fog { Mode Off }\n" +
|
|
" SetTexture [__RenderTex] { combine texture }" +
|
|
" }}\n" +
|
|
"Fallback Off }"
|
|
);
|
|
// Blit Add
|
|
m_BlitMaterials[3] = new Material(
|
|
"Shader \"BlitAdd\" {\n" +
|
|
" SubShader { Pass {\n" +
|
|
" Blend One One\n" +
|
|
" ZTest Always Cull Off ZWrite Off Fog { Mode Off }\n" +
|
|
" SetTexture [__RenderTex] { combine texture }" +
|
|
" }}\n" +
|
|
"Fallback Off }"
|
|
);
|
|
// Blit AddSmooth
|
|
m_BlitMaterials[4] = new Material(
|
|
"Shader \"BlitAddSmooth\" {\n" +
|
|
" SubShader { Pass {\n" +
|
|
" Blend OneMinusDstColor One\n" +
|
|
" ZTest Always Cull Off ZWrite Off Fog { Mode Off }\n" +
|
|
" SetTexture [__RenderTex] { combine texture }" +
|
|
" }}\n" +
|
|
"Fallback Off }"
|
|
);
|
|
// Blit Blend
|
|
m_BlitMaterials[5] = new Material(
|
|
"Shader \"BlitBlend\" {\n" +
|
|
" SubShader { Pass {\n" +
|
|
" Blend SrcAlpha OneMinusSrcAlpha\n" +
|
|
" ZTest Always Cull Off ZWrite Off Fog { Mode Off }\n" +
|
|
" SetTexture [__RenderTex] { combine texture }" +
|
|
" }}\n" +
|
|
"Fallback Off }"
|
|
);
|
|
for (int i = 0; i < m_BlitMaterials.Length; ++i)
|
|
{
|
|
m_BlitMaterials[i].hideFlags = HideFlags.HideAndDontSave;
|
|
m_BlitMaterials[i].shader.hideFlags = HideFlags.HideAndDontSave;
|
|
}
|
|
return m_BlitMaterials[index];
|
|
}
|
|
|
|
|
|
/// Copies one render texture onto another.
|
|
/// This function copies /source/ onto /dest/, optionally using a custom blend mode.
|
|
/// If /blendMode/ is left out, the default operation is simply to copy one texture on to another.
|
|
/// This function will copy the whole source texture on to the whole destination texture. If the sizes differ,
|
|
/// the image in the source texture will get stretched to fit.
|
|
/// The source and destination textures cannot be the same.
|
|
public static void Blit(RenderTexture source, RenderTexture dest, BlendMode blendMode)
|
|
{
|
|
Blit(source, new Rect(0, 0, 1, 1), dest, new Rect(0, 0, 1, 1), blendMode);
|
|
}
|
|
public static void Blit(RenderTexture source, RenderTexture dest)
|
|
{
|
|
Blit(source, dest, BlendMode.Copy);
|
|
}
|
|
|
|
/// Copies one render texture onto another.
|
|
public static void Blit(RenderTexture source, Rect sourceRect, RenderTexture dest, Rect destRect, BlendMode blendMode)
|
|
{
|
|
// Make the destination texture the target for all rendering
|
|
RenderTexture.active = dest;
|
|
// Assign the source texture to a property from a shader
|
|
source.SetGlobalShaderProperty("__RenderTex");
|
|
bool invertY = source.texelSize.y < 0.0f;
|
|
// Set up the simple Matrix
|
|
GL.PushMatrix();
|
|
GL.LoadOrtho();
|
|
Material blitMaterial = GetBlitMaterial(blendMode);
|
|
for (int i = 0; i < blitMaterial.passCount; i++)
|
|
{
|
|
blitMaterial.SetPass(i);
|
|
DrawQuad(invertY);
|
|
}
|
|
GL.PopMatrix();
|
|
}
|
|
|
|
public static void BlitWithMaterial(Material material, RenderTexture source, RenderTexture destination)
|
|
{
|
|
Graphics.Blit(source, destination, material);
|
|
}
|
|
|
|
|
|
public static void RenderDistortion(Material material, RenderTexture source, RenderTexture destination, float angle, Vector2 center, Vector2 radius)
|
|
{
|
|
bool invertY = source.texelSize.y < 0.0f;
|
|
if (invertY)
|
|
{
|
|
center.y = 1.0f - center.y;
|
|
angle = -angle;
|
|
}
|
|
|
|
Matrix4x4 rotationMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0, 0, angle), Vector3.one);
|
|
|
|
material.SetMatrix("_RotationMatrix", rotationMatrix);
|
|
material.SetVector("_CenterRadius", new Vector4(center.x, center.y, radius.x, radius.y));
|
|
material.SetFloat("_Angle", angle * Mathf.Deg2Rad);
|
|
|
|
Graphics.Blit(source, destination, material);
|
|
}
|
|
|
|
|
|
public static void DrawQuad(bool invertY)
|
|
{
|
|
GL.Begin(GL.QUADS);
|
|
float y1, y2;
|
|
if (invertY)
|
|
{
|
|
y1 = 1.0f; y2 = 0.0f;
|
|
}
|
|
else
|
|
{
|
|
y1 = 0.0f; y2 = 1.0f;
|
|
}
|
|
GL.TexCoord2(0.0f, y1); GL.Vertex3(0.0f, 0.0f, 0.1f);
|
|
GL.TexCoord2(1.0f, y1); GL.Vertex3(1.0f, 0.0f, 0.1f);
|
|
GL.TexCoord2(1.0f, y2); GL.Vertex3(1.0f, 1.0f, 0.1f);
|
|
GL.TexCoord2(0.0f, y2); GL.Vertex3(0.0f, 1.0f, 0.1f);
|
|
GL.End();
|
|
}
|
|
|
|
public static void DrawGrid(int xSize, int ySize)
|
|
{
|
|
GL.Begin(GL.QUADS);
|
|
|
|
float xDelta = 1.0F / xSize;
|
|
float yDelta = 1.0F / ySize;
|
|
|
|
for (int y = 0; y < xSize; y++)
|
|
{
|
|
for (int x = 0; x < ySize; x++)
|
|
{
|
|
GL.TexCoord2((x + 0) * xDelta, (y + 0) * yDelta); GL.Vertex3((x + 0) * xDelta, (y + 0) * yDelta, 0.1f);
|
|
GL.TexCoord2((x + 1) * xDelta, (y + 0) * yDelta); GL.Vertex3((x + 1) * xDelta, (y + 0) * yDelta, 0.1f);
|
|
GL.TexCoord2((x + 1) * xDelta, (y + 1) * yDelta); GL.Vertex3((x + 1) * xDelta, (y + 1) * yDelta, 0.1f);
|
|
GL.TexCoord2((x + 0) * xDelta, (y + 1) * yDelta); GL.Vertex3((x + 0) * xDelta, (y + 1) * yDelta, 0.1f);
|
|
}
|
|
}
|
|
GL.End();
|
|
}
|
|
} |