内容还没完善,有时间会增加反射,各向异性处理等。相互学习。
Shader “water/fresnelpbr”
{
Properties
{
_MainTex (“Texture”, 2D) = “white” {}
_fresnelBase(“fresnelBase”, Range(0, 1)) = 1
_fresnelScale(“fresnelScale”, Range(0, 1)) = 1
_fresnelIndensity(“fresnelIndensity”, Range(0, 5)) = 5
_fresnelCol("_fresnelCol", Color) = (1,1,1,1)
_frequency(“频率”,Range(0,100)) = 1
_wavelength(“波长”,Range(0,100)) = 1
_magnitude(“振幅”,Range(0,100)) = 1
//pbr
_Diffuse ("DiffuseColor" , Color) = (1,1,1,1)
_DiffuseStrength ("DiffuseStrength", float) = 1.0
_Specular ("SpecularColor", Color) = (1,1,1,1)
_SpecularStrength("SpecularStrength", float) = 1.0
_Gloss ("Gloss", float) = 1.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
tags{"LightMode" = "ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float3 worldlight : TEXCOORD1;
float3 worldnormal : TEXCOORD2;
float3 worldview : TEXCOORD3;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _fresnelBase;
float _fresnelScale;
float _fresnelIndensity;
float4 _fresnelCol;
float _frequency;
float _wavelength;
float _magnitude;
//pbr
fixed4 _Diffuse;
float _DiffuseStrength;
fixed4 _Specular;
float _SpecularStrength;
float _Gloss;
v2f vert (appdata v)
{
v2f o;
v.vertex.y = v.vertex.y + _magnitude * sin(_frequency * _Time.y + _wavelength * (v.vertex.x + v.vertex.y + v.vertex.z));
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
//将法线转到世界坐标
o.worldnormal = mul(v.normal, (float3x3)unity_WorldToObject);
//获取世界坐标的光向量
o.worldlight = WorldSpaceLightDir(v.vertex);
//获取世界坐标的视角向量
o.worldview = WorldSpaceViewDir(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
float3 worldnormal = normalize(i.worldnormal);
float3 worldlight = normalize(i.worldlight);
float3 worldview = normalize(i.worldview);
//菲尼尔公式
float fresnel = _fresnelBase + _fresnelScale*pow(1 - dot(worldnormal, worldview), _fresnelIndensity);
//pbr
fixed4 ambient = UNITY_LIGHTMODEL_AMBIENT.rgba;
fixed4 lightColor = _LightColor0.rgba;
fixed4 diffuse = 1 / UNITY_PI * _Diffuse * (dot(worldnormal ,worldlight) * 0.5 + 0.5) * _DiffuseStrength * lightColor;
fixed4 specular = (8 + _Gloss) / (8 * UNITY_PI) * _Specular * _SpecularStrength * pow(saturate(dot(normalize(worldview + worldlight),worldnormal)),_Gloss)* lightColor;
col = col * diffuse;
col.rgb += lerp(col.rgb, _fresnelCol, fresnel) * _fresnelCol.a;
col = col + ambient + specular;
return col;
}
ENDCG
}
}
}