文章目录

  • 前言
  • 修改MiniEngine的坐标转换
  • d3d12book的光照shader
  • 添加shapes对应的光照shader
  • 最终结果
  • 为什么结果比d3d12book的要亮

前言

光照的实现,主要是shader做的,C++代码层没添加多少东西。
理解了shader,看懂d3d12book的源码,shader直接拷进来,C++代码直接转过来就可以了。
难度主要是看懂shader。对于光照的计算,应该说我也没有深入学,仅仅是了解了一些概念,就像是很多数学公式我也不会推一样。正确理解自己的能力,做好能力范围内的事情,对于数学的提高,觉得可以稍微靠后放一放。主要还是学习d3d12的一些使用上的东西。

修改MiniEngine的坐标转换

在前边的学习过程中,就挺纠结的。因为在VS shader中mul函数的俩参数是反过来的。最初以为是MiniEngine做了什么奇怪的操作,后来发现不是。
这篇博客讲得很清楚,可以学习下。
https://www.cnblogs.com/X-Jun/p/9808727.html

我觉得 mul(点,矩阵) 更符合直觉,也更符合公式。
所以第八章第一步就是要在C++部分对传入的矩阵先做一次转置。
为了更好的贴合d3d12book的shader,也同样的把常量缓冲区改成3部分,只是槽有点区别。

