您好,登录后才能下订单哦!
在Unity3D中,渲染路径(Rendering Paths)和光照模式(LightMode)是决定场景如何渲染和光照如何计算的关键因素。理解这些概念对于优化渲染性能、实现特定视觉效果至关重要。本文将深入探讨Unity3D中的Rendering Paths和LightMode,并通过示例分析它们在实际项目中的应用。
Rendering Paths决定了Unity如何计算和渲染光照。Unity支持多种渲染路径,每种路径都有其特定的优势和适用场景。
Forward Rendering(前向渲染)是Unity中最常用的渲染路径之一。它逐像素计算光照,适用于大多数场景,尤其是移动设备和低端硬件。
特点: - 逐像素光照计算 - 支持多种光源类型 - 适用于移动设备和低端硬件
适用场景: - 移动游戏 - 低端硬件 - 需要实时动态光照的场景
Deferred Rendering(延迟渲染)是一种更复杂的渲染路径,适用于需要处理大量光源的场景。它将光照计算延迟到几何渲染之后,通过G-Buffer存储几何信息。
特点: - 延迟光照计算 - 支持大量光源 - 需要较高的硬件性能
适用场景: - 高端PC游戏 - 需要大量动态光源的场景 - 复杂的光照效果
Legacy Deferred Lighting(传统延迟光照)是Unity早期版本的延迟渲染路径,现已不推荐使用。它使用不同的G-Buffer格式和光照计算方式。
特点: - 旧版延迟渲染 - 不推荐使用 - 兼容性较差
适用场景: - 旧版Unity项目 - 需要兼容旧版硬件的场景
Legacy Vertex Lit(传统顶点光照)是Unity早期版本的顶点光照渲染路径,现已不推荐使用。它逐顶点计算光照,适用于低端硬件。
特点: - 逐顶点光照计算 - 不推荐使用 - 兼容性较差
适用场景: - 旧版Unity项目 - 需要兼容旧版硬件的场景
LightMode是Shader中的一个标签,用于指定Shader在特定渲染路径下的行为。不同的LightMode决定了Shader如何处理光照和阴影。
Always
模式表示Shader在所有渲染路径下都会执行,不受光照影响。
适用场景: - 不需要光照的Shader - 全屏特效 - UI元素
ForwardBase
模式用于Forward Rendering中的基础通道,处理环境光和主方向光。
适用场景: - Forward Rendering中的基础光照 - 环境光和主方向光
ForwardAdd
模式用于Forward Rendering中的附加通道,处理额外的逐像素光源。
适用场景: - Forward Rendering中的附加光源 - 逐像素光源
Deferred
模式用于Deferred Rendering中的几何通道,将几何信息写入G-Buffer。
适用场景: - Deferred Rendering中的几何通道 - G-Buffer写入
ShadowCaster
模式用于生成阴影贴图,计算物体的阴影。
适用场景: - 阴影生成 - 阴影贴图计算
PrepassBase
模式用于Legacy Deferred Lighting中的基础通道,处理环境光和主方向光。
适用场景: - Legacy Deferred Lighting中的基础光照 - 环境光和主方向光
PrepassFinal
模式用于Legacy Deferred Lighting中的最终通道,计算最终光照。
适用场景: - Legacy Deferred Lighting中的最终光照 - 最终光照计算
Vertex
模式用于Legacy Vertex Lit中的顶点光照计算。
适用场景: - Legacy Vertex Lit中的顶点光照 - 顶点光照计算
VertexLMRGBM
模式用于Legacy Vertex Lit中的顶点光照计算,使用RGBM编码。
适用场景: - Legacy Vertex Lit中的顶点光照 - RGBM编码
VertexLM
模式用于Legacy Vertex Lit中的顶点光照计算,使用LDR编码。
适用场景: - Legacy Vertex Lit中的顶点光照 - LDR编码
Rendering Paths和LightMode密切相关,不同的渲染路径决定了Shader中LightMode的行为。例如,在Forward Rendering中,ForwardBase
和ForwardAdd
模式分别处理基础光照和附加光源;而在Deferred Rendering中,Deferred
模式负责将几何信息写入G-Buffer。
在Forward Rendering中,ForwardBase
模式处理环境光和主方向光,ForwardAdd
模式处理附加光源。以下是一个简单的Forward Rendering Shader示例:
Shader "Custom/ForwardRenderingExample" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
_Color ("Color", Color) = (1,1,1,1)
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
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;
};
struct v2f {
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
float3 worldNormal : TEXCOORD1;
};
sampler2D _MainTex;
float4 _Color;
v2f vert (appdata v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.worldNormal = UnityObjectToWorldNormal(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target {
fixed4 texcol = tex2D(_MainTex, i.uv);
float3 worldNormal = normalize(i.worldNormal);
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
float NdotL = max(0, dot(worldNormal, lightDir));
fixed4 finalColor = texcol * _Color * NdotL;
return finalColor;
}
ENDCG
}
Pass {
Tags { "LightMode"="ForwardAdd" }
Blend One One
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f {
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
float3 worldNormal : TEXCOORD1;
};
sampler2D _MainTex;
float4 _Color;
v2f vert (appdata v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.worldNormal = UnityObjectToWorldNormal(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target {
fixed4 texcol = tex2D(_MainTex, i.uv);
float3 worldNormal = normalize(i.worldNormal);
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
float NdotL = max(0, dot(worldNormal, lightDir));
fixed4 finalColor = texcol * _Color * NdotL;
return finalColor;
}
ENDCG
}
}
FallBack "Diffuse"
}
在Deferred Rendering中,Deferred
模式负责将几何信息写入G-Buffer。以下是一个简单的Deferred Rendering Shader示例:
Shader "Custom/DeferredRenderingExample" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
_Color ("Color", Color) = (1,1,1,1)
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
Pass {
Tags { "LightMode"="Deferred" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f {
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
float3 worldNormal : TEXCOORD1;
};
sampler2D _MainTex;
float4 _Color;
v2f vert (appdata v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.worldNormal = UnityObjectToWorldNormal(v.vertex);
return o;
}
void frag (v2f i, out half4 outDiffuse : SV_Target0, out half4 outSpecular : SV_Target1, out half4 outNormal : SV_Target2, out half4 outEmission : SV_Target3) {
fixed4 texcol = tex2D(_MainTex, i.uv);
float3 worldNormal = normalize(i.worldNormal);
outDiffuse = texcol * _Color;
outSpecular = fixed4(0, 0, 0, 0);
outNormal = fixed4(worldNormal * 0.5 + 0.5, 1);
outEmission = fixed4(0, 0, 0, 0);
}
ENDCG
}
}
FallBack "Diffuse"
}
在Legacy Deferred Lighting中,PrepassBase
和PrepassFinal
模式分别处理基础光照和最终光照。以下是一个简单的Legacy Deferred Lighting Shader示例:
Shader "Custom/LegacyDeferredLightingExample" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
_Color ("Color", Color) = (1,1,1,1)
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
Pass {
Tags { "LightMode"="PrepassBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f {
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
float3 worldNormal : TEXCOORD1;
};
sampler2D _MainTex;
float4 _Color;
v2f vert (appdata v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.worldNormal = UnityObjectToWorldNormal(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target {
fixed4 texcol = tex2D(_MainTex, i.uv);
float3 worldNormal = normalize(i.worldNormal);
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
float NdotL = max(0, dot(worldNormal, lightDir));
fixed4 finalColor = texcol * _Color * NdotL;
return finalColor;
}
ENDCG
}
Pass {
Tags { "LightMode"="PrepassFinal" }
Blend One One
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f {
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
float3 worldNormal : TEXCOORD1;
};
sampler2D _MainTex;
float4 _Color;
v2f vert (appdata v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.worldNormal = UnityObjectToWorldNormal(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target {
fixed4 texcol = tex2D(_MainTex, i.uv);
float3 worldNormal = normalize(i.worldNormal);
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
float NdotL = max(0, dot(worldNormal, lightDir));
fixed4 finalColor = texcol * _Color * NdotL;
return finalColor;
}
ENDCG
}
}
FallBack "Diffuse"
}
在Legacy Vertex Lit中,Vertex
模式用于逐顶点光照计算。以下是一个简单的Legacy Vertex Lit Shader示例:
Shader "Custom/LegacyVertexLitExample" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
_Color ("Color", Color) = (1,1,1,1)
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
Pass {
Tags { "LightMode"="Vertex" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f {
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
float3 worldNormal : TEXCOORD1;
};
sampler2D _MainTex;
float4 _Color;
v2f vert (appdata v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.worldNormal = UnityObjectToWorldNormal(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target {
fixed4 texcol = tex2D(_MainTex, i.uv);
float3 worldNormal = normalize(i.worldNormal);
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
float NdotL = max(0, dot(worldNormal, lightDir));
fixed4 finalColor = texcol * _Color * NdotL;
return finalColor;
}
ENDCG
}
}
FallBack "Diffuse"
}
Unity3D中的Rendering Paths和LightMode是决定场景渲染和光照计算的关键因素。通过理解这些概念,开发者可以更好地优化渲染性能,实现特定的视觉效果。本文详细介绍了Unity3D中的各种Rendering Paths和LightMode,并通过示例展示了它们在实际项目中的应用。希望本文能为Unity开发者提供有价值的参考,帮助他们在项目中更好地应用这些技术。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。