Unity3d Shader篇(四)— Phong顶点高光反射着色器

文章目录

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


前言

在 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 color:COLOR; // 颜色
};// 顶点着色器函数
v2f vert(appdata_base v)
{v2f o;o.vertex = UnityObjectToClipPos(v.vertex); // 顶点位置变换到裁剪空间//unity_ObjectToWorld 是一个变换矩阵,用于将顶点从对象空间变换到世界空间。//v.vertex 是顶点的位置信息。//mul() 函数表示矩阵相乘操作,这里将对象空间中的顶点位置矩阵与对象到世界的变换矩阵相乘,得到世界空间中的顶点位置。fixed3 worldPos=mul(unity_ObjectToWorld,v.vertex);fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; //获取环境光fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); // 世界空间法线//漫反射计算//光源位置//fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz); //光源位置简化fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(worldPos)); fixed3 diffuse = _LightColor0 * _Diffuse.rgb * max(0, dot(worldNormal, worldLightDir)); // 漫反射颜色计算//高光反射计算// 计算反射方向fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));// 计算视线方向//fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - UnityObjectToWorldDir(v.vertex));//计算视线方向简化版本fixed3 viewDir=normalize(UnityWorldSpaceViewDir(worldPos));// 计算高光颜色fixed3 specular = _LightColor0 * _Specular * pow(max(0, dot(reflectDir, viewDir)), _Gloss);o.color = diffuse + ambient + specular; // 输出颜色return o;
}

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

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

  1. 使用 UnityObjectToClipPos 函数,将顶点的位置从对象空间变换到裁剪空间,这是渲染管线的必要步骤。
  2. 使用 unity_ObjectToWorld 矩阵,将顶点的位置从对象空间变换到世界空间,这是为了计算光照效果所需的坐标系。
  3. 使用 UNITY_LIGHTMODEL_AMBIENT 宏,获取环境光的颜色,这是 Phong 光照模型的第一个分量。
  4. 使用 UnityObjectToWorldNormal 函数,将顶点的法线从对象空间变换到世界空间,这是为了计算光照效果所需的方向向量。
  5. 使用 UnityWorldSpaceLightDir 函数,获取光源的方向向量,这是为了计算漫反射和高光效果所需的角度。
  6. 使用 _LightColor0 和 _Diffuse 变量,获取光源的颜色和物体的漫反射颜色,然后使用 max 和 dot 函数,计算光源和法线的夹角的余弦值,这是 Phong 光照模型的第二个分量。
  7. 使用 reflect 函数,计算光源的反射方向向量,这是为了计算高光效果所需的角度。
    然后,使用 UnityWorldSpaceViewDir 函数,获取视线的方向向量,这是为了计算高光效果所需的角度。
  8. 使用 _LightColor0 和 _Specular 变量,获取光源的颜色和物体的高光颜色,然后使用 max 和 dot 函数,计算反射方向和视线方向的夹角的余弦值,然后使用 pow 函数,计算高光的强度,这是 Phong 光照模型的第三个分量。
  9. 将环境光、漫反射和高光的颜色相加,得到最终的光照颜色,作为顶点着色器的输出。

5. 片元着色器函数

// 片段着色器函数
fixed4 frag(v2f i) : SV_Target
{return fixed4(i.color, 1); // 输出颜色
}

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

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

  1. 使用 fixed4 构造函数,将光照颜色转换为颜色值,同时设置透明度为 1 。
  2. 直接返回颜色值,作为片段着色器的输出。

三、效果

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

四、总结

Phong 顶点高光反射着色器是一种基于 Phong 光照模型的着色器,它可以模拟物体表面的漫反射、环境光和高光效果。它的主要特点是,在顶点着色器中计算光照颜色,然后在片段着色器中插值输出颜色。这样做的好处是,可以减少片段着色器的计算量,提高性能。但是,这样做的缺点是,会导致光照效果不够精细,尤其是在物体表面有弯曲或者高光区域时,会出现明显的锯齿或者平面化的现象。Phong 顶点高光反射着色器的应用场景主要是,当需要模拟物体表面的光照效果,但又不需要太高的精度和细节时,可以使用这种着色器。Phong 顶点高光反射着色器也可以作为一种基础的着色器,用于学习和理解 Phong 光照模型的原理和实现,以及顶点着色器和片段着色器的区别和作用。

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

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

