mirror of
https://github.com/FriendshipIsEpic/FiE-Game.git
synced 2024-11-30 00:48:00 +01:00
205 lines
7.1 KiB
C#
205 lines
7.1 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
namespace UnityStandardAssets.ImageEffects
|
|
{
|
|
[ExecuteInEditMode]
|
|
[RequireComponent (typeof(Camera))]
|
|
[AddComponentMenu("Image Effects/Rendering/Screen Space Ambient Occlusion")]
|
|
public class ScreenSpaceAmbientOcclusion : MonoBehaviour
|
|
{
|
|
public enum SSAOSamples
|
|
{
|
|
Low = 0,
|
|
Medium = 1,
|
|
High = 2,
|
|
}
|
|
|
|
[Range(0.05f, 1.0f)]
|
|
public float m_Radius = 0.4f;
|
|
public SSAOSamples m_SampleCount = SSAOSamples.Medium;
|
|
[Range(0.5f, 4.0f)]
|
|
public float m_OcclusionIntensity = 1.5f;
|
|
[Range(0, 4)]
|
|
public int m_Blur = 2;
|
|
[Range(1,6)]
|
|
public int m_Downsampling = 2;
|
|
[Range(0.2f, 2.0f)]
|
|
public float m_OcclusionAttenuation = 1.0f;
|
|
[Range(0.00001f, 0.5f)]
|
|
public float m_MinZ = 0.01f;
|
|
|
|
public Shader m_SSAOShader;
|
|
private Material m_SSAOMaterial;
|
|
|
|
public Texture2D m_RandomTexture;
|
|
|
|
private bool m_Supported;
|
|
|
|
private static Material CreateMaterial (Shader shader)
|
|
{
|
|
if (!shader)
|
|
return null;
|
|
Material m = new Material (shader);
|
|
m.hideFlags = HideFlags.HideAndDontSave;
|
|
return m;
|
|
}
|
|
private static void DestroyMaterial (Material mat)
|
|
{
|
|
if (mat)
|
|
{
|
|
DestroyImmediate (mat);
|
|
mat = null;
|
|
}
|
|
}
|
|
|
|
|
|
void OnDisable()
|
|
{
|
|
DestroyMaterial (m_SSAOMaterial);
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
if (!SystemInfo.supportsImageEffects || !SystemInfo.SupportsRenderTextureFormat (RenderTextureFormat.Depth))
|
|
{
|
|
m_Supported = false;
|
|
enabled = false;
|
|
return;
|
|
}
|
|
|
|
CreateMaterials ();
|
|
if (!m_SSAOMaterial || m_SSAOMaterial.passCount != 5)
|
|
{
|
|
m_Supported = false;
|
|
enabled = false;
|
|
return;
|
|
}
|
|
|
|
//CreateRandomTable (26, 0.2f);
|
|
|
|
m_Supported = true;
|
|
}
|
|
|
|
void OnEnable () {
|
|
GetComponent<Camera>().depthTextureMode |= DepthTextureMode.DepthNormals;
|
|
}
|
|
|
|
private void CreateMaterials ()
|
|
{
|
|
if (!m_SSAOMaterial && m_SSAOShader.isSupported)
|
|
{
|
|
m_SSAOMaterial = CreateMaterial (m_SSAOShader);
|
|
m_SSAOMaterial.SetTexture ("_RandomTexture", m_RandomTexture);
|
|
}
|
|
}
|
|
|
|
[ImageEffectOpaque]
|
|
void OnRenderImage (RenderTexture source, RenderTexture destination)
|
|
{
|
|
if (!m_Supported || !m_SSAOShader.isSupported) {
|
|
enabled = false;
|
|
return;
|
|
}
|
|
CreateMaterials ();
|
|
|
|
m_Downsampling = Mathf.Clamp (m_Downsampling, 1, 6);
|
|
m_Radius = Mathf.Clamp (m_Radius, 0.05f, 1.0f);
|
|
m_MinZ = Mathf.Clamp (m_MinZ, 0.00001f, 0.5f);
|
|
m_OcclusionIntensity = Mathf.Clamp (m_OcclusionIntensity, 0.5f, 4.0f);
|
|
m_OcclusionAttenuation = Mathf.Clamp (m_OcclusionAttenuation, 0.2f, 2.0f);
|
|
m_Blur = Mathf.Clamp (m_Blur, 0, 4);
|
|
|
|
// Render SSAO term into a smaller texture
|
|
RenderTexture rtAO = RenderTexture.GetTemporary (source.width / m_Downsampling, source.height / m_Downsampling, 0);
|
|
float fovY = GetComponent<Camera>().fieldOfView;
|
|
float far = GetComponent<Camera>().farClipPlane;
|
|
float y = Mathf.Tan (fovY * Mathf.Deg2Rad * 0.5f) * far;
|
|
float x = y * GetComponent<Camera>().aspect;
|
|
m_SSAOMaterial.SetVector ("_FarCorner", new Vector3(x,y,far));
|
|
int noiseWidth, noiseHeight;
|
|
if (m_RandomTexture) {
|
|
noiseWidth = m_RandomTexture.width;
|
|
noiseHeight = m_RandomTexture.height;
|
|
} else {
|
|
noiseWidth = 1; noiseHeight = 1;
|
|
}
|
|
m_SSAOMaterial.SetVector ("_NoiseScale", new Vector3 ((float)rtAO.width / noiseWidth, (float)rtAO.height / noiseHeight, 0.0f));
|
|
m_SSAOMaterial.SetVector ("_Params", new Vector4(
|
|
m_Radius,
|
|
m_MinZ,
|
|
1.0f / m_OcclusionAttenuation,
|
|
m_OcclusionIntensity));
|
|
|
|
bool doBlur = m_Blur > 0;
|
|
Graphics.Blit (doBlur ? null : source, rtAO, m_SSAOMaterial, (int)m_SampleCount);
|
|
|
|
if (doBlur)
|
|
{
|
|
// Blur SSAO horizontally
|
|
RenderTexture rtBlurX = RenderTexture.GetTemporary (source.width, source.height, 0);
|
|
m_SSAOMaterial.SetVector ("_TexelOffsetScale",
|
|
new Vector4 ((float)m_Blur / source.width, 0,0,0));
|
|
m_SSAOMaterial.SetTexture ("_SSAO", rtAO);
|
|
Graphics.Blit (null, rtBlurX, m_SSAOMaterial, 3);
|
|
RenderTexture.ReleaseTemporary (rtAO); // original rtAO not needed anymore
|
|
|
|
// Blur SSAO vertically
|
|
RenderTexture rtBlurY = RenderTexture.GetTemporary (source.width, source.height, 0);
|
|
m_SSAOMaterial.SetVector ("_TexelOffsetScale",
|
|
new Vector4 (0, (float)m_Blur/source.height, 0,0));
|
|
m_SSAOMaterial.SetTexture ("_SSAO", rtBlurX);
|
|
Graphics.Blit (source, rtBlurY, m_SSAOMaterial, 3);
|
|
RenderTexture.ReleaseTemporary (rtBlurX); // blurX RT not needed anymore
|
|
|
|
rtAO = rtBlurY; // AO is the blurred one now
|
|
}
|
|
|
|
// Modulate scene rendering with SSAO
|
|
m_SSAOMaterial.SetTexture ("_SSAO", rtAO);
|
|
Graphics.Blit (source, destination, m_SSAOMaterial, 4);
|
|
|
|
RenderTexture.ReleaseTemporary (rtAO);
|
|
}
|
|
|
|
/*
|
|
private void CreateRandomTable (int count, float minLength)
|
|
{
|
|
Random.seed = 1337;
|
|
Vector3[] samples = new Vector3[count];
|
|
// initial samples
|
|
for (int i = 0; i < count; ++i)
|
|
samples[i] = Random.onUnitSphere;
|
|
// energy minimization: push samples away from others
|
|
int iterations = 100;
|
|
while (iterations-- > 0) {
|
|
for (int i = 0; i < count; ++i) {
|
|
Vector3 vec = samples[i];
|
|
Vector3 res = Vector3.zero;
|
|
// minimize with other samples
|
|
for (int j = 0; j < count; ++j) {
|
|
Vector3 force = vec - samples[j];
|
|
float fac = Vector3.Dot (force, force);
|
|
if (fac > 0.00001f)
|
|
res += force * (1.0f / fac);
|
|
}
|
|
samples[i] = (samples[i] + res * 0.5f).normalized;
|
|
}
|
|
}
|
|
// now scale samples between minLength and 1.0
|
|
for (int i = 0; i < count; ++i) {
|
|
samples[i] = samples[i] * Random.Range (minLength, 1.0f);
|
|
}
|
|
|
|
string table = string.Format ("#define SAMPLE_COUNT {0}\n", count);
|
|
table += "const float3 RAND_SAMPLES[SAMPLE_COUNT] = {\n";
|
|
for (int i = 0; i < count; ++i) {
|
|
Vector3 v = samples[i];
|
|
table += string.Format("\tfloat3({0},{1},{2}),\n", v.x, v.y, v.z);
|
|
}
|
|
table += "};\n";
|
|
Debug.Log (table);
|
|
}
|
|
*/
|
|
}
|
|
}
|