Unity3d Shader篇(三)— 片元半兰伯特着色器解析
文章目录
- 前言
- 一、片元半兰伯特着色器是什么?
- 1. 片元漫反射着色器的工作原理
- 2. 片元半兰伯特着色器的优缺点
- 优点:
- 缺点:
- 3. 公式
- 二、使用步骤
- 1. Shader 属性定义
- 2. SubShader 设置
- 3. 渲染 Pass
- 4. 定义结构体和顶点着色器函数
- 5. 片元着色器函数
- 三、效果
- 四、总结
前言
在 Unity 中,Shader 可以用来实现各种视觉效果。本教程将详细介绍如何编写一个基于片元半兰伯特着色器,使物体的颜色根据光照和法线方向的变化而变化。
一、片元半兰伯特着色器是什么?
1. 片元漫反射着色器的工作原理
片元半兰伯特着色器是一种用于在计算机图形学中模拟物体光照效果的着色器技术。它基于半兰伯特(Half Lambert)模型,用于计算物体在光照条件下的漫反射光照强度。与标准的兰伯特模型相比,片元半兰伯特着色器采用了一种简化的方法来计算漫反射光的强度,使得物体在光照变化时表现出更加柔和的过渡效果。
2. 片元半兰伯特着色器的优缺点
优点:
计算简单:片元半兰伯特着色器采用了简化的半兰伯特模型,计算相对较简单,不需要复杂的数学运算,因此性能开销较小。
柔和的光照过渡:由于采用了半兰伯特模型,产生的光照效果更加柔和,物体在光照变化时表现出更加自然的明暗过渡效果。
适用性广泛:片元半兰伯特着色器适用于对光照效果要求不是特别高的场景,能够在性能受限的情况下实现基本的光照效果。
性能开销较小:简化的计算模型使得片元半兰伯特着色器的性能开销相对较小,适用于需要在性能受限情况下实现光照效果的场景。
缺点:
缺乏真实感:片元半兰伯特着色器采用了简化的模型,可能无法准确地模拟真实世界中复杂的光照效果,导致生成的图像缺乏真实感。
不适用于高要求场景:由于是基于简化的模型,片元半兰伯特着色器在需要较高光照效果真实感的场景下可能表现不佳,无法满足高要求的视觉效果。
局限性:半兰伯特模型适用于特定类型的材质和光照条件,对于一些特殊情况可能无法准确表现,导致着色效果不理想。
有限的光照控制:片元半兰伯特着色器对于光照效果的控制有限,无法实现一些复杂的光照效果,如阴影和反射等。
3. 公式

二、使用步骤
1. Shader 属性定义
Properties
{_Diffuse("Diffuse", Color) = (1, 1, 1, 1) // 漫反射颜色属性,默认白色
}
这段代码定义了 Shader 的属性。在本例中,我们只有一个属性 _Diffuse,表示物体的基本颜色,使用 RGBA 形式表示。默认为白色。
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; // 颜色
};v2f vert(appdata_base v)
{v2f o;o.vertex = UnityObjectToClipPos(v.vertex); // 顶点位置变换到裁剪空间fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); // 世界空间法线o.worldNormal = worldNormal;return o;
}
这里定义了结构体 v2f,用于从顶点着色器向片元着色器传递数据。在顶点着色器函数中,我们将顶点位置转换到裁剪空间,并计算世界空间的法线向量。
5. 片元着色器函数
fixed4 frag(v2f i) : SV_Target
{fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; //获取环境光fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz); //获取光源位置//* 0.5 + 0.5半兰伯特模型fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * (dot(worldLightDir, i.worldNormal) * 0.5 + 0.5);fixed3 color = diffuse + ambient; // 最终颜色return fixed4(color, 1); // 输出颜色
}
片元着色器函数计算最终的颜色。首先,我们获取环境光和光源位置。然后,计算漫反射光照,并将环境光和漫反射光照相加得到最终颜色。
三、效果
左:顶点漫反射 中:片元漫反射 右:片元半兰伯特


