Created
March 7, 2017 16:21
Revisions
-
rc1 created this gist
Mar 7, 2017 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,99 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; [ExecuteInEditMode] public class PointLightsImageEffect : MonoBehaviour { private Camera _camera; public Material EffectMaterial; public Transform pointLight; void OnEnable() { _camera = GetComponent<Camera>(); _camera.depthTextureMode = DepthTextureMode.DepthNormals; } [ImageEffectOpaque] void OnRenderImage(RenderTexture src, RenderTexture dst) { // EffectMaterial.SetVector("_WorldSpaceScannerPos", ScannerOrigin.position); // EffectMaterial.SetFloat("_ScanDistance", ScanDistance); // Get the camera matrix to convert the view space normals to world normals Matrix4x4 MV = _camera.cameraToWorldMatrix; EffectMaterial.SetMatrix( "_CameraMV", MV); // Update the point light if ( pointLight != null ) { EffectMaterial.SetVector( "_LightPosition", pointLight.position ); } RaycastCornerBlit(src, dst, EffectMaterial); } void RaycastCornerBlit(RenderTexture source, RenderTexture dest, Material mat) { // Compute Frustum Corners float camFar = _camera.farClipPlane; float camFov = _camera.fieldOfView; float camAspect = _camera.aspect; float fovWHalf = camFov * 0.5f; Vector3 toRight = _camera.transform.right * Mathf.Tan(fovWHalf * Mathf.Deg2Rad) * camAspect; Vector3 toTop = _camera.transform.up * Mathf.Tan(fovWHalf * Mathf.Deg2Rad); Vector3 topLeft = (_camera.transform.forward - toRight + toTop); float camScale = topLeft.magnitude * camFar; topLeft.Normalize(); topLeft *= camScale; Vector3 topRight = (_camera.transform.forward + toRight + toTop); topRight.Normalize(); topRight *= camScale; Vector3 bottomRight = (_camera.transform.forward + toRight - toTop); bottomRight.Normalize(); bottomRight *= camScale; Vector3 bottomLeft = (_camera.transform.forward - toRight - toTop); bottomLeft.Normalize(); bottomLeft *= camScale; // Custom Blit, encoding Frustum Corners as additional Texture Coordinates RenderTexture.active = dest; mat.SetTexture("_MainTex", source); GL.PushMatrix(); GL.LoadOrtho(); mat.SetPass(0); GL.Begin(GL.QUADS); GL.MultiTexCoord2(0, 0.0f, 0.0f); GL.MultiTexCoord(1, bottomLeft); GL.Vertex3(0.0f, 0.0f, 0.0f); GL.MultiTexCoord2(0, 1.0f, 0.0f); GL.MultiTexCoord(1, bottomRight); GL.Vertex3(1.0f, 0.0f, 0.0f); GL.MultiTexCoord2(0, 1.0f, 1.0f); GL.MultiTexCoord(1, topRight); GL.Vertex3(1.0f, 1.0f, 0.0f); GL.MultiTexCoord2(0, 0.0f, 1.0f); GL.MultiTexCoord(1, topLeft); GL.Vertex3(0.0f, 1.0f, 0.0f); GL.End(); GL.PopMatrix(); } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,113 @@ Shader "PointLightsImageEffect" { Properties { _MainTex ("Texture", 2D) = "white" {} _LightColor ("Light Color", Color) = ( 1.0, 1.0, 1.0 ) _LightPosition ("Light Position", Vector) = ( 0.0, 0.0, 0.0 ) _LightRange ("Light Range", Float) = 1.0 } SubShader { // No culling or depth Cull Off ZWrite Off ZTest Always Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct VertIn { float4 vertex : POSITION; float2 uv : TEXCOORD0; float4 ray : TEXCOORD1; }; struct VertOut { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; float2 uv_depth : TEXCOORD1; float4 interpolatedRay : TEXCOORD2; }; VertOut vert (VertIn v) { VertOut o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = v.uv; o.uv_depth = v.uv.xy; #if UNITY_UV_STARTS_AT_TOP if (_MainTex_TexelSize.y < 0) o.uv.y = 1 - o.uv.y; #endif o.interpolatedRay = v.ray; return o; } sampler2D _MainTex; // Provided by the camera sampler2D_float _CameraDepthNormalsTexture; // Provided by the material property float4x4 _CameraMV; float3 _LightPosition; float4 _LightColor; float _LightRange; float3 lightDistanceNormalised ( float3 surfacePosition, float3 lightPosition, float lightRange ) { float dis = distance( surfacePosition, lightPosition ); return 1.0 - clamp( dis / lightRange, 0.0, 1.0 ); } fixed4 frag (VertOut i) : SV_Target { float4 finalColor; // Get the surface color float4 surfaceColor = tex2D(_MainTex, i.uv); // Get the depth & normal float rawDepth = 1.0; float3 viewSpaceNormal; DecodeDepthNormal( tex2D(_CameraDepthNormalsTexture, i.uv_depth.xy), rawDepth, viewSpaceNormal ); // Get the world position float4 directionWorldSpace = rawDepth * i.interpolatedRay; float3 surfaceWorldPosition = _WorldSpaceCameraPos + directionWorldSpace; // Get the world normal float3 surfaceWorldNormal = mul((float3x3)_CameraMV, viewSpaceNormal); // Return the distance from the light float distanceFromLight = clamp( 1.0 - distance( surfaceWorldPosition, _LightPosition ) / _LightRange, 0, 1 ); // Get the vector from the surface to the light float3 surfaceToLight = _LightPosition - surfaceWorldPosition; // Get the brightness of the surface (cosine of the angle of incidence). 1 means it is facing the light. 0 means it's not float brightness = dot(surfaceWorldNormal, surfaceToLight) / (length(surfaceToLight) * length(surfaceWorldNormal)); brightness = clamp( brightness, 0, 1 ); // Get the intensity of the light based on the distance and the direction float intensity = lerp( 0, brightness, distanceFromLight ); // Add the light to the surface color... there will be better ways finalColor = surfaceColor + ( _LightColor * intensity ); return finalColor; } ENDCG } } }