(1)效果图如下:
(2)效果分析:
1.边缘 :”高亮“ "通透"效果 。
2.非边缘的"厚重"效果
3.光滑的反射"环境"信息
看到有的博客里 是使用 “深度差” 来控制效果分析中 1和2 的实现
思路链接
思路如图:
(3)本文的思路和上图不同:
hua 不多说,直接上源码 代码有注释
Shader "Unlit/Dragon_01"
{
Properties
{
_DiffuseColor("Diffuse Color",Color) = (0,0.352,0.219,1)
_BasePassDistortion("Bass Pass Distortion", Range(0,1)) = 0.2
_CubeMap("Env Map", Cube) = "white" {}
_EnvRotate("Env Rotate",Range(0,360)) = 0
_BasePassPower("_BasePassPower",Range(0,50)) = 5
_BasePassScale("_BasePassScale",Range(0,50)) = 1
_ThicknessMap("Thickness Map",2D) = "black"{}
}
SubShader
{
Tags { "LightMode" = "ForwardBase" }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include "UnityCG.cginc"
#include "AutoLight.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
float4 pos_World : TEXCOORD1;
float3 normal_world : TEXCOORD2;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _LightColor0;
float _BasePassDistortion;
float4 _DiffuseColor;
samplerCUBE _CubeMap;
float4 _CubeMap_HDR;
sampler2D _ThicknessMap;
float _EnvRotate;
float _BasePassPower;
float _BasePassScale;
v2f vert (appdata v)
{
v2f o;
o.normal_world = UnityObjectToWorldNormal(v.normal);
o.pos_World = mul(unity_ObjectToWorld, v.vertex);
o.uv = v.texcoord;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
float3 normal_dir = normalize(i.normal_world);
float3 view_dir = normalize(_WorldSpaceCameraPos - i.pos_World.xyz);
float3 light_dir = normalize(_WorldSpaceLightPos0.xyz);
/// diffuse
float diff_term = max(0.0, dot(normal_dir, light_dir));
float3 diffuseColor = _DiffuseColor * diff_term * _LightColor0.rgb;
///// 此处模拟 skybox的天光效果: 在Y轴上的强度 影响漫反射的强度
// float sky_sphere = (dot(normalDir,float3(0,1,0)) + 1.0) * 0.5;
// float3 sky_light = sky_sphere * diffuse_color;
// float3 final_diffuse = diffuselight_color + sky_light * _Opacity + _AddColor.xyz;
///// 透射光
// 加了参数扰乱一下
float3 back_dir = normalize(light_dir + normal_dir * _BasePassDistortion);
// view 和 light 的夹角
float VdotB = max(0,dot(view_dir,back_dir));
// 控制一下强度: pow函数使效果更加显著!!!!!
float backlight_term = max(0.0,pow(VdotB, _BasePassPower)) * _BasePassScale;
// 对厚度图采样
float thickness = 1.0 - tex2D(_ThicknessMap, i.uv).r;
// 透视光的效果
float3 backlight = backlight_term * thickness * _LightColor0.xyz;
///// 环境光的反射
float3 reflect_dir = reflect(-view_dir,normal_dir);
//控制反射方向(绕Y轴旋转),将角度 转化为弧度
float theta = _EnvRotate * UNITY_PI / 180.0f;
float2x2 m_rot = float2x2(cos(theta), -sin(theta), sin(theta),cos(theta));
float2 v_rot = mul(m_rot, reflect_dir.xz);
reflect_dir = half3(v_rot.x, reflect_dir.y, v_rot.y);
// 采样环境反射
float4 hdrColor = texCUBE(_CubeMap,reflect_dir);
//菲涅尔
float fresnel = 1 - max(0,dot(normal_dir,view_dir));
//解码HDR 确保在移动端也能显示正常
half3 env_color = DecodeHDR(hdrColor, _CubeMap_HDR);
float3 final_env = env_color * fresnel;
float3 final_color =diffuseColor + backlight + final_env;
return float4(final_color,1);
}
ENDCG
}
}
}