//10.1.4
Shader "Unlit/Chapter10-Reflection"
{
Properties
{
//物体颜色
_Color("Color Tint",Color) = (1,1,1,1)
//折射颜色
_RefractColor("Refract Color",Color) = (1,1,1,1)
//折射程度
_ReflractAmount("Refract Amount",Range(0,1)) = 1
//模拟折射的环境映射纹理
_Cubemap("Refraction Cubemap",Cube) = "_Skybox"{}
//折射比
_RefractRatio("Refraction Ratio",Range(0.1,1))=0.5
}
SubShader
{
//渲染类型=不透明 队列=几何
Tags{ "RenderType" = "Opaque" "Queue" = "Geometry" }
Pass
{
//光照模式=向前渲染
Tags{ "LightMode" = "ForwardBase" }
CGPROGRAM
//定义顶点片元
#pragma vertex vert
#pragma fragment frag
//确保光照衰减等光照变量可以被正确赋值
#pragma multi_compile_fwdbase
//包含引用的内置文件
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
//声明属性变量
fixed4 _Color;
fixed4 _RefractColor;
float _ReflractAmount;
//cube 属性用 samplerCUBE 来声明
samplerCUBE _Cubemap;
float _RefractRatio;
//定义输入结构体
struct a2v
{
float4 vertex : POSITION;
float3 normal:NORMAL;
};
//定义输出结构体
struct v2f
{
float4 pos:SV_POSITION;
fixed3 worldNormal : TEXCOORD0;
float3 worldPos:TEXCOORD1;
fixed3 worldViewDir : TEXCOORD2;
fixed3 worldRefr : TEXCOORD3;
//添加内置宏,声明一个用于阴影纹理采集的坐标,参数是下一个可用的插值寄存器的索引值
SHADOW_COORDS(4)
};
//顶点着色器
v2f vert(a2v v) {
v2f o;
//转换顶点坐标到裁剪空间
o.pos = UnityObjectToClipPos(v.vertex);
//转换法线到世界空间
o.worldNormal = UnityObjectToWorldNormal(v.normal);
//转换顶点坐标到世界空间
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
//获取世界空间下的视角方向
o.worldViewDir = UnityWorldSpaceViewDir(o.worldPos);
//compute the reflect dir in world space(计算世界空间中的反射方向)
//用CG的reflect函数来计算该处顶点的反射方向 reflect(物体反射到摄像机的光线方向,法线方向)
//物体反射到摄像机的的光线方向,可以由光路可逆的原则反向求得,
//o.worldRefl = reflect(-o.worldViewDir, o.worldNormal);
//计算世界空间中的折射方向
o.worldRefr = refract(-normalize(o.worldViewDir), normalize(o.worldNormal),_RefractRatio);
//内置宏,计算上一步中声明的阴影纹理坐标
TRANSFER_SHADOW(o);
return o;
}
//片元着色器
fixed4 frag(v2f i) :SV_Target{
//获取归一化的法线
fixed3 worldNormal = normalize(i.worldNormal);
//获取归一化的光线方向
//fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
//获取归一化的视角方向
//fixed3 worldViewDir = normalize(i.worldViewDir);
fixed3 worldViewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
//获取环境光
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
//漫反射计算 =光照颜色*物体颜色*大于零的 法线和光照方向的点积
fixed3 diffuse = _LightColor0.rgb*_Color.rgb*max(0, dot(worldNormal, worldLightDir));
//在世界空间中使用折射方向访问立方体图
fixed3 refraction = texCUBE(_Cubemap, i.worldRefr).rgb*_RefractColor.rgb;
//光照衰减程度
UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
//Mix the diffuse color whith the reflected color(混合漫反射的颜色和反射的颜色)
//环境光+插值(漫反射,反射,折射程度)*光照衰减程度
//fixed3 color = ambient + lerp(diffuse, reflection, _ReflectAmount)*atten;
//return fixed4(color, 1.0);
return fixed4(ambient + lerp(diffuse, refraction, _ReflractAmount)*atten, 1.0);
}
ENDCG
}
}
FallBack "Reflective/VertexLit"
}