相关文章

99.网游逆向分析与插件开发-网络通信封包解析-数据包组织与发送过程逆向分析

内容参考于:易道云信息技术研究院VIP课 上一个内容:定位明文发送数据的关键函数 首先来到下图位置,查看edi的值是怎样来的 然后使用高亮模式查看edi,看看谁给edi赋过值 首先是下图红框位置,mov ecx, edi也就是edi是一…

读千脑智能笔记12_阻止人类灭绝

1. 阻止人类灭绝 1.1. 宇宙中唯一知道这些的物体,唯一知道宇宙存在的物体,是我们的大脑 1.2. 如果没有关于某个事物的知识,我们能说这个事物就一定存在吗? 1.2.1. 我们的大脑扮演着这样一个独特的角色,这很令人着迷…

网络安全检查表

《网络攻击检查表》 1.应用安全漏洞 2.弱口令,默认口令 3.服务器互联网暴露 4.操作系统,中间件安全漏洞 5.研发服务器,邮件服务器等安全检查

《软件方法》强化自测题-杂项题目解析01

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 杂项(1) 3 [ 单选题 ] 《软件方法》第1章“建模和UML”开头所引用的歌曲,其词曲作者还写过下列歌曲中的: A) 爱江山更爱美人&#…

2024.2.3 作业

1、实现单向循环链表的头插头删尾插尾删 #include<stdio.h> #include<string.h> #include<stdlib.h> typedef int datatype; typedef struct node {//数据域int data;//指针域struct node *next; }*Linklist; Linklist create() {Linklist s(Linklist)mallo…

【项目日记(九)】项目整体测试,优化以及缺陷分析

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:项目日记-高并发内存池⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你做项目   &#x1f51d;&#x1f51d; 开发环境: Visual Studio 2022 项目日…

米贸搜|Facebook在购物季使用的Meta广告投放流程

一、账户简化 当广告系列开始投放后&#xff0c;每个广告组都会经历一个初始的“机器学习阶段”。简化账户架构可以帮助AI系统更快获得广告主所需的成效。例如&#xff1a; 每周转化次数超过50次的广告组&#xff0c;其单次购物费用要低28%&#xff1b;成功结束机器学习阶段的…

代码随想录day20--二叉树的应用8

LeetCode669.修剪二叉搜索树 题目描述&#xff1a; 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即&#xff0c;如果没…

红队笔记Day2 -->上线不出网机器

今天就来讲一下在企业攻防中如何上线不出网的机器&#xff01;&#xff01; 1.基本网络拓扑 基本的网络拓扑就是这样 以下是对应得的P信息&#xff0c;其中的52网段充当一个内网的网段&#xff0c;而111充当公网网段 先ping一下&#xff0c;确保外网ping不通内网&#xff0c;内…

0206作业

TCP&#xff08;传输控制协议&#xff09;和 UDP&#xff08;用户数据报协议&#xff09;是两种常用的网络传输协议。它们之间的主要区别在于&#xff1a; 可靠性&#xff1a;TCP 是一种可靠的传输协议&#xff0c;它提供了数据传输的确认、重传和排序功能。如果数据在传输过程…

电商小程序04实现登录逻辑

目录 1 创建自定义方法2 获取用户名和密码3 验证用户是否同意协议4 验证用户名和密码总结 上一篇我们实现了登录功能的前端界面&#xff0c;这一篇实现一下登录的具体逻辑。 1 创建自定义方法 一般如果页面点击按钮需要有事件响应的&#xff0c;我们用自定义方法来实现。打开我…

【C语言】assert断言:保护程序的利器

在软件开发过程中&#xff0c;我们经常会遇到一些假设条件或者预期行为。例如&#xff0c;我们可能假设一个函数的输入参数必须在某个范围内&#xff0c;或者某个变量的值应该满足特定的条件。当这些假设或预期行为被打破时&#xff0c;程序可能会出现异常行为&#xff0c;甚至…