我们知道,眼睛从不同角度和位置去看物体时,看到的画面是不一样的。比如看到这一面就看不到另一面;比如会透视——拍过照的都知道,要显脸小得后拉。
而在3D世界中,我们对一个物体进行操作时,摄像机看到的画面也会随着物体位置的改变而变化。大多数情况下,这是没有问题的。
但是,如果物体相对屏幕很小,而且需要任意拖拽到屏幕上的不同位置,那么就无法保证物体总是呈现设计好的那一面。
针对这种需求,我整理下面这一套方案。
文章目录
- 解决方案
- 方案一
- 方案二
- 延申问题
- 透明对象在RenderTexture上的显示问题
- 源码
解决方案
方案一
首先,我们可能会想到,让物体设计好的那一面始终朝向摄像机不就行了,就像招牌板一样。
这是一个很巧妙的方法,的确可以满足一些项目的需求。
但是,我遇到一个问题,越靠近屏幕边缘,透视造成的变形越严重。就像这样:
方案二
然后我们想到,既要能任意拖动,又要保持画面不变,不就是UI吗?那么使用RenderTexture将对象做成UI不就行了。
好主意!
我也这么做了,具体的做法就是:
1.创建一个RenderTexture,将其尺寸设置为屏幕尺寸;
2.给要观察的对象设置一个层,比如UI层;
3.创建RawImage,添加RenderTexture,并设置尺寸;
4.在主摄像机下添加一个摄像机,该摄像机有四处需要设置:
通过以上操作,就可以对3D对象进行任意位置的拖拽——实际上是拖拽RawImage。
延申问题
透明对象在RenderTexture上的显示问题
我发现,在对透明对象进行RenderTexture渲染时,会显示不出来。
查阅过相关资料后,我整理了一个解决方案—— 给RawImage添加一个包含以下shader的材质球:
Shader "ImageEffect/RT"
{
Properties
{
[PerRendererData] _MainTex("Sprite Texture", 2D) = "white" { }
_Color("Tint", Color) = (1,1,1,1)
_StencilComp("Stencil Comparison", Float) = 8
_Stencil("Stencil ID", Float) = 0
_StencilOp("Stencil Operation", Float) = 0
_StencilWriteMask("Stencil Write Mask", Float) = 255
_StencilReadMask("Stencil Read Mask", Float) = 255
_ColorMask("Color Mask", Float) = 15
}
SubShader
{
Pass
{
Tags{ "Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType" = "Plane"
"CanUseSpriteAtlas" = "True"}
Stencil
{
Ref[_Stencil]
Comp[_StencilComp]
Pass[_StencilOp]
ReadMask[_StencilReadMask]
WriteMask[_StencilWriteMask]
}
ZTest Always Cull Off ZWrite Off
Blend One OneMinusSrcAlpha
ColorMask[_ColorMask]
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 uv : TEXCOORD0;
float4 Color : COLOR;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Color;
v2f vert(appdata v)
{
v2f o;
o.uv.xy = v.uv.xy;
o.vertex = UnityObjectToClipPos(v.vertex);
o.Color = v.color * _Color;
return o;
}
half4 frag(v2f i) : SV_Target
{
float4 color = tex2D(_MainTex, i.uv.xy);
color.w = step(0.05, color.w);
return color * i.Color;
}
ENDCG
}
}
FallBack "Diffuse"
}
源码
https://github.com/yzy1987523/SugarToolProject/tree/master