首页 > 其他分享 >简单边缘光

简单边缘光

时间:2023-02-16 00:45:02浏览次数:52  
标签:MainTex Color fixed3 边缘 rgb Specular worldNormal 简单

 

贴图漫反射(MainTex)+高光反射+边缘光

Shader "My/Light/RimLight"
{
    Properties
    {
        _MainTex("Main Tex", 2D) = "white" {}
        _Color("Diffuse Color", Color) = (1, 1, 1, 1) //类似之前的Diffuse

        _Specular("Specular", Color) = (1, 1, 1, 1) //高光反射颜色
        _Gloss("Gloss", Range(8.0, 256)) = 20 //高光区域大小

        _RimColor("Rim Color", Color) = (1, 1, 1, 1) //边缘光颜色
        _RimPower("Rim Power", Range(0.7, 9)) = 4 //边缘光强度
    }

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

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "Lighting.cginc"

            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _Color;

            fixed4 _Specular;
            float _Gloss;

            fixed4 _RimColor;
            float _RimPower;

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL; //顶点法线
                float2 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
                float3 worldNormal : TEXCOORD1;
                float3 worldPos: TEXCOORD2;
            };

            v2f vert(appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;

                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                fixed3 worldNormal = normalize(i.worldNormal);
                fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos)); //指向光源向量(世界空间)

                fixed3 albedo = tex2D(_MainTex, i.uv).rgb * _Color.rgb; //取贴图颜色作为漫反射颜色
                fixed3 ambientColor = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo; //环境光,这里需要*albedo吗?

                fixed lambert = max(0, dot(worldNormal, worldLightDir)); //表面法线和光线方向夹角的cos值成正比
                fixed3 diffuseColor = _LightColor0.rgb * albedo * lambert; //漫反射计算公式

                fixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos)); //视线方向(顶点到相机)

                //fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));
                //fixed3 specularColor = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir, worldViewDir)), _Gloss); //phong模型高光反射计算公式

                fixed3 halfDir = normalize(worldLightDir + worldViewDir); // blinn模型引入的h向量
                fixed3 specularColor = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(worldNormal, halfDir)), _Gloss); // blinn模型高光反射计算公式(更亮, 高光区域更大)

                float rim = 1 - abs(dot(worldNormal, worldViewDir)); //正对视线时边缘光最弱(0), 垂直视线时最强(1)
                rim = pow(rim, _RimPower); //_RimPower>1时, 正对附近缓慢变大, 快到垂直了快速变大;
            
                fixed4 c = fixed4(ambientColor + diffuseColor + specularColor, 1);
                c.rgb = c.rgb * (1-rim) + _RimColor.rgb * rim;
                return c;
            }
            ENDCG
        }
    }

    Fallback "Specular"
}

对rim因子增加一个power是为了让其可以非线性变化

a) >1时

b) <1时

 

 

不足

a) 边缘存在锯齿

b) 背面也有边缘光,且和前面是一样的

 

参考

Shader学习——边缘光 - 简书 (jianshu.com)

【玉兔 | 图形学与游戏开发】游戏中的人物边缘发光效果是如何实现的?码农小姐姐手把手教你写Shader | 2022开工啦,快来学习!_哔哩哔哩_bilibili

标签:MainTex,Color,fixed3,边缘,rgb,Specular,worldNormal,简单
From: https://www.cnblogs.com/sailJs/p/17121726.html

相关文章

  • 简单-SpringBoot整合RabbitMQ
    目录1.windows下安装erlang环境和rabbitMq服务1.1客户端页面2.准备工作2.1pom依赖2.1启动类注解开启:@EnableRabbit2.2application配置文件3.队列的简单使用3.1配置交换器......
  • 聊一聊HTTPS双向认证的简单应用
    目录背景准备工作ASP.NETCorenginx反向代理IIS部署总结参考资料背景在三方接口对接中,偶尔会遇到需要传递证书的情况,这种方式其实是在SSL握手过程中会同时验证客户端和......
  • SpringMVC02 - 简单实现
    开发环境IDEA2022.1.2构建工具:Maven3.8.7服务器:tomcat9.0Spring版本:5.3.3JDK17创建maven工程加入web模块->web.xml中添加打包方式<packing>war<packing......
  • VUE简单实用
    目录v-for的循环方式原生js的循环方式v-for中key值方法的解释vue中数组和对象的检测更新input事件v-model双向数据绑定过滤案例箭头函数事件修饰符按键修饰符Input表单控制......
  • 如何简单有效的对云上数据进行备份、处理与分析
    随着越来越多的企业选择迁移数据上云,云上服务逐渐接管了大量的计算和数据量,如何简单有效的对云上数据进行持久化储存、对数据做进一步处理与分析、挖掘数据价值是云上用户......
  • 实现简单的`Blazor`低代码
    本篇博客只实现基本的低代码,比如新增组件,动态修改组件参数创建项目首先创建一个空的BlazorServer,并且命名LowCode.Web实现我们还需要引用一个Blazor组件库,由于作者用Ma......
  • 直播系统app源码,shiro简单的密码加盐与密码验证
    直播系统app源码,shiro简单的密码加盐与密码验证 publicclasstest{  publicstaticvoidmain(String[]args){                ......
  • wsl简单记录
    1.装了windowterminal,打开ubuntu终端的时候,不知道root密码,可以用wsl -u root来打开终端,再`passwdroot`修改root密码就可以了2.wsl的文件目录位置文件系统路......
  • 简单试用Android Annotations
    AndroidAnnotations号称"是一个能够加速Android开发的开源框架,它可以帮助开发者处理一些前后台任务、rest服务、应用类、代码片段等,让开发者专......
  • js 简单算法学习
    http://liting.ltd/#/algorithm_js/翻转字符串转算法http://liting.ltd/#/js简单算法学习......