当前位置:   article > 正文

Unity用相机实现的镜子效果_unity游戏反光镜效果

unity游戏反光镜效果

首先登场

场景中的元素
在这里插入图片描述
mirror是镜子,挂着我们的脚本,Quad是一个面片。Camera是用来生成RenderTexture给面片的。里面的test1是我用来调试位置的球。
在这里插入图片描述
在这里插入图片描述
镜子size是大小,x是-2,为了反转一下贴图

在这里插入图片描述
相机直接可以禁用掉,用脚本来调用。

玩家就是一个胶囊,里面的eye位置把玩家视角的相机放上去,其他没什么特别的。

代码的原理就是把相机拍摄到的图给Quad的Texture,脚本根据人物的位置来改变位置,并计算近裁面,这里因为有旋转,所以镜子后面最好不要有东西,否则相机会拍摄到,或者用层来避免拍摄到的问题。

附上代码:


using UnityEngine;

//一个用相机当镜子的脚本,相机的FOV可以设置成40
public class MirrorEffect : MonoBehaviour
{
    public float disableDis = 20f;  //超过一定距离就不计算了
    public Transform eye;   //玩家的眼睛
    public Camera mirrorCamera;   //镜子相机
    public Transform targetObject;  //画布


    public Transform test1;
    public Transform test2;
    RenderTexture txture;


    float maxResolution = 1024;//根据宽度计算高度,这个是精度
    float maxWidth;
    float maxHeight;
    void Start()
    {


        maxWidth = maxResolution;
        maxHeight = Mathf.Abs(targetObject.localScale.y / targetObject.localScale.x * maxWidth);
        txture = new RenderTexture((int)maxWidth, (int)maxHeight, 24);

        Renderer rend = targetObject.GetComponent<Renderer>();
        if (rend == null)
        {
            Debug.LogWarning("MirrorEffect找不到Renderer.");
            return;
        }
        mirrorCamera.enabled = false;

        rend.material.mainTexture = txture;
        mirrorCamera.targetTexture = txture;

    }

    private void Update()
    {
        Comput();
    }

    private void OnDestroy()
    {
        DestroyImmediate(txture, true);
    }

    void Comput()
    {


        float dis = Vector3.Distance(eye.transform.position, transform.position);
        if (dis > disableDis)
        {
            return;
        }

        //计算视口高度和宽度
        float frustumHeight = targetObject.transform.localScale.y;

        //float frustumWidth = frustumHeight * mainCamera.aspect;

        //缩放目标面片物体大小
        //targetObject.transform.localScale = new Vector3(frustumWidth, frustumHeight, 1f);
        float distance = frustumHeight * 0.5f / Mathf.Tan(mirrorCamera.fieldOfView * 0.5f * Mathf.Deg2Rad);


        //镜子左右边的位置
        float sz = Mathf.Abs(targetObject.transform.localScale.x);
        Vector3 v3l = new Vector3(sz * -0.5f, 0f, 0f);
        Vector3 v3r = new Vector3(sz * 0.5f, 0f, 0f);
        v3l = transform.TransformPoint(v3l);
        v3r = transform.TransformPoint(v3r);
        //test1.position = v3l;
        //test2.position = v3r;

        //计算相机在镜子对象的局部坐标

        //计算反射位置
        Vector3 dir1 = (v3l - eye.transform.position).normalized;
        Vector3 dir2 = (v3r - eye.transform.position).normalized;

        Vector3 mirDir = -(dir1 + dir2).normalized;

        Vector3 dirref2 = Vector3.Reflect(mirDir, -transform.forward);
        //Debug.DrawRay(transform.position, dirref, Color.yellow, 1f);
        //Debug.DrawRay(transform.position, dirref2, Color.red,1f);



        //相机位于镜子正后方,要保持相机所有平移要水平与镜子
        Vector3 dirref3 = Vector3.ProjectOnPlane(dirref2, transform.up);

        Debug.DrawRay(transform.position, dirref3, Color.green, 1f);

        Vector3 cameraPlace = transform.position + dirref3.normalized * distance;


        mirrorCamera.transform.position = cameraPlace;// new Vector3(at2.x, 0f, distance);
        mirrorCamera.nearClipPlane = distance;

        Quaternion q = Quaternion.LookRotation((targetObject.transform.position - mirrorCamera.transform.position).normalized);
        mirrorCamera.transform.rotation = q;

        mirrorCamera.Render();

    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113

画质可以修改maxResolution ,disableDis 是20米距离就不进入Update了,可以节省一些性能,根据自己情况来。

最后放一个效果图。
请添加图片描述
镜面清晰,但是算法还是有点问题,比实时反射来的性能好一点。凑合用还行。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/108372
推荐阅读
相关标签
  

闽ICP备14008679号