Unity的Shader学习笔记(16)[21/01/09_周六][56]

目录

课时56:FragmentShader-片段级模型动态变色3

1.CheckVertex

2.汽车模型

3.修改shader,需要调整方向


课时56:FragmentShader-片段级模型动态变色3

1.CheckVertex

    public MeshFilter[] filters;
 
    [ContextMenu("GetMaxVertex")]
    private void GetMaxVertex()
    {
        foreach (var filter in filters)
        {
            var vertices = filter.mesh.vertices;
            var max = vertices.Max(i => i.x);
            var min = vertices.Min(i => i.x);
            print(string.Format("{0} maxX:{1},minX:{2}", filter.name, max, min));
        }
    }

和教程有所不同,大体是这样的。

2.汽车模型

教程是一辆汽车模型,用于动态变色的,找模型找了一会。

找unity模型插件资源比找max模型方便,max模型的vray版本不统一,我的老是丢失材质。

Realistic Car HD 02 1.0.unitypackage:

3.修改shader,需要调整方向

效果:

 

设置个枚举变量

[Enum(X,1,Y,2,Z,3)] _Dir("Dir", Int) = 1
            v2f vert(appdata_base v) 
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                if (_Dir == 1) {
                    o.y = v.vertex.x;
                }
                if (_Dir == 2) {
                    o.y = v.vertex.y;
                }
                if (_Dir == 3) {
                    o.y = v.vertex.z;
                }
                return o;
            }

效果:

门的部分和车主体是不同的模型,用模型坐标,就不连贯了,自己管自己的,除非模型上处理一下,合并成一个模型。

而用世界坐标的话,参数比较难设置,物体的绝对位置必须清楚,还和模型角度有关,除非和代码结合,用基于整个模型的局部坐标来设置参数。

用屏幕坐标:

            v2f vert(appdata_base v) 
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                if (_Dir == 1) {
                    o.y = v.vertex.x;
                }
                if (_Dir == 2) {
                    o.y = v.vertex.y;
                }
                if (_Dir == 3) {
                    o.y = v.vertex.z;
                }
                return o;
            }

先不管了。

3.光照

前面的颜色是没有任何光照的,车体上的细节在一片纯色下面根本看不到。

方案是创建surfaceShader+vertex函数

默认的surfaceShader:

Shader "Custom/NewSurfaceShader 17"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
        // #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

https://docs.unity3d.com/Manual/SL-SurfaceShaderExamples.html

需要的话,有空得把这些例子看看

移植改造后

Shader "Custom/NewSurfaceShader 17"
{
    Properties
    {
        _MainColor("MainColor",color) = (1,1,1,1)
        _SecondColor("SecondColor",color) = (1,1,1,1)
        _CenterY("CenterY",range(-3,3)) = 0
        [Enum(X,1,Y,2,Z,3)] _Dir("Dir", Int) = 1
        _R("R",range(0,1)) = 0.1
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        //LOD 200

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows vertex:vert
        //#pragma surface surf Standard vertex:vert

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        fixed4 _MainColor;
        fixed4 _SecondColor;
        float _CenterY;
        float _R;
        int _Dir;

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
            //float4 pos;
            float y;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
        // #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)

    void vert (inout appdata_full v, out Input o) {
        //UNITY_INITIALIZE_OUTPUT(Input,o);
        //o.customColor = abs(v.normal);
        o.uv_MainTex=v.texcoord.xy;
        o.y=v.vertex.x;
        float3 p = v.vertex;
        //float3 p = o.pos;
        if (_Dir == 1) {
            o.y = p.x;
        }
        if (_Dir == 2) {
            o.y = p.y;
        }
        if (_Dir == 3) {
            o.y = p.z;
        }
        //return o;
      }
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) ;
            //o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
            float d = IN.y - _CenterY;//到分界线的距离,(-0.5,0.5)
            float s = abs(d);//距离的绝对值
            float u = d / s;//1:在上方,-1:在下方
            float f = s / _R;//距离相对于过渡区域的比例,在过渡区域内(0,1),在过渡区域外(1,...)
            f = saturate(f);//限制在(0,1)范围,大于1的也是1,在过渡区域外则是 两种颜色之一,不融合。
            float g = u * f;//给系数一个正负
            //float l = g;
            float l = g / 2 + 0.5;//从-1到1变成0,1
            //在分界线上时,f=0,g=0,l=0.5,融合。
            //在红色那边是,f=1,g=1,l=1;
            //黄色那边,f=-1,g=-1,l=0;
            o.Albedo= lerp(_SecondColor,_MainColor, l);
            //o.Albedo= fixed4(1,0,0,1);
            // if(IN.y>_CenterY)
            // {
            //     o.Albedo=_MainColor;
            // }
            // else{
            //     o.Albedo=_SecondColor;
            // }
        }
        ENDCG
    }
    FallBack "Diffuse"
}

1.添加属性

2.Input中添加y

3.通过vertex:vert,设置顶点函数

4.通过out Input o,将参数传递给surf

5.不知道v.vertex是模型坐标还是世界坐标...

 

最终效果配合脚本可以实现汽车整体涂色改变。

颜色有点暗,在最后乘上一个系数

o.Albedo= lerp(_SecondColor,_MainColor, l)* _Intensity;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值