Unity3d Shader篇(五)— Phong片元高光反射着色器

文章目录

  • 前言
  • 一、Phong片元高光反射着色器是什么?
    • 1. Phong片元高光反射着色器的工作原理
    • 2. Phong片元高光反射着色器的优缺点
      • 优点
      • 缺点
  • 二、使用步骤
    • 1. Shader 属性定义
    • 2. SubShader 设置
    • 3. 渲染 Pass
    • 4. 定义结构体和顶点着色器函数
    • 5. 片元着色器函数
  • 三、效果
  • 四、总结
    • Phong 片元高光反射着色器的优劣势
    • 使用场景
    • Phong 顶点高光反射着色器的优劣势
    • 使用场景


前言

在 Unity 中,Shader 可以用来实现各种视觉效果。本教程将详细介绍如何编写一个基于 Phong片元高光反射着色器,使物体的颜色根据光照和法线方向的变化而变化。


一、Phong片元高光反射着色器是什么?

1. Phong片元高光反射着色器的工作原理

Phong 片元高光反射着色器是一种基于 Phong 光照模型的着色器,它可以模拟物体表面的漫反射、环境光和高光效果。Phong 光照模型是一种经验性的局部光照模型,它描述了物体表面反射光的方式,是一种常用的光照模拟方法。

Phong 片元高光反射着色器的主要特点是,它在片元着色器中计算光照颜色,而不是在顶点着色器中。这样做的好处是,可以提高光照效果的精细度和真实度,尤其是在物体表面有弯曲或者高光区域时,可以避免出现锯齿或者平面化的现象。但是,这样做的缺点是,会增加片元着色器的计算量,降低性能和效率。

2. Phong片元高光反射着色器的优缺点

优点

它可以模拟出比较真实的光照效果,使物体表面有明暗、光滑、粗糙等不同的感觉。
它可以适用于各种类型的物体表面和光源,具有很强的通用性和灵活性。
它可以在片元着色器中进行计算,使得每个片元的光照效果更加精细和准确。

缺点

它的计算量较大,需要对每个片元进行多次的向量运算和幂运算,消耗较多的性能资源。
它是一个经验模型,并不完全符合真实世界中的光照现象,有一些物理上的不准确和不一致。
它的高光反射的形状不够自然,往往是一个圆形或椭圆形,不能模拟出复杂的高光形状,比如星形、心形等。

二、使用步骤

1. Shader 属性定义

// 定义属性
Properties
{_Diffuse("Diffuse",Color)=(1,1,1,1) // 漫反射颜色属性,默认白色_Specular("Specular",Color)=(1,1,1,1) // 高光颜色性,默认白色_Gloss("Gloss",Range(1,256))=5// 高光反射系数
}

这段代码定义了Shader的属性,其中:
_Diffuse: 表示漫反射颜色属性,使用RGBA格式表示颜色,默认为白色 (1, 1, 1, 1)。
_Specular: 表示高光颜色属性,同样使用RGBA格式表示颜色,默认为白色 (1, 1, 1, 1)。
_Gloss: 表示高光反射系数属性,使用Range声明范围为1到256,默认值为5。

2. SubShader 设置

