D3D12渲染技术之光源

2023-10-11 16:59
文章标签 技术 渲染 光源 d3d12

本文主要是介绍D3D12渲染技术之光源,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

灯光有Point光源,Spot光源,Directional光源,Area光源等等,网上这方面的文章很多,在此我们就不详细介绍每个光源的计算公式了,我们直接介绍将光源应用到我们的案例中。先看我们已经实现好的案例截图:
在这里插入图片描述

顶点格式

照明计算需要表面法线, 我们使用顶点定义法线,然后在三角形的像素上插入这些法线,以便我们可以对每个像素进行光照计算。 而且,我们不再指定顶点颜色, 相反,通过对每个像素应用照明方程来生成像素颜色, 为了支持顶点法线,我们修改我们的顶点结构,如下所示:

// C++ Vertex structure
struct Vertex
{DirectX::XMFLOAT3 Pos;DirectX::XMFLOAT3 Normal;
};// Corresponding HLSL vertex structure
struct VertexIn
{float3 PosL  : POSITION;float3 NormalL : NORMAL;
};
When we add a new vertex format, we need to describe it with a new input layout description:
mInputLayout =,
{{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
};

法线计算

GeometryGenerator中的形状函数已经创建了具有顶点法线的数据,因此我们都设置在那里。 但是,因为我们在这个演示中修改网格的高度使其看起来像地形,我们需要自己为地形生成法线向量。
因为我们的地形表面由函数y = f(x,z)给出,我们可以使用微积分直接计算法向量,而不是前面描述的常规平均计算。 对于曲面上的每个点,我们通过取偏导数在+ x-和+ z-方向上形成两个切向量:
在这里插入图片描述
这两个矢量位于表面点的切平面中, 计算法线向量得到:
在这里插入图片描述
我们用于生成地形网格的函数是:
在这里插入图片描述
偏导数是:
在这里插入图片描述
因此,表面点(x,f(x,z),z)处的表面法线由下式给出:
在这里插入图片描述
我们注意到这个曲面法线不是单位长度,因此需要在光照计算之前进行标准化。特别是,我们在每个顶点处进行上述常规计算以获得顶点法线:

XMFLOAT3 LitWavesApp::GetHillsNormal(float x, float z)const
{// n = (-df/dx, 1, -df/dz)XMFLOAT3 n( -0.03f*z*cosf(0.1f*x) - 0.3f*cosf(0.1f*z),1.0f,-0.3f*sinf(0.1f*x) + 0.03f*x*sinf(0.1f*z));XMVECTOR unitNormal = XMVector3Normalize(XMLoadFloat3(&n));XMStoreFloat3(&n, unitNormal);return n;
}

水面的法向矢量以类似的方式完成, 可以使用有限差分方案来近似每个顶点处的切向量。

更新灯光方向

我们的Lights数组被放入per-pass常量缓冲区, 该案例使用一个方向灯来表示太阳,并允许用户使用向左,向右,向上和向下箭头键旋转太阳位置。 因此,每一帧,我们都需要从太阳计算新的光方向,并将其设置为通道常量缓冲区。
我们以球坐标(ρ,θ,φ)跟踪太阳位置,但半径ρ无关紧要,因为我们假设太阳是无限远的。 特别是,我们只使用ρ= 1使其位于单位球面上并将(1,θ,φ)解释为朝向太阳的方向,以下是更新太阳的相关代码。

float mSunTheta = 1.25f*XM_PI;
float mSunPhi = XM_PIDIV4;void LitWavesApp::OnKeyboardInput(const GameTimer& gt)
{const float dt = gt.DeltaTime();if(GetAsyncKeyState(VK_LEFT) & 0x8000)mSunTheta -= 1.0f*dt;if(GetAsyncKeyState(VK_RIGHT) & 0x8000)mSunTheta += 1.0f*dt;if(GetAsyncKeyState(VK_UP) & 0x8000)mSunPhi -= 1.0f*dt;if(GetAsyncKeyState(VK_DOWN) & 0x8000)mSunPhi += 1.0f*dt;mSunPhi = MathHelper::Clamp(mSunPhi, 0.1f, XM_PIDIV2);
}void LitWavesApp::UpdateMainPassCB(const GameTimer& gt)
{…XMVECTOR lightDir = -MathHelper::SphericalToCartesian(1.0f, mSunTheta, mSunPhi);XMStoreFloat3(&mMainPassCB.Lights[0].Direction, lightDir);mMainPassCB.Lights[0].Strength = { 0.8f, 0.8f, 0.7f };auto currPassCB = mCurrFrameResource->PassCB.get();currPassCB->CopyData(0, mMainPassCB);
}

Light数组放入per-pass常量缓冲区意味着每个渲染通道不能超过16个(我们支持的最大光数)灯, 这对于Demo来说已经足够了。 然而,对于大型游戏世界来说,这还不够,因为你可以想象有数百个灯光的游戏关卡遍布整个关卡, 解决此问题的一种方法是将Light数组移动到每个对象的常量缓冲区。 然后,对于每个对象,搜索场景并找到影响对象的灯光,并将这些灯光绑定到常量缓冲区。 影响对象的灯光是其体积(点光源和聚光灯锥体)与其相交的灯光, 另一种流行的策略是使用延迟渲染或前向+渲染。

Lighting为我们的着色器程序引入了一个新的材质常量缓冲区, 为了支持这一点,我们需要更新根签名以支持额外的常量缓冲区。 与每个对象常量缓冲区一样,我们使用材质常量缓冲区的根描述符来支持直接绑定常量缓冲区,而不是通过描述符堆。

代码下载地址:链接:https://pan.baidu.com/s/1X0Vikf6qGYGPKU-Nwf-wYA 密码:h79q

这篇关于D3D12渲染技术之光源的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/189514

相关文章

Java中的登录技术保姆级详细教程

《Java中的登录技术保姆级详细教程》:本文主要介绍Java中登录技术保姆级详细教程的相关资料,在Java中我们可以使用各种技术和框架来实现这些功能,文中通过代码介绍的非常详细,需要的朋友可以参考... 目录1.登录思路2.登录标记1.会话技术2.会话跟踪1.Cookie技术2.Session技术3.令牌技

Web技术与Nginx网站环境部署教程

《Web技术与Nginx网站环境部署教程》:本文主要介绍Web技术与Nginx网站环境部署教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、Web基础1.域名系统DNS2.Hosts文件3.DNS4.域名注册二.网页与html1.网页概述2.HTML概述3.

Python Selenium动态渲染页面和抓取的使用指南

《PythonSelenium动态渲染页面和抓取的使用指南》在Web数据采集领域,动态渲染页面已成为现代网站的主流形式,本文将从技术原理,环境配置,核心功能系统讲解Selenium在Python动态... 目录一、Selenium技术架构解析二、环境搭建与基础配置1. 组件安装2. 驱动配置3. 基础操作模

Java使用WebView实现桌面程序的技术指南

《Java使用WebView实现桌面程序的技术指南》在现代软件开发中,许多应用需要在桌面程序中嵌入Web页面,例如,你可能需要在Java桌面应用中嵌入一部分Web前端,或者加载一个HTML5界面以增强... 目录1、简述2、WebView 特点3、搭建 WebView 示例3.1 添加 JavaFX 依赖3

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

Java利用JSONPath操作JSON数据的技术指南

《Java利用JSONPath操作JSON数据的技术指南》JSONPath是一种强大的工具,用于查询和操作JSON数据,类似于SQL的语法,它为处理复杂的JSON数据结构提供了简单且高效... 目录1、简述2、什么是 jsONPath?3、Java 示例3.1 基本查询3.2 过滤查询3.3 递归搜索3.4

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2

详解如何在React中执行条件渲染

《详解如何在React中执行条件渲染》在现代Web开发中,React作为一种流行的JavaScript库,为开发者提供了一种高效构建用户界面的方式,条件渲染是React中的一个关键概念,本文将深入探讨... 目录引言什么是条件渲染?基础示例使用逻辑与运算符(&&)使用条件语句列表中的条件渲染总结引言在现代

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

金融业开源技术 术语

金融业开源技术  术语 1  范围 本文件界定了金融业开源技术的常用术语。 本文件适用于金融业中涉及开源技术的相关标准及规范性文件制定和信息沟通等活动。