我们知道,眼睛从不同角度和位置去看物体时,看到的画面是不一样的。比如看到这一面就看不到另一面;比如会透视——拍过照的都知道,要显脸小得后拉。
而在3D世界中,我们对一个物体进行操作时,摄像机看到的画面也会随着物体位置的改变而变化。大多数情况下,这是没有问题的。
但是,如果物体相对屏幕很小,而且需要任意拖拽到屏幕上的不同位置,那么就无法保证物体总是呈现设计好的那一面。
针对这种需求,我整理下面这一套方案。


文章目录

  • 解决方案
  • 方案一
  • 方案二
  • 延申问题
  • 透明对象在RenderTexture上的显示问题
  • 源码



解决方案

方案一

首先,我们可能会想到,让物体设计好的那一面始终朝向摄像机不就行了,就像招牌板一样。

这是一个很巧妙的方法,的确可以满足一些项目的需求。

但是,我遇到一个问题,越靠近屏幕边缘,透视造成的变形越严重。就像这样:

unity cube怎么调成透明_Unity


unity cube怎么调成透明_unity cube怎么调成透明_02

方案二

然后我们想到,既要能任意拖动,又要保持画面不变,不就是UI吗?那么使用RenderTexture将对象做成UI不就行了。
好主意!
我也这么做了,具体的做法就是:

1.创建一个RenderTexture,将其尺寸设置为屏幕尺寸;

2.给要观察的对象设置一个层,比如UI层;

3.创建RawImage,添加RenderTexture,并设置尺寸;

4.在主摄像机下添加一个摄像机,该摄像机有四处需要设置:

unity cube怎么调成透明_unity cube怎么调成透明_03

通过以上操作,就可以对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