返回 登录
0

Unity3D实战之移动端实时阴影技术

移动端实时阴影绘制考虑到硬件的限制,使用的实时阴影主要是对主要角色绘制的,场景的阴影渲染采用LightMap技术将其烘焙到地面上就可以了。换句话说本节实现的实时阴影主要是针对角色的,不是对场景建筑。移动端实时阴影绘制的实现方式,首先需要一个3D摄像机,将这个摄像机设置成正交摄像机,并将其放置到角色的头顶上,它主要的作用是在每一帧渲染需要加阴影的物体,渲染物体时需要一个接收面,用于接收实时阴影,为了优化效率,阴影的接收面加一个Quad四边形。如下图所示:
图片描述
设置的接受层是一个Quad四边形面片,所以再设计场景时,就不要设置比较陡的斜坡,这样不利于阴影的展示,这个也是它的一个缺点,当然坡度小时没有任何问题,这个已在项目中进行过验证,下面谈谈它的技术实现。
实时阴影的前期工作已完成,接下来是实现代码的编写工作,实现的原理就是把角色头顶的Camera捕捉到的每一帧渲染到设置的面片上,首先需要把一个物体摆放到场景中,然后在角色的下面新建一个面片,同时在物体的上方设置一个相机Camera,如下图所示:
图片描述
在这里面有几个地方需要注意一下:一个是需要自己建一个RenderTexture,然后将其赋值给Camera里面的参数RenderTexture项。另一个是Quad面需要挂接一个Shader,选择的是Transparent/Diffuse Shader可以渲染有Alpha通道的材质,这就要求Quad四边形的材质必须是有Alpha通道,这样角色才可以渲染到Quad四边形上,从而把阴影渲染绘制出来,当然需要调整摄像机的角度,还有其ViewPort视口的值,下面把操作步骤给大家一一讲解。
首先在模型的子节点处新建一个GameObject,将对象的名字改成Shadow,然后在其下面再建两个子节点,一个是Camera,另一个是Quad四边形,效果如下图:
图片描述
下面编写一个脚本用于RenderTexture的渲染,完整的代码如下所示:

using UnityEngine;
using System.Collections;

public class ShadowScript : MonoBehaviour {

    public Transform obj;

    private GameObject plane;
    private RenderTexture mTex = null;

    void Start()
    {
        plane = transform.FindChild("Plane").gameObject;
        Camera ShadowCamera = transform.FindChild("Camera").GetComponent<Camera>();

        if (!obj)
            obj = transform.parent;
        mTex = new RenderTexture(256, 256, 0);
        mTex.name = Random.Range(0, 100).ToString();
        ShadowCamera.targetTexture = mTex;
    }

    void Update()
    {
        plane.renderer.material.mainTexture = mTex;
    }
}

设置的RenderTexture效果的代码如下:

     mTex = new RenderTexture(256, 256, 0);
        mTex.name = Random.Range(0, 100).ToString();
        ShadowCamera.targetTexture = mTex;

接下来介绍一下脚本的设计思路,在Start函数中new一个RenderTexture用于存放实时绘制的阴影,同时会将其赋值给ShadowCamera.targetTexture,在Update函数中每帧实时绘制,这个脚本是挂接在上面的Shadow对象上的,效果如下图:
图片描述
同时设置一下对象的Layer,用于确定渲染的角色,这里设置了是aaa。然后调整Camera的大小和角度,效果图如下图:
图片描述
通过上图的参数设置大家可以一目了然,非常清晰。接下来最后一步设置Quad四边形将它的摆放位置放置在角色的正中,这个四边形面片是要随着角色移动的,所以要将它挂到骨骼上。效果如下图:
图片描述
整个实时阴影的前期工作就完成了,接下来运行程序看看效果,我们这里摆放了两个角色,运行效果如下图:
图片描述

最后,要注意一个问题,如果角色的材质含有Alpha通道该如何处理?因为如果还使用以前的Shader渲染,二者都有Apha通道在混合时就会出现问题。这个问题的解决方案在笔者已出版的《Unity3D实战核心技术详解》电子工业出版社一书中,有详细讲解。
笔者简介:姜雪伟个人网页

评论