做网站py和php,企业型网站建设费用,网站制作公司咨询,网站如何做微信支付宝目录
前言
一、效果预览
1.弧形边缘光
二、效果制作
1. 制作弧形边缘光
2.弧形边缘光进阶
3.弧形边缘光调节渐变范围
4.边缘光突变
5.同心圆 三、加入世界坐标做效果
1.绘制结界
2.斑马球
3.效果合并 四、作者的碎碎念 前言
有粉丝建议说#xff0c;让我继续更新…目录
前言
一、效果预览
1.弧形边缘光
二、效果制作
1. 制作弧形边缘光
2.弧形边缘光进阶
3.弧形边缘光调节渐变范围
4.边缘光突变
5.同心圆 三、加入世界坐标做效果
1.绘制结界
2.斑马球
3.效果合并 四、作者的碎碎念 前言
有粉丝建议说让我继续更新Shader我可以出一些简单常用的效果带着大家写一下我觉得这是个好主意。
换句话说带着大家看一下学到的知识应该怎么去应用。
我会把常见的调节的一些细致过程逐步写下来如果遇见没讲过的知识点就详细讲解一下。
一、效果预览
1.弧形边缘光
这个效果是对于圆形或者圆弧形的物体在边缘发光。如图1所示 图1 边缘光 二、效果制作
1. 制作弧形边缘光
我们先统一一下思路发光用到的语义是自发光之前有讲过详情看链接。
Unity | Shader基础知识(第十二集颜色混合)_shade 颜色混合接口-CSDN博客
边缘发光就是当我们的视线和法线的点乘的值在0附近或0以下的时候就发光也是之前讲的看链接。如图2所示Unity | Shader基础知识(第十三集编写内置着色器阶段总结和表面着色器的补充介绍)_unity viewdir-CSDN博客 图2 viewDir 后面写代码讲太多遍的就不重新注释了只注释没讲过的。
Shader Custom/010
{Properties{//设置自发光的颜色_Color(Color,Color)(0,0.5,0.5,0)}SubShader{CGPROGRAM#pragma surface surf Lambertfloat4 _Color;struct Input{//直接获取viewDirfloat3 viewDir;};void surf(Input IN,inout SurfaceOutput o){//点乘后如果接近1说明在视线正中接近0则在视线边缘 half dotp dot(IN.viewDir,o.Normal);//设置自发光我们需要当正中时没有颜色就是*0在边缘有颜色就是*1//和上面的数字刚好相反所以我们用1-dotp来得到上面的效果o.Emission _Color.rgb*(1-dotp);}ENDCG}
}得到效果为如图3所示 图3 发光球 2.弧形边缘光进阶
大部分模型都是有自己贴图的所以我们在发光的基础上加上贴图。
Shader Custom/010
{Properties{//放图片进入_MainTex(MainTex,2D)white{} //设置自发光的颜色_Color(Color,Color)(0,0.5,0.5,0)}SubShader{CGPROGRAM#pragma surface surf Lambertsampler2D _MainTex;float4 _Color;struct Input{float2 uv_MainTex;//直接获取viewDirfloat3 viewDir;};void surf(Input IN,inout SurfaceOutput o){//这都是之前讲过的不进行二次讲解了o.Albedo tex2D(_MainTex,IN.uv_MainTex).rgb;//点乘后如果接近1说明在视线正中接近0则在视线边缘 half dotp dot(IN.viewDir,o.Normal);//设置自发光我们需要当正中时没有颜色就是*0在边缘有颜色就是*1//和上面的数字刚好相反所以我们用1-dotp来得到上面的效果o.Emission _Color.rgb*(1-dotp);}ENDCG}
}
得到的效果为如图4所示 图4 弧形边缘光进阶 3.弧形边缘光调节渐变范围
大部分时候上面的发光范围都是有点大了所以我们需要加个参数进行调节。 数学知识 _Color.rgb*(1-dotp)中的(1-dotp)是一个线性变化的数据变化是平均的就像数数一样0.1,0.2,0.3...... 我们怎么才能让它的增长变快前面一直比较小越往后越大。 有一个非常简单的方法平方 ....... 如果你觉得平方变化不满意可以是其他次方 所以我们增加一个参数来改变光范围。 函数知识 次方的公式是pow(底数,次方) Shader Custom/010
{Properties{_MainTex(MainTex,2D)white{} _Color(Color,Color)(0,0.5,0.5,0)//边缘光范围参数_Power(Power,Range(0.8,8)) 3}SubShader{CGPROGRAM#pragma surface surf Lambertsampler2D _MainTex;float4 _Color;//接入参数float _Power;struct Input{float2 uv_MainTex;float3 viewDir;};void surf(Input IN,inout SurfaceOutput o){o.Albedo tex2D(_MainTex,IN.uv_MainTex).rgb; half dotp dot(IN.viewDir,o.Normal);//重新设置范围变化曲线o.Emission _Color.rgb*pow((1-dotp),_Power);}ENDCG}
}
效果如图5所示 图5 弧形边缘光调节渐变范围 4.边缘光突变
截止到上图虽然我们把边缘光可以锁定在非常边缘但它的过度还是一个渐变的如果我希望它不要渐变而是突然出现怎么办
答做条件判断但在此之前为了后面计算方便我们对数据做一个简单的处理
我们知道前面的乘积最终结果是-1,1但实际我们应用时小于-1的部分我们完全不需要因为都是看不见的部分和0的效果一样。 函数知识 当数据小于0时直接取0当数据大于1时直接取1其他数据不变。 saturate 因为前面的代码没变这里只复制修改过的代码块。要么太长了 void surf(Input IN,inout SurfaceOutput o){o.Albedo tex2D(_MainTex,IN.uv_MainTex).rgb; //把小于0的数据都删掉half dotp saturate(dot(IN.viewDir,o.Normal));o.Emission _Color.rgb*pow((1-dotp),_Power);}
为了方便计算我们把1-dotp也合并到上面。 void surf(Input IN,inout SurfaceOutput o){o.Albedo tex2D(_MainTex,IN.uv_MainTex).rgb; //合并计算half dotp 1-saturate(dot(IN.viewDir,o.Normal));o.Emission _Color.rgb*pow(dotp,_Power);}
我们可以进行突变判断当dotp0.8时显示边缘光反之不显示。 void surf(Input IN,inout SurfaceOutput o){o.Albedo tex2D(_MainTex,IN.uv_MainTex).rgb; //合并计算half dotp 1-saturate(dot(IN.viewDir,o.Normal));//渐变边缘光暂时废弃//o.Emission _Color.rgb*pow(dotp,_Power);//突变边缘光 //如果大于0.8就等于1反之等于0o.Emission _Color.rgb*dotp0.8?1:0;}
效果如图6所示 图6 突变边缘光 如果你还是希望有一点渐变不太明显哈哈~可以自己尝试。 //有一点渐变o.Emission _Color.rgb*dotp0.8?dotp:0;
5.同心圆
同样继续利用这个规律我们可以做出同心圆。打了注释的地方是有增加其他地方不变。
Shader Custom/010
{Properties{_MainTex(MainTex,2D)white{} //外圈颜色_Color(Color,Color)(0,0.5,0.5,0)//内圈颜色_Color2(Color2,Color)(0,0.5,0.5,0)_Power(Power,Range(0.8,8)) 3}SubShader{CGPROGRAM#pragma surface surf Lambertsampler2D _MainTex;//外圈声明float4 _Color;//内圈声明float4 _Color2;float _Power;struct Input{float2 uv_MainTex;float3 viewDir;};void surf(Input IN,inout SurfaceOutput o){o.Albedo tex2D(_MainTex,IN.uv_MainTex).rgb; half dotp 1-saturate(dot(IN.viewDir,o.Normal));//同心圆o.Emission dotp0.5?_Color.rgb:_Color2.rgb;}ENDCG}
}
效果如图7所示 图7 同心圆 备注多层同心圆
//多层同心圆 //用了个绿色
o.Emission dotp0.8?_Color.rgb:dotp0.5?_Color2.rgb:float4(0,1,0,0); 图8 多层同心圆 三、加入世界坐标做效果
1.绘制结界
动画片里经常有那种从地底下穿越上来东西就变色了这里也可以做这种效果不过我们需要先加入世界坐标。
其他的代码还是用之前的改了改了哪里下面就替换哪部分 struct Input{float2 uv_MainTex;float3 viewDir;//加入世界坐标float3 worldPos;};
当y0时变色~ void surf(Input IN,inout SurfaceOutput o){o.Albedo tex2D(_MainTex,IN.uv_MainTex).rgb; half dotp 1-saturate(dot(IN.viewDir,o.Normal));//绘制结界o.Emission IN.worldPos.y0?_Color:float4(1,1,1,1);}
效果如图9所示 图9 结界球 2.斑马球 我们继续对世界坐标做文章无论我们球的y坐标是多少我们把奇数染成白的偶数染成黑的。 数学知识 整数位是偶数除以2结果的小数位在0~0.5之间 整数位是奇数除以2结果的小数位在0.5~1之间 备注你们可以验证一下 3.2/21.6因为3.2的整数位3是奇数所以结果的小数位0.6在0.5~1之间。 函数知识 取小数的函数。 frac() 例frac(16.89)0.89 因为我们的球目前本来就不大所以我们把y坐标都乘10然后再计算。 void surf(Input IN,inout SurfaceOutput o){half dotp 1-saturate(dot(IN.viewDir,o.Normal));//绘制斑马 //黑色 //白色o.Emission frac(IN.worldPos.y*10/2)0.5?float4(1,1,1,1):float4(0,0,0,0);}
效果如图10所示 图10 斑马球 3.效果合并
我们可以把之前的边缘光效果和贴图效果再打开。 void surf(Input IN,inout SurfaceOutput o){//打开贴图o.Albedo tex2D(_MainTex,IN.uv_MainTex).rgb; half dotp 1-saturate(dot(IN.viewDir,o.Normal));//绘制斑马o.Emission frac(IN.worldPos.y*10/2)0.5?//颜色乘了边缘光那会的数值
float4(1,1,1,1)*dotp:float4(0,0,0,0)*dotp;}
效果如图11所示 图11 效果合并 是不是有那味了~ 四、作者的碎碎念
考虑到好多宝宝学了功能也不知道怎么去用 专门出了这个简单应用专题供大家练习。
喜欢的话希望大家给我点赞收藏加关注哦~ღ( ´ᴗ )比心