Advertisement
krides

lightshafts

Jun 8th, 2016
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.57 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. using System;
  5.  
  6. [ExecuteInEditMode]
  7. [RequireComponent(typeof(Light))]
  8. [RequireComponent(typeof(LightShaftsOptim))]
  9. public partial class LightShafts : MonoBehaviour
  10. {
  11.     public void Start()
  12.     {
  13.         CheckMinRequirements();
  14.         // HACK (Event[0]): Get camera on player
  15.         if(Player.Instance != null && Player.Instance.head != null) {
  16.             m_Cameras = new Camera[]{ Player.Instance.head.GetComponentInChildren<Camera>() };
  17.         } else {
  18.             m_Cameras = new Camera[]{ Camera.main };
  19.         }
  20.  
  21.         UpdateCameraDepthMode();
  22.     }
  23.  
  24.     void UpdateShadowmap()
  25.     {
  26.         if (m_ShadowmapMode == LightShaftsShadowmapMode.Static && !m_ShadowmapDirty)
  27.             return;
  28.  
  29.         InitShadowmap();
  30.  
  31.         if (m_ShadowmapCamera == null)
  32.         {
  33.             GameObject go = new GameObject("Depth Camera");
  34.             go.AddComponent(typeof(Camera));
  35.             m_ShadowmapCamera = go.GetComponent<Camera>();
  36.             go.hideFlags = HideFlags.HideAndDontSave;
  37.             m_ShadowmapCamera.enabled = false;
  38.             m_ShadowmapCamera.clearFlags = CameraClearFlags.SolidColor;
  39.         }
  40.         Transform cam = m_ShadowmapCamera.transform;
  41.         cam.position = transform.position;
  42.         cam.rotation = transform.rotation;
  43.  
  44.         if (directional)
  45.         {
  46.             m_ShadowmapCamera.orthographic = true;
  47.             m_ShadowmapCamera.nearClipPlane = 0;
  48.             m_ShadowmapCamera.farClipPlane = m_Size.z;
  49.             m_ShadowmapCamera.orthographicSize = m_Size.y * 0.5f;
  50.             m_ShadowmapCamera.aspect = m_Size.x / m_Size.y;
  51.         }
  52.         else
  53.         {
  54.             m_ShadowmapCamera.orthographic = false;
  55.             m_ShadowmapCamera.nearClipPlane = m_SpotNear * m_Light.range;
  56.             m_ShadowmapCamera.farClipPlane = m_SpotFar * m_Light.range;
  57.             m_ShadowmapCamera.fieldOfView = m_Light.spotAngle;
  58.             m_ShadowmapCamera.aspect = 1.0f;
  59.         }
  60.         m_ShadowmapCamera.renderingPath = RenderingPath.Forward;
  61.         m_ShadowmapCamera.targetTexture = m_Shadowmap;
  62.         m_ShadowmapCamera.cullingMask = m_CullingMask;
  63.         m_ShadowmapCamera.backgroundColor = Color.white;
  64.  
  65.         m_ShadowmapCamera.RenderWithShader(m_DepthShader, "RenderType");
  66.  
  67.         if (m_Colored)
  68.         {
  69.             m_ShadowmapCamera.targetTexture = m_ColorFilter;
  70.             m_ShadowmapCamera.cullingMask = m_ColorFilterMask;
  71.             m_ShadowmapCamera.backgroundColor = new Color(m_ColorBalance, m_ColorBalance, m_ColorBalance);
  72.             m_ShadowmapCamera.RenderWithShader(m_ColorFilterShader, "");
  73.         }
  74.  
  75.         m_ShadowmapDirty = false;
  76.     }
  77.    
  78.     void RenderCoords(int width, int height, Vector4 lightPos)
  79.     {
  80.         SetFrustumRays(m_CoordMaterial);
  81.  
  82.         RenderBuffer[] buffers = {m_CoordEpi.colorBuffer, m_DepthEpi.colorBuffer};
  83.         Graphics.SetRenderTarget(buffers, m_DepthEpi.depthBuffer);
  84.         m_CoordMaterial.SetVector("_LightPos", lightPos);
  85.         m_CoordMaterial.SetVector("_CoordTexDim", new Vector4(m_CoordEpi.width, m_CoordEpi.height, 1.0f / m_CoordEpi.width, 1.0f / m_CoordEpi.height));
  86.         m_CoordMaterial.SetVector("_ScreenTexDim", new Vector4(width, height, 1.0f / width, 1.0f / height));
  87.         m_CoordMaterial.SetPass(0);
  88.         RenderQuad();
  89.     }
  90.  
  91.     void RenderInterpolationTexture(Vector4 lightPos)
  92.     {
  93.         Graphics.SetRenderTarget(m_InterpolationEpi.colorBuffer, m_RaymarchedLightEpi.depthBuffer);
  94.         if (!m_DX11Support && (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsWebPlayer))
  95.         {
  96.             // Looks like in dx9 stencil is not cleared properly with GL.Clear()
  97.             // Edit: fixed in 4.5, so this hack can be removed
  98.             m_DepthBreaksMaterial.SetPass(1);
  99.             RenderQuad();
  100.         }
  101.         else
  102.         {
  103.             GL.Clear(true, true, new Color(0, 0, 0, 1));
  104.         }
  105.         m_DepthBreaksMaterial.SetFloat("_InterpolationStep", m_InterpolationStep);
  106.         m_DepthBreaksMaterial.SetFloat("_DepthThreshold", GetDepthThresholdAdjusted());
  107.         m_DepthBreaksMaterial.SetTexture("_DepthEpi", m_DepthEpi);
  108.         m_DepthBreaksMaterial.SetVector("_DepthEpiTexDim", new Vector4(m_DepthEpi.width, m_DepthEpi.height, 1.0f / m_DepthEpi.width, 1.0f / m_DepthEpi.height));
  109.         m_DepthBreaksMaterial.SetPass(0);
  110.         RenderQuadSections(lightPos);
  111.     }
  112.  
  113.     void InterpolateAlongRays(Vector4 lightPos)
  114.     {
  115.         Graphics.SetRenderTarget(m_InterpolateAlongRaysEpi);
  116.         m_InterpolateAlongRaysMaterial.SetFloat("_InterpolationStep", m_InterpolationStep);
  117.         m_InterpolateAlongRaysMaterial.SetTexture("_InterpolationEpi", m_InterpolationEpi);
  118.         m_InterpolateAlongRaysMaterial.SetTexture("_RaymarchedLightEpi", m_RaymarchedLightEpi);
  119.         m_InterpolateAlongRaysMaterial.SetVector("_RaymarchedLightEpiTexDim", new Vector4(m_RaymarchedLightEpi.width, m_RaymarchedLightEpi.height, 1.0f / m_RaymarchedLightEpi.width, 1.0f / m_RaymarchedLightEpi.height));
  120.         m_InterpolateAlongRaysMaterial.SetPass(0);
  121.         RenderQuadSections(lightPos);
  122.     }
  123.    
  124.     void RenderSamplePositions(int width, int height, Vector4 lightPos)
  125.     {
  126.         InitRenderTexture (ref m_SamplePositions, width, height, 0, RenderTextureFormat.ARGB32, false);
  127.         // Unfortunately can't be a temporary RT if we want random write
  128.         m_SamplePositions.enableRandomWrite = true;
  129.         m_SamplePositions.filterMode = FilterMode.Point;
  130.                
  131.         Graphics.SetRenderTarget (m_SamplePositions);
  132.         GL.Clear (false, true, new Color(0,0,0,1));
  133.        
  134.         Graphics.ClearRandomWriteTargets();
  135.         Graphics.SetRandomWriteTarget(1, m_SamplePositions);
  136.        
  137.         //We need a render target with m_Coord dimensions, but reading and writing
  138.         //to the same target produces wrong read results, so using a dummy.
  139.         Graphics.SetRenderTarget(m_RaymarchedLightEpi);
  140.        
  141.         m_SamplePositionsMaterial.SetVector("_OutputTexDim", new Vector4(width-1, height-1, 0, 0));
  142.         m_SamplePositionsMaterial.SetVector("_CoordTexDim", new Vector4(m_CoordEpi.width, m_CoordEpi.height, 0, 0));
  143.         m_SamplePositionsMaterial.SetTexture("_Coord", m_CoordEpi);
  144.         m_SamplePositionsMaterial.SetTexture("_InterpolationEpi", m_InterpolationEpi);
  145.  
  146.         if (m_ShowInterpolatedSamples)
  147.         {
  148.             m_SamplePositionsMaterial.SetFloat("_SampleType", 1);
  149.             m_SamplePositionsMaterial.SetVector("_Color", new Vector4(0.4f, 0.4f, 0, 0));
  150.             m_SamplePositionsMaterial.SetPass(0);
  151.             RenderQuad();
  152.         }
  153.  
  154.         m_SamplePositionsMaterial.SetFloat("_SampleType", 0);
  155.         m_SamplePositionsMaterial.SetVector("_Color", new Vector4(1, 0, 0, 0));
  156.         m_SamplePositionsMaterial.SetPass(0);
  157.         RenderQuadSections(lightPos);
  158.        
  159.         Graphics.ClearRandomWriteTargets();
  160.     }
  161.  
  162.     void ShowSamples(int width, int height, Vector4 lightPos)
  163.     {
  164.         bool showSamples = m_ShowSamples && m_DX11Support && m_SamplePositionsShaderCompiles;
  165.         SetKeyword(showSamples, "SHOW_SAMPLES_ON", "SHOW_SAMPLES_OFF");
  166.         if (showSamples)
  167.             RenderSamplePositions(width, height, lightPos);
  168.  
  169.         m_FinalInterpolationMaterial.SetFloat("_ShowSamplesBackgroundFade", m_ShowSamplesBackgroundFade);
  170.     }
  171.  
  172.     void Raymarch(int width, int height, Vector4 lightPos)
  173.     {
  174.         SetFrustumRays(m_RaymarchMaterial);
  175.  
  176.         int shadowmapWidth = m_Shadowmap.width;
  177.         int shadowmapHeight = m_Shadowmap.height;
  178.  
  179.         Graphics.SetRenderTarget(m_RaymarchedLightEpi.colorBuffer, m_RaymarchedLightEpi.depthBuffer);
  180.         GL.Clear(false, true, new Color(0, 0, 0, 1));
  181.         m_RaymarchMaterial.SetTexture("_Coord", m_CoordEpi);
  182.         m_RaymarchMaterial.SetTexture("_InterpolationEpi", m_InterpolationEpi);
  183.         m_RaymarchMaterial.SetTexture("_Shadowmap", m_Shadowmap);
  184.         float brightness = m_Colored ? m_BrightnessColored/m_ColorBalance : m_Brightness;
  185.         brightness *= m_Light.intensity;
  186.         m_RaymarchMaterial.SetFloat("_Brightness", brightness);
  187.         m_RaymarchMaterial.SetFloat("_Extinction", -m_Extinction);
  188.         m_RaymarchMaterial.SetVector("_ShadowmapDim", new Vector4(shadowmapWidth, shadowmapHeight, 1.0f / shadowmapWidth, 1.0f / shadowmapHeight));
  189.         m_RaymarchMaterial.SetVector("_ScreenTexDim", new Vector4(width, height, 1.0f / width, 1.0f / height));
  190.         m_RaymarchMaterial.SetVector("_LightColor", m_Light.color.linear);
  191.         m_RaymarchMaterial.SetFloat("_MinDistFromCamera", m_MinDistFromCamera);
  192.         SetKeyword(m_Colored, "COLORED_ON", "COLORED_OFF");
  193.         m_RaymarchMaterial.SetTexture("_ColorFilter", m_ColorFilter);
  194.         SetKeyword(m_AttenuationCurveOn, "ATTENUATION_CURVE_ON", "ATTENUATION_CURVE_OFF");
  195.         m_RaymarchMaterial.SetTexture("_AttenuationCurveTex", m_AttenuationCurveTex);
  196.         Texture cookie = m_Light.cookie;
  197.         SetKeyword(cookie != null, "COOKIE_TEX_ON", "COOKIE_TEX_OFF");
  198.         if (cookie != null)
  199.             m_RaymarchMaterial.SetTexture("_Cookie", cookie);
  200.         m_RaymarchMaterial.SetPass(0);
  201.  
  202.         RenderQuadSections(lightPos);
  203.     }
  204.  
  205.     public void OnRenderObject ()
  206.     {
  207.         m_CurrentCamera = Camera.current;
  208.         if (!m_MinRequirements || !CheckCamera() || !IsVisible())
  209.             return;
  210.  
  211.         // Prepare
  212.         RenderBuffer depthBuffer = Graphics.activeDepthBuffer;
  213.         RenderBuffer colorBuffer = Graphics.activeColorBuffer;
  214.         InitResources();
  215.         Vector4 lightPos = GetLightViewportPos();
  216.         bool lightOnScreen = lightPos.x >= -1 && lightPos.x <= 1 && lightPos.y >= -1 && lightPos.y <= 1;
  217.         SetKeyword(lightOnScreen, "LIGHT_ON_SCREEN", "LIGHT_OFF_SCREEN");
  218.         int width = Screen.width;
  219.         int height = Screen.height;
  220.        
  221.         // Render the buffers, raymarch, interpolate along rays
  222.         UpdateShadowmap();
  223.         SetKeyword(directional, "DIRECTIONAL_SHAFTS", "SPOT_SHAFTS");
  224.         RenderCoords(width, height, lightPos);
  225.         RenderInterpolationTexture(lightPos);
  226.         Raymarch(width, height, lightPos);
  227.         InterpolateAlongRays(lightPos);
  228.  
  229.         ShowSamples(width, height, lightPos);
  230.  
  231.         // Final interpolation and blending onto the screen
  232.         SetFrustumRays(m_FinalInterpolationMaterial);
  233.         m_FinalInterpolationMaterial.SetTexture("_InterpolationEpi", m_InterpolationEpi);
  234.         m_FinalInterpolationMaterial.SetTexture("_DepthEpi", m_DepthEpi);
  235.         m_FinalInterpolationMaterial.SetTexture("_Shadowmap", m_Shadowmap);
  236.         m_FinalInterpolationMaterial.SetTexture("_Coord", m_CoordEpi);
  237.         m_FinalInterpolationMaterial.SetTexture("_SamplePositions", m_SamplePositions);
  238.         m_FinalInterpolationMaterial.SetTexture("_RaymarchedLight", m_InterpolateAlongRaysEpi);
  239.         m_FinalInterpolationMaterial.SetVector("_CoordTexDim", new Vector4(m_CoordEpi.width, m_CoordEpi.height, 1.0f / m_CoordEpi.width, 1.0f / m_CoordEpi.height));
  240.         m_FinalInterpolationMaterial.SetVector("_ScreenTexDim", new Vector4(width, height, 1.0f / width, 1.0f / height));
  241.         m_FinalInterpolationMaterial.SetVector("_LightPos", lightPos);
  242.         m_FinalInterpolationMaterial.SetFloat("_DepthThreshold", GetDepthThresholdAdjusted());
  243.         bool renderAsQuad = directional || IntersectsNearPlane();
  244.         m_FinalInterpolationMaterial.SetFloat("_ZTest", (float)(renderAsQuad ? UnityEngine.Rendering.CompareFunction.Always : UnityEngine.Rendering.CompareFunction.Less));
  245.         SetKeyword(renderAsQuad, "QUAD_SHAFTS", "FRUSTUM_SHAFTS");
  246.  
  247.         Graphics.SetRenderTarget(colorBuffer, depthBuffer);
  248.         m_FinalInterpolationMaterial.SetPass(0);
  249.         if (renderAsQuad)
  250.             RenderQuad();
  251.         else
  252.             RenderSpotFrustum();
  253.  
  254.         ReleaseResources();
  255.     }
  256. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement