游戏人生
首页
(current)
GameDevTools
登陆
|
注册
个人中心
注销
游戏引擎 浅入浅出
Introduction
Introduction
前言
前言
1. 游戏引擎框架介绍
1. 游戏引擎框架介绍
1.1 Unity的组成
1.2 游戏引擎组成
2. Opengl开发环境搭建
2. Opengl开发环境搭建
2.1 Opengl到底是什么
2.2 搭建Opengl开发环境
2.3 使用VisualStudio开发
3. 绘制多边形
3. 绘制多边形
3.1 画个三角形
3.2 画个正方形
3.3 画个立方体
4. 着色器
4. 着色器
4.1 Unity Shader和OpenGL Shader
4.2 顶点着色器
4.3 片段着色器
5. 绘制贴图
5. 绘制贴图
5.1 颜色和贴图
5.2 贴图文件介绍
5.3 CPU与GPU的通信方式
5.4 使用stb_image解析图片
5.5 绘制带贴图的立方体盒子
5.6 压缩纹理
5.7 图片压缩工具
5.8 使用压缩纹理
5.9 DXT压缩纹理扩展
6. 索引与缓冲区对象
6. 索引与缓冲区对象
6.1 顶点索引
6.2 缓冲区对象
6.3 OpenGL Core Profile
6.4 顶点数组对象
7. 绘制Mesh和材质
7. 绘制Mesh和材质
7.1 导出Mesh文件
7.2 使用Mesh文件
7.3 Shader文件创建与使用
7.4 创建材质
7.5 使用材质
7.6 MeshRenderer
8. 绘制静态模型
8. 绘制静态模型
8.1 Blender安装与配置
8.2 Blender制作模型
8.3 Blender Python设置开发环境
8.4 Blender Python创建物体
8.5 Blender Python导出顶点数据
8.6 加载导出的Mesh
9. 基于组件开发
9. 基于组件开发
9.1 基于RTTR实现反射
9.2 实现GameObject-Component
10. 相机
10. 相机
10.1 最简单的相机
10.2 多相机渲染
10.3 相机排序
10.4 CullingMask
11. 控制系统
11. 控制系统
11.1 键盘控制
11.2 鼠标控制
12. 拆分引擎和项目
12. 拆分引擎和项目
13. 绘制文字
13. 绘制文字
13.1 TrueType简介
13.2 绘制单个字符
13.3 绘制多个文字
13.4 彩色字
14. GUI
14. GUI
14.1 正交相机
14.2 UIImage
14.3 UIMask
14.4 UIText
14.5 UIButton
15. 播放音效
15. 播放音效
15.1 播放2D音效
15.2 播放3D音效
15.3 使用FMOD Studio音频引擎
16. Profiler
16. Profiler
16.1 初识easy_profiler
16.2 集成easy_profiler
17. 嵌入Lua
17. 嵌入Lua
17.1 Sol2与C++交互
17.2 更加友好的Lua框架设计
17.3 引擎集成sol2
17.4 调试Lua
18. 骨骼动画
18. 骨骼动画
18.1 Blender制作骨骼动画
18.2 Blender导出骨骼动画
18.3 解析骨骼动画
18.4 矩阵的主序
19. 骨骼蒙皮动画
19. 骨骼蒙皮动画
19.1 骨骼蒙皮动画实现
19.2 骨骼权重
19.3 Blender蒙皮刷权重
19.4 Blender导出蒙皮权重
19.5 加载权重文件
20. 解析FBX文件
20. 解析FBX文件
20.1 导出Mesh
20.2 导出骨骼动画
20.3 导出权重
20.4 渲染骨骼蒙皮动画
21. 多线程渲染
21. 多线程渲染
21.1 GLFW多线程渲染
21.2 基于任务队列的多线程渲染
21.3 完全异步的多线程模型
21.4 引擎支持多线程渲染
22. Physx物理引擎
22. Physx物理引擎
22.1 Physx实例-小球掉落
22.2 物理材质
22.3 碰撞检测
22.4 连续碰撞检测
22.5 场景查询
22.6 引擎集成Physx
23. 经典光照
23. 经典光照
23.1 环境光
23.2 漫反射光照模型
23.3 镜面高光光照模型
23.4 高光贴图
23.5 Shader结构体
23.6 Uniform Buffer Object
23.7 方向光
23.8 点光源
23.9 多光源
24. 引擎编辑器的实现
24. 引擎编辑器的实现
24.1 分析Godot引擎编辑器
24.2 FBO RenderTexture GameTurbo DLSS
24.3 ImGui介绍与使用
24.4 分离引擎核心层和应用层
24.5 使用ImGui实现引擎编辑器
24.6 Hierarchy与Inspector面板
24.7 Geometry Buffer
25. Shadow Mapping
25. Shadow Mapping
25.1 深度图
25.2 简单阴影
88. VSCode扩展开发与定制
88. VSCode扩展开发与定制
88.1 第一个VSCode扩展程序
88.2 从源码编译VSCode
88.3 打包VSCode内置扩展
88.4 打包LuaHelper到Code-OSS
89. Doxygen生成API文档
89. Doxygen生成API文档
90. GPU分析工具
90. GPU分析工具
90.1 RenderDoc分析不显示bug
98. SubstancePainter插件开发
98. SubstancePainter插件开发
98.1 SP插件开发环境
98.2 开发SP功能性插件
98.3 开发SP渲染插件
99. Toolbag插件开发
99. Toolbag插件开发
99.1 插件开发环境
99.2 API介绍
99.3 命令行调用Toolbag
99.4 更多实现
99.5 代码参考
附录1. Wwise音频引擎
附录1. Wwise音频引擎
1.1 Wwise名词概念
1.2 Wwise制作音效导出SoundBank
1.3 集成Wwise
1.4 封装Wwise播放3D音效
1.5 Wwise性能分析器介绍
1.6 猎人开发后记
代码资源下载
点我下载
Github
点赞、收藏、关注
目录
<< 23.2 漫反射光照模型
23.4 高光贴图 >>
## 23.3 镜面高光光照模型 ```text 「游戏引擎 浅入浅出」是一本开源电子书,PDF/随书代码/资源下载: https://github.com/ThisisGame/cpp-game-engine-book ``` ```bash CLion项目文件位于 samples\classic_lighting\specular_highlight ``` 拿着手电筒,举高到眼镜位置,站在镜子前面,会看到镜子特别亮。 这是因为人看的方向,和电筒光的方向相同,镜子会将手电筒的光完全反射到眼镜里。 这种某一个区域,比其他的地方更特别亮,这个区域被称为高光区域,这种现象就称之为镜面高光。 ### 1. 现实世界的镜面高光 用灯,照射到公仔上,会发现拳套上,有高光区域。 当灯位置改变,这个高光区域会移动到其他地方。 <iframe width="800" height="450" src="https://player.bilibili.com/player.html??aid=301217402&bvid=BV1bF411P7rc&cid=780258674&page=1" frameborder="0" allowfullscreen> </iframe> 当人走动,这个高光区域也会移动。 这说明高光的效果,和灯的位置、眼睛的位置有关系。 <iframe width="800" height="450" src="https://player.bilibili.com/player.html?aid=428643507&bvid=BV1rG411n7yC&cid=780259314&page=1" frameborder="0" allowfullscreen> </iframe> 同一个公仔,会发现布料区域,亮度很均匀,不会出现某一块特别亮的情况。 这说明高光的效果,和物体表面材质有关系。 #### 1.1 微平面模型 为什么布料不会出现强反射光,而拳套会出现? 微平面理论认为:世界上不存在百分百的平面,达到微观尺度后,物体表面都是由n个细小的镜面组成的。 粗糙的表面,如公仔的布料,这些细小镜面朝向乱七八糟,就导致了光子射向表面时,被反射到了四面八方。 ![](md/cpp-game-engine-book/imgs/classic_lighting/specular_highlighting/microfacets.png) 光滑的表面,如玩偶的拳套,这些细小镜面朝向一致,就导致光子射向表面后,朝一个方向反弹。 ![](md/cpp-game-engine-book/imgs/classic_lighting/specular_highlighting/microfacets_light_rays.png) ### 2.镜面高光光照模型 前面说过了,人之所以能看见东西,是因为光子从光源发射后,击中了物体表面,然后反弹到人眼睛中,然后大脑生成了亮的区域。 当光子击中某个区域反弹,人眼正好位于它反弹的路线,那么此时,这个区域就是最亮的。 ![](md/cpp-game-engine-book/imgs/classic_lighting/specular_highlighting/specular_reflect.png) 镜面高光受到3个因素影响: 1. 灯位置 2. 眼睛位置 3. 物体表面材质反光能力 在上一节漫反射中,已经引入了灯位置,根据灯光方向 与 法线方向 ,计算其Cos值作为受光强度。 现在还需要引入眼睛位置、物体表面材质反光能力。 首先计算光的反射方向,然后计算眼睛的视线方向,求两者的夹角Cos值。 夹角越小,人眼看到的越亮。 这就是镜面高光光照模型。 下面来看片段着色器中具体的实现。<a id="antiCollectorAdTxt" href="https://github.com/ThisisGame/cpp-game-engine-book">「游戏引擎 浅入浅出」是一本开源电子书,PDF/随书代码/资源下载: https://github.com/ThisisGame/cpp-game-engine-book</a> ```glsl //file:data/shader/specular_highlight.frag #version 330 core uniform sampler2D u_diffuse_texture;//颜色纹理 uniform vec3 u_ambient_light_color;//环境光 uniform float u_ambient_light_intensity;//环境光强度 uniform vec3 u_light_pos; uniform vec3 u_light_color; uniform float u_light_intensity; //specular(镜面高光) uniform vec3 u_view_pos;//眼睛的位置 uniform float u_specular_highlight_intensity;//镜面高光强度 uniform float u_specular_highlight_shininess;//物体反光度,越高反光能力越强,高光点越小。 in vec4 v_color;//顶点色 in vec2 v_uv; in vec3 v_normal; in vec3 v_frag_pos; layout(location = 0) out vec4 o_fragColor; void main() { //ambient(环境光) vec3 ambient_color = u_ambient_light_color * u_ambient_light_intensity * texture(u_diffuse_texture,v_uv).rgb; //diffuse(漫反射) vec3 normal=normalize(v_normal); vec3 light_dir=normalize(u_light_pos - v_frag_pos); float diffuse_intensity = max(dot(normal,light_dir),0.0); vec3 diffuse_color = u_light_color * diffuse_intensity * u_light_intensity * texture(u_diffuse_texture,v_uv).rgb; //specular(镜面高光) vec3 reflect_dir=reflect(-light_dir,v_normal);//计算反射光的方向向量 vec3 view_dir=normalize(u_view_pos-v_frag_pos);//计算视线方向向量 float cos_value=max(dot(view_dir,reflect_dir),0.0);//计算反射光与视线的夹角cos值 float spec=pow(cos_value,u_specular_highlight_shininess);//用反光度做次方,计算得到高光值。 vec3 specular_color = u_light_color * spec * u_specular_highlight_intensity * texture(u_diffuse_texture,v_uv).rgb; o_fragColor = vec4(ambient_color + diffuse_color + specular_color,1.0); } ``` ### 3. 设置视角、灯光位置、表面参数 设置相机位置: ```lua --file:example/login_scene.lua line:49 --- 创建主相机 function LoginScene:CreateMainCamera() --创建相机1 GameObject self.go_camera_= GameObject.new("main_camera") --挂上 Transform 组件 self.go_camera_:AddComponent(Transform):set_position(glm.vec3(0, 0, 10)) self.go_camera_:GetComponent(Transform):set_rotation(glm.vec3(0, 0, 0)) --挂上 Camera 组件 self.camera_=self.go_camera_:AddComponent(Camera) --设置为黑色背景 self.camera_:set_clear_color(0,0,0,1) end ``` 设置灯光位置、物体反射参数: ```lua --file:example/login_scene.lua line:96 function LoginScene:Update() ...... --设置灯光位置、颜色、强度 self.material_:SetUniform3f("u_light_pos",glm.vec3(0,0,20)) self.material_:SetUniform3f("u_light_color",glm.vec3(1.0,1.0,1.0)) self.material_:SetUniform1f("u_light_intensity",1.0) --设置观察者世界坐标(即相机位置) local camera_position=self.go_camera_:GetComponent(Transform):position() self.material_:SetUniform3f("u_view_pos",camera_position) --设置物体反射度、高光强度 self.material_:SetUniform1f("u_specular_highlight_intensity",1.0) self.material_:SetUniform1f("u_specular_highlight_shininess",32.0) ...... end ``` ### 4. 测试 ![](md/cpp-game-engine-book/imgs/classic_lighting/specular_highlighting/specular_highlight_model.gif) 因为设置的灯光 和 相机,是同一方向的,都位于模型正前方。 所以看到正前方多出高光区域。 ![](md/cpp-game-engine-book/imgs/classic_lighting/specular_highlighting/specular_highlight_area.jpg) ### 5. 效果分解 在片段着色器最后的颜色叠加代码,可以单独输出环境光照、Diffuse、高光颜色,来对效果进行分解。 ![](md/cpp-game-engine-book/imgs/classic_lighting/specular_highlighting/combine_light_effect_specular.jpg) 单独输出高光颜色时,如 Specular highlight only 图所示,显示了高光区域。
<< 23.2 漫反射光照模型
23.4 高光贴图 >>
12
代码资源下载
点我下载
Github
点赞、收藏、关注
目录
Introduction
Introduction
前言
前言
1. 游戏引擎框架介绍
1. 游戏引擎框架介绍
1.1 Unity的组成
1.2 游戏引擎组成
2. Opengl开发环境搭建
2. Opengl开发环境搭建
2.1 Opengl到底是什么
2.2 搭建Opengl开发环境
2.3 使用VisualStudio开发
3. 绘制多边形
3. 绘制多边形
3.1 画个三角形
3.2 画个正方形
3.3 画个立方体
4. 着色器
4. 着色器
4.1 Unity Shader和OpenGL Shader
4.2 顶点着色器
4.3 片段着色器
5. 绘制贴图
5. 绘制贴图
5.1 颜色和贴图
5.2 贴图文件介绍
5.3 CPU与GPU的通信方式
5.4 使用stb_image解析图片
5.5 绘制带贴图的立方体盒子
5.6 压缩纹理
5.7 图片压缩工具
5.8 使用压缩纹理
5.9 DXT压缩纹理扩展
6. 索引与缓冲区对象
6. 索引与缓冲区对象
6.1 顶点索引
6.2 缓冲区对象
6.3 OpenGL Core Profile
6.4 顶点数组对象
7. 绘制Mesh和材质
7. 绘制Mesh和材质
7.1 导出Mesh文件
7.2 使用Mesh文件
7.3 Shader文件创建与使用
7.4 创建材质
7.5 使用材质
7.6 MeshRenderer
8. 绘制静态模型
8. 绘制静态模型
8.1 Blender安装与配置
8.2 Blender制作模型
8.3 Blender Python设置开发环境
8.4 Blender Python创建物体
8.5 Blender Python导出顶点数据
8.6 加载导出的Mesh
9. 基于组件开发
9. 基于组件开发
9.1 基于RTTR实现反射
9.2 实现GameObject-Component
10. 相机
10. 相机
10.1 最简单的相机
10.2 多相机渲染
10.3 相机排序
10.4 CullingMask
11. 控制系统
11. 控制系统
11.1 键盘控制
11.2 鼠标控制
12. 拆分引擎和项目
12. 拆分引擎和项目
13. 绘制文字
13. 绘制文字
13.1 TrueType简介
13.2 绘制单个字符
13.3 绘制多个文字
13.4 彩色字
14. GUI
14. GUI
14.1 正交相机
14.2 UIImage
14.3 UIMask
14.4 UIText
14.5 UIButton
15. 播放音效
15. 播放音效
15.1 播放2D音效
15.2 播放3D音效
15.3 使用FMOD Studio音频引擎
16. Profiler
16. Profiler
16.1 初识easy_profiler
16.2 集成easy_profiler
17. 嵌入Lua
17. 嵌入Lua
17.1 Sol2与C++交互
17.2 更加友好的Lua框架设计
17.3 引擎集成sol2
17.4 调试Lua
18. 骨骼动画
18. 骨骼动画
18.1 Blender制作骨骼动画
18.2 Blender导出骨骼动画
18.3 解析骨骼动画
18.4 矩阵的主序
19. 骨骼蒙皮动画
19. 骨骼蒙皮动画
19.1 骨骼蒙皮动画实现
19.2 骨骼权重
19.3 Blender蒙皮刷权重
19.4 Blender导出蒙皮权重
19.5 加载权重文件
20. 解析FBX文件
20. 解析FBX文件
20.1 导出Mesh
20.2 导出骨骼动画
20.3 导出权重
20.4 渲染骨骼蒙皮动画
21. 多线程渲染
21. 多线程渲染
21.1 GLFW多线程渲染
21.2 基于任务队列的多线程渲染
21.3 完全异步的多线程模型
21.4 引擎支持多线程渲染
22. Physx物理引擎
22. Physx物理引擎
22.1 Physx实例-小球掉落
22.2 物理材质
22.3 碰撞检测
22.4 连续碰撞检测
22.5 场景查询
22.6 引擎集成Physx
23. 经典光照
23. 经典光照
23.1 环境光
23.2 漫反射光照模型
23.3 镜面高光光照模型
23.4 高光贴图
23.5 Shader结构体
23.6 Uniform Buffer Object
23.7 方向光
23.8 点光源
23.9 多光源
24. 引擎编辑器的实现
24. 引擎编辑器的实现
24.1 分析Godot引擎编辑器
24.2 FBO RenderTexture GameTurbo DLSS
24.3 ImGui介绍与使用
24.4 分离引擎核心层和应用层
24.5 使用ImGui实现引擎编辑器
24.6 Hierarchy与Inspector面板
24.7 Geometry Buffer
25. Shadow Mapping
25. Shadow Mapping
25.1 深度图
25.2 简单阴影
88. VSCode扩展开发与定制
88. VSCode扩展开发与定制
88.1 第一个VSCode扩展程序
88.2 从源码编译VSCode
88.3 打包VSCode内置扩展
88.4 打包LuaHelper到Code-OSS
89. Doxygen生成API文档
89. Doxygen生成API文档
90. GPU分析工具
90. GPU分析工具
90.1 RenderDoc分析不显示bug
98. SubstancePainter插件开发
98. SubstancePainter插件开发
98.1 SP插件开发环境
98.2 开发SP功能性插件
98.3 开发SP渲染插件
99. Toolbag插件开发
99. Toolbag插件开发
99.1 插件开发环境
99.2 API介绍
99.3 命令行调用Toolbag
99.4 更多实现
99.5 代码参考
附录1. Wwise音频引擎
附录1. Wwise音频引擎
1.1 Wwise名词概念
1.2 Wwise制作音效导出SoundBank
1.3 集成Wwise
1.4 封装Wwise播放3D音效
1.5 Wwise性能分析器介绍
1.6 猎人开发后记