Initial Commit
This commit is contained in:
commit
ee5c2f922d
2255 changed files with 547750 additions and 0 deletions
773
Assets/Plugins/Light2D/Scripts/LightingSystem.cs
Normal file
773
Assets/Plugins/Light2D/Scripts/LightingSystem.cs
Normal file
|
|
@ -0,0 +1,773 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Light2D
|
||||
{
|
||||
/// <summary>
|
||||
/// Main script for lights. Should be attached to camera.
|
||||
/// Handles lighting operation like camera setup, shader setup, merging cameras output together, blurring and some others.
|
||||
/// </summary>
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof (Camera))]
|
||||
public class LightingSystem : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Size of lighting pixel in Unity meters. Controls resoultion of lighting textures.
|
||||
/// Smaller value - better quality, but lower performance.
|
||||
/// </summary>
|
||||
public float LightPixelSize = 0.05f;
|
||||
|
||||
/// <summary>
|
||||
/// Needed for off screen lights to work correctly. Set that value to radius of largest light.
|
||||
/// Used only when camera is in orthographic mode. Big values could cause a performance drop.
|
||||
/// </summary>
|
||||
public float LightCameraSizeAdd = 3;
|
||||
|
||||
/// <summary>
|
||||
/// Needed for off screen lights to work correctly.
|
||||
/// Used only when camera is in perspective mode.
|
||||
/// </summary>
|
||||
public float LightCameraFovAdd = 30;
|
||||
|
||||
/// <summary>
|
||||
/// Enable/disable ambient lights. Disable it to improve performance if you not using ambient light.
|
||||
/// </summary>
|
||||
public bool EnableAmbientLight = true;
|
||||
|
||||
/// <summary>
|
||||
/// LightSourcesBlurMaterial is applied to light sources texture if enabled. Disable to improve performance.
|
||||
/// </summary>
|
||||
public bool BlurLightSources = true;
|
||||
|
||||
/// <summary>
|
||||
/// AmbientLightBlurMaterial is applied to ambient light texture if enabled. Disable to improve performance.
|
||||
/// </summary>
|
||||
public bool BlurAmbientLight = true;
|
||||
|
||||
/// <summary>
|
||||
/// If true RGBHalf RenderTexture type will be used for light processing.
|
||||
/// That could improve smoothness of lights. Will be turned off if device is not supports it.
|
||||
/// </summary>
|
||||
public bool HDR = true;
|
||||
|
||||
/// <summary>
|
||||
/// If true light obstacles will be rendered in 2x resolution and then downsampled to 1x.
|
||||
/// </summary>
|
||||
public bool LightObstaclesAntialiasing = true;
|
||||
|
||||
/// <summary>
|
||||
/// Set it to distance from camera to plane with light obstacles. Used only when camera in perspective mode.
|
||||
/// </summary>
|
||||
public float LightObstaclesDistance = 10;
|
||||
|
||||
/// <summary>
|
||||
/// Billinear for blurred lights, Point for pixelated lights.
|
||||
/// </summary>
|
||||
public FilterMode LightTexturesFilterMode = FilterMode.Bilinear;
|
||||
|
||||
/// <summary>
|
||||
/// Normal mapping. Not supported on mobiles.
|
||||
/// </summary>
|
||||
public bool EnableNormalMapping = false;
|
||||
|
||||
/// <summary>
|
||||
/// If true lighting won't be seen on contents of previous cameras.
|
||||
/// </summary>
|
||||
public bool AffectOnlyThisCamera;
|
||||
|
||||
public Material AmbientLightComputeMaterial;
|
||||
public Material LightOverlayMaterial;
|
||||
public Material LightSourcesBlurMaterial;
|
||||
public Material AmbientLightBlurMaterial;
|
||||
public Camera LightCamera;
|
||||
public int LightSourcesLayer;
|
||||
public int AmbientLightLayer;
|
||||
public int LightObstaclesLayer;
|
||||
public LayerMask LightObstaclesReplacementShaderLayer;
|
||||
|
||||
private RenderTexture _ambientEmissionTexture;
|
||||
private RenderTexture _ambientTexture;
|
||||
private RenderTexture _prevAmbientTexture;
|
||||
private RenderTexture _bluredLightTexture;
|
||||
private RenderTexture _obstaclesUpsampledTexture;
|
||||
private RenderTexture _lightSourcesTexture;
|
||||
private RenderTexture _obstaclesTexture;
|
||||
private RenderTexture _screenBlitTempTex;
|
||||
private RenderTexture _normalMapBuffer;
|
||||
private RenderTexture _singleLightSourceTexture;
|
||||
private RenderTexture _renderTargetTexture;
|
||||
private RenderTexture _oldActiveRenderTexture;
|
||||
|
||||
private Camera _camera;
|
||||
private ObstacleCameraPostPorcessor _obstaclesPostProcessor;
|
||||
private Point2 _extendedLightTextureSize;
|
||||
private Point2 _smallLightTextureSize;
|
||||
private Vector3 _oldPos;
|
||||
private Vector3 _currPos;
|
||||
private RenderTextureFormat _texFormat;
|
||||
private int _aditionalAmbientLightCycles = 0;
|
||||
private static LightingSystem _instance;
|
||||
private Shader _normalMapRenderShader;
|
||||
private Camera _normalMapCamera;
|
||||
private List<LightSprite> _lightSpritesCache = new List<LightSprite>();
|
||||
private Material _normalMappedLightMaterial;
|
||||
private Material _lightCombiningMaterial;
|
||||
private Material _alphaBlendedMaterial;
|
||||
private bool _halfTexelOffest;
|
||||
private Shader _lightBlockerReplacementShader;
|
||||
#if LIGHT2D_2DTK
|
||||
private tk2dCamera _tk2dCamera;
|
||||
#endif
|
||||
|
||||
private float LightPixelsPerUnityMeter
|
||||
{
|
||||
get { return 1/LightPixelSize; }
|
||||
}
|
||||
|
||||
public static LightingSystem Instance
|
||||
{
|
||||
get { return _instance != null ? _instance : (_instance = FindObjectOfType<LightingSystem>()); }
|
||||
}
|
||||
|
||||
[ContextMenu("Create Camera")]
|
||||
private void CreateCamera()
|
||||
{
|
||||
if (LightCamera == null)
|
||||
{
|
||||
var go = new GameObject("Ligt Camera",typeof(Camera));
|
||||
go.transform.SetParent(transform,false);
|
||||
LightCamera = go.GetComponent<Camera>();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_instance = this;
|
||||
_camera = GetComponent<Camera>();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
Shader.SetGlobalTexture("_ObstacleTex", Texture2D.whiteTexture);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (LightCamera == null)
|
||||
{
|
||||
Debug.LogError(
|
||||
"Lighting Camera in LightingSystem is null. Please, select Lighting Camera camera for lighting to work.");
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
if (LightOverlayMaterial == null)
|
||||
{
|
||||
Debug.LogError(
|
||||
"LightOverlayMaterial in LightingSystem is null. Please, select LightOverlayMaterial camera for lighting to work.");
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
if (AffectOnlyThisCamera && _camera.targetTexture != null)
|
||||
{
|
||||
Debug.LogError("\"Affect Only This Camera\" will not work if camera.targetTexture is set.");
|
||||
AffectOnlyThisCamera = false;
|
||||
}
|
||||
|
||||
_camera = GetComponent<Camera>();
|
||||
|
||||
if (EnableNormalMapping && !_camera.orthographic)
|
||||
{
|
||||
Debug.LogError("Normal mapping is not supported with perspective camera.");
|
||||
EnableNormalMapping = false;
|
||||
}
|
||||
|
||||
if (!SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf))
|
||||
HDR = false;
|
||||
_texFormat = HDR ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGB32;
|
||||
|
||||
var lightPixelsPerUnityMeter = LightPixelsPerUnityMeter;
|
||||
|
||||
_halfTexelOffest = SystemInfo.graphicsDeviceVersion.StartsWith("Direct3D 9");
|
||||
|
||||
InitTK2D();
|
||||
|
||||
if (_camera.orthographic)
|
||||
{
|
||||
var rawCamHeight = (_camera.orthographicSize + LightCameraSizeAdd)*2f;
|
||||
var rawCamWidth = (_camera.orthographicSize*_camera.aspect + LightCameraSizeAdd)*2f;
|
||||
|
||||
_extendedLightTextureSize = new Point2(
|
||||
Mathf.RoundToInt(rawCamWidth*lightPixelsPerUnityMeter),
|
||||
Mathf.RoundToInt(rawCamHeight*lightPixelsPerUnityMeter));
|
||||
|
||||
var rawSmallCamHeight = _camera.orthographicSize*2f*lightPixelsPerUnityMeter;
|
||||
_smallLightTextureSize = new Point2(
|
||||
Mathf.RoundToInt(rawSmallCamHeight*_camera.aspect),
|
||||
Mathf.RoundToInt(rawSmallCamHeight));
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
var lightCamHalfFov = (_camera.fieldOfView + LightCameraFovAdd)*Mathf.Deg2Rad/2f;
|
||||
var lightCamSize = Mathf.Tan(lightCamHalfFov)*LightObstaclesDistance*2;
|
||||
//var gameCamHalfFov = _camera.fieldOfView*Mathf.Deg2Rad/2f;
|
||||
var texHeight = Mathf.RoundToInt(lightCamSize/LightPixelSize);
|
||||
var texWidth = texHeight*_camera.aspect;
|
||||
_extendedLightTextureSize = Point2.Round(new Vector2(texWidth, texHeight));
|
||||
|
||||
}
|
||||
{
|
||||
var lightCamHalfFov = _camera.fieldOfView*Mathf.Deg2Rad/2f;
|
||||
var lightCamSize = Mathf.Tan(lightCamHalfFov)*LightObstaclesDistance*2;
|
||||
//LightCamera.orthographicSize = lightCamSize/2f;
|
||||
|
||||
var gameCamHalfFov = _camera.fieldOfView*Mathf.Deg2Rad/2f;
|
||||
var gameCamSize = Mathf.Tan(gameCamHalfFov)*LightObstaclesDistance*2;
|
||||
_camera.orthographicSize = gameCamSize/2f;
|
||||
|
||||
var texHeight = Mathf.RoundToInt(lightCamSize/LightPixelSize);
|
||||
var texWidth = texHeight*_camera.aspect;
|
||||
_smallLightTextureSize = Point2.Round(new Vector2(texWidth, texHeight));
|
||||
}
|
||||
}
|
||||
|
||||
if (_extendedLightTextureSize.x%2 != 0)
|
||||
_extendedLightTextureSize.x++;
|
||||
if (_extendedLightTextureSize.y%2 != 0)
|
||||
_extendedLightTextureSize.y++;
|
||||
|
||||
if (_extendedLightTextureSize.x > 1024 || _extendedLightTextureSize.y > 1024 ||
|
||||
_smallLightTextureSize.x > 1024 || _smallLightTextureSize.y > 1024)
|
||||
{
|
||||
Debug.LogError("LightPixelSize is too small. Turning off lighting system.");
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_extendedLightTextureSize.x < 4 || _extendedLightTextureSize.y < 4 ||
|
||||
_smallLightTextureSize.x < 4 || _smallLightTextureSize.y < 4)
|
||||
{
|
||||
Debug.LogError("LightPixelSize is too big. Turning off lighting system.");
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_screenBlitTempTex = new RenderTexture((int)_camera.pixelWidth, (int)_camera.pixelHeight, 0, _texFormat);
|
||||
_screenBlitTempTex.filterMode = FilterMode.Point;
|
||||
|
||||
LightCamera.orthographic = _camera.orthographic;
|
||||
|
||||
if (EnableNormalMapping)
|
||||
{
|
||||
_lightSourcesTexture = new RenderTexture((int)_camera.pixelWidth, (int)_camera.pixelHeight,
|
||||
0, _texFormat);
|
||||
_lightSourcesTexture.filterMode = FilterMode.Point;
|
||||
}
|
||||
else
|
||||
{
|
||||
_lightSourcesTexture = new RenderTexture(_smallLightTextureSize.x, _smallLightTextureSize.y,
|
||||
0, _texFormat);
|
||||
_lightSourcesTexture.filterMode = LightTexturesFilterMode;
|
||||
}
|
||||
|
||||
_obstaclesTexture = new RenderTexture(_extendedLightTextureSize.x, _extendedLightTextureSize.y,
|
||||
0, _texFormat);
|
||||
_ambientTexture = new RenderTexture(_extendedLightTextureSize.x, _extendedLightTextureSize.y,
|
||||
0, _texFormat);
|
||||
|
||||
_ambientTexture.filterMode = LightTexturesFilterMode;
|
||||
|
||||
var upsampledObstacleSize = _extendedLightTextureSize * (LightObstaclesAntialiasing ? 2 : 1);
|
||||
_obstaclesUpsampledTexture = new RenderTexture(
|
||||
upsampledObstacleSize.x, upsampledObstacleSize.y, 0, _texFormat);
|
||||
|
||||
if (AffectOnlyThisCamera)
|
||||
{
|
||||
_renderTargetTexture = new RenderTexture((int)_camera.pixelWidth, (int)_camera.pixelHeight, 0, RenderTextureFormat.ARGB32);
|
||||
_renderTargetTexture.filterMode = FilterMode.Point;
|
||||
}
|
||||
|
||||
_obstaclesPostProcessor = new ObstacleCameraPostPorcessor();
|
||||
|
||||
_lightBlockerReplacementShader = Shader.Find(@"Light2D/Internal/LightBlockerReplacementShader");
|
||||
|
||||
LoopAmbientLight(100);
|
||||
}
|
||||
|
||||
private void OnRenderImage(RenderTexture src, RenderTexture dest)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying || Util.IsSceneViewFocused)
|
||||
{
|
||||
Shader.SetGlobalTexture("_ObstacleTex", Texture2D.whiteTexture);
|
||||
if (dest != null)
|
||||
dest.DiscardContents();
|
||||
Graphics.Blit(src, dest);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
Update2DTK();
|
||||
UpdateCamera();
|
||||
RenderObstacles();
|
||||
SetupShaders();
|
||||
RenderNormalBuffer();
|
||||
RenderLightSources();
|
||||
RenderLightSourcesBlur();
|
||||
RenderAmbientLight();
|
||||
RenderLightOverlay(src, dest);
|
||||
}
|
||||
|
||||
void OnPreRender()
|
||||
{
|
||||
if (Application.isPlaying && AffectOnlyThisCamera)
|
||||
{
|
||||
_oldActiveRenderTexture = RenderTexture.active;
|
||||
RenderTexture.active = _renderTargetTexture;
|
||||
GL.Clear(true, true, new Color(0, 0, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void OnPostRender()
|
||||
{
|
||||
if (Application.isPlaying && AffectOnlyThisCamera)
|
||||
{
|
||||
RenderTexture.active = _oldActiveRenderTexture;
|
||||
//if (_alphaBlendedMaterial == null)
|
||||
// _alphaBlendedMaterial = new Material(Shader.Find("Unlit/Transparent"));
|
||||
//_alphaBlendedMaterial.SetTexture("_MainTex", _screenBlitTempTex);
|
||||
//Graphics.Blit(_screenBlitTempTex, _renderTargetTexture, _alphaBlendedMaterial);
|
||||
}
|
||||
}
|
||||
|
||||
void InitTK2D()
|
||||
{
|
||||
#if LIGHT2D_2DTK
|
||||
_tk2dCamera = GetComponent<tk2dCamera>();
|
||||
if (_tk2dCamera != null && _tk2dCamera.CameraSettings.projection == tk2dCameraSettings.ProjectionType.Orthographic)
|
||||
{
|
||||
_camera.orthographic = true;
|
||||
_camera.orthographicSize = _tk2dCamera.ScreenExtents.yMax;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Update2DTK()
|
||||
{
|
||||
#if LIGHT2D_2DTK
|
||||
if (_tk2dCamera != null && _tk2dCamera.CameraSettings.projection == tk2dCameraSettings.ProjectionType.Orthographic)
|
||||
{
|
||||
_camera.orthographic = true;
|
||||
_camera.orthographicSize = _tk2dCamera.ScreenExtents.yMax;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying && LightCamera != null)
|
||||
{
|
||||
_camera = GetComponent<Camera>();
|
||||
if (_camera != null)
|
||||
{
|
||||
InitTK2D();
|
||||
LightCamera.orthographic = _camera.orthographic;
|
||||
if (_camera.orthographic)
|
||||
{
|
||||
LightCamera.orthographicSize = _camera.orthographicSize + LightCameraSizeAdd;
|
||||
}
|
||||
else
|
||||
{
|
||||
LightCamera.fieldOfView = _camera.fieldOfView + LightCameraFovAdd;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Application.isPlaying || Util.IsSceneViewFocused)
|
||||
{
|
||||
Shader.SetGlobalTexture("_ObstacleTex", Texture2D.whiteTexture);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private void RenderObstacles()
|
||||
{
|
||||
ConfigLightCamera(true);
|
||||
|
||||
var oldColor = LightCamera.backgroundColor;
|
||||
var oldClearFlags = LightCamera.clearFlags;
|
||||
LightCamera.enabled = false;
|
||||
LightCamera.targetTexture = _obstaclesUpsampledTexture;
|
||||
|
||||
//main
|
||||
LightCamera.clearFlags = CameraClearFlags.SolidColor;
|
||||
LightCamera.cullingMask = 1 << LightObstaclesLayer;
|
||||
LightCamera.backgroundColor = new Color(1, 1, 1, 0);
|
||||
_obstaclesPostProcessor.DrawMesh(LightCamera, LightObstaclesAntialiasing ? 2 : 1);
|
||||
LightCamera.Render();
|
||||
|
||||
//replacement
|
||||
LightCamera.clearFlags = CameraClearFlags.Nothing;
|
||||
LightCamera.cullingMask = LightObstaclesReplacementShaderLayer;
|
||||
LightCamera.RenderWithShader(_lightBlockerReplacementShader, "RenderType");
|
||||
//LightCamera.Render();
|
||||
|
||||
//LightCamera.ResetReplacementShader();
|
||||
LightCamera.targetTexture = null;
|
||||
LightCamera.cullingMask = 0;
|
||||
LightCamera.backgroundColor = oldColor;
|
||||
LightCamera.clearFlags = oldClearFlags;
|
||||
|
||||
_obstaclesTexture.DiscardContents();
|
||||
Graphics.Blit(_obstaclesUpsampledTexture, _obstaclesTexture);
|
||||
}
|
||||
|
||||
private void SetupShaders()
|
||||
{
|
||||
var lightPixelsPerUnityMeter = LightPixelsPerUnityMeter;
|
||||
|
||||
if (HDR) Shader.EnableKeyword("HDR");
|
||||
else Shader.DisableKeyword("HDR");
|
||||
|
||||
if (_camera.orthographic) Shader.DisableKeyword("PERSPECTIVE_CAMERA");
|
||||
else Shader.EnableKeyword("PERSPECTIVE_CAMERA");
|
||||
|
||||
Shader.SetGlobalTexture("_ObstacleTex", _obstaclesTexture);
|
||||
Shader.SetGlobalFloat("_PixelsPerBlock", lightPixelsPerUnityMeter);
|
||||
Shader.SetGlobalVector("_ExtendedToSmallTextureScale", new Vector2(
|
||||
_smallLightTextureSize.x / (float)_extendedLightTextureSize.x,
|
||||
_smallLightTextureSize.y / (float)_extendedLightTextureSize.y));
|
||||
Shader.SetGlobalVector("_PosOffset", LightObstaclesAntialiasing
|
||||
? (EnableNormalMapping ? _obstaclesUpsampledTexture.texelSize * 0.75f : _obstaclesUpsampledTexture.texelSize * 0.25f)
|
||||
: (EnableNormalMapping ? _obstaclesTexture.texelSize : _obstaclesTexture.texelSize * 0.5f));
|
||||
}
|
||||
|
||||
private void RenderNormalBuffer()
|
||||
{
|
||||
if (!EnableNormalMapping)
|
||||
return;
|
||||
|
||||
if (_normalMapBuffer == null)
|
||||
{
|
||||
_normalMapBuffer = new RenderTexture(
|
||||
(int) _camera.pixelWidth, (int) _camera.pixelHeight, 0, RenderTextureFormat.ARGB32);
|
||||
_normalMapBuffer.filterMode = FilterMode.Point;
|
||||
}
|
||||
|
||||
if (_normalMapRenderShader == null)
|
||||
_normalMapRenderShader = Shader.Find("Light2D/Internal/Normal Map Drawer");
|
||||
|
||||
if (_normalMapCamera == null)
|
||||
{
|
||||
var camObj = new GameObject();
|
||||
camObj.name = "Normals Camera";
|
||||
camObj.transform.parent = _camera.transform;
|
||||
camObj.transform.localScale = Vector3.one;
|
||||
camObj.transform.localPosition = Vector3.zero;
|
||||
camObj.transform.localRotation = Quaternion.identity;
|
||||
_normalMapCamera = camObj.AddComponent<Camera>();
|
||||
_normalMapCamera.enabled = false;
|
||||
}
|
||||
|
||||
_normalMapBuffer.DiscardContents();
|
||||
_normalMapCamera.CopyFrom(_camera);
|
||||
_normalMapCamera.transform.position = LightCamera.transform.position;
|
||||
_normalMapCamera.clearFlags = CameraClearFlags.SolidColor;
|
||||
_normalMapCamera.targetTexture = _normalMapBuffer;
|
||||
_normalMapCamera.cullingMask = int.MaxValue;
|
||||
_normalMapCamera.backgroundColor = new Color(0.5f, 0.5f, 0, 1);
|
||||
_normalMapCamera.RenderWithShader(_normalMapRenderShader, "LightObstacle");
|
||||
|
||||
Shader.SetGlobalTexture("_NormalsBuffer", _normalMapBuffer);
|
||||
Shader.EnableKeyword("NORMAL_MAPPED_LIGHTS");
|
||||
}
|
||||
|
||||
private void RenderLightSources()
|
||||
{
|
||||
ConfigLightCamera(false);
|
||||
|
||||
if (EnableNormalMapping)
|
||||
{
|
||||
if(_singleLightSourceTexture == null)
|
||||
{
|
||||
_singleLightSourceTexture = new RenderTexture(
|
||||
_smallLightTextureSize.x, _smallLightTextureSize.y, 0, _texFormat);
|
||||
_singleLightSourceTexture.filterMode = LightTexturesFilterMode;
|
||||
}
|
||||
|
||||
if (_normalMappedLightMaterial == null)
|
||||
{
|
||||
_normalMappedLightMaterial = new Material(Shader.Find("Light2D/Internal/Normal Mapped Light"));
|
||||
_normalMappedLightMaterial.SetTexture("_MainTex", _singleLightSourceTexture);
|
||||
}
|
||||
|
||||
if (_lightCombiningMaterial == null)
|
||||
{
|
||||
_lightCombiningMaterial = new Material(Shader.Find("Light2D/Internal/Light Blender"));
|
||||
_lightCombiningMaterial.SetTexture("_MainTex", _singleLightSourceTexture);
|
||||
}
|
||||
|
||||
var cameraPlanes = GeometryUtility.CalculateFrustumPlanes(_camera);
|
||||
_lightSourcesTexture.DiscardContents();
|
||||
|
||||
var oldBackgroundColor = LightCamera.backgroundColor;
|
||||
var oldRt = RenderTexture.active;
|
||||
Graphics.SetRenderTarget(_lightSourcesTexture);
|
||||
GL.Clear(false, true, oldBackgroundColor);
|
||||
Graphics.SetRenderTarget(oldRt);
|
||||
|
||||
_lightSpritesCache.Clear();
|
||||
foreach (var lightSprite in LightSprite.AllLightSprites)
|
||||
{
|
||||
if (lightSprite.RendererEnabled &&
|
||||
GeometryUtility.TestPlanesAABB(cameraPlanes, lightSprite.Renderer.bounds))
|
||||
{
|
||||
_lightSpritesCache.Add(lightSprite);
|
||||
}
|
||||
}
|
||||
|
||||
var lightCamLocPos = LightCamera.transform.localPosition;
|
||||
LightCamera.targetTexture = _singleLightSourceTexture;
|
||||
LightCamera.cullingMask = 0;
|
||||
LightCamera.backgroundColor = new Color(0, 0, 0, 0);
|
||||
|
||||
foreach (var lightSprite in _lightSpritesCache)
|
||||
{
|
||||
// HACK: won't work for unknown reason without that line
|
||||
LightCamera.RenderWithShader(_normalMapRenderShader, "f84j");
|
||||
|
||||
Graphics.SetRenderTarget(_singleLightSourceTexture);
|
||||
lightSprite.DrawLightingNow(lightCamLocPos);
|
||||
Graphics.SetRenderTarget(_lightSourcesTexture);
|
||||
lightSprite.DrawLightNormalsNow(_normalMappedLightMaterial);
|
||||
}
|
||||
Graphics.SetRenderTarget(oldRt);
|
||||
|
||||
LightCamera.cullingMask = 1 << LightSourcesLayer;
|
||||
LightCamera.Render();
|
||||
Graphics.Blit(_singleLightSourceTexture, _lightSourcesTexture, _lightCombiningMaterial);
|
||||
|
||||
LightCamera.targetTexture = null;
|
||||
LightCamera.cullingMask = 0;
|
||||
LightCamera.backgroundColor = oldBackgroundColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
LightCamera.targetTexture = _lightSourcesTexture;
|
||||
LightCamera.cullingMask = 1 << LightSourcesLayer;
|
||||
//LightCamera.backgroundColor = new Color(0, 0, 0, 0);
|
||||
LightCamera.Render();
|
||||
LightCamera.targetTexture = null;
|
||||
LightCamera.cullingMask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void RenderLightSourcesBlur()
|
||||
{
|
||||
if (BlurLightSources && LightSourcesBlurMaterial != null)
|
||||
{
|
||||
UnityEngine.Profiling.Profiler.BeginSample("LightingSystem.OnRenderImage Bluring Light Sources");
|
||||
|
||||
if (_bluredLightTexture == null)
|
||||
{
|
||||
var w = _lightSourcesTexture.width == _smallLightTextureSize.x
|
||||
? _lightSourcesTexture.width*2
|
||||
: _lightSourcesTexture.width;
|
||||
var h = _lightSourcesTexture.height == _smallLightTextureSize.y
|
||||
? _lightSourcesTexture.height*2
|
||||
: _lightSourcesTexture.height;
|
||||
_bluredLightTexture = new RenderTexture(w, h, 0, _texFormat);
|
||||
}
|
||||
|
||||
_bluredLightTexture.DiscardContents();
|
||||
_lightSourcesTexture.filterMode = FilterMode.Bilinear;
|
||||
LightSourcesBlurMaterial.mainTexture = _lightSourcesTexture;
|
||||
Graphics.Blit(null, _bluredLightTexture, LightSourcesBlurMaterial);
|
||||
|
||||
if (LightTexturesFilterMode == FilterMode.Point)
|
||||
{
|
||||
_lightSourcesTexture.filterMode = FilterMode.Point;
|
||||
_lightSourcesTexture.DiscardContents();
|
||||
Graphics.Blit(_bluredLightTexture, _lightSourcesTexture);
|
||||
}
|
||||
|
||||
UnityEngine.Profiling.Profiler.EndSample();
|
||||
}
|
||||
}
|
||||
|
||||
private void RenderAmbientLight()
|
||||
{
|
||||
if (!EnableAmbientLight || AmbientLightComputeMaterial == null)
|
||||
return;
|
||||
|
||||
UnityEngine.Profiling.Profiler.BeginSample("LightingSystem.OnRenderImage Ambient Light");
|
||||
|
||||
ConfigLightCamera(true);
|
||||
|
||||
if (_ambientTexture == null)
|
||||
{
|
||||
_ambientTexture =
|
||||
new RenderTexture(_extendedLightTextureSize.x, _extendedLightTextureSize.y, 0, _texFormat);
|
||||
}
|
||||
if (_prevAmbientTexture == null)
|
||||
{
|
||||
_prevAmbientTexture =
|
||||
new RenderTexture(_extendedLightTextureSize.x, _extendedLightTextureSize.y, 0, _texFormat);
|
||||
}
|
||||
if (_ambientEmissionTexture == null)
|
||||
{
|
||||
_ambientEmissionTexture =
|
||||
new RenderTexture(_extendedLightTextureSize.x, _extendedLightTextureSize.y, 0, _texFormat);
|
||||
}
|
||||
|
||||
if (EnableAmbientLight)
|
||||
{
|
||||
var oldBackgroundColor = LightCamera.backgroundColor;
|
||||
LightCamera.targetTexture = _ambientEmissionTexture;
|
||||
LightCamera.cullingMask = 1 << AmbientLightLayer;
|
||||
LightCamera.backgroundColor = new Color(0, 0, 0, 0);
|
||||
LightCamera.Render();
|
||||
LightCamera.targetTexture = null;
|
||||
LightCamera.cullingMask = 0;
|
||||
LightCamera.backgroundColor = oldBackgroundColor;
|
||||
}
|
||||
|
||||
for (int i = 0; i < _aditionalAmbientLightCycles + 1; i++)
|
||||
{
|
||||
var tmp = _prevAmbientTexture;
|
||||
_prevAmbientTexture = _ambientTexture;
|
||||
_ambientTexture = tmp;
|
||||
|
||||
var texSize = new Vector2(_ambientTexture.width, _ambientTexture.height);
|
||||
var posShift = ((Vector2) (_currPos - _oldPos)/LightPixelSize).Div(texSize);
|
||||
_oldPos = _currPos;
|
||||
|
||||
AmbientLightComputeMaterial.SetTexture("_LightSourcesTex", _ambientEmissionTexture);
|
||||
AmbientLightComputeMaterial.SetTexture("_MainTex", _prevAmbientTexture);
|
||||
AmbientLightComputeMaterial.SetVector("_Shift", posShift);
|
||||
|
||||
_ambientTexture.DiscardContents();
|
||||
Graphics.Blit(null, _ambientTexture, AmbientLightComputeMaterial);
|
||||
|
||||
if (BlurAmbientLight && AmbientLightBlurMaterial != null)
|
||||
{
|
||||
UnityEngine.Profiling.Profiler.BeginSample("LightingSystem.OnRenderImage Bluring Ambient Light");
|
||||
|
||||
_prevAmbientTexture.DiscardContents();
|
||||
AmbientLightBlurMaterial.mainTexture = _ambientTexture;
|
||||
Graphics.Blit(null, _prevAmbientTexture, AmbientLightBlurMaterial);
|
||||
|
||||
var tmpblur = _prevAmbientTexture;
|
||||
_prevAmbientTexture = _ambientTexture;
|
||||
_ambientTexture = tmpblur;
|
||||
|
||||
UnityEngine.Profiling.Profiler.EndSample();
|
||||
}
|
||||
}
|
||||
|
||||
_aditionalAmbientLightCycles = 0;
|
||||
UnityEngine.Profiling.Profiler.EndSample();
|
||||
}
|
||||
|
||||
private void RenderLightOverlay(RenderTexture src, RenderTexture dest)
|
||||
{
|
||||
UnityEngine.Profiling.Profiler.BeginSample("LightingSystem.OnRenderImage Light Overlay");
|
||||
|
||||
ConfigLightCamera(false);
|
||||
|
||||
Vector2 lightTexelSize = new Vector2(1f / _smallLightTextureSize.x, 1f / _smallLightTextureSize.y);
|
||||
float lightPixelsPerUnityMeter = LightPixelsPerUnityMeter;
|
||||
Vector2 worldOffset = Quaternion.Inverse(_camera.transform.rotation)*(LightCamera.transform.position - _camera.transform.position);
|
||||
Vector2 offset = Vector2.Scale(lightTexelSize, -worldOffset*lightPixelsPerUnityMeter);
|
||||
|
||||
var lightSourcesTex = BlurLightSources && LightSourcesBlurMaterial != null && LightTexturesFilterMode != FilterMode.Point
|
||||
? _bluredLightTexture
|
||||
: _lightSourcesTexture;
|
||||
float xDiff = _camera.aspect/LightCamera.aspect;
|
||||
|
||||
if (!_camera.orthographic)
|
||||
{
|
||||
var gameCamHalfFov = _camera.fieldOfView * Mathf.Deg2Rad / 2f;
|
||||
var gameCamSize = Mathf.Tan(gameCamHalfFov) * LightObstaclesDistance * 2;
|
||||
_camera.orthographicSize = gameCamSize / 2f;
|
||||
}
|
||||
|
||||
float scaleY = _camera.orthographicSize/LightCamera.orthographicSize;
|
||||
var scale = new Vector2(scaleY*xDiff, scaleY);
|
||||
|
||||
var oldAmbientFilterMode = _ambientTexture == null ? FilterMode.Point : _ambientTexture.filterMode;
|
||||
LightOverlayMaterial.SetTexture("_AmbientLightTex", EnableAmbientLight ? _ambientTexture : null);
|
||||
LightOverlayMaterial.SetTexture("_LightSourcesTex", lightSourcesTex);
|
||||
LightOverlayMaterial.SetTexture("_GameTex", src);
|
||||
LightOverlayMaterial.SetVector("_Offset", offset);
|
||||
LightOverlayMaterial.SetVector("_Scale", scale);
|
||||
|
||||
if (_screenBlitTempTex == null || _screenBlitTempTex.width != src.width ||
|
||||
_screenBlitTempTex.height != src.height)
|
||||
{
|
||||
if (_screenBlitTempTex != null)
|
||||
_screenBlitTempTex.Release();
|
||||
_screenBlitTempTex = new RenderTexture(src.width, src.height, 0, RenderTextureFormat.ARGB32);
|
||||
_screenBlitTempTex.filterMode = FilterMode.Point;
|
||||
}
|
||||
|
||||
_screenBlitTempTex.DiscardContents();
|
||||
Graphics.Blit(null, _screenBlitTempTex, LightOverlayMaterial);
|
||||
|
||||
if (_ambientTexture != null)
|
||||
_ambientTexture.filterMode = oldAmbientFilterMode;
|
||||
|
||||
if (!AffectOnlyThisCamera)
|
||||
Graphics.Blit(_screenBlitTempTex, dest);
|
||||
|
||||
UnityEngine.Profiling.Profiler.EndSample();
|
||||
}
|
||||
|
||||
private void UpdateCamera()
|
||||
{
|
||||
LightPixelSize = _camera.orthographicSize*2f/_smallLightTextureSize.y;
|
||||
|
||||
var lightPixelsPerUnityMeter = LightPixelsPerUnityMeter;
|
||||
var mainPos = _camera.transform.position;
|
||||
var camRot = _camera.transform.rotation;
|
||||
var unrotMainPos = Quaternion.Inverse(camRot) * mainPos;
|
||||
var gridPos = new Vector2(
|
||||
Mathf.Round(unrotMainPos.x * lightPixelsPerUnityMeter) / lightPixelsPerUnityMeter,
|
||||
Mathf.Round(unrotMainPos.y * lightPixelsPerUnityMeter) / lightPixelsPerUnityMeter);
|
||||
Vector2 posDiff = gridPos - (Vector2)unrotMainPos;
|
||||
var pos = camRot*posDiff + mainPos;
|
||||
LightCamera.transform.position = pos;
|
||||
_currPos = pos;
|
||||
}
|
||||
|
||||
public void LoopAmbientLight(int cycles)
|
||||
{
|
||||
_aditionalAmbientLightCycles += cycles;
|
||||
}
|
||||
|
||||
void ConfigLightCamera(bool extended)
|
||||
{
|
||||
if (extended)
|
||||
{
|
||||
LightCamera.orthographicSize =
|
||||
_camera.orthographicSize*(_extendedLightTextureSize.y/(float)_smallLightTextureSize.y);// _extendedLightTextureSize.y/(2f*LightPixelsPerUnityMeter);
|
||||
LightCamera.fieldOfView = _camera.fieldOfView + LightCameraFovAdd;
|
||||
LightCamera.aspect = _extendedLightTextureSize.x/(float) _extendedLightTextureSize.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
LightCamera.orthographicSize = _camera.orthographicSize;// _smallLightTextureSize.y / (2f * LightPixelsPerUnityMeter);
|
||||
LightCamera.fieldOfView = _camera.fieldOfView;
|
||||
LightCamera.aspect = _smallLightTextureSize.x / (float)_smallLightTextureSize.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue