游戏人生
首页
(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.7 方向光
23.9 多光源 >>
## 23.8 点光源 ```text 「游戏引擎 浅入浅出」是一本开源电子书,PDF/随书代码/资源下载: https://github.com/ThisisGame/cpp-game-engine-book ``` ```bash CLion项目文件位于 samples\classic_lighting\point_light ``` 点光源发出的光子,向四面八方发射,到一定距离后消亡,例如萤火虫的光。 ![](md/cpp-game-engine-book/imgs/classic_lighting/point_light/firefly.jpg) ### 1. 点光源特点 点光源有以下特点: 1. 与位置有关 2. 无方向 3. 有衰减 ### 2. 点光源衰减 位置、方向这两个特点,之前都实现过了,现在要考虑衰减的问题。 衰减就是随距离越大,受到光照影响越弱,也就是受光强度越小。 #### 2.1 线性衰减 我们可以简单的写个函数,来做线性的衰减。 ![](md/cpp-game-engine-book/imgs/classic_lighting/point_light/linear_attenuation.jpg) $ x $ 是与光源距离。 #### 2.2 带一次项曲线衰减 也可以做比较真的模拟。 现实世界里,在靠近光源的一段距离内,衰减的厉害,随着距离远了,变化就不是很大。 我们可以用一个稍微复杂的公式来模拟。 ![](md/cpp-game-engine-book/imgs/classic_lighting/point_light/one_param_attenuation.jpg) $ x $ 是与光源距离。 $ K $是一次项,和距离相乘,随着$ K $增大,衰减值变化如下图。 ![](md/cpp-game-engine-book/imgs/classic_lighting/point_light/one_param_attenuation.gif) #### 2.3 带二次项曲线衰减 一般来说带一次项曲线衰减,效果足够了,不过科学家写了一个更真实的模拟函数。 ![](md/cpp-game-engine-book/imgs/classic_lighting/point_light/simulation_att.jpg) $ d $ 是与光源距离。 $ K_c $是常数项,一般是1.0,这是为了保证衰减值不会大于1.0。 $ K_l $是一次项,和距离相乘,就是线性的。 $ K_q $是二次项,和距离平方相乘。 由于二次项的存在,光线会在大部分时候以线性的方式衰退,直到距离变得足够大,让二次项超过一次项,光的强度会以更快的速度下降。 这样的结果就是,光在近距离时亮度很高,但随着距离变远亮度迅速降低,最后会以更慢的速度减少亮度。 ![](md/cpp-game-engine-book/imgs/classic_lighting/point_light/two_param_attenuation.gif) 从上面的动图可以看到,在二次项的影响下,在近距离衰减的更厉害了,然后远距离衰减的变缓了。 针对不同的效果,大家也总结出了一些参数值,供我们直接套用,下面是Ogre3d引擎给出的一套参数。 ```c++ Range Constant Linear Quadratic 3250, 1.0, 0.0014, 0.000007 600, 1.0, 0.007, 0.0002 325, 1.0, 0.014, 0.0007 200, 1.0, 0.022, 0.0019 160, 1.0, 0.027, 0.0028 100, 1.0, 0.045, 0.0075 65, 1.0, 0.07, 0.017 50, 1.0, 0.09, 0.032 32, 1.0, 0.14, 0.07 20, 1.0, 0.22, 0.20 13, 1.0, 0.35, 0.44 7, 1.0, 0.7, 1.8 ``` 衰减曲线如下图: ![](md/cpp-game-engine-book/imgs/classic_lighting/point_light/ogre_Attenuation_Graph.jpg) 原文地址:`https://wiki.ogre3d.org/tiki-index.php?page=-Point+Light+Attenuation` 依据想要的效果,自己多测试几套。 ### 3. 点光源实现 将上面的公式,套入到片段Shader中。<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/point_light.frag #version 330 core uniform sampler2D u_diffuse_texture;//颜色纹理 //环境光 struct Ambient{ vec3 color;//环境光 alignment:12 offset:0 float intensity;//环境光强度 alignment:4 offset:12 }; layout(std140) uniform AmbientBlock { Ambient data; }u_ambient; //点光 struct PointLight { vec3 pos;//位置 alignment:16 offset:0 vec3 color;//颜色 alignment:12 offset:16 float intensity;//强度 alignment:4 offset:28 float constant;//点光衰减常数项 alignment:4 offset:32 float linear;//点光衰减一次项 alignment:4 offset:36 float quadratic;//点光衰减二次项 alignment:4 offset:40 }; layout(std140) uniform PointLightBlock { PointLight data; }u_point_light; uniform vec3 u_view_pos; uniform sampler2D u_specular_texture;//颜色纹理 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.data.color * u_ambient.data.intensity * texture(u_diffuse_texture,v_uv).rgb; //diffuse vec3 normal=normalize(v_normal); vec3 light_dir=normalize(u_point_light.data.pos - v_frag_pos); float diffuse_intensity = max(dot(normal,light_dir),0.0); vec3 diffuse_color = u_point_light.data.color * diffuse_intensity * u_point_light.data.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 spec=pow(max(dot(view_dir,reflect_dir),0.0),u_specular_highlight_shininess); float specular_highlight_intensity = texture(u_specular_texture,v_uv).r;//从纹理中获取高光强度 vec3 specular_color = u_point_light.data.color * spec * specular_highlight_intensity * texture(u_diffuse_texture,v_uv).rgb; // attenuation float distance=length(u_point_light.data.pos - v_frag_pos); float attenuation = 1.0 / (u_point_light.data.constant + u_point_light.data.linear * distance + u_point_light.data.quadratic * (distance * distance)); o_fragColor = vec4(ambient_color + diffuse_color*attenuation + specular_color*attenuation,1.0); } ``` 计算出衰减值之后,作用到漫反射和高光上。 ### 4. 设置点光源参数 新建`PointLight` 类,来负责点光源参数的更新。 ```c++ //file:source/lighting/point_light.cpp ...... void PointLight::set_color(glm::vec3 color) { Light::set_color(color); UniformBufferObjectManager::UpdateUniformBlockSubData3f("u_point_light","data.color",color_); }; void PointLight::set_intensity(float intensity) { Light::set_intensity(intensity); UniformBufferObjectManager::UpdateUniformBlockSubData1f("u_point_light","data.intensity",intensity_); }; /// 设置衰减常数项 /// \param attenuation_constant void PointLight::set_attenuation_constant(float attenuation_constant){ attenuation_constant_ = attenuation_constant; UniformBufferObjectManager::UpdateUniformBlockSubData1f("u_point_light","data.constant",attenuation_constant_); } /// 设置衰减一次项 /// \param attenuation_linear void PointLight::set_attenuation_linear(float attenuation_linear){ attenuation_linear_ = attenuation_linear; UniformBufferObjectManager::UpdateUniformBlockSubData1f("u_point_light","data.linear",attenuation_linear_); } /// 设置衰减二次项 /// \param attenuation_quadratic void PointLight::set_attenuation_quadratic(float attenuation_quadratic){ attenuation_quadratic_ = attenuation_quadratic; UniformBufferObjectManager::UpdateUniformBlockSubData1f("u_point_light","data.quadratic",attenuation_quadratic_); } void PointLight::Update(){ glm::vec3 light_position=game_object()->GetComponent<Transform>()->position(); UniformBufferObjectManager::UpdateUniformBlockSubData3f("u_point_light","data.pos",light_position); } ``` ### 5. 测试 编写测试代码,创建点光源,并且给定衰减参数。 ```lua --file:example/login_scene.lua function LoginScene:Awake() ...... self:CreateLight() ...... end ...... --- 创建灯 function LoginScene:CreateLight() self.go_light_= GameObject.new("point_light") self.go_light_:AddComponent(Transform):set_position(glm.vec3(0,0,5)) ---@type PointLight local light=self.go_light_:AddComponent(PointLight) light:set_color(glm.vec3(1.0,0.0,0.0)) light:set_intensity(1.0) --衰减曲线 https://wiki.ogre3d.org/tiki-index.php?page=-Point+Light+Attenuation light:set_attenuation_constant(1.0) light:set_attenuation_linear( 0.35) light:set_attenuation_quadratic( 0.44) end ...... ``` 这里添加了一个红色的点光源,效果如下图。 ![](md/cpp-game-engine-book/imgs/classic_lighting/point_light/point_light_test.gif)
<< 23.7 方向光
23.9 多光源 >>
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 猎人开发后记