Unity 渲染路径:
Forward (前向渲染)
Deferred (延迟渲染)
Legacy Vertex Lit
Legacy Deferred
Unity 前向渲染:逐顶点,逐像素处理,球谐函数。
逐像素光源:
1,当光源设置为Import时,是逐像素光源。(不受限制于质量设置里面pixel light count )(Forward Add)
2,光源为auto时,个数在pixel light count 以内的光源都是逐像素光源。(Forward Add)
3,光源为auto时,个数超过pixel light count ,那么按光源对物体影响重要程度排序后,前pixel light count个数的光源为逐像素光源。(Forward Add)
4,最重要的平行光为逐像素光源。(Forward Base)
逐顶点光源:(unity默认要求逐顶点光源不超过4个,超过的按SH光源处理)
1,当光源设置为NotImport时,是逐顶点光源。(Forward Base)
2,超过pixel light count 的光源为逐顶点光源。(Forward Base)
Pass
1,除了设置Pass标签外,还使用了#pragma multi_compile_fwdbase这样的编译指令。只有使用了这样的指令,才可以在相关的pass中得到一些正确的光照变量,例如光照衰减值等。
2,Base Pass中支持一些光照特性,如lightmap。
3,Base Pass中渲染的平行光默认是支持阴影的,而Additional Pass中渲染的光源默认情况下是没有阴影的。可以在additional pass中使用#pragma multi_compile_fwdadd_fullshadows代替#pragma multi_compile_fwdadd来打开阴影。
4,环境光和自发光是在Base Pass中计算的。
5,Additional Pass中开启了混合模式,如果不开启就会替换之前的渲染。通常使用Blend One One。
6,前向渲染一般会定义一个Base Pass(除双面渲染等)以及一个Additional Pass。一个Base Pass仅会执行一次,而一个Additional Pass会根据影响该物体的其他逐像素光源数目被多次调用,即每个逐像素光源会执行一次Additional Pass.
前向渲染补充:
1,ForwardAdd这个Pass需要和ForwardBase一起使用,否则会被Unity忽略掉(unity5.x),在新版本中,不会忽略,但是渲染会出错。
2,在Forward和Deferred渲染路径下,Forward的Pass均能被正常渲染。
3,ForwardAdd对每一个逐像素光源都会执行一次Pass,所以不要在ForwardAdd里面计算 unity_4LightPos[x,y,z]0中的数据。会重复计算。
前向渲染shader代码:
Shader "MyShader/001"
{
Properties
{
_Diffuse("diffuse",Color) = (1,1,1,1)
_Specular("specular",Color) = (1,1,1,1)
_Gloss("gloss",Range(1,256)) = 20
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 100
Pass
{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma multi_compile_fwdbase
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _Diffuse;
fixed4 _Specular;
float _Gloss;
struct appdata
{
float4 vertex : POSITION;
float3 normal:NORMAL;
};
struct v2f
{
float4 vertex : SV_POSITION;
float3 worldNormal:TEXCOORD0;
float3 worldPos:TEXCOORD1;
float3 vertexLight : TEXCOORD2;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
#ifdef LIGHTMAP_OFF
float3 shLight = ShadeSH9(float4(v.normal, 1.0));
o.vertexLight = shLight;
#ifdef VERTEXLIGHT_ON
float3 vertexLight = 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, o.worldPos, o.worldNormal
);
o.vertexLight += vertexLight;
#endif
#endif
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
float3 worldNormal = normalize(i.worldNormal);
float3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos);
fixed3 diffuse = _LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal, worldLightDir));
fixed3 halfDir = normalize(viewDir + worldLightDir);
fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(saturate(dot(worldNormal, halfDir)), _Gloss);
return fixed4(ambient + (diffuse + specular)+i.vertexLight, 1);
}
ENDCG
}
Pass
{
Tags{"LightMode"="ForwardAdd"}
Blend One One
CGPROGRAM
#pragma multi_compile_fwdadd
#pragma vertex vert
#pragma fragment frag
#include"UnityCG.cginc"
#include"Lighting.cginc"
#include"AutoLight.cginc"
float4 _Diffuse;
float4 _Specular;
float _Gloss;
struct a2v
{
float4 vertex:POSITION;
float3 normal:NORMAL;
};
struct v2f
{
float4 vertex:SV_POSITION;
float3 worldPos:TEXCOORD0;
float3 worldNormal:TEXCOORD1;
LIGHTING_COORDS(2, 3)
};
v2f vert(a2v v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
TRANSFER_VERTEX_TO_FRAGMENT(o);
return o;
}
fixed4 frag(v2f i):SV_Target
{
float3 worldNormal = normalize(i.worldNormal);
float3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.vertex));
fixed3 diffuse = _LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal, worldLightDir));
float3 viewDir = normalize(UnityWorldSpaceViewDir(i.vertex));
float3 halfDir = normalize(viewDir + worldLightDir);
fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(saturate(dot(worldNormal, halfDir)), _Gloss);
fixed atten = LIGHT_ATTENUATION(i);
return fixed4((diffuse + specular)*atten, 1);
}
ENDCG
}
}
}
Unity小林
发布了24 篇原创文章 · 获赞 0 · 访问量 422
私信
关注