FiE-Game/Assets/Cinematic Effects/BloomBeta/Scripts/BokehRenderer.cs

192 lines
6.4 KiB
C#
Raw Permalink Normal View History

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
class BokehRenderer
{
Texture2D m_CurrentTexture;
//Mesh[] m_FlareMeshes = null;
Material m_FlareMaterial;
int m_CurrentWidth;
int m_CurrentHeight;
float m_CurrentRelativeScaleX;
float m_CurrentRelativeScaleY;
public BokehRenderer()
{
}
public void RebuildMeshIfNeeded(int width, int height, float spriteRelativeScaleX, float spriteRelativeScaleY, ref Mesh[] meshes)
{
if (m_CurrentWidth == width && m_CurrentHeight == height && m_CurrentRelativeScaleX == spriteRelativeScaleX && m_CurrentRelativeScaleY == spriteRelativeScaleY && meshes != null)
return;
if (meshes != null)
foreach (Mesh m in meshes)
{
GameObject.DestroyImmediate(m, true);
}
meshes = null;
BuildMeshes(width, height, spriteRelativeScaleX, spriteRelativeScaleY, ref meshes);
}
public void BuildMeshes(int width, int height, float spriteRelativeScaleX, float spriteRelativeScaleY, ref Mesh[] meshes)
{
int maxQuads = 65000 / 6;
int totalQuads = width * height;
int meshCount = Mathf.CeilToInt((1.0f * totalQuads) / (1.0f * maxQuads));
meshes = new Mesh[meshCount];
int currentQuads = totalQuads;
m_CurrentWidth = width;
m_CurrentHeight = height;
m_CurrentRelativeScaleX = spriteRelativeScaleX;
m_CurrentRelativeScaleY = spriteRelativeScaleY;
int currentPixel = 0;
for (int m = 0; m < meshCount; ++m)
{
Mesh currentMesh = new Mesh();
currentMesh.hideFlags = HideFlags.HideAndDontSave;
int nbQuads = currentQuads;
if (currentQuads > maxQuads)
nbQuads = maxQuads;
currentQuads -= nbQuads;
Vector3[] vertices = new Vector3[nbQuads * 4];
int[] triangles = new int[nbQuads * 6];
Vector2[] uv0 = new Vector2[nbQuads * 4];
Vector2[] uv1 = new Vector2[nbQuads * 4];
Vector3[] normals = new Vector3[nbQuads * 4];
Color[] colors = new Color[nbQuads * 4];
float spriteWidth = m_CurrentRelativeScaleX * width;
float spriteHeigth = m_CurrentRelativeScaleY * height;
for (int i = 0; i < nbQuads; ++i)
{
int x = currentPixel % width;
int y = (currentPixel - x) / width;
SetupSprite(i, x, y, vertices, triangles, uv0, uv1, normals, colors, new Vector2((float)x / (float)width, 1.0f - ((float)y / (float)height)), spriteWidth * 0.5f, spriteHeigth * 0.5f);
currentPixel++;
}
currentMesh.vertices = vertices;
currentMesh.triangles = triangles;
currentMesh.colors = colors;
currentMesh.uv = uv0;
currentMesh.uv2 = uv1;
currentMesh.normals = normals;
currentMesh.RecalculateBounds();
currentMesh.UploadMeshData(true);
meshes[m] = currentMesh;
}
}
public void Clear(ref Mesh[] meshes)
{
if (meshes != null)
foreach (Mesh m in meshes)
{
GameObject.DestroyImmediate(m, true);
}
meshes = null;
}
public void SetTexture(Texture2D texture)
{
m_CurrentTexture = texture;
m_FlareMaterial.SetTexture("_MainTex", m_CurrentTexture);
}
public void SetMaterial(Material flareMaterial)
{
m_FlareMaterial = flareMaterial;
}
public void RenderFlare(RenderTexture brightPixels, RenderTexture destination, float intensity, ref Mesh[] meshes)
{
RenderTexture lastActive = RenderTexture.active;
RenderTexture.active = destination;
GL.Clear(true, true, Color.black);
Matrix4x4 proj = Matrix4x4.Ortho(0, m_CurrentWidth, 0, m_CurrentHeight, -1.0f, 1.0f);
m_FlareMaterial.SetMatrix("_FlareProj", proj);
m_FlareMaterial.SetTexture("_BrightTexture", brightPixels);
m_FlareMaterial.SetFloat("_Intensity", intensity);
if (m_FlareMaterial.SetPass(0))
{
//Debug.Log("MeshCount=" + m_FlareMeshes.Length);
for (int i = 0; i < meshes.Length; ++i )
Graphics.DrawMeshNow(meshes[i], Matrix4x4.identity);
}
else
{
Debug.LogError("Can't render flare mesh");
}
RenderTexture.active = lastActive;
}
public void SetupSprite(int idx, int x, int y, Vector3[] vertices, int[] triangles, Vector2[] uv0, Vector2[] uv1, Vector3[] normals, Color[] colors, Vector2 targetPixelUV, float halfWidth, float halfHeight)
{
int vIdx = idx * 4;
int tIdx = idx * 6;
triangles[tIdx + 0] = vIdx + 0;
triangles[tIdx + 1] = vIdx + 2;
triangles[tIdx + 2] = vIdx + 1;
triangles[tIdx + 3] = vIdx + 2;
triangles[tIdx + 4] = vIdx + 3;
triangles[tIdx + 5] = vIdx + 1;
vertices[vIdx + 0] = new Vector3((-halfWidth + x), (-halfHeight + y), 0);
vertices[vIdx + 1] = new Vector3((halfWidth + x), (-halfHeight + y), 0);
vertices[vIdx + 2] = new Vector3((-halfWidth + x), (halfHeight + y), 0);
vertices[vIdx + 3] = new Vector3((halfWidth + x), (halfHeight + y), 0);
Vector2 p = targetPixelUV;
colors[vIdx + 0] = new Color((-halfWidth / m_CurrentWidth + p.x), (-halfHeight*-1/ m_CurrentHeight + p.y), 0, 0);
colors[vIdx + 1] = new Color((halfWidth / m_CurrentWidth + p.x), (-halfHeight * -1 / m_CurrentHeight + p.y), 0, 0);
colors[vIdx + 2] = new Color((-halfWidth / m_CurrentWidth + p.x), (halfHeight * -1 / m_CurrentHeight + p.y), 0, 0);
colors[vIdx + 3] = new Color((halfWidth / m_CurrentWidth + p.x), (halfHeight * -1 / m_CurrentHeight + p.y), 0, 0);
normals[vIdx + 0] = -Vector3.forward;
normals[vIdx + 1] = -Vector3.forward;
normals[vIdx + 2] = -Vector3.forward;
normals[vIdx + 3] = -Vector3.forward;
uv0[vIdx + 0] = new Vector2(0, 0);
uv0[vIdx + 1] = new Vector2(1.0f, 0);
uv0[vIdx + 2] = new Vector2(0, 1.0f);
uv0[vIdx + 3] = new Vector2(1.0f, 1.0f);
uv1[vIdx + 0] = targetPixelUV;
uv1[vIdx + 1] = targetPixelUV;
uv1[vIdx + 2] = targetPixelUV;
uv1[vIdx + 3] = targetPixelUV;
}
}