SubShader
{Tags{"RenderType" = "Opaque" // 渲染类型为不透明}LOD 100 // 细节级别
}

SubShader 定义了一组渲染设置,包括标签和细节级别。在这里,我们将渲染类型标签设置为 “Opaque”,表示物体是不透明的。

3. 渲染 Pass

Pass
{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#include "Lighting.cginc"
}

这里开始了渲染 Pass 部分。在这里,我们使用了 CGPROGRAM 指令来声明顶点着色器和片元着色器函数。#pragma vertex vert 和 #pragma fragment frag 分别指定了顶点着色器函数和片元着色器函数的名称。

然后,我们包含了 UnityCG.cginc 和 Lighting.cginc,它们提供了许多有用的函数和宏,用于简化编写 Shader。

4. 定义结构体和顶点着色器函数

// 定义结构体:从顶点到片元的数据传递
struct v2f
{float4 vertex:SV_POSITION; // 顶点位置fixed3 worldNormal:TEXCOORD0; // 颜色fixed3 worldPos:TEXCOORD1;
};// 顶点着色器函数
v2f vert(appdata_base v)
{v2f o;o.vertex = UnityObjectToClipPos(v.vertex); // 顶点位置变换到裁剪空间fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); // 世界空间法线o.worldNormal = worldNormal;//unity_ObjectToWorld 是一个变换矩阵,用于将顶点从对象空间变换到世界空间。//v.vertex 是顶点的位置信息。//mul() 函数表示矩阵相乘操作,这里将对象空间中的顶点位置矩阵与对象到世界的变换矩阵相乘,得到世界空间中的顶点位置。o.worldPos=mul(unity_ObjectToWorld,v.vertex);return o;
}

顶点着色器的输入是一个结构体 appdata_base ,它包含了顶点的位置和法线信息。顶点着色器的输出是一个结构体 v2f ,它包含了顶点的裁剪空间位置和世界空间法线和位置信息。

顶点着色器的主要逻辑是:

  1. 使用 UnityObjectToClipPos 函数,将顶点的位置从对象空间变换到裁剪空间,这是渲染管线的必要步骤。

  2. 使用 UnityObjectToWorldNormal 函数,将顶点的法线从对象空间变换到世界空间,这是为了计算光照效果所需的方向向量。

  3. 使用 unity_ObjectToWorld 矩阵,将顶点的位置从对象空间变换到世界空间,这是为了计算光照效果所需的坐标系。

5. 片元着色器函数

// 片元着色器函数
fixed4 frag(v2f i) : SV_Target
{//获取环境光fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;//漫反射//获取光源位置//fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);//获取光源位置简化函数fixed3 worldLightDir = UnityWorldSpaceLightDir(i.worldPos);fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0, dot(worldLightDir, i.worldNormal));//高光反射// 计算反射方向fixed3 reflectDir = normalize(reflect(-worldLightDir, i.worldNormal));//计算视角//fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.WorldPos);//计算视角简化版本fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));// 计算高光颜色fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(reflectDir, viewDir)), _Gloss);fixed3 color = diffuse + ambient + specular;return fixed4(color, 1); // 输出颜色
}

片元着色器的输入是一个结构体 v2f ,它包含了顶点的裁剪空间位置和世界空间法线和位置信息。片元着色器的输出是一个 fixed4 类型的颜色值,它表示了片元的颜色。

片元着色器的主要逻辑是:

  1. 使用 UNITY_LIGHTMODEL_AMBIENT 宏,获取环境光的颜色,这是 Phong 光照模型的第一个分量。

  2. 使用 UnityWorldSpaceLightDir 函数,获取光源的方向向量,这是为了计算漫反射和高光效果所需的角度。

  3. 使用 _LightColor0 和 _Diffuse 变量,获取光源的颜色和物体的漫反射颜色,然后使用 max 和 dot 函数,计算光源和法线的夹角的余弦值,这是 Phong 光照模型的第二个分量。

  4. 使用 reflect 函数,计算光源的反射方向向量,这是为了计算高光效果所需的角度。

  5. 使用 UnityWorldSpaceViewDir 函数,获取视线的方向向量,这是为了计算高光效果所需的角度。

  6. 使用 _LightColor0 和 _Specular 变量,获取光源的颜色和物体的高光颜色,然后使用 max 和 dot 函数,计算反射方向和视线方向的夹角的余弦值,然后使用 pow 函数,计算高光的强度,这是 Phong 光照模型的第三个分量。

  7. 将环境光、漫反射和高光的颜色相加,得到最终的光照颜色,作为片元着色器的输出。

三、效果

左:Phong顶点高光反射着色器 右:Phong片元高光反射着色器 (_Diffuse设置成了红色)
在这里插入图片描述

四、总结

Phong 片元高光反射着色器和 Phong 顶点高光反射着色器都是基于 Phong 光照模型的着色器,可以模拟物体表面的漫反射、环境光和高光效果,使物体看起来更加真实和立体。

Phong 片元高光反射着色器的优劣势

在片元着色器中计算光照颜色,提高了光照效果的精细度和真实度,尤其是在物体表面有弯曲或者高光区域时,可以避免出现锯齿或者平面化的现象。它的劣势是,会增加片元着色器的计算量,降低性能和效率,尤其是在物体的面数较多或者光源的数量较多时,会造成较大的开销。它不能处理复杂的光照情况,例如多光源、阴影、透明度、反射、折射等,需要使用更高级的着色器来实现。

使用场景

当需要模拟物体表面的光照效果,且需要较高的精度和细节时,可以使用这种着色器。例如,一些复杂的几何形状,或者一些近处的物体,或者一些需要重点关注的物体,都可以使用这种着色器来提高视觉效果和真实感。

Phong 顶点高光反射着色器的优劣势

在顶点着色器中计算光照颜色,减少了片元着色器的计算量,提高了性能和效率。它的劣势是,会导致光照效果不够精细,尤其是在物体表面有弯曲或者高光区域时,会出现明显的锯齿或者平面化的现象。它不能处理复杂的光照情况,例如多光源、阴影、透明度、反射、折射等,需要使用更高级的着色器来实现。

使用场景

当需要模拟物体表面的光照效果,但又不需要太高的精度和细节时,可以使用这种着色器。例如,一些简单的几何形状,或者一些远处的物体,或者一些不需要太多关注的物体,都可以使用这种着色器来提高性能和节省资源。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/459918.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

邮箱营销软件推荐?企业邮箱群发会限制吗?

邮箱营销平台怎么选择?哪种邮箱适合做外贸邮件群发? 邮箱营销凭借其精准触达、低成本和高回报的特点,依然是许多企业不可或缺的营销手段。该如何选择一款适合自己的工具呢?蜂邮EDM将为您推荐几款优秀的邮箱营销软件,并…

【Git】08 多人单分支协作场景

文章目录 一、场景1:不同人修改不同文件1.1 场景描述1.2 场景复现1.2.1 克隆到本地1.2.2 新建分支1.2.3 B修改、提交与推送1.2.4 A修改与提交1.2.5 B再次修改并推送1.2.6 A推送报错 1.3 解决 二、场景2:不同人修改同文件的不同区域2.1 场景描述2.2 场景复…

代码随想录算法训练营第30天| 51. N皇后、总结

51. N皇后 完成 思路&#xff1a; 如何用回溯法搜索二维棋盘是这道题目和之前不一样的地方&#xff0c;也是题目的难点。 在树形结构中&#xff0c;同层取同一行棋盘的不同列遍历。每递归一次就往下遍历一行。 代码 class Solution {List<List<String>> res n…

Pytorch+NCCL源码编译

目录 环境1. 安装cudnn2. 使用pytorch自带NCCL库进行编译3. 修改NCCL源代码并重新编译后测试&#xff0c;体现出源码更改 环境 Ubuntu 22.04.3 LTS (GNU/Linux 5.15.0-91-generic x86_64)cuda 11.8 cudnn 8python 3.10torch V2.0.1 nccl 2.14.3NVIDIA GeForce RTX 4090 *2 1.…

疑似针对安全研究人员的窃密与勒索

前言 笔者在某国外开源样本沙箱平台闲逛的时候&#xff0c;发现了一个有趣的样本&#xff0c;该样本伪装成安全研究人员经常使用的某个渗透测试工具的破解版压缩包&#xff0c;对安全研究人员进行窃密与勒索双重攻击&#xff0c;这种双重攻击的方式也是勒索病毒黑客组织常用的…

python入门篇11-面向对象的基础使用

全文目录,一步到位 1.前言简介1.1 专栏传送门1.1.1 上文小总结1.1.2 上文传送门 2. python基础使用2.1 面向对象的基础使用2.1.1 创建类2.1.2 使用对象(定义成员变量)2.1.3 成员方法的定义与使用2.1.4 构造方法的使用2.1.5 常用魔术方法 2.2 面向对象思想核心2.2.1 面向对象_私…

【知识整理】管理即服务,识人、识己

1. 背景 一个人的力量是有限的&#xff0c;如何规模化生产&#xff0c;人员的规模化组织&#xff0c;如何提升合作的规模和效率。 管理的本质&#xff1a; 1、服务他人&#xff1f; 2、激发主动性&#xff1f; 3、氛围宽松&#xff1f; 上面是理念&#xff0c; 1、那如何…

006集——where语句进行属性筛选——arcgis

在arcgis中&#xff0c; dBASE 文件除了 WHERE 语句以外&#xff0c;不支持 其它 SQL 命令。选择窗口如下&#xff1a; 首先&#xff0c;我们了解下什么是where语句。 WHERE语句是SQL语言中使用频率很高的一种语句。它的作用是从数据库表中选择一些特定的记录行来进行操作。WHE…

Spring Cloud使用ZooKeeper作为注册中心的示例

简单的Spring Cloud应用程序使用ZooKeeper作为注册中心的示例&#xff1a; 1.新建模块&#xff1a; 2.勾选依赖&#xff1a; 3.在pom.xml文件中做出部分修改及添加Spring Cloud Zookeeper 依赖版本&#xff1a; 完整pom文件 <?xml version"1.0" encoding&q…

LoveWall v2.0Pro社区型校园表白墙源码

校园表白墙&#xff0c;一个接近于社区类型的表白墙&#xff0c;LoveWall。 源码特色&#xff1b; 点赞&#xff0c; 发评论&#xff0c; 发弹幕&#xff0c; 多校区&#xff0c; 分享页&#xff0c; 涉及违禁物等名词进行检测&#xff01; 安装教程: 环境要求&#xff1b;…

Vue中v-on 可以监听多个方法吗

当然可以&#xff01;Vue.js是一款非常强大的JavaScript库&#xff0c;它提供了很多方便的方法和指令&#xff0c;使我们可以更容易地构建交互式的Web应用程序。其中&#xff0c;v-on指令是Vue.js中一个非常重要也非常常用的指令&#xff0c;它用于监听DOM事件&#xff0c;并在…

vite项目配置根据不同的打包环境使用不同的请求路径VITE_BASE_URL,包括报错解决

vite环境配置可以看官方文档&#xff1a;环境变量和模式 | Vite 官方中文文档 创建环境配置文件 在项目根目录下面创建.env和.env.production文件&#xff0c;.env是开发环境使用的&#xff0c;.env.production是生产环境使用的。 .env文件&#xff1a; # 基本环境 VITE_APP…