Directx3D
DirectX11--深入理解与使用2D纹理资源
DirectX11--HLSL语法入门
介绍
在VS2019中,选择【使用C++的桌面开发】会默认选中一个叫做Windows 10 SDK的组件。这个SDK已经集成DirectX的开发库。
XNA数学库
缩放
XMMatrixScaling
// 调用 XMMatrixScaling() 函数用以生成缩放矩阵, 该函数 3 个参数分别表示
// 在 X, Y, Z 轴上的缩放量
// 在 X, Y, Z 轴上缩小到 1/5 (即 0.2), 然后将生成的缩放矩阵赋值给 mScal
XMMATRIX mScal = XMMatrixScaling(0.2f, 0.2f, 0.2f);
旋转
XMMatrixRotation*
// 绕 Y 轴旋转 45 度, 即 1/4 PI
// 调用 XMMatrixRotationY() 函数用以生成旋转矩阵, 该函数的参数为旋转的弧度
// XM_PIDIV4 为 XNA 库定义的数据常量表示 1/4 PI
XMMATRIX mRota = XMMatrixRotationY(XM_PIDIV4);
平移
XMMatrixTranslation
// 在 X 轴平移 1 个单位, 在 Y 轴平移 2 个单位, 在 Z 轴平移 -3 个单位
// 调用函数 XMMatrixTranslation() 生成平移矩阵
// 该函数 3 个参数分别表示在 X, Y, Z 轴上的平移量
XMMATRIX mTrans = XMMatrixTranslation(1.0f, 2.0f, -3.0f);
矩阵相乘
XMMatrixMultiply
变换向量
XMVector4Transform
通过矩阵变换一个4D向量,并返回转换后的向量。
参考: 《基于 DirectX11 的 3D 图形程序设计案例教程》学习二 MatrixTrans
Directx3D龙书记录
输入装配阶段
输入装配(Input Assembler,简称IA)阶段从内存读取几何数据(顶点和索引)并将这些数据组合为几何图元(例如,三角形、直线)
图元拓扑
通过指定图元拓扑来告诉Direct3D以何种方式组成几何图元。
void ID3D11Device::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topology);
顶点着色器阶段
在完成图元装配后,顶点将被送往顶点着色器(vertex shader)阶段。顶点着色器可以被看成是一个以顶点作为输入输出数据的函数。每个将要绘制的顶点都会通过顶点着色器推送至硬件;实际上,我们可以概念性地认为在硬件上执行了如下代码:
for(UINT i = 0; i < numVertices; ++i)
outputVertex[i] = VertexShader(inputVertex[i]);
顶点着色器函数由我们自己编写,但是它会在GPU上运行,所以执行速度非常快。
许多效果,比如变换(transformation)、光照(lighting)和置换贴图映射(displacement mapping)都是由顶点着色器来实现的。记住,在顶点着色器中,我们不仅可以访问输入的顶点数据,也可以访问在内存中的纹理和其他数据,比如变换矩阵和场景灯光。
Direct3D也希望我们将深度坐标映射到一个规范化区间[0,1]中。
规范化设备坐标(NDC)
透视投影矩阵
透视投影矩阵可由如下XNA函数生成:
XMMATRIX XMMatrixPerspective FovLH(// returns projection matrix
FLOAT FovAngleY, // vertical field of view angle in radians
FLOAT AspectRatio, // aspect ratio = width / height
FLOAT NearZ, // distance to near plane
FLOAT FarZ); // distance to far plane
下面的代码片段示范了XMMatrixPerspectiveFovLH函数的使用方法。这里,我们将垂直视域角设为45°,近平面z设为1,远平面z设为1000(这些长度是在观察空间中的)。
XMMATRIX P = XMMatrixPerspectiveFovLH(0.25f*MathX::Pi,
AspectRatio(),1.0f,1000.0f);
float D3Dapp::AspectRatio() const
{
return static_cast<float>(mClientWidth)/mClientHeight;
}
几何着色器阶段
几何着色器以完整的图元作为输入数据。例如,当我们绘制三角形列表时,输入到几何着色器的数据是构成三角形的三个点。(注意,这三个点是从顶点着色器传递过来的。)几何着色器的主要优势是它可以创建或销毁几何体。例如,输入图元可以被扩展为一个或多个其他图元,或者几何着色器可以根据某些条件拒绝输出某些图元。这一点与顶点着色器有明显的不同:顶点着色器无法创建顶点,只要输入一个顶点,那么就必须输出一个顶点。几何着色器通常用于将一个点扩展为一个四边形,或者将一条线扩展为一个四边形。
光栅化阶段
光栅化(rasterization)阶段的主要任务是为投影后的3D三角形计算像素颜色。
视口变换
在裁剪之后,硬件会自动执行透视除法,将顶点从齐次裁剪空间变换到规范化设备空间(NDC)。一旦顶点进入NDC空间,构成2D图像的2D x、y坐标就会被变换到后台缓冲区中的一个称为视口的矩形区域内。在该变换之后,x、y坐标将以像素为单位。通常,视口变换不修改z坐标,因为z坐标还要由深度缓存使用,但是我们可以通过D3D11_VIEWPORT结构体的MinDepth和MaxDepth值修改z坐标的取值范围。MinDepth和MaxDepth的值必须在0和1之间。
顶点属性插值
除位置外,顶点还可以包含其他属性,比如颜色、法线向量和纹理坐标。在视口变换之后,这些属性必须为三角形表面上的每个像素进行插值。顶点深度值也必须进行插值,以使每个像素都有一个可用于深度缓存算法的深度值。对屏幕空间中的顶点属性进行插值,其实就是对3D空间中的三角形表面进行线性插值(如图5.33所示);这一工作需要借助所谓的透视矫正插值(perspective correct interpolation)来实现。本质上,三角形表面内部的像素颜色都是通过顶点插值得到的。
图5.34
图5.34 一条3D线被投影到投影窗口上(在屏幕空间中投影是一条2D线)。我们看到,在3D线上取等距离的点,在2D屏幕空间上的投影点却不是等距离的。所以,我们在3D空间中执行线性插值,在屏幕空间需要执行非线性插值。
像素着色器阶段
像素着色器会处理每个像素片段(pixel fragment),它的输入是插值后的顶点属性,由此计算出一个颜色。
输出合并阶段
当像素片段由像素着色器生成之后,它们会被传送到渲染管线的输出合并(output merger,简称OM)阶段。在该阶段中,某些像素片段会被丢弃(例如,未能通过深度测试或模板测试)。未丢弃的像素片段会被写入后台缓冲区。混合(blending)工作是在该阶段中完成的,一个像素可以与后台缓冲区中的当前像素进行混合,并以混合后的值作为该像素的最终颜色。某些特殊效果,比如透明度,就是通过混合来实现的
chili教程记录
chili的原版英文教程-中文字幕
chili的原版英文教程
模板继承
在第20讲大约13:40中讲到,如果一个子类模板,继承的父类也是一个模板,并且子类需要使用父类模板的父类中的方法,则需要显示指明,如下:
class Bindable
{
public:
virtual void Bind( Graphics& gfx ) noexcept = 0;
virtual ~Bindable() = default;
protected:
static ID3D11DeviceContext* GetContext( Graphics& gfx ) noexcept;
static ID3D11Device* GetDevice( Graphics& gfx ) noexcept;
static DxgiInfoManager& GetInfoManager( Graphics& gfx ) noexcept(IS_DEBUG);
};
template<typename C>
class ConstantBuffer : public Bindable
{
....
}
template<typename C>
class VertexConstantBuffer : public ConstantBuffer<C>
{
using ConstantBuffer<C>::pConstantBuffer;
using Bindable::GetContext;
public:
void Bind( Graphics& gfx ) noexcept override
{
// 这里这个GetContext需要显示指明
// 1. 使用using Bindable::GetContext;
// 2. 使用this->GetContext
// 3. 使用域作用符Bindable::GetContext
GetContext( gfx )->VSSetConstantBuffers( 0u,1u,pConstantBuffer.GetAddressOf() );
}
};