Last active
May 7, 2020 15:22
-
-
Save TelpeNight/b34cb740c708823897ae2c7d6cdf52b1 to your computer and use it in GitHub Desktop.
This file contains 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 characters
using UnityEngine; | |
[ExecuteInEditMode] | |
public class PerspectiveLock : MonoBehaviour | |
{ | |
public Camera _otherCam; | |
private Camera _cam; | |
private Renderer _renderer; | |
private MaterialPropertyBlock _propertyBlock; | |
private static readonly int VirtualMatrix = Shader.PropertyToID("_VirtualMatrix"); | |
private static readonly int TrueVp = Shader.PropertyToID("_TrueVP"); | |
private static readonly int TrueIvp = Shader.PropertyToID("_TrueIVP"); | |
// Start is called before the first frame update | |
void Start() | |
{ | |
_cam = Camera.main; | |
_renderer = GetComponent<Renderer>(); | |
} | |
// Update is called once per frame | |
void Update() | |
{ | |
if (_propertyBlock == null) | |
{ | |
_propertyBlock = new MaterialPropertyBlock(); | |
} | |
Matrix4x4 virtualMatrix = GL.GetGPUProjectionMatrix(_otherCam.projectionMatrix, true) * _otherCam.worldToCameraMatrix; | |
Matrix4x4 inversCamProjection = GL.GetGPUProjectionMatrix(_otherCam.projectionMatrix, true).inverse; | |
Matrix4x4 currentCW = _cam.cameraToWorldMatrix; | |
Matrix4x4 currentWC = _cam.worldToCameraMatrix; | |
Matrix4x4 VP = GL.GetGPUProjectionMatrix(_otherCam.projectionMatrix, true) * currentWC; | |
Matrix4x4 IVP = currentCW * inversCamProjection; | |
_renderer.GetPropertyBlock(_propertyBlock); | |
_propertyBlock.SetMatrix(VirtualMatrix, virtualMatrix); | |
_propertyBlock.SetMatrix(TrueVp, VP); | |
_propertyBlock.SetMatrix(TrueIvp, IVP); | |
_renderer.SetPropertyBlock(_propertyBlock); | |
} | |
} |
This file contains 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 characters
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' | |
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' | |
Shader "Renovation/PerspectiveLockShader" | |
{ | |
Properties | |
{ | |
_Color ("Color", Color) = (1,1,1,1) | |
_MainTex ("Albedo (RGB)", 2D) = "white" {} | |
_Glossiness ("Smoothness", Range(0,1)) = 0.5 | |
_Metallic ("Metallic", Range(0,1)) = 0.0 | |
} | |
SubShader | |
{ | |
Tags { "RenderType"="Opaque" } | |
LOD 200 | |
CGPROGRAM | |
// Physically based Standard lighting model, and enable shadows on all light types | |
#pragma surface surf Standard fullforwardshadows vertex:vert | |
// Use shader model 3.0 target, to get nicer looking lighting | |
#pragma target 3.0 | |
#pragma enable_d3d11_debug_symbols | |
sampler2D _MainTex; | |
struct Input | |
{ | |
float2 uv_MainTex; | |
float multiplyValue; | |
}; | |
half _Glossiness; | |
half _Metallic; | |
fixed4 _Color; | |
fixed _Amount; | |
float4x4 _VirtualMatrix; | |
float4x4 _TrueVP; | |
float4x4 _TrueIVP; | |
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader. | |
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing. | |
// #pragma instancing_options assumeuniformscaling | |
UNITY_INSTANCING_BUFFER_START(Props) | |
// put more per-instance properties here | |
UNITY_INSTANCING_BUFFER_END(Props) | |
void vert(inout appdata_full v, out Input o) { | |
float4 globalPos = mul(unity_ObjectToWorld, float4(v.vertex.xyz, 1)); | |
float4 globalPos0 = float4(globalPos.xy, 0, 1); | |
float4 virtualClipPos = mul(_VirtualMatrix, globalPos); | |
float4 virtualNormalClipPos = virtualClipPos / virtualClipPos.w; | |
float4 virtualClipPos0 = mul(_VirtualMatrix, globalPos0); | |
float4 virtualNormClipPos0 = virtualClipPos0 / virtualClipPos0.w; | |
float4 clipDistance = virtualNormalClipPos - virtualNormClipPos0; | |
float4 clipPos0 = mul(_TrueVP, globalPos0); | |
float4 normClipPos0 = clipPos0 / clipPos0.w; | |
float perspectiveCoe = virtualClipPos0.w / clipPos0.w; | |
float4 perspectiveClipDistance = clipDistance * perspectiveCoe; | |
float4 normClipPos = normClipPos0 + perspectiveClipDistance; | |
float a = mul(_TrueIVP._m20_m21_m23, float3(normClipPos.xy, 1)); | |
float b = mul(_TrueIVP._m30_m31_m33, float3(normClipPos.xy, 1)); | |
float w = (globalPos.z * _TrueIVP._m32 - _TrueIVP._m22) / (a * _TrueIVP._m32 - b * _TrueIVP._m22); | |
float z = (1 - b * w) / _TrueIVP._m32 / w; | |
float4 normClipPosFixed = float4(normClipPos.xy, z, 1); | |
float4 clipPos = normClipPosFixed * w; | |
float4 resGlobalPos = mul(_TrueIVP, clipPos); | |
float4 resPos = mul(unity_WorldToObject, resGlobalPos); | |
v.vertex.xyz = resPos; | |
UNITY_INITIALIZE_OUTPUT(Input, o); | |
} | |
void surf (Input IN, inout SurfaceOutputStandard o) | |
{ | |
// Albedo comes from a texture tinted by color | |
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; | |
o.Albedo = c.rgb; | |
// Metallic and smoothness come from slider variables | |
o.Metallic = _Metallic; | |
o.Smoothness = _Glossiness; | |
o.Alpha = c.a; | |
} | |
ENDCG | |
} | |
FallBack "Diffuse" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment