代码来源于 shader 入门精要
其实关键的代码就三句
1.根据视角方向和法线求出反射反向
o.worldRef1 = reflect(-o.worldViewDir,o.worldNormal);
2.对 _Cubemap 进行采样
fixed3 reflection = texCUBE(_Cubemap,i.worldRef1).rgb * _ReflectColor;
3. 当_ReflectAmount从 0 到 1 变化就相当去 diffuse 到 reflection的变化,lerp操作
fixed3 color = ambient + lerp(diffuse,reflection,_ReflectAmount)*atten;
Shader "Chapter10/ReflectionShader"
{
Properties
{
_Color("Main Color",Color) = (1,1,1,1)
_ReflectColor("Reflect Color",Color) = (1,1,1,1)
_ReflectAmount("Reflect Amount",Range(0,1)) = 1
_Cubemap("Cube Map",Cube) = "_Skybox"{}
}
SubShader
{
Tags { "RenderType"="Opaque" "Queue"="Geometry"}
Pass
{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
#include "AutoLight.cginc"
struct a2v{
float4 vertex: POSITION;
float3 normal: NORMAL;
};
struct v2f{
float4 pos: SV_POSITION;
fixed3 worldNormal:TEXCOORD;
fixed3 worldPos:TEXCOORD1;
fixed3 worldViewDir: TEXCOORD2;
fixed3 worldRef1:TEXCOORD3;
SHADOW_COORDS(4)
};
fixed4 _Color;
samplerCUBE _Cubemap;
fixed4 _ReflectColor;
fixed _ReflectAmount;
v2f vert (a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
o.worldViewDir = UnityWorldSpaceViewDir(o.worldPos);
o.worldRef1 = reflect(-o.worldViewDir,o.worldNormal);
TRANSFER_SHADOW(o);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed3 worldNormal = normalize(i.worldNormal);
fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
fixed3 worldViewDir = normalize(i.worldViewDir);
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 diffuse = _LightColor0.rgb *_Color.rgb* max(0,dot(worldNormal,worldLightDir));
fixed3 reflection = texCUBE(_Cubemap,i.worldRef1).rgb * _ReflectColor;
UNITY_LIGHT_ATTENUATION(atten,i,i.worldPos);
fixed3 color = ambient + lerp(diffuse,reflection,_ReflectAmount)*atten;
return fixed4(color,1.0);
}
ENDCG
}
}
Fallback "Reflective/VertexLit"
}