Shader学习笔记(实战篇)

UnityShader 初级篇

实现简易的渐变Shader

过完初级篇,进入实战

  1. 设置属性
    在这里插入图片描述
  2. 设置Pass的渲染路径
    在这里插入图片描述
    3.片元着色器
    在这里插入图片描述

最终效果

在这里插入图片描述

模拟玻璃上雨滴滑落的效果

  1. 声明属性
    在这里插入图片描述
  2. 设置渲染路径
    在这里插入图片描述
  3. 定义顶点着色器
    在这里插入图片描述
  4. 定义片元着色器
    在这里插入图片描述
  5. 定义片元着色器
    在这里插入图片描述

最终效果

在这里插入图片描述

边缘发光

RinLight 边缘光
核心:

根据点积来判断模型的边缘,在模型的边缘位置着色一层颜色光。

着色光核心原理:

通过视角方向和法线方向点积,结果等于0则片元处于模型的边缘,这时,视角和法线相互垂直,与切线方向共线。反之越靠近1片元则越靠近模型中心。因此可用点积来计算边缘光的强弱

边缘光核心计算公式:

float rim=1-saturate(dot(WorldNormalDir,WorldViewDir));
float3 rimColor=_RimColor * pow(rim,1/_RimColor);

Shader 源码:

Shader “Unity/RimLight”
{
Properties
{
_MainTex (“Texture”, 2D) = “white” {}
_Diffuse(“Diffuse”,Color) =(1,1,1,1)
//边缘光颜色
_RimColor(“RimColor”,Color)=(1,1,1,1)
_RimPower(“RimPower”,Range(0,1)) =0
}
SubShader
{
Tags { “RenderType” = “Transparent” }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include “UnityCG.cginc”
#include “Lighting.cginc”
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _Diffuse;
float4 _RimColor;
float _RimPower;
struct v2f
{
float4 vertex:SV_POSITION;
float2 uv:TEXCOORD0;
float3 worldLightNormal:TEXCOORD1;
float3 worldNormal:TEXCOORD2;
float3 worldViewNormal:TEXCOORD3;
};
v2f vert(appdata_base v)
{
v2f o;
o.vertex=UnityObjectToClipPos(v.vertex);
o.uv=TRANSFORM_TEX(v.texcoord,_MainTex);
float3 worldPos=mul(unity_ObjectToWorld,v.vertex);
//获取世界法线 视角方向 光源防线
o.worldLightNormal= UnityWorldSpaceLightDir(worldPos);
o.worldViewNormal=UnityWorldSpaceViewDir(worldPos);
o.worldNormal=UnityObjectToWorldNormal(v.normal);
return o;
};
fixed4 frag(v2f i):SV_TARGET
{
//归一化法线 因为从顶点着色器到片源着色器阶段有差值处理,所以在顶点着色器归一化并不是最好的选择
float3 worldNormalDir=normalize(i.worldNormal);
float3 WorldLightDir=normalize(i.worldLightNormal);
float3 WorldViewDir=normalize(i.worldViewNormal);
float3 texColor=tex2D(_MainTex,i.uv).rgb;
float3 ambient=UNITY_LIGHTMODEL_AMBIENT.rgbtexColor.rgb;
//计算半兰伯特漫反射
float3 diffuse=_LightColor0.rgb
_Diffuse.rgbtexColor.rgb(dot(worldNormalDir,WorldLightDir)*0.5+0.5);
//计算边缘光颜色 Dot结果为0-1之间 结果越靠近0说明越靠近边缘颜色越重,故1-Dot
float rim =1-saturate(dot(worldNormalDir,WorldViewDir));
//计算RimLight
float3 rimColor=_RimColor * pow(rim,1/_RimPower);
//输出片源颜色
float3 color=diffuse+ambient+rimColor;
return fixed4(color,1);
};
ENDCG
}
}
Fallback “Diffuse”
}

最终效果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42050609/article/details/124883443
今日推荐