四、总结
片元漫反射、顶点漫反射和片元半兰伯特着色器是用于模拟物体在光照条件下的重要技术,它们各自有着不同的特点和适用场景。
片元漫反射:在每个像素上计算的漫反射光照效果。它提供了更精细的光照效果,因为考虑了每个像素的光照情况。适用于需要高度真实感和精细光照效果的场景,例如逼真的游戏场景、影视特效等。
顶点漫反射:在顶点级别计算的漫反射光照效果。计算量较小,适用于对性能要求较高或需要大量物体渲染的场景。可以在渲染管线的早期阶段就进行计算,节省计算资源。
片元半兰伯特着色器:常用于实现逼真的漫反射效果,考虑了光线入射角和表面法线之间的关系,符合半兰伯特定律。能够为渲染场景增加一定的真实感,特别是在模拟粗糙表面时效果较好。
然而,片元半兰伯特着色器也有局限性,它仅考虑了漫反射光照,未考虑其他光照效果,如镜面反射、环境光照等。在某些场景中,特别是需要更复杂光照效果以增强真实感时,仅使用片元半兰伯特着色器可能会导致渲染结果缺乏真实感。
因此,为了实现高度逼真的渲染效果,通常需要综合考虑多种光照技术,并根据场景需求选择和调整。片元半兰伯特着色器在模拟物体表面的漫反射方面表现良好,但在其他方面可能需要配合其他技术以获得更好效果。
相关文章:
Unity3d Shader篇(三)— 片元半兰伯特着色器解析
文章目录 前言一、片元半兰伯特着色器是什么?1. 片元漫反射着色器的工作原理2. 片元半兰伯特着色器的优缺点优点:缺点: 3. 公式 二、使用步骤1. Shader 属性定义2. SubShader 设置3. 渲染 Pass4. 定义结构体和顶点着色器函数5. 片元着色器函数…...
【vue3学习P5-P10】vue3语法;vue响应式实现
0、vue2和vue3对比 框架版本API方式双向绑定原理domFragmentsTree-Shakingvue2选项式API(Options API)基于Object.defineProperty(监听)实现,不能双向绑定对象类型的数据【通过Object.defineProperty里面的set和get做…...
相机图像质量研究(3)图像质量测试介绍
系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结:光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结:光学结构对成…...
PaddleDetection学习5——使用Paddle-Lite在 Android 上实现实时的人脸检测(C++)
使用Paddle-Lite在 Android 上实现实时的人脸检测 1 环境准备2. 部署步骤2.1 下载Paddle-Lite-Demo2.2 运行face_detection_demo项目3 使用Opencv对后处理进行优化4 开启手机摄像头进行人脸检测1 环境准备 参考前一篇在 Android 上使用Paddle-Lite实现实时的目标检测功能 2. …...
全套电气自动化样例图纸分享,使用SuperWorks自动化版免费设计软件!
今天给大家分享一套完备的电气自动化样例图纸,结构准确、内容清晰,适合初学者入门操作练习。 整套图纸包含图纸目录、原理图、端子列表、连接列表、元件列表、接线图,具有较高的参考价值,请大家点击自行下载文件! 1e8…...
带你实现用自己域名打开Tomcat
文章目录 Tomcat1.1、Tomcat 下载1.2、Tomcat 文件图解1.3、 启动或关闭 Tomcat1.3.1、 启动1.3.2、 关闭程序2.1、 修改端口号2.2、修改主机名称Tomcat 1.1、Tomcat 下载 首先去Tomcat 官网下载找到我们需要下载的版本 1.2、To...
python coding with ChatGPT 打卡第18天| 二叉树:从中序与后序遍历序列构造二叉树、最大二叉树
相关推荐 python coding with ChatGPT 打卡第12天| 二叉树:理论基础 python coding with ChatGPT 打卡第13天| 二叉树的深度优先遍历 python coding with ChatGPT 打卡第14天| 二叉树的广度优先遍历 python coding with ChatGPT 打卡第15天| 二叉树:翻转…...
java基础训练题(1)
1.下列代码段中,存在编译错误的语句是(B C D) byte b1 1,b2 2,b3,b6,b8; final byte b4 4,b5 6,b7; b3 (b1 b2);/*语句1*/ b6 b4 b5 ; /*语句2*/ b8 (b1 b4);/*语句3*/ b7 (b2 b5);/*语句4*/ System.out.println(b3 b6);A: 语句2 B: 语句1 C: 语句3…...
【自定义序列化器】⭐️通过继承JsonSerializer和实现WebMvcConfigurer类完成自定义序列化
目录 前言 解决方案 具体实现 一、自定义序列化器 二、两种方式指定作用域 1、注解 JsonSerialize() 2、实现自定义全局配置 WebMvcConfigurer 三、拓展 WebMvcConfigurer接口 章末 前言 小伙伴们大家好,上次做了自定义对象属性拷贝&#x…...
闲聊电脑(5)装个 Windows(一)
夜深人静,万籁俱寂,老郭趴在电脑桌上打盹,桌子上的小黄鸭和桌子旁的冰箱又开始窃窃私语…… 小黄鸭:冰箱大哥,上次说到硬盘分区和格式化,弄完之后,就该装系统了吧? 冰箱&#x…...
力扣(leetcode)第414题第三大的数(Python)
414.第三大的数 题目链接:414.第三大的数 给你一个非空数组,返回此数组中 第三大的数 。如果不存在,则返回数组中最大的数。 示例 1: 输入:[3, 2, 1] 输出:1 解释:第三大的数是 1 。 示例 2&a…...
使用wda框架实现IOS自动化测试详解
目录 1、weditor元素定位工具 1.1、weditor的安装和使用 2、wda iOS自动化框架 2.1、wda概述 2.2、wda安装 2.3、wda的使用 2.3.1、全局配置 2.3.2、创建客户端 2.3.3、APP相关操作 1、启动APP 2、关闭APP 3、获取APP状态信息 4、获取当前APP的运行信息 2.3.4、设…...
LeetCode--代码详解 2.两数相加
2.两数相加 题目 难度:中等 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数…...
【Django开发】美多商城项目第3篇:用户注册和图片验证码开发(附代码,文档已分享)
本系列文章md笔记(已分享)主要讨论django商城项目开发相关知识。本项目利用Django框架开发一套前后端不分离的商城项目(4.0版本)含代码和文档。功能包括前后端不分离,方便SEO。采用Django Jinja2模板引擎 Vue.js实现…...
代码随想录算法训练营DAY10 | 栈与队列 (1)
理论基础及Java实现参考文章:栈和队列 一、LeetCode 232 用栈实现队列 题目链接:232.用栈实现队列https://leetcode.cn/problems/implement-queue-using-stacks/ 思路:使用两个栈stack1、stack2实现队列;stack1用来存储入队元素&…...
flinkjar开发 自定义函数
编写自定义加密函数,继承ScalarFunction类,实现eval方法,参数个数类型和返回值根据业务来自定义。 import org.apache.flink.table.functions.ScalarFunction; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax…...
Golang 学习(一)基础知识
面向对象 Golang 也支持面向对象编程(OOP),但是和传统的面向对象编程有区别,并不是纯粹的面向对象语言。 Golang 没有类(class),Go 语言的结构体(struct)和其它编程语言的类(class)有同等的地位,Golang 是基于 struct 来实现 OOP…...
C++学习:string的了解
1.string的介绍 #include<string> 对于字符串的操作 自动处理内存的分配和释放 2.string的声明与初始化 1.std::string str1;空的 2.string str2 "afhsihsa" 3.string str3 str2 4.string str3 str2.substr(0,5) .substr(位置,长度) 5.c…...
Webpack源码浅析
webpack启动方式 webpack有两种启动方式: 通过webpack-cli脚手架来启动,即可以在Terminal终端直接运行; webpack ./debug/index.js --config ./debug/webpack.config.js通过require(webpack)引入包的方式执行;其实第一种方式最终…...
Hadoop:HDFS学习巩固——基础习题及编程实战
一 HDFS 选择题 1.对HDFS通信协议的理解错误的是? A.客户端与数据节点的交互是通过RPC(Remote Procedure Call)来实现的 B.HDFS通信协议都是构建在IoT协议基础之上的 C.名称节点和数据节点之间则使用数据节点协议进行交互 D.客户端通过一…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
