任意门效果

这是一个模拟机器猫里面的任意门的显示效果,即通过门可以看到千里之外的地方,而门边缘以外的地方则仍然是眼前的场景,废话不说,先上效果图:

任意门效果_第1张图片任意门效果_第2张图片

任意门效果_第3张图片

这里就不讲一个个制作的步骤了,主要讲一下原理以及相应的代码实现吧,理解了原理就很容易做出来了。

其实就是用一个保持与主相机一致的附属相机观察另一个场景,将画面输出都一个rendertexture中,然后把这个观察出来的纹理实时绘制到门上。难点就在于纹理的映射上,如何能够准确的把照相机纹理映射到门框,没有任何赘余。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class main : MonoBehaviour {
	public Camera m_cam;
	public Material m_mat;
	// Use this for initialization
	void Start () {
		m_mat.SetMatrix ("_WorldToCameraMatrix", m_cam.worldToCameraMatrix);
		m_mat.SetMatrix ("_ProjectionMatrix", m_cam.projectionMatrix);
	}
	
	// Update is called once per frame
	void Update () {
		m_mat.SetMatrix ("_WorldToCameraMatrix", m_cam.worldToCameraMatrix);
		m_mat.SetMatrix ("_ProjectionMatrix", m_cam.projectionMatrix);
	}
}
以上代码把观察远处场景的照相机(以下称为相机b)的投影矩阵以及世界转相机矩阵传入了下方的着色器中:

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'

Shader "Hidden/Door"
{
	Properties
	{
		_MainTex("Texture", 2D) = "white" {}
	}
		SubShader
	{
		Tags
	{
		"Queue" = "Transparent+100"
	}
	zwrite off
		Pass
	{
		Blend SrcAlpha OneMinusSrcAlpha
		CGPROGRAM
#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"
		uniform float4x4 _WorldToCameraMatrix;
		uniform float4x4 _ProjectionMatrix;

		struct appdata
		{
			float4 vertex : POSITION;
			float2 uv : TEXCOORD0;
		};

		struct v2f
		{
			float2 uv : TEXCOORD0;
			float4 vertex : SV_POSITION;
		};

		v2f vert(appdata v)
		{
			v2f o;
			o.vertex = UnityObjectToClipPos(v.vertex);

			float4 worldCoord = mul(unity_ObjectToWorld, v.vertex);
			float4 cameraCoord = mul(_WorldToCameraMatrix, worldCoord);
			float4 projectionCoord = mul(_ProjectionMatrix, cameraCoord);
			o.uv = projectionCoord / projectionCoord.w;
			o.uv = 0.5f*o.uv + float2(0.5f, 0.5f);
			return o;
		}

		sampler2D _MainTex;

		fixed4 frag(v2f i) : SV_Target
		{
			float dis = (i.uv.x - 0.5f)*(i.uv.x - 0.5f) + (i.uv.y - 0.5f)*(i.uv.y - 0.5f);
			fixed4 col = tex2D(_MainTex, i.uv);
			return col;
		}
			ENDCG
		}
	}
}

上面shader代码做的就是把模型(门)在相机b中的投影和相机的拍摄的纹理坐标相互对应。

你可能感兴趣的:(unity,图形学)