Unity ShaderLab(二) 支持透明的边缘发光Shader

ShaderLab

ShaderLab模块将持续更新,ShaderLab中将会陆续更新较为常见的Unity Shader,比如常见于游戏中的部分特效,常见于三维可视化的特效Shader

  • 目前打算每周更新多个,两个?三个?四个?都有可能

  • 目前打算每十个为一组,直接根据顺序进行分组

利用这个ShaderLab模块来记录自己的Shader学习过程并且也有给学习Shader的同学一些练习的内容。本文不讲解shader的基础语法,建议有一定shader基础的同学学习,如果你想从基础学起,我给你一张飞机票,点击这里起飞,【浅墨Unity3D Shader编程】

目录

    1. 支持透明的边缘发光着色器(SupportAlphaRim.shader)

1.支持透明的边缘发光

效果图

材质球

这里写图片描述这里写图片描述
这里写图片描述这里写图片描述

实际效果

这里写图片描述

简要原理

  • 支持透明,需要将ZWrite设置为OFF,然后开启Blend,进行混合操作
  • 计算漫反射利用法线和视角方向点积值乘以颜色并混合环境光。
    • 这里为什么没有利用传统的法线和灯光方向,因为利用灯光的话就是产生背面阴影,当然你也可以使用半柏林光照让背面也产生一定的光强,根据需要自行修改。
  • 计算边缘光,利用法线和视角方向的点积角度取反,乘以边缘色得到边缘光
  • 混合漫反射和边缘光,利用float值控制输出颜色的alpha值,以实现透明控制

Shader代码


Shader "Custom/SupportAlphaRim"
{
    Properties
    {
        _Color("Main Color",Color) = (0.6,0.6,0.6,1)
        _AlphaRange("Alpha Range",Range(0,1)) = 0
        _RimColor("Rim Color",Color) = (1,1,1,1)
    }

    SubShader
    {
        Tags{"RenderType"="Transparent" "Queue"="Transparent" }     
        LOD 200         

        Pass
        {
            Tags{"LightMode"="ForwardBase"}

            Cull back
            Blend SrcAlpha OneMinusSrcAlpha 
            ZWrite OFF

            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag           
            #include "unitycg.cginc"
            #include "unitylightingcommon.cginc"

            struct a2v
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;             
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
                float3 normalDir : Texcoord0;
                float3 worldPos : TEXCOORD1;
            };

            fixed4 _Color;
            float _AlphaRange;
            fixed4 _RimColor;

            v2f vert( a2v i )
            {
                v2f o;
                // 转化顶点位置
                o.pos = mul(UNITY_MATRIX_MVP,i.vertex);
                // 获取世界空间法线向量
                o.normalDir = mul(float4(i.normal,0),_World2Object).xyz;
                // 获取世界坐标系顶点位置
                o.worldPos = mul(_Object2World,i.vertex);
                return o;
            }

            fixed4 frag( v2f v ):COLOR
            {
                // 法线标准化
                float3 normal = normalize(v.normalDir);
                // 视角方向标准化
                float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - v.worldPos.xyz);
                // 点积
                float NdotV = saturate(dot(normal,viewDir));
                // 漫反射
                fixed3 diffuse = NdotV *_Color + UNITY_LIGHTMODEL_AMBIENT.rgb;
                float alpha =  1 -  NdotV;      
                // 边缘色
                fixed3 rim = _RimColor *alpha;  
                // 混合输出
                return fixed4(diffuse + rim ,alpha * (1-_AlphaRange)+_AlphaRange);
            }

            ENDCG
        }
    }
    // 如果需要阴影在此回滚 不需要注释掉即可
    Fallback "Diffuse"
}

结尾

猜你喜欢

转载自blog.csdn.net/qq_29579137/article/details/77483394