邢台建设一个企业网站,apt安装wordpress,做网站的是些什么公司,烟台网站排名系统文章目录 前言一、BlinnPhong高光反射着色器是什么#xff1f;1. BlinnPhong高光反射着色器的工作原理2. BlinnPhong高光反射着色器的优缺点优点缺点 3. 公式 二、使用步骤1. Shader 属性定义2. SubShader 设置3. 渲染 Pass4. 定义结构体和顶点着色器函数5. 片元着色器函数 三… 文章目录 前言一、BlinnPhong高光反射着色器是什么1. BlinnPhong高光反射着色器的工作原理2. BlinnPhong高光反射着色器的优缺点优点缺点 3. 公式 二、使用步骤1. Shader 属性定义2. SubShader 设置3. 渲染 Pass4. 定义结构体和顶点着色器函数5. 片元着色器函数 三、效果四、总结Phong 顶点高光反射着色器的优劣势Phong 片元高光反射着色器的优劣势Blinn-Phong 高光反射着色器的优劣势 前言
在 Unity 中Shader 可以用来实现各种视觉效果。本教程将详细介绍如何编写一个基于 BlinnPhong高光反射着色器使物体的颜色根据光照和法线方向的变化而变化。 一、BlinnPhong高光反射着色器是什么
1. BlinnPhong高光反射着色器的工作原理
Blinn-Phong 高光反射着色器是一种常用的光照模型它可以模拟物体表面在不同光源和观察角度下的明暗变化从而增强物体的立体感和真实感。它是由 Jim Blinn 和 Bui Tuong Phong 在 1970 年代提出的是对 Phong 光照模型的改进和简化。
Blinn-Phong 高光反射着色器的基本思想是物体表面的颜色由三个分量组成环境光分量漫反射分量和高光分量。环境光分量表示物体表面接收到的来自四面八方的间接光照它是一个常量与光源和观察者的位置无关。漫反射分量表示物体表面接收到的来自光源的直接光照它与光源和物体表面的法线的夹角成正比即 Lambert 定律。高光分量表示物体表面反射的光线进入观察者的眼睛它与光源物体表面的法线和观察者的位置有关即 Blinn-Phong 反射模型。
2. BlinnPhong高光反射着色器的优缺点
优点
简单易实现计算量相对较低适合实时渲染。 可以调节物体表面的各种参数例如颜色亮度高光系数等来模拟不同的材质效果。 可以与纹理贴图法线贴图等技术结合进一步增强物体表面的细节和真实感。 产生的高光效果比 Phong 模型更加柔和和自然。
缺点
不符合物理规律只是一种经验模型无法模拟复杂的光照现象例如阴影折射散射等。 对于一些高光敏感的材质例如金属玻璃等可能无法产生理想的效果。 对于一些弯曲的物体例如球体圆柱体等可能会出现高光断裂的现象因为半向量的变化不够平滑
3. 公式 二、使用步骤
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.worldPosmul(unity_ObjectToWorld,v.vertex);return o;
}顶点着色器的输入是一个结构体 appdata_base 它包含了顶点的位置和法线信息。顶点着色器的输出是一个结构体 v2f 它包含了顶点的裁剪空间位置和世界空间法线和位置信息。
顶点着色器的主要逻辑是 使用 UnityObjectToClipPos 函数将顶点的位置从对象空间变换到裁剪空间这是渲染管线的必要步骤。 使用 UnityObjectToWorldNormal 函数将顶点的法线从对象空间变换到世界空间这是为了计算光照效果所需的方向向量。 使用 unity_ObjectToWorld 矩阵将顶点的位置从对象空间变换到世界空间这是为了计算光照效果所需的坐标系。
5. 片元着色器函数
// 片段着色器函数
fixed4 frag(v2f i) : SV_Target
{// 获取环境光fixed3 ambient UNITY_LIGHTMODEL_AMBIENT.xyz;// 漫反射// 获取光源位置//fixed3 worldLightDir normalize(_WorldSpaceLightPos0.xyz);// 获取光源位置简化fixed3 worldLightDir normalize(UnityWorldSpaceLightDir(i.worldPos));fixed3 diffuse _LightColor0.rgb * _Diffuse.rgb * max(0, dot(worldLightDir, i.worldNormal));// 高光反射// 计算视角方向//fixed3 viewDir normalize(_WorldSpaceCameraPos.xyz - i.WorldPos);fixed3 viewDir normalize(UnityWorldSpaceViewDir(i.worldPos));// 计算半向量fixed3 halfDir normalize(worldLightDir viewDir);// 计算高光颜色fixed3 specular _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(i.worldNormal, halfDir)), _Gloss);// 组合最终颜色fixed3 color diffuse ambient specular;return fixed4(color, 1); // 输出颜色
}
片元着色器的输入是一个结构体 v2f 它包含了顶点的裁剪空间位置和世界空间法线和位置信息。片元着色器的输出是一个 fixed4 类型的颜色值它表示了片元的颜色。
片元着色器的主要逻辑是 使用 UNITY_LIGHTMODEL_AMBIENT 宏获取环境光的颜色这是 Blinn-Phong 光照模型的第一个分量。 使用 UnityWorldSpaceLightDir 函数获取光源的方向向量这是为了计算漫反射和高光效果所需的角度。 使用 _LightColor0 和 _Diffuse 变量获取光源的颜色和物体的漫反射颜色然后使用 max 和 dot 函数计算光源和法线的夹角的余弦值这是 Blinn-Phong 光照模型的第二个分量。 使用 UnityWorldSpaceViewDir 函数获取视线的方向向量这是为了计算高光效果所需的角度。 使用 normalize 函数计算视线方向和光源方向的半向量这是为了简化高光效果的计算。 使用 _LightColor0 和 _Specular 变量获取光源的颜色和物体的高光颜色然后使用 max 和 dot 函数计算法线和半向量的夹角的余弦值然后使用 pow 函数计算高光的强度这是 Blinn-Phong 光照模型的第三个分量。 将环境光、漫反射和高光的颜色相加得到最终的光照颜色作为片元着色器的输出。
三、效果
左:Phong顶点高光反射着色器 中:Phong片元高光反射着色器 右:BlinnPhong高光反射着色器 _Diffuse设置成了红色) 四、总结
Phong 片元高光反射着色器和 Phong 顶点高光反射着色器都是基于 Phong 光照模型的着色器可以模拟物体表面的漫反射、环境光和高光效果使物体看起来更加真实和立体。Blinn-Phong 高光反射着色器是对 Phong 高光反射着色器的改进和简化主要区别在于计算高光反射时使用了半向量half vector代替镜面反射向量reflection vector从而减少了计算量和误差。
Phong 顶点高光反射着色器的优劣势
它的优势是 在顶点着色器中计算光照颜色减少了片元着色器的计算量提高了性能和效率。
它的劣势是会导致光照效果不够精细尤其是在物体表面有弯曲或者高光区域时会出现明显的锯齿或者平面化的现象。它不能处理复杂的光照情况例如多光源、阴影、透明度、反射、折射等需要使用更高级的着色器来实现。
使用场景 当需要模拟物体表面的光照效果但又不需要太高的精度和细节时可以使用这种着色器。例如一些简单的几何形状或者一些远处的物体或者一些不需要太多关注的物体都可以使用这种着色器来提高性能和节省资源。
Phong 片元高光反射着色器的优劣势
它的优势是 在片元着色器中计算光照颜色提高了光照效果的精细度和真实度尤其是在物体表面有弯曲或者高光区域时可以避免出现锯齿或者平面化的现象。
它的劣势是 会增加片元着色器的计算量降低性能和效率尤其是在物体的面数较多或者光源的数量较多时会造成较大的开销。它不能处理复杂的光照情况例如多光源、阴影、透明度、反射、折射等需要使用更高级的着色器来实现。
使用场景 当需要模拟物体表面的光照效果且需要较高的精度和细节时可以使用这种着色器。例如一些复杂的几何形状或者一些近处的物体或者一些需要重点关注的物体都可以使用这种着色器来提高视觉效果和真实感。
Blinn-Phong 高光反射着色器的优劣势
它的优势是 简单易实现计算量相对较低适合实时渲染。 可以调节物体表面的高光反射系数和指数来模拟不同的材质效果。 产生的高光效果比 Phong 模型更加柔和和自然更接近真实的光照现象。
它的劣势是 不符合物理规律只是一种经验模型无法模拟复杂的光照现象例如阴影折射散射等。 对于一些高光敏感的材质例如金属玻璃等可能无法产生理想的效果。 对于一些弯曲的物体例如球体圆柱体等可能会出现高光断裂的现象因为半向量的变化不够平滑。
使用场景 当需要模拟物体表面的高光反射效果且需要较好的效率和真实感时可以使用这种着色器。例如一些光滑的几何形状或者一些中等距离的物体或者一些需要突出高光的物体都可以使用这种着色器来增强光照效果和立体感。