先实现shapes这个例子,只需要两个常量缓冲区,一个放入模型转世界的矩阵,一个放入摄像机的世界转投影矩阵。
简易的修改如下:

  1. 修改根签名:
 m_RootSignature.Reset(3, 0);m_RootSignature[0].InitAsConstantBuffer(0, D3D12_SHADER_VISIBILITY_VERTEX);m_RootSignature[1].InitAsConstantBuffer(1, D3D12_SHADER_VISIBILITY_ALL);
  1. 动态传入投影矩阵的转置矩阵
 __declspec(align(16)) struct{Matrix4 viewProj;  // 从世界坐标转为投影坐标的矩阵}passConstants;// https://www.cnblogs.com/X-Jun/p/9808727.html// C++代码端进行转置,HLSL中使用matrix(列矩阵)// mul函数让向量放在左边(行向量),实际运算是(行向量 X 行矩阵) 然后行矩阵为了使用dp4运算发生了转置成了列矩阵passConstants.viewProj = Transpose(m_ViewProjMatrix);gfxContext.SetDynamicConstantBufferView(1, sizeof(passConstants), &passConstants);
  1. 修改模型的世界矩阵为转置矩阵
 // boxitem.modelToWorld = Transpose(Matrix4(AffineTransform(Matrix3::MakeScale(2.0f, 2.0f, 2.0f), Vector3(0.0f, 0.5f, 0.0f))));item.indexCount = (UINT)box.Indices32.size();item.startIndex = boxIndexOffset;item.baseVertex = boxVertexOffset;item.diffuseAlbedo = XMFLOAT4(Colors::LightSteelBlue);item.fresnelR0 = XMFLOAT3(0.05f, 0.05f, 0.05f);item.roughness = 0.3f;m_vecShapes.push_back(item);....
  1. 修改vs shader中mul的参数顺序

    本步骤的github代码地址:
    https://github.com/mversace/DirectX12-MiniEngine-Dragon/tree/9ac87af5b5bab2da12f745a75936f6a45ca736b1

d3d12book的光照shader

对于光照,书中讲的已经很详细了。
在d3d12book项目中。LightingUtil.hlsl就是一个通用的计算光照的文件。
就是把书中讲的计算公式写成了shader。

而对于MiniEngine中呢,这一部分写的是比较复杂的,主要是牵扯的参数比较多,比如包含了纹理的参数。
本章内容纹理是没有的,只是提供了光照渲染需要的3个参数。
对于MiniEngine中的光照shader,将在学习纹理之后一次性加进去,到时候做个替换。

d3d12book的shader复杂就是计算光照的模块,这部分跳过,因为我也没背下来。我觉得暂时会用就可以了。

添加shapes对应的光照shader

我们直接把LightingUtil.hls放入我们工程,然后改写vs和ps文件
在vs文件中,传入的不再是颜色,而是当前顶点的法向量。传给ps多一个法向量参数

   VertexOut vout = (VertexOut)0.0f;// 将定点转化为世界坐标系中的点float4 posW = mul(float4(vin.PosL, 1.0f), modelToWorld);vout.PosW = posW.xyz;// 将法向量转换成世界坐标系中的法向量vout.NormalW = mul(vin.NormalL, (float3x3)modelToWorld);// 点转化为投影坐标系中的点vout.PosH = mul(posW, gViewProj);return vout;

再来看下ps文件,ps文件中有一个常量缓冲区,也就是1槽的数据,这个每一帧都会写入的
不需要d3d12book中的那么多参数,只需要如下几个就好了

cbuffer cbPass : register(b1)
{float4x4 gViewProj;       // 投影坐标系矩阵float3 gEyePosW;         // 摄像机位置float cbPerObjectPad1;  // 忘记删了,没啥用float4 gAmbientLight;   // 环境光// Indices [0, NUM_DIR_LIGHTS) are directional lights;// indices [NUM_DIR_LIGHTS, NUM_DIR_LIGHTS+NUM_POINT_LIGHTS) are point lights;// indices [NUM_DIR_LIGHTS+NUM_POINT_LIGHTS, NUM_DIR_LIGHTS+NUM_POINT_LIGHT+NUM_SPOT_LIGHTS)// are spot lights for a maximum of MaxLights per object.Light gLights[MaxLights];   // 平行光源
};// 2槽放入纹理,不同的渲染物体会动态塞入不同的纹理
cbuffer cbMaterial : register(b2)
{float4 gDiffuseAlbedo;  // 漫反射反射率float3 gFresnelR0;        // 材质属性float  gRoughness;  // 粗糙度
};

main函数也是很简单的,因为复杂的光照计算都封装在LightingUtil.hls中了

 // 法向量规范化pin.NormalW = normalize(pin.NormalW);// 当前点反射到眼睛的向量 float3 toEyeW = normalize(gEyePosW - pin.PosW);// 漫发射直接点积就可以float4 ambient = gAmbientLight * gDiffuseAlbedo;// 构造材质参数,计算光照结果。gLights是一个光照数组const float shininess = 1.0f - gRoughness;Material mat = { gDiffuseAlbedo, gFresnelR0, shininess };float3 shadowFactor = 1.0f;float4 directLight = ComputeLighting(gLights, mat, pin.PosW,pin.NormalW, toEyeW, shadowFactor);// 漫反射+其他光源,得出最后的颜色值float4 litColor = ambient + directLight;// Common convention to take alpha from diffuse material.litColor.a = gDiffuseAlbedo.a;return litColor;

最终结果

shapes git:
https://github.com/mversace/DirectX12-MiniEngine-Dragon/tree/b1fd81579267c8b8f657c62a90d8e4314fd174ec
land and waves git:
https://github.com/mversace/DirectX12-MiniEngine-Dragon/tree/032bc099f71261fed81c497406b864d39885979f

为什么结果比d3d12book的要亮

最初我看到,也是调了挺久。后来发现是MiniEngine自带了动态光照技术(HDR,LDR)。
可以直接把图象渲染到交换链中的缓冲区就可以了。

还有一个帧数问题。debug版本和release版本帧数差距极大,这点要注意。

d3d12龙书学习之MiniEngine的最小化实现(四) 光照shader的实现相关推荐

  1. DX11龙书学习笔记---渲染管线

    DX11龙书学习笔记---渲染管线 1.输入装配阶段 - 顶点 - 图元拓扑 - 点列表 - 线带 - 线列表 - 三角形带 - 三角形列表 - 带有邻接信息的图元 - 控制点面片列表 - 索引 2. ...

  2. DX11龙书学习笔记---准备工作

    DX11龙书学习笔记---准备工作 1.交换链和页面翻转 深度缓冲区 多重采样 1.交换链和页面翻转 为了避免在动画中出现闪烁,最好的做法是在一个离屏(off-screen)纹理中执行所有的动画帧绘制 ...

  3. 【DirectX 12 GJ的龙书学习笔记 一】前言与配置环境

    终于开始DirectX 12的学习了! 首先简单介绍下Direct3D 12: Direct3D 12是一个用于在各种Windows 10平台(Windows,移动设备和Xbox One)上使用现代图 ...

  4. D3D12龙书入手指南

    文章目录 前言 创建第一个工程 利用DirectXMath库进行向量运算 易错问题 前言 由于我们一般是用VS2019了,而示例都是2015版,所以这里写一个踩坑记录. 创建第一个工程 首先把源代码下 ...

  5. 《JavaScript高级程序设计(第四版)》红宝书学习笔记(2)(第四章:变量、作用域与内存)

    个人对第四版红宝书的学习笔记.不适合小白阅读.这是part2.持续更新,其他章节笔记看我主页. (记 * 的表示是ES6新增的知识点,记 ` 表示包含新知识点) 第四章:变量.作用域与内存 4.1 原 ...

  6. dx12 龙书第九章学习笔记 -- 纹理贴图

    1.纹理与资源的回顾 我们其实很早就接触过纹理了,之前的深度缓冲区与后台缓冲区,它们都是通过ID3D12Resource接口表示,并以D3D12_RESOURCE_DESC::Dimension成员中 ...

  7. 编译原理(龙书)学习笔记 第一章

    编译原理(龙书)学习笔记 第一章 1.1语言处理器 解释器(interpreter) : 编译器(compiler): 一个语言处理系统 练习 1.1.1:编译器和解释器之间的区别 1.1.2:相对优 ...

  8. DirectX 9.0c游戏开发手记之“龙书”第二版学习笔记之1: 开场白

    在开场白之前的说明: 这是"DirectX 9.0c游戏开发手记"的第一部分,叫做"'龙书'第二版学习笔记",讲的是我做"龙书"第二版(原名 ...

  9. dx12 龙书第二十章学习笔记 -- 阴影贴图

    对于龙书这本入门级别的书籍来说,我们仅关注于基本的阴影贴图算法.而像级联阴影贴图(cascading shadow map)[Engel06]这种效果更佳却也更为复杂的阴影技术,实则都是由这基本的阴影 ...

最新文章

  1. Nginx 常用配置清单
  2. numpy 中的 random.rand() 函数
  3. eclipse远程连接hadoop_Hadoop之HDFS基本操作实验
  4. 科大星云诗社动态20210305
  5. cmd小游戏编程100例_学宏程序编程,这些知识必不可少!
  6. HTML、CSS 和 JS框架之Bootstrap
  7. Visual Studio内存泄漏检测
  8. 学习Java的相关知识
  9. chrome91 后 SameSite by default cookies 不对外开放 解决方案
  10. oracle 11g r2 安装过程与卸载详细图解
  11. Bootstrap 带下拉的导航
  12. 基于JAVA+SpringMVC+Mybatis+MYSQL的旅游景点酒店预订网站设计
  13. java 中的jframe_java中JFrame是什么
  14. 【转】关于大型网站技术演进的思考(七)--存储的瓶颈(7)
  15. 解决 el-autocomplete 不显示及没数据时闪一下的问题
  16. TextView属性设置
  17. 如何使用python合并多个excel文件
  18. html链接位置移动,锚点链接点击缓慢移动到目标位置
  19. 让你的Win10桌面比macOS还简洁漂亮高大上
  20. 计算机怎么设置加密文件,怎么把电脑文件加密_怎么把文件加密-win7之家

热门文章

  1. Java常用类工具-泛型
  2. 光伏发电的“城市绿色电厂”策略研究
  3. 活/死细胞双染色试剂盒工作原理揭晓
  4. STM32-TFT-LCD
  5. Z-Wave Multi Channel Basics zwave多功能复合设备实现
  6. 面试java-002
  7. 我什么要坚持学技术?
  8. win10桌面计算机被删了,Windows10系统桌面图标被误删了的找回方法
  9. 提示工程L2:提示迭代
  10. ICRA的5篇最佳操作机械手论文逐个看 | ICRA 2017