Unity Shader模型显示在NGUI上并可以scrollview裁剪

发表于2019-01-03
评论0 3.5k浏览
模型显示在ui上面

如图显示模型

1.设置模型的Layer为ui相机显示的值,这里设置为NGUI
2.把模型拉近相机,不要被ui渲染遮挡
3.需要放大模型因为NGUI的UIRoot会缩小

有一个问题就是我使用了Scrollview组件我希望ui被裁减时,模型也一起裁剪

自定义裁剪shader

1. 设置显示范围,超出这个范围就丢弃当前片段

这里我是全局设置一个裁剪范围
public class test : MonoBehaviour {
    public Transform left;
    public Transform right;
    // Use this for initialization
    void Start () {
    UnityEngine.Shader.SetGlobalVector("clipRange", new Vector4(left.position.x,        left.position.y, right.position.x, right.position.y));
    }
}

Shader "Unlit/clipModel"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100
        Pass
    {
        Cull Back
        Lighting Off
        Offset -1, -1
        Fog{ Mode Off }
        ColorMask RGB
        Blend SrcAlpha OneMinusSrcAlpha
        CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
    sampler2D _MainTex;
    float4 clipRange;//渲染范围 左上到右下的矩形范围显示
    struct appdata_t
    {
        float4 vertex : POSITION;
        half4 color : COLOR;
        float2 texcoord : TEXCOORD0;
    };
        struct v2f
        {
            float4 vertex : POSITION;
            half4 color : COLOR;
            float2 texcoord : TEXCOORD0;
            float2 worldPos : TEXCOORD1;
        };
        v2f vert(appdata_t v)
        {
            v2f o;
            o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
            o.color = v.color;
            o.texcoord = v.texcoord;
            o.worldPos = mul(unity_ObjectToWorld, v.vertex);
            return o;
        }
        half4 frag(v2f IN) : COLOR
        {
            half4 col = tex2D(_MainTex, IN.texcoord) * IN.color;
            float2 factor = float2(0, 0);
            //判断是否在显示框内
            if (IN.worldPos.x >clipRange.x && IN.worldPos.x < clipRange.z)
            {
                factor.x = 1;
            }
            if (IN.worldPos.y < clipRange.y && IN.worldPos.y > clipRange.w)
            {
                factor.y = 1;
            }
            //x,y坐标一个出框了就裁剪掉
            col.a = min(factor.x, factor.y);
            clip(col.a < 0.1f ? -1 : 1);
            return col;
        }
        ENDCG
        }
    }
}

效果出了,还不错

这里我用了,两个位置去定义裁剪范围,不想用的话就用UIScrollView.panel的属性计算裁剪框吧

UIScrollView.panel 计算裁剪位置

UIScrollView.panel.finalClipRegion 里面包含了裁剪相关信息,xy是center zw是size offset已经计算好了,根据这两个位置就可以计算出来左上,右下点裁剪点。

示意代码
    public void Update()
    {
        var pos = sv.transform.position;
        Vector3 tl = Vector3.zero;
        Vector3 rb = Vector3.zero;
        //关键计算
        tl.x = sv.panel.finalClipRegion.x - sv.panel.finalClipRegion.z / 2;
        tl.y = sv.panel.finalClipRegion.y + sv.panel.finalClipRegion.w / 2;
        rb.x = sv.panel.finalClipRegion.x + sv.panel.finalClipRegion.z / 2;
        rb.y = sv.panel.finalClipRegion.y - sv.panel.finalClipRegion.w / 2;
        leftTop.transform.position = (tl + pos) * 0.00149925f;//uiroot 需要缩小的倍数
        rightBottom.transform.position = (rb + pos)* 0.00149925f;//uiroot 需要缩小的倍数
    }


效果图

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引