当前位置: 首页 > news >正文

Unity Shader 入门教程:从零开始编写你的第一个 Shader

引言

光照模型是 Shader 编程的核心部分,它决定了物体表面如何与光线交互,从而影响最终的视觉效果。在 Unity 中,常见的光照模型包括 Lambert 漫反射模型Phong 高光反射模型Blinn-Phong 模型
本文将详细介绍这些光照模型的原理,并展示如何在 Unity Shader 中实现它们。


1. Lambert 光照模型

1.1 基本原理

Lambert 光照模型是最基础的漫反射模型,基于 Lambert 余弦定律,模拟光线在粗糙表面的均匀散射效果。其核心公式为:
$$
I = I_0 \cdot \cos(\theta)
$$
其中:

  • $I$ 是反射光强度。
  • $I_0$ 是入射光强度。
  • $\theta$ 是光线入射方向与表面法线方向的夹角。

1.2 Unity Shader 实现

以下是 Lambert 光照模型的实现代码:

Shader "LightModel/LambertShader"
{Properties{_MainTex("Texture", 2D) = "white" {}_Color("Color", Color) = (1,1,1,1)}SubShader{Tags { "RenderType" = "Opaque" }LOD 200Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float3 worldNormal : TEXCOORD1;float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;float4 _Color;v2f vert(appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);  // 顶点变换o.worldNormal = UnityObjectToWorldNormal(v.normal);  // 法线变换o.uv = TRANSFORM_TEX(v.uv, _MainTex);  // 纹理坐标变换return o;}fixed4 frag(v2f i) : SV_Target{float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);  // 光源方向float3 normal = normalize(i.worldNormal);  // 法线方向float diff = max(dot(normal, lightDir), 0);  // 漫反射强度fixed4 col = tex2D(_MainTex, i.uv) * _Color * diff;  // 最终颜色return col;}ENDCG}}FallBack "Diffuse"
}

Lambert模型实现效果如图:
在这里插入图片描述


2. Phong 光照模型

2.1 基本原理

Phong 光照模型在 Lambert 模型的基础上增加了 高光反射,模拟光线在光滑表面的镜面反射效果。其核心公式为:
$$
I = I_{\text{diffuse}} + I_{\text{specular}}
$$
其中:

  • $I_{\text{diffuse}}$ 是漫反射强度(Lambert 模型)。
  • $I_{\text{specular}}$ 是高光反射强度,计算公式为:
    $$
    I_{\text{specular}} = I_0 \cdot (\mathbf{R} \cdot \mathbf{V})^n
    $$
  • $\mathbf{R}$ 是反射方向。
  • $\mathbf{V}$ 是视线方向。
  • $n$ 是高光指数,控制高光的集中程度。

2.2 Unity Shader 实现

以下是 Phong 光照模型的实现代码:

Shader "LightModel/PhongShader"
{Properties{_MainTex ("Texture", 2D) = "white" {}_Color("Color", Color) = (1,1,1,1)_SpecularColor("Specular Color", Color) = (1,1,1,1)  // 高光颜色_Gloss("Gloss", Range(1, 256)) = 32   // 高光指数(控制高光集中程度}SubShader{Tags { "RenderType"="Opaque" }LOD 200Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float3 worldNormal : TEXCOORD1;float3 worldPos : TEXCOORD2;    // 世界空间顶点位置float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;float4 _Color;float4 _SpecularColor;float _Gloss;v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);  // 法线变换o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;  // 顶点变换到世界空间o.uv = TRANSFORM_TEX(v.uv, _MainTex);return o;}fixed4 frag (v2f i) : SV_Target{float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);  // 光源方向float3 normal = normalize(i.worldNormal);              // 法线方向float3 viewDir = normalize(_WorldSpaceCameraPos - i.worldPos);  // 视线方向float3 reflectDir = reflect(-lightDir, normal);        // 反射方向float diff = max(dot(normal, lightDir), 0);            // 漫反射强度float spec = pow(max(dot(reflectDir, viewDir), 0), _Gloss);  // 高光强度fixed4 texColor = tex2D(_MainTex, i.uv); // 纹理颜色fixed4 col = texColor * _Color * diff + spec;  // 最终颜色return col;}ENDCG}}
}

Phong模型实现效果如图:
在这里插入图片描述


3. Blinn-Phong 光照模型

3.1 基本原理

Blinn-Phong 模型是 Phong 模型的改进版,通过引入 半角向量 简化了高光反射的计算。其核心公式为:
$$
I = I_{\text{diffuse}} + I_{\text{specular}}
$$
其中:

  • $I_{\text{specular}}$ 的计算公式为:
    $$
    I_{\text{specular}} = I_0 \cdot (\mathbf{N} \cdot \mathbf{H})^n
    $$
  • $\mathbf{H}$ 是半角向量,计算公式为:
    $$
    \mathbf{H} = \frac{\mathbf{L} + \mathbf{V}}{|\mathbf{L} + \mathbf{V}|}
    $$

# 3.2 Unity Shader 实现

以下是 Blinn-Phong 光照模型的实现代码:

Shader "LightModel/BlinnPhongShader"
{Properties{_MainTex("Texture", 2D) = "white" {}_Color("Color", Color) = (1,1,1,1)_SpecularColor("Specular Color", Color) = (1,1,1,1)  // 高光颜色_Gloss("Gloss", Range(1, 256)) = 32   // 高光指数(控制高光集中程度}SubShader{Tags { "RenderType" = "Opaque" }LOD 200Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float3 worldNormal : TEXCOORD1;float3 worldPos : TEXCOORD2;    // 世界空间顶点位置float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;float4 _Color;float4 _SpecularColor;float _Gloss;v2f vert(appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);  // 法线变换o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;  // 顶点变换到世界空间o.uv = TRANSFORM_TEX(v.uv, _MainTex);return o;}fixed4 frag(v2f i) : SV_Target{float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);  // 光源方向float3 normal = normalize(i.worldNormal);              // 法线方向float3 viewDir = normalize(_WorldSpaceCameraPos - i.worldPos);  // 视线方向float3 halfDir = normalize(lightDir + viewDir);        // 半角向量float diff = max(dot(normal, lightDir), 0);            // 漫反射强度float spec = pow(max(dot(normal, halfDir), 0), _Gloss);  // 高光强度fixed4 texColor = tex2D(_MainTex, i.uv); // 纹理颜色fixed4 col = texColor * _Color * diff + spec;  // 最终颜色return col;}ENDCG}}
}

Blinn-Phong模型实现效果如图:
在这里插入图片描述


4. 光照模型的对比与选择

4.1 对比

  • Lambert 模型:简单高效,适合粗糙表面,但缺乏高光反射。
  • Phong 模型:增加了高光反射,适合光滑表面,但计算量较大。
  • Blinn-Phong 模型:高光计算更高效,适合大多数场景。

4.2 选择建议

  • 如果需要快速实现基础光照效果,选择 Lambert 模型
  • 如果需要表现光滑表面的高光效果,选择 Phong 模型Blinn-Phong 模型
  • 在性能要求较高的场景中,优先选择 Blinn-Phong 模型

http://www.jsqmd.com/news/34140/

相关文章:

  • 中电金信​​:「AI智变」这个AI自动化工厂,助力模型高质效落地
  • 实用指南:Linux内核架构浅谈2- Linux内核与硬件交互的底层逻辑:硬件抽象层的作用
  • 2025年有机纯驼奶粉加工厂权威推荐榜单:初乳配方驼乳粉/全脂羊奶粉/绵羊奶粉源头厂家精选
  • 2025年网络安全法要求下,主流项目管理工具如何选
  • 转录组基因表达差异分析全流程:以GSE65682为例
  • 英伟达DCGM说明和安装
  • 阿卡德付费文章:让每个普通人的知识,都能变成真金白银
  • Mysql杂志(三十)——索引失效情况 - 指南
  • 84用python命令查看安装了那些库
  • 84用python命令查看安装了那些库
  • 使用NIFI 同步数据库表
  • 2025年尖顶篷房生产厂家权威推荐榜单:球形篷房/多边形篷房/会展篷房源头厂家精选
  • 手把手教你在unity中实现一个视觉小说系统(一)
  • 2025 年 1688 店铺代运营品牌最新推荐排行榜,专业机构实力测评及高性价比选择指南
  • 开发快、团队小、竞争狠:小游戏项目管理的破局之道,如何在高并发项目中兼顾速度与质量?
  • 2025 东莞外贸独立站公司最新推荐榜:全链路服务商测评解析与优质品牌优选指南东莞/广州/深圳/佛山/中山/惠州外贸独立站运营公司推荐
  • 2025年深圳刑事辩护律师权威推荐榜单:医疗纠纷案/婚姻家庭案/知识产权案法律服务专家精选
  • BMS(电池管理便捷的系统)的主要作用和架构简述
  • 某场模拟赛
  • 2025-11-07
  • 2025年真空润滑脂厂家权威推荐榜单:无尘室润滑脂/位移平台润滑脂/电子显微镜润滑脂源头厂家精选
  • 微信银行组件接口
  • 2025低烟无卤/UL3302/UL3767/UL4413辐照线厂家推荐明秀电子,品质可靠认证齐全
  • 2025年无火焰泄压阀厂家权威推荐榜单:无火焰泄爆装置/重复式无火焰泄爆装置/重复式无火焰泄爆阀源头厂家精选
  • 2025内窥镜电缆线/B超线厂家推荐明秀电子,专业制造品质可靠
  • CF1834E
  • 2025 年 11 月聚氨酯冷库板厂家推荐排行榜,聚氨酯冷库板,冷库保温板,阻燃冷库板,装配式冷库板公司推荐,高效保温与耐用品质口碑之选
  • 2025 年 11 月机制板厂家推荐排行榜,机制板,机制板厂家,机制板销售厂家,机制板公司推荐,专业品质与高效供应口碑之选
  • 2025年11月杜甫研究学者专家推荐榜:程韬光教授跨界传播实绩排行
  • 2025 年 11 月冷库集成工厂推荐排行榜,速冻冷库,冷藏冷库,保鲜冷库,工业冷库集成厂家精选推荐