失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 钢铁侠材质制作——2 线条轮廓部分的制作

钢铁侠材质制作——2 线条轮廓部分的制作

时间:2022-07-25 22:09:12

相关推荐

钢铁侠材质制作——2 线条轮廓部分的制作

钢铁侠Unlit光照Shader,三种效果变化

返回目录

大家好,我是阿赵,这里是钢铁侠材质制作第二部分,线条轮廓部分的制作

为了实现这个效果,可以把细节拆分成以下几个部分:

1、轮廓光

1.效果分析

这是一个很基础的轮廓光实现,用到的就是法线和观察方向的点乘(NdotV)。

2.shader实现

Shader "azhao/IronManBodyCode"{Properties{_RimBias("RimBias", Float) = 1_RimPow("RimlPow", Float) = 2_RimlCol("RimCol", Color) = (0,0,0,0)}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;};struct v2f{float4 pos : SV_POSITION;float3 worldPos :TEXCOORD0;float3 worldNormal : TEXCOORD1;};float _RimBias;float _RimPow;float4 _RimlCol;v2f vert (appdata v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.worldPos = mul(unity_ObjectToWorld, v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);return o;}half4 frag (v2f i) : SV_Target{float3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));float NdotV = dot(i.worldNormal, worldViewDir);float fresnelVal = pow((1 - NdotV)*_RimBias, _RimPow);half4 col = _RimlCol* fresnelVal;return col;}ENDCG}}}

3.说明

这个其实就是菲涅尔的标准算法,在1-NdotV后,乘以一个bias值控制边缘光的强度,再计算一个Pow运算,控制边缘光的边缘厚度。

2、添加横纹

1.效果分析

看到这个效果,可能很多人都在考虑怎样画这个横纹的贴图。其实这个实现方式很巧妙,只需要一张Noise噪声图就可以了。

2.shader实现

Shader "azhao/IronManBodyCode"{Properties{_RimBias("RimBias", Float) = 1_RimPow("RimlPow", Float) = 2_RimlCol("RimCol", Color) = (0,0,0,0)_NoiseMap("NoiseMap",2D) = "black"{}_NoiseTiling("NoiseTiling",Vector) = (1,1,0,0)}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;float3 normal : NORMAL;};struct v2f{float4 pos : SV_POSITION;float3 worldPos :TEXCOORD0;float3 worldNormal : TEXCOORD1;};float _RimBias;float _RimPow;float4 _RimlCol;sampler2D _NoiseMap;float4 _NoiseTiling;v2f vert (appdata v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.worldPos = mul(unity_ObjectToWorld, v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);return o;}half4 frag (v2f i) : SV_Target{float3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));float NdotV = dot(i.worldNormal, worldViewDir);float fresnelVal = pow((1 - NdotV)*_RimBias, _RimPow);float2 noiseUV = i.worldPos.xy *_NoiseTiling.xy + _NoiseTiling.zw;float4 noiseCol = tex2D(_NoiseMap, noiseUV);half4 col = _RimlCol * (fresnelVal+noiseCol.r);return col;}ENDCG}}}

3.说明

这里多添加了一张Noise贴图

由于我们想要的横纹是永远水平于世界空间,并不是希望会随着角色的动作而变形的,所以我这里并没有使用模型本身的UV坐标来采样,而是使用了模型的顶点世界坐标的xy坐标来模拟了UV坐标,并且添加了一个Tiling值来控制Noise贴图的平铺次数。

如果不调整参数的情况下,添加Noise到材质球,会看到下面的效果。

虽然这个效果看起来也很cool,但并不是我想要的效果,所以再调整一下Tiling值

把平铺y值调大,这个时候,就可以看到,Noise图就变成了横纹了。

3、横纹动画

我希望在显示这个光线轮廓的过程中,身上的横纹是有一个慢慢上升的动画效果的

这个实现起来很简单,只需要给Noise图的uv做一个偏移就可以了,这里用到了_Time,根据时间来让UV偏移。

float2 noiseUV = i.worldPos.xy_NoiseTiling.xy + _NoiseTiling.zw;

noiseUV.y += frac(_Time.y)_NoiseSpeed;

这里还加了一个frac函数,frac函数的作用是去掉数值的整数部分只保留小数部分。由于某些设备的数值精度支持范围有问题,如果_Time不停的累加,达到很大的值时,可能会出问题。所以加一个frac函数让它的值只使用小数部分。

4、完整shader

Shader "azhao/IronManBodyCode"{Properties{_RimBias("RimBias", Float) = 1_RimPow("RimlPow", Float) = 2_RimlCol("RimCol", Color) = (0,0,0,0)_NoiseMap("NoiseMap",2D) = "black"{}_NoiseTiling("NoiseTiling",Vector) = (1,1,0,0)_NoiseSpeed("NoiseSpeed",float) = 0}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;};struct v2f{float4 pos : SV_POSITION;float3 worldPos :TEXCOORD0;float3 worldNormal : TEXCOORD1;};float _RimBias;float _RimPow;float4 _RimlCol;sampler2D _NoiseMap;float4 _NoiseTiling;float _NoiseSpeed;v2f vert (appdata v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.worldPos = mul(unity_ObjectToWorld, v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);return o;}half4 frag (v2f i) : SV_Target{float3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));float NdotV = dot(i.worldNormal, worldViewDir);float fresnelVal = pow((1 - NdotV)*_RimBias, _RimPow);float2 noiseUV = i.worldPos.xy *_NoiseTiling.xy + _NoiseTiling.zw;noiseUV.y += frac(_Time.y)*_NoiseSpeed;float4 noiseCol = tex2D(_NoiseMap, noiseUV);half4 col = _RimlCol * (fresnelVal+noiseCol.r);return col;}ENDCG}}}

如果觉得《钢铁侠材质制作——2 线条轮廓部分的制作》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。