D3D12渲染技术之纹理案例

2023-10-11 16:59

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

我们现在回顾一下将纹理添加到箱子模型上面,就跟以前的博客中提到的那样。下面我们详细介绍如何实现?

指定纹理坐标

GeometryGenerator :: CreateBox生成箱子的纹理坐标,以便将整个纹理图像映射到箱子的每个面上。 为简洁起见,我们仅显示正面,背面和顶面的顶点定义。 另请注意,我们省略了顶点构造函数中法线和切线向量的坐标(纹理坐标以粗体显示)。

GeometryGenerator::MeshData GeometryGenerator::CreateBox(float width, float height, float depth, uint32 numSubdivisions)
{MeshData meshData;Vertex v[24];float w2 = 0.5f*width;float h2 = 0.5f*height;float d2 = 0.5f*depth;// Fill in the front face vertex data.v[0] = Vertex(-w2, -h2, -d2, …, 0.0f, 1.0f);v[1] = Vertex(-w2, +h2, -d2, …, 0.0f, 0.0f);v[2] = Vertex(+w2, +h2, -d2, …, 1.0f, 0.0f);v[3] = Vertex(+w2, -h2, -d2, …, 1.0f, 1.0f);// Fill in the back face vertex data.v[4] = Vertex(-w2, -h2, +d2, …, 1.0f, 1.0f);v[5] = Vertex(+w2, -h2, +d2, …, 0.0f, 1.0f);v[6] = Vertex(+w2, +h2, +d2, …, 0.0f, 0.0f);v[7] = Vertex(-w2, +h2, +d2, …, 1.0f, 0.0f);// Fill in the top face vertex data.v[8] = Vertex(-w2, +h2, -d2, …, 0.0f, 1.0f);v[9] = Vertex(-w2, +h2, +d2, …, 0.0f, 0.0f);v[10] = Vertex(+w2, +h2, +d2, …, 1.0f, 0.0f);v[11] = Vertex(+w2, +h2, -d2, …, 1.0f, 1.0f);

创建纹理

我们在初始化时从文件创建纹理,如下所示:

// Helper structure to group data related to the texture.
struct Texture
{// Unique material name for lookup.std::string Name;std::wstring Filename;Microsoft::WRL::ComPtr<ID3D12Resource> Resource = nullptr;Microsoft::WRL::ComPtr<ID3D12Resource> UploadHeap = nullptr;};std::unordered_map<std::string, std::unique_ptr<Texture>> mTextures;void CrateApp::LoadTextures()
{auto woodCrateTex = std::make_unique<Texture>();woodCrateTex->Name = "woodCrateTex";woodCrateTex->Filename = L"Textures/WoodCrate01.dds";ThrowIfFailed(DirectX::CreateDDSTextureFromFile12(md3dDevice.Get(),mCommandList.Get(), woodCrateTex->Filename.c_str(),woodCrateTex->Resource, woodCrateTex->UploadHeap));mTextures[woodCrateTex->Name] = std::move(woodCrateTex);
}

我们将所有独特纹理存储在无序地图中,以便我们可以按名称查找它们。 在代码中,在加载纹理之前,需要检查纹理数据是否已经加载(即,它是否已经包含在无序映射中),以便它不会多次加载。

设置纹理

一旦创建了纹理并在描述符堆中为它创建了SRV,将纹理绑定到管道以便可以在着色器程序中使用它只需将其设置为需要纹理的根签名参数:

// Get SRV to texture we want to bind.
CD3DX12_GPU_DESCRIPTOR_HANDLE tex(
mSrvDescriptorHeap->GetGPUDescriptorHandleForHeapStart());
tex.Offset(ri->Mat->DiffuseSrvHeapIndex, mCbvSrvDescriptorSize);…// Bind to root parameter 0. The root parameter description specifies which 
// shader register slot this corresponds to.
cmdList->SetGraphicsRootDescriptorTable(0, tex);

纹理转换

我们没有讨论过的两个常量缓冲区变量是gTexTransform和gMatTransform。 这些变量在顶点着色器中用于变换输入纹理坐标:

在这里插入代码片// Output vertex attributes for interpolation across triangle.
float4 texC = mul(float4(vin.TexC, 0.0f, 1.0f), gTexTransform);
vout.TexC = mul(texC, gMatTransform).xy;

纹理坐标表示纹理平面中的2D点, 因此,我们可以像任何其他点一样平移,旋转和缩放它们, 以下是转换纹理的一些示例用法:
1、砖纹理沿墙壁被拉伸, 墙顶点当前具有范围[0,1]中的纹理坐标。 我们将纹理坐标放大4倍,以将它们放大到范围[0,4],这样纹理将在墙上重复四到四次。
2、天空飘动的云层, 通过将纹理坐标转换为时间的函数,云在天空上就可以飘动了。
3、纹理旋转有时对粒子效果非常有用,例如,我们会随着时间的推移旋转火球纹理。

在本篇博客提供的案例中,我们使用单位矩阵变换,以便输入纹理坐标保持不变,但在下篇博客中,我们将解释使用纹理变换的演示。

请注意,要将2D纹理坐标转换为4×4矩阵,我们将其扩展为4D矢量:

vin.TexC ---> float4(vin.Tex, 0.0f, 1.0f)

在乘法完成之后,通过丢弃z分量和w分量将得到的4D矢量转回到2D矢量。

vout.TexC = mul(float4(vin.TexC, 0.0f, 1.0f), gTexTransform).xy;

我们使用两个单独的纹理变换矩阵gTexTransform和gMatTransform,因为有时它对材质转换纹理(对于像水这样的动画材料)更有意义,但有时它使纹理变换更有意义成为对象的属性。
因为我们正在处理2D纹理坐标,所以我们只关心对前两个坐标进行的转换。 例如,如果纹理矩阵转换了z坐标,则它对结果纹理坐标没有影响。最后给大家看一下实现的Demo:
在这里插入图片描述

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

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



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

相关文章

六个案例搞懂mysql间隙锁

《六个案例搞懂mysql间隙锁》MySQL中的间隙是指索引中两个索引键之间的空间,间隙锁用于防止范围查询期间的幻读,本文主要介绍了六个案例搞懂mysql间隙锁,具有一定的参考价值,感兴趣的可以了解一下... 目录概念解释间隙锁详解间隙锁触发条件间隙锁加锁规则案例演示案例一:唯一索引等值锁定存在的数据案例二:

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

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

MySQL 表的内外连接案例详解

《MySQL表的内外连接案例详解》本文给大家介绍MySQL表的内外连接,结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录表的内外连接(重点)内连接外连接表的内外连接(重点)内连接内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我

Java Stream.reduce()方法操作实际案例讲解

《JavaStream.reduce()方法操作实际案例讲解》reduce是JavaStreamAPI中的一个核心操作,用于将流中的元素组合起来产生单个结果,:本文主要介绍JavaStream.... 目录一、reduce的基本概念1. 什么是reduce操作2. reduce方法的三种形式二、reduce

Spring Boot 整合 Redis 实现数据缓存案例详解

《SpringBoot整合Redis实现数据缓存案例详解》Springboot缓存,默认使用的是ConcurrentMap的方式来实现的,然而我们在项目中并不会这么使用,本文介绍SpringB... 目录1.添加 Maven 依赖2.配置Redis属性3.创建 redisCacheManager4.使用Sp

springboot项目redis缓存异常实战案例详解(提供解决方案)

《springboot项目redis缓存异常实战案例详解(提供解决方案)》redis基本上是高并发场景上会用到的一个高性能的key-value数据库,属于nosql类型,一般用作于缓存,一般是结合数据... 目录缓存异常实践案例缓存穿透问题缓存击穿问题(其中也解决了穿透问题)完整代码缓存异常实践案例Red

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

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

Nginx使用Keepalived部署web集群(高可用高性能负载均衡)实战案例

《Nginx使用Keepalived部署web集群(高可用高性能负载均衡)实战案例》本文介绍Nginx+Keepalived实现Web集群高可用负载均衡的部署与测试,涵盖架构设计、环境配置、健康检查、... 目录前言一、架构设计二、环境准备三、案例部署配置 前端 Keepalived配置 前端 Nginx

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