URP 镜面
资源绑定 下载
namespace UnityEngine.Rendering.Universal
{ [ExecuteInEditMode]public class PlanarURP : MonoBehaviour{public bool VR = false;public int ReflectionTexResolution = 512;public float Offset = 0.0f;[Range(0, 1)]public float ReflectionAlpha = 0.5f;public bool BlurredReflection;public LayerMask LayersToReflect = -1;private Camera reflectionCamera;private RenderTexture reflectionTexture = null, reflectionTextureRight = null;private static bool isRendering = false;private Material material;private static readonly int reflectionTexString = Shader.PropertyToID("_ReflectionTex");private static readonly int reflectionTexRString = Shader.PropertyToID("_ReflectionTexRight");private static readonly int reflectionAlphaString = Shader.PropertyToID("_RefAlpha");private static readonly string blurString = "BLUR";private static readonly string vrString = "VRon";private Matrix4x4 reflectionMatrix;private Vector4 reflectionPlane;private Vector3 posistion;private Vector3 normal;private Matrix4x4 projection;private Vector4 oblique;private Matrix4x4 worldToCameraMatrix;private Vector3 clipNormal;private Vector4 clipPlane;private Vector3 oldPosition;Vector3 eulerAngles;void OnEnable(){RenderPipelineManager.beginCameraRendering += this.RenderObject;Start();}private void OnDisable(){RenderPipelineManager.beginCameraRendering -= this.RenderObject;if (reflectionTexture){RemoveObject(reflectionTexture);reflectionTexture = null;}if (reflectionTextureRight){RemoveObject(reflectionTextureRight);reflectionTextureRight = null;}if (reflectionCamera){RemoveObject(reflectionCamera.gameObject);reflectionCamera = null;}}public void Start(){material = GetComponent<Renderer>().sharedMaterials[0];QualitySettings.pixelLightCount = 0;var go = new GameObject(GetInstanceID().ToString(), typeof(Camera), typeof(Skybox));reflectionCamera = go.GetComponent<Camera>();var lwrpCamData = go.AddComponent(typeof(UniversalAdditionalCameraData)) as UniversalAdditionalCameraData;lwrpCamData.renderShadows = false;lwrpCamData.requiresColorOption = CameraOverrideOption.Off;lwrpCamData.requiresDepthOption = CameraOverrideOption.Off;reflectionCamera.enabled = false;reflectionCamera.transform.position = transform.position;reflectionCamera.transform.rotation = transform.rotation;reflectionCamera.cullingMask = ~(1 << 4) & LayersToReflect.value;reflectionCamera.cameraType = CameraType.Reflection;go.hideFlags = HideFlags.HideAndDontSave;if (reflectionTexture){RemoveObject(reflectionTexture);}reflectionTexture = new RenderTexture(ReflectionTexResolution, ReflectionTexResolution, 16){isPowerOfTwo = true,hideFlags = HideFlags.DontSave};if (reflectionTextureRight){RemoveObject(reflectionTextureRight);}reflectionTextureRight = new RenderTexture(ReflectionTexResolution, ReflectionTexResolution, 16){isPowerOfTwo = true,hideFlags = HideFlags.DontSave};}void RenderObject(ScriptableRenderContext context, Camera cam){if (isRendering){return;}isRendering = true;posistion = transform.position;normal = transform.up;reflectionCamera.clearFlags = cam.clearFlags;reflectionCamera.backgroundColor = cam.backgroundColor;reflectionCamera.farClipPlane = cam.farClipPlane;reflectionCamera.nearClipPlane = cam.nearClipPlane;reflectionCamera.orthographic = cam.orthographic;reflectionCamera.fieldOfView = cam.fieldOfView;reflectionCamera.aspect = cam.aspect;reflectionCamera.orthographicSize = cam.orthographicSize;if (cam.clearFlags == CameraClearFlags.Skybox){var sky = cam.GetComponent(typeof(Skybox)) as Skybox;var mysky = reflectionCamera.GetComponent(typeof(Skybox)) as Skybox;if (!sky || !sky.material){mysky.enabled = false;}else{mysky.enabled = true;mysky.material = sky.material;}}reflectionPlane = new Vector4(normal.x, normal.y, normal.z, -Vector3.Dot(normal, posistion) - Offset);reflectionMatrix.m00 = (1F - 2F * reflectionPlane[0] * reflectionPlane[0]);reflectionMatrix.m01 = (-2F * reflectionPlane[0] * reflectionPlane[1]);reflectionMatrix.m02 = (-2F * reflectionPlane[0] * reflectionPlane[2]);reflectionMatrix.m03 = (-2F * reflectionPlane[3] * reflectionPlane[0]);reflectionMatrix.m10 = (-2F * reflectionPlane[1] * reflectionPlane[0]);reflectionMatrix.m11 = (1F - 2F * reflectionPlane[1] * reflectionPlane[1]);reflectionMatrix.m12 = (-2F * reflectionPlane[1] * reflectionPlane[2]);reflectionMatrix.m13 = (-2F * reflectionPlane[3] * reflectionPlane[1]);reflectionMatrix.m20 = (-2F * reflectionPlane[2] * reflectionPlane[0]);reflectionMatrix.m21 = (-2F * reflectionPlane[2] * reflectionPlane[1]);reflectionMatrix.m22 = (1F - 2F * reflectionPlane[2] * reflectionPlane[2]);reflectionMatrix.m23 = (-2F * reflectionPlane[3] * reflectionPlane[2]);reflectionMatrix.m30 = 0F;reflectionMatrix.m31 = 0F;reflectionMatrix.m32 = 0F;reflectionMatrix.m33 = 1F;oldPosition = cam.transform.position;reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflectionMatrix;worldToCameraMatrix = reflectionCamera.worldToCameraMatrix;clipNormal = worldToCameraMatrix.MultiplyVector(normal).normalized;clipPlane = new Vector4(clipNormal.x, clipNormal.y, clipNormal.z, -Vector3.Dot(worldToCameraMatrix.MultiplyPoint(posistion + normal * Offset), clipNormal));if (!VR){RenderObjectCamera(cam.projectionMatrix, false);material.DisableKeyword(vrString);GL.invertCulling = true;reflectionCamera.transform.position = reflectionMatrix.MultiplyPoint(oldPosition);eulerAngles = cam.transform.eulerAngles;reflectionCamera.transform.eulerAngles = new Vector3(0, eulerAngles.y, eulerAngles.z);UniversalRenderPipeline.RenderSingleCamera(context, reflectionCamera);reflectionCamera.transform.position = oldPosition;GL.invertCulling = false;material.SetTexture(reflectionTexString, reflectionTexture);}else{RenderObjectCamera(cam.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left), false);material.EnableKeyword(vrString);GL.invertCulling = true;reflectionCamera.transform.position = reflectionMatrix.MultiplyPoint(oldPosition);eulerAngles = cam.transform.eulerAngles;reflectionCamera.transform.eulerAngles = new Vector3(0, eulerAngles.y, eulerAngles.z);UniversalRenderPipeline.RenderSingleCamera(context, reflectionCamera);reflectionCamera.transform.position = oldPosition;GL.invertCulling = false;material.SetTexture(reflectionTexString, reflectionTexture);RenderObjectCamera(cam.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right), true);GL.invertCulling = true;reflectionCamera.transform.position = reflectionMatrix.MultiplyPoint(oldPosition);eulerAngles = cam.transform.eulerAngles;reflectionCamera.transform.eulerAngles = new Vector3(0, eulerAngles.y, eulerAngles.z);UniversalRenderPipeline.RenderSingleCamera(context, reflectionCamera);reflectionCamera.transform.position = oldPosition;GL.invertCulling = false;material.SetTexture(reflectionTexRString, reflectionTextureRight);}material.SetFloat(reflectionAlphaString, ReflectionAlpha);if (BlurredReflection){material.EnableKeyword(blurString);}else{material.DisableKeyword(blurString);}isRendering = false;}void RemoveObject(Object obj){if (Application.isEditor){DestroyImmediate(obj);}else{Destroy(obj);}}private void RenderObjectCamera(Matrix4x4 projection, bool right){oblique = clipPlane * (2.0F / (Vector4.Dot(clipPlane, projection.inverse * new Vector4(sgn(clipPlane.x), sgn(clipPlane.y), 1.0f, 1.0f))));projection[2] = oblique.x - projection[3];projection[6] = oblique.y - projection[7];projection[10] = oblique.z - projection[11];projection[14] = oblique.w - projection[15];reflectionCamera.projectionMatrix = projection;reflectionCamera.targetTexture = right ? reflectionTextureRight : reflectionTexture;}private static float sgn(float a){return a > 0.0f ? 1.0f : a < 0.0f ? -1.0f : 0.0f;}}
}
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'Shader "SupGames/PlanarReflectionURP/Diffuse"
{Properties{_Color("Color", Color) = (1,1,1,1)_MainTex("Main Texture", 2D) = "white" {}_MaskTex("Mask Texture", 2D) = "white" {}_BlurAmount("Blur Amount", Range(0,7)) = 1[Toggle(RECEIVE_SHADOWS)]_ReceiveShadows("Recieve Shadows", Float) = 0}SubShader{Tags {"RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "IgnoreProjector" = "True"}LOD 100Pass {Tags { "LightMode" = "UniversalForward" }Blend SrcAlpha OneMinusSrcAlphaHLSLPROGRAM#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"#pragma vertex vert#pragma fragment frag#pragma shader_feature_local BLUR#pragma shader_feature_local VRon#pragma shader_feature RECEIVE_SHADOWS#pragma multi_compile _ _MAIN_LIGHT_SHADOWS#pragma multi_compile _ LIGHTMAP_ON#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS#pragma multi_compile_instancing#pragma multi_compile_fogTEXTURE2D(_MainTex);SAMPLER(sampler_MainTex);TEXTURE2D(_ReflectionTex);SAMPLER(sampler_ReflectionTex);
#ifdef VRonTEXTURE2D(_ReflectionTexRight);SAMPLER(sampler_ReflectionTexRight);
#endifTEXTURE2D(_MaskTex);SAMPLER(sampler_MaskTex);half _BlurAmount;half _RefAlpha;half4 _MainTex_ST;half4 _Color;half4 _ReflectionTex_TexelSize;struct Attributes{half4 pos : POSITION;half4 uv : TEXCOORD0;half4 normal : NORMAL;UNITY_VERTEX_INPUT_INSTANCE_ID};struct Varyings{half4 pos : SV_POSITION;half4 uv : TEXCOORD0;half4 normal : TEXCOORD1;
#ifdef LIGHTMAP_ONhalf3 lightmapUV : TEXCOORD2;
#elsehalf4 vertexSH : TEXCOORD2;
#endif
#if defined(BLUR)half4 offset : TEXCOORD3;
#endif
#if defined(_MAIN_LIGHT_SHADOWS)half4 shadowCoord : TEXCOORD4;
#endif
#if defined(_ADDITIONAL_LIGHTS) || defined(_ADDITIONAL_LIGHTS_VERTEX)half3 lightData : TEXCOORD5;
#endifUNITY_VERTEX_INPUT_INSTANCE_IDUNITY_VERTEX_OUTPUT_STEREO};Varyings vert(Attributes i){Varyings o = (Varyings)0;UNITY_SETUP_INSTANCE_ID(i);UNITY_TRANSFER_INSTANCE_ID(i, o);UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);o.uv.xy = TRANSFORM_TEX(i.uv, _MainTex);o.normal.xyz = normalize(mul(i.normal, unity_WorldToObject).xyz);half4 ws = mul(unity_ObjectToWorld, i.pos);o.pos = mul(unity_MatrixVP, ws);half4 scrPos = ComputeScreenPos(o.pos);o.uv.zw = scrPos.xy;o.normal.w = scrPos.w;
#if defined(BLUR)half2 offset = _ReflectionTex_TexelSize.xy * _BlurAmount;o.offset = half4(-offset, offset);
#endif
#if defined(_MAIN_LIGHT_SHADOWS)o.shadowCoord = TransformWorldToShadowCoord(ws.xyz);
#endif
#ifdef LIGHTMAP_ONo.lightmapUV.xy = i.uv.zw * unity_LightmapST.xy + unity_LightmapST.zw;o.lightmapUV.z = ComputeFogFactor(o.pos.z);
#elseo.vertexSH.xyz = SampleSHVertex(i.normal.xyz);o.vertexSH.w = ComputeFogFactor(o.pos.z);
#endif
#ifdef _ADDITIONAL_LIGHTS_VERTEXo.lightData = half3(0.0h, 0.0h, 0.0h);uint lightsCount = GetAdditionalLightsCount();for (uint lightIndex = 0u; lightIndex < lightsCount; ++lightIndex){Light light = GetAdditionalLight(lightIndex, ws.xyz);o.lightData += light.color * light.distanceAttenuation * saturate(dot(o.normal.xyz, light.direction));}
#endif
#ifdef _ADDITIONAL_LIGHTSo.lightData = ws.xyz;
#endifreturn o;}half4 frag(Varyings i) : SV_Target{UNITY_SETUP_INSTANCE_ID(i);UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);half3 diffuseReflection = _MainLightColor.rgb * dot(i.normal.xyz, _MainLightPosition.xyz);half3 bakedGI = SAMPLE_GI(i.lightmapUV.xy, i.vertexSH.xyz, i.normal.xyz);
#if defined(_MAIN_LIGHT_SHADOWS) && defined(RECEIVE_SHADOWS)half3 realtimeShadow = lerp(bakedGI, max(bakedGI - diffuseReflection * (1.0h - MainLightRealtimeShadow(i.shadowCoord)), _SubtractiveShadowColor.xyz), _MainLightShadowData.x);bakedGI = min(bakedGI, realtimeShadow);
#endifhalf4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv.xy);half4 mask = SAMPLE_TEXTURE2D(_MaskTex, sampler_MaskTex, i.uv.xy);i.uv.zw /= i.normal.w;half4 reflection = SAMPLE_TEXTURE2D(_ReflectionTex, sampler_ReflectionTex, i.uv.zw);
#if defined(BLUR)i.offset /= i.normal.w;i.offset = half4(i.uv.zz + i.offset.xz, i.uv.ww + i.offset.yw);reflection += SAMPLE_TEXTURE2D(_ReflectionTex, sampler_ReflectionTex, i.offset.xz);reflection += SAMPLE_TEXTURE2D(_ReflectionTex, sampler_ReflectionTex, i.offset.xw);reflection += SAMPLE_TEXTURE2D(_ReflectionTex, sampler_ReflectionTex, i.offset.yz);reflection += SAMPLE_TEXTURE2D(_ReflectionTex, sampler_ReflectionTex, i.offset.yw);reflection *= 0.2h;
#endif
#ifdef VRonhalf4 reflectionr = SAMPLE_TEXTURE2D(_ReflectionTexRight, sampler_ReflectionTexRight, i.uv.zw);
#ifdef BLURreflectionr += SAMPLE_TEXTURE2D(_ReflectionTexRight, sampler_ReflectionTexRight, i.offset.xz);reflectionr += SAMPLE_TEXTURE2D(_ReflectionTexRight, sampler_ReflectionTexRight, i.offset.xw);reflectionr += SAMPLE_TEXTURE2D(_ReflectionTexRight, sampler_ReflectionTexRight, i.offset.yz);reflectionr += SAMPLE_TEXTURE2D(_ReflectionTexRight, sampler_ReflectionTexRight, i.offset.yw);reflectionr *= 0.2h;
#endifreflection = lerp(reflection, reflectionr, unity_StereoEyeIndex);
#endif
#ifdef _ADDITIONAL_LIGHTSuint pixelLightCount = GetAdditionalLightsCount();for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex){Light light = GetAdditionalLight(lightIndex, i.lightData.xyz);diffuseReflection += light.color * light.distanceAttenuation * light.shadowAttenuation * saturate(dot(i.normal.xyz, light.direction));}
#endif
#ifdef _ADDITIONAL_LIGHTS_VERTEXdiffuseReflection += i.lightData;
#endifcolor.rgb *= (diffuseReflection + bakedGI);
#ifdef LIGHTMAP_ONcolor.rgb = MixFog(color.rgb, i.lightmapUV.z);
#elsecolor.rgb = MixFog(color.rgb, i.vertexSH.w);
#endifreturn (lerp(color, reflection, _RefAlpha * mask.r) + lerp(reflection, color, 1 - _RefAlpha * mask.r))*_Color * 0.5h;}ENDHLSL}}
}