短视频系统,实现界面阴影效果
为了便于实现,方便理解实现逻辑,本案例在Lambert光照模型(逐像素光照渲染)基础上进行改进。
原代码
Shader "Chapter6/LambertFrag"
{
Properties
{
_MainCol ("Main Color", Color) = (1,1,1,1)
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "UnityLightingCommon.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float3 normal : TEXCOORD0;//这里不能是NORMAL,会跟appdata_base冲突
float4 vertex : TEXCOORD1;
};
fixed4 _MainCol;
v2f vert (appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.normal = v.normal;
o.vertex = v.vertex;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
//法线向量
float3 n = UnityObjectToWorldNormal(i.normal);
//n = normalize(n);
//灯光方向向量
fixed3 l = normalize(_WorldSpaceLightPos0.xyz);
//计算漫反射
fixed ndotl = dot(n,l);
fixed4 color = _LightColor0 * _MainCol *saturate(ndotl);
return color;
}
ENDCG
}
}
}
附上代码:
Shader "Chapter6/LambertFrag"
{
Properties
{
_MainColor ("Main Color", Color) = (1,1,1,1)
}
SubShader
{
Pass
{
Tags { "LightMode"="ForwardBase" }//第一步:添加标签,计算主要灯光模式
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//第二步:调用多重编译指令,为当前pass中渲染的每个灯光编译出不同变体
#pragma multi_compile_fwdbase
#include "UnityCG.cginc"
//第三步:引入相关文件,便于使用内置变量和预定义函数
#include "Lighting.cginc"
#include "AutoLight.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float3 normal : TEXCOORD0;//这里不能是NORMAL,会跟appdata_base冲突
float4 vertex: TEXCOORD1;
SHADOW_COORDS(2)//第四步:使用预定义宏保存阴影贴图坐标,2表示texcoord后的序号,前面两套已经被使用了
};
fixed4 _MainColor;
v2f vert (appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.normal = v.normal;
o.vertex = v.vertex;
//第五步:TRANSFER_SHADOW
//1:如果当前平台可以使用屏幕空间的阴影映射技术(SCREENSPACE_SHADOWS),则会调用内置的ComputeScreenPos函数计算屏幕空间的uv坐标,存储在_ShadowCoord,后续直接用屏幕uv坐标采样屏幕阴影贴图;
//2:如果不支持则会使用传统的阴影映射技术,TRANSFER_SHADOW会把顶点坐标从模型空间转换到光源空间后存储到_ShadowCoord中,后续根据坐标信息对ShadowMap采样。
TRANSFER_SHADOW(o)
//我的理解是,如果使用屏幕空间的阴影映射技术,会计算物体在光照下阴影对应的屏幕空间的uv坐标
return o;
}
fixed4 frag (v2f i) : SV_Target
{
//法线向量
float3 n = UnityObjectToWorldNormal(i.normal);
//n = normalize(n);
//灯光方向向量
//fixed3 l = normalize(_WorldSpaceLightPos0.xyz);//意思是第一个平行光的方向
float3 l = WorldSpaceLightDir(i.vertex);//第六步:会根据不同类型的灯光计算灯光方向,没有归一化
l = normalize(l);
float4 worldPos = mul(unity_ObjectToWorld,i.vertex);//第七步:获取世界空间顶点坐标
//计算漫反射Lambert光照
fixed ndotl = dot(n,l);
fixed4 color = _LightColor0 * _MainColor *saturate(ndotl);
//第八步:加上4个点光源的光照
//Shade4PointLights: 从4个点光源计算漫反射照明,并以特殊方式打包数据。
//unity_4LightPosX0,unity_4LightPosY0,unity_4LightPosZ0,4个坐标的向量数据
color.rgb += Shade4PointLights(
unity_4LightPosX0,unity_4LightPosY0,unity_4LightPosZ0,
unity_LightColor[0].rgb,unity_LightColor[1].rgb,
unity_LightColor[2].rgb,unity_LightColor[3].rgb,
unity_4LightAtten0,worldPos.rgb,n) * _MainColor;
//第九步:加上环境光照
color += unity_AmbientSky;
//第十步:使用宏定义计算阴影系数
//用于计算光照衰减系数。参数一为返回值(光照衰减系数),参数二用于阴影计算,参数三是世界坐标
UNITY_LIGHT_ATTENUATION(shadowmask,i,worldPos.rgb)
//第十一步:阴影合成
color.rgb *= shadowmask;
return color;
}
ENDCG
}
}
FallBack "Diffuse"//第十二步:这里的Fallback并不是备胎,而是必要的保存投影的方式 https://blog.csdn.net/shenmifangke/article/details/50466798
}
以上就是短视频系统,实现界面阴影效果, 更多内容欢迎关注之后的文章