多层相机叠加

需求

需要实时截出不同背景的图片(要求背景颜色对场景有反射效果),但是场景中用到PostProcessing等后处理,还有影子、倒影等效果,所以单纯更换背景很难将这些效果叠加上去。

解决方案:由于在pc上应用,所以处理起来比较简单粗暴。通过三层相机分别来渲染模型影子、倒影以及地面与模型,背景为白色,通过颜色相乘来换成其他背景。

1.解决步骤

1.1 新建显示容器

场景中分别新四个quad,并调整quad大小到需要的尺寸,四个quad放在同一位置,调整Z值使之错开(可根据需要调整前后顺序)

1.2 设置背景

设置最后面一个quad为背景色(白色),材质为Unlit/Color。

1.3 渲染模型和地面

用一个Solid Color类型的Camera来渲染模型和地面(此camera指渲染模型和地面),通过RenderTexture赋值给1.1中的一个quad,此quad的shader为UI/Unlit/Transparent(亦可以用Unlit/texture)。

1.4 渲染影子

用一个Solid Color类型的Camera来渲染模型,通过RenderTexture赋值给1.1中另外一个quad,此quad的shader为UI/Unlit/Transparent。把此quad放置在1.3中quad背后,并调整材质的透明通道使之看起来像影子,可调整quad的位置。
注:此影子为模拟灯光照射产生的影子。

1.5 渲染倒影

用一个Solid Color类型的Camera来渲染倒影,此camera放在始终与1.3中的相机始终关于地面对称的位置,并始终LookAt相机。通过RenderTexture赋值给1.1中最后一个quad,此quad的shader为UI/Unlit/Transparent。调整材质的透明通道使之看起来像倒影,可调整quad的位置,如果需要把Scale的y值改为-1 。
注:倒影为三位模型在比较光滑地面上的镜面反射图

1.6 获取合成图像

通过一个正交相机来获取上述四个quad叠加倒影,并通过像素相乘来更改背景。

1.7 更换背景

通过1.6中的正交相机即可获取混合后的图片,然后通过像素相乘,即可获取更换背景后的图片,且背景图片对影子、倒影等都会产生混合效果。

IEnumerator CaptureEffect()
    {
        //RenderTexture rt = RenderTexture.active;
        RenderTexture rt = new RenderTexture(width, height, 16);
        effectCamera.targetTexture = rt;
        effectCamera.Render();

        yield return new WaitForEndOfFrame();
        RenderTexture.active = rt;
        effectTex = new Texture2D(width, height);
        effectTex.ReadPixels(new Rect(0, 0, effectTex.width, effectTex.height), 0, 0);
        effectTex.Apply();

        //CreateKaleidoscope();//生成万花筒图片

        effectImage.texture = effectTex;
        effectCamera.targetTexture = null;

        int w = effectTex.width;
        int h = effectTex.height;

        for(int i=0;i<w;i++)
        {
            for(int j=0;j<h;j++)
            {
                Color color = effectTex.GetPixel(i, j);
                Color modifiedColor = color * Color.yellow;
                effectTex.SetPixel(i, j, modifiedColor);
            }
        }

        byte[] bytes = effectTex.EncodeToPNG();
        File.WriteAllBytes(@"D:\image.png", bytes);
        //RenderTexture.active = rt;
        //rt = null;
        /*
        byte[] imageBytes = effectTex.EncodeToJPG();
        string picName = DateTime.Now.ToString("yyyyMMddHHmmss") + ".jpg";

        WWWForm form = new WWWForm();
        form.AddField("resource_name", picName);
        form.AddBinaryData("file", imageBytes, picName, "file/jpg");

        //Dictionary<object, object> dic = new Dictionary<object, object>();
        //dic.Add("resource_name", picName);

        WWWWebRequest.Instance.PostForm(APiInfo.UploadImage, form, OnImagePosted);
        */

        //后续删除
        //cover.SetActive(false);
    }

也可以统一获取到像素颜色数组,然后更改颜色,最后赋值给TexturedD,这样效率更高

Texture2D ChangeColor(Color color)
    {
        int width = currentTex.width;
        int height = currentTex.height;

        Texture2D modifiedTex = new Texture2D(width, height);

        Color[] colors = currentTex.GetPixels();

        for(int i=0;i<colors.Length;i++)
        {
            colors[i] = colors[i] * color;
        }

        modifiedTex.SetPixels(colors);
        modifiedTex.Apply();

        /*
        for(int i=0;i<width;i++)
        {
            for(int j=0;j<height;j++)
            {
                Color currentColor = picTex.GetPixel(i, j);
                Color modifiedColor = currentColor * color;
                modifiedTex.SetPixel(i, j, modifiedColor);
            }
        }*/

        finalTex = modifiedTex;

        return modifiedTex;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值