D3D12渲染技术之顶点着色器
相信大家以前用过D3D9的或是编写过Shader的对顶点着色器都比较了解,现在我们回顾一下:
cbuffer cbPerObject : register(b0)
{float4x4 gWorldViewProj;
};void VS(float3 iPosL : POSITION, float4 iColor : COLOR, out float4 oPosH : SV_POSITION,out float4 oColor : COLOR)
{// Transform to homogeneous clip space.oPosH = mul(float4(iPosL, 1.0f), gWorldViewProj);// Just pass vertex color into the pixel shader.oColor = iColor;
}
Shader的编程语言我们称为HLSL(the high level shading language),语法跟C++类似,比较容易学习。我们教HLSL和编程着色器的方法将以示例为基础, 也就是说,随着博客的进展,我们将介绍需要的任何新的HLSL概念,以便实现Demo的演示, 着色器脚本通常用基于文本的文件编写,扩展名为.hlsl。
顶点着色器是名为VS的函数, 请注意,可以为顶点着色器指定任何有效的函数名称, 该顶点着色器有四个参数; 前两个是输入参数,后两个是输出参数(由out关键字表示)。 HLSL没有引用或指针,因此要从函数返回多个值,需要使用结构或输出参数, 在HLSL中,函数始终内联。
前两个输入参数构成顶点着色器的输入签名,并对应于我们用于绘制的自定义顶点结构中的数据成员。 参数语义“:POSITION”和“:COLOR”用于将顶点结构中的元素映射到顶点着色器输入参数,如下图所示。
每个顶点元素都有一个由D3D12_INPUT_ELEMENT_DESC数组指定的相关语义, 顶点着色器的每个参数也具有附加的语义, 语义用于将顶点元素与顶点着色器参数进行匹配。
输出参数也有附加的语义(“:SV_POSITION”和“:COLOR”),这些用于将顶点着色器输出映射到下一级的相应输入(几何着色器或像素着色器)。 请注意,SV_POSITION语义是特殊的(SV代表系统值), 它用于表示在裁剪空间中保存顶点位置的顶点着色器输出元素。 我们必须将SV_POSITION语义附加到位置输出,因为GPU需要知道这个值,因为它涉及其他属性不涉及的操作,例如裁剪,深度测试和光栅化, 非系统值的输出参数的语义名称可以是任何命名有效的语义名称。
第一行通过乘以4×4矩阵gWorldViewProj将顶点位置从局部空间转换为均匀裁剪空间:
oPosH = mul(float4(iPosL, 1.0f), gWorldViewProj);
使用构造函数语法float4(iPosL,1.0f)构造一个4D向量,相当于float4(iPosL.x,iPosL.y,iPosL.z,1.0f); 因为我们知道顶点的位置是点而不是矢量,所以我们在第四个分量中放置1(w = 1)。 float2和float3类型分别代表2D和3D向量。 矩阵变量gWorldViewProj存在于所谓的常量缓冲区中,这将在后面讨论。 内置函数mul用于向量矩阵乘法。 顺便提一下,对于不同大小的矩阵乘法,mul函数是重载的; 例如,可以使用它来乘以两个4×4矩阵,两个3×3矩阵,或1×3矢量和3×3矩阵。 着色器主体中的最后一行只是将输入颜色复制到输出参数,以便将颜色输入到管道的下一个阶段:
oColor = iColor;
我们可以使用返回类型和输入签名的结构(而不是长参数列表)重写上面的顶点着色器:
cbuffer cbPerObject : register(b0)
{float4x4 gWorldViewProj;
};struct VertexIn
{float3 PosL : POSITION;float4 Color : COLOR;
};struct VertexOut
{float4 PosH : SV_POSITION;float4 Color : COLOR;
};VertexOut VS(VertexIn vin)
{VertexOut vout;// Transform to homogeneous clip space.vout.PosH = mul(float4(vin.PosL, 1.0f), gWorldViewProj);// Just pass vertex color into the pixel shader.vout.Color = vin.Color;return vout;}
注意:
如果没有几何着色器(后面介绍几何着色器),则顶点着色器必须使用SV_POSITION语义输出到裁剪空间中的顶点位置,因为这是硬件在离开顶点时期望顶点所在的空间 着色器(如果没有几何着色器)。 如果存在几何着色器,则输出裁剪空间位置可以推迟到几何着色器。
顶点着色器(或几何着色器)不执行透视处理, 它只是投影矩阵部分。,透视处理将在稍后由硬件完成。
在管道的顶点属性之间存在链接,该属性由输入布局描述定义。 如果输入的顶点不提供顶点着色器所需的所有输入,则会产生错误。 例如,以下顶点着色器输入签名和顶点数据不兼容:
//--------------
// C++ app code
//--------------
struct Vertex
{XMFLOAT3 Pos;XMFLOAT4 Color;
};D3D12_INPUT_ELEMENT_DESC desc[] =
{{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_PER_VERTEX_DATA, 0},{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_PER_VERTEX_DATA, 0}
};//--------------
// Vertex shader
//--------------
struct VertexIn
{float3 PosL : POSITION;float4 Color : COLOR;float3 Normal : NORMAL;
};struct VertexOut
{float4 PosH : SV_POSITION;float4 Color : COLOR;
};
VertexOut VS(VertexIn vin) { … }
当我们创建一个ID3D12PipelineState对象时,我们必须指定输入布局描述和顶点着色器。 然后,Direct3D将验证输入布局描述和顶点着色器是否兼容。
顶点数据和输入签名不需要完全匹配, 所需要的是顶点数据提供顶点着色器所期望的所有数据。 因此,允许顶点数据提供顶点着色器不使用的附加数据。 也就是说,以下是兼容的:
//--------------
// C++ app code
//--------------
struct Vertex
{XMFLOAT3 Pos;XMFLOAT4 Color;XMFLOAT3 Normal;
};D3D12_INPUT_ELEMENT_DESC desc[] =
{{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_PER_VERTEX_DATA, 0},{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_PER_VERTEX_DATA, 0},{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 28, D3D12_INPUT_PER_VERTEX_DATA, 0 }
};//--------------
// Vertex shader
//--------------
struct VertexIn
{float3 PosL : POSITION;float4 Color : COLOR;
};struct VertexOut
{float4 PosH : SV_POSITION;float4 Color : COLOR;
};VertexOut VS(VertexIn vin) { … }
现在考虑的是顶点结构和输入签名具有匹配的顶点元素的情况,但颜色属性的类型是不同的:
//--------------
// C++ app code
//--------------
struct Vertex
{XMFLOAT3 Pos;XMFLOAT4 Color;
};D3D12_INPUT_ELEMENT_DESC desc[] =
{{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_PER_VERTEX_DATA, 0},{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_PER_VERTEX_DATA, 0}
};//--------------
// Vertex shader
//--------------
struct VertexIn
{float3 PosL : POSITION;int4 Color : COLOR;
};struct VertexOut
{float4 PosH : SV_POSITION;float4 Color : COLOR;
};VertexOut VS(VertexIn vin) { … }
这实际上是合法的,因为Direct3D允许重新解释输入寄存器中的位。 但是,VC ++调试输出窗口提供以下警告:
D3D12 WARNING: ID3D11Device::CreateInputLayout: The provided input signature expects to read an element with SemanticName/Index: ‘COLOR’/0 and component(s) of the type ‘int32’. However, the matching entry in the Input Layout declaration, element[1], specifies mismatched format: ‘R32G32B32A32_FLOAT’.
这不是错误。。。。。。。。。
D3D12渲染技术之顶点着色器相关推荐
- opengl 纹理贴到对应的位置_一步步学OpenGL(27) -《公告牌技术与几何着色器》
教程 27 公告牌技术与几何着色器 原文: http://ogldev.atspace.co.uk/www/tutorial27/tutorial27.html CSDN完整版专栏: https:// ...
- 渲染 光栅化 光线追踪 着色器 投影视图模型矩阵 未来VR关键技术
渲染介绍得非常详细易懂(强烈建议观看):https://www.zhihu.com/question/31971846/answer/36727962 https://www.zhihu.com/qu ...
- D3D12渲染技术之渲染管线
渲染管线指的是通过虚拟相机看到的内容生成2D图像的整个步骤序列,在博客D3D12渲染技术概述中介绍过渲染管线,本篇博客具体讲解各个模块的作用,先看下图所示: Input Assembler Stage ...
- D3D12渲染技术之常量缓冲区
常量缓冲区是GPU资源(ID3D12Resource),其数据内容可以在着色器程序中引用,正如我们将在博客中学到的,纹理和其他类型的缓冲区资源也可以在着色器程序中引用.顶点着色器具有以下代码: cbu ...
- 3D可视化开发(基于顶点着色器和片元着色器)
3D可视化开发(基于顶点着色器和片元着色器) 背景:最近在做大屏的3d地图可视化开发,技术采用three.js+glsl这样的是一种实现方式,其中使用glsl实现顶点着色器和片元着色器. GLSL G ...
- opengl之高级GLSL(1)-顶点着色器变量与片段着色器变量
官方教程位置 openglCN GLSL的内建变量: 我们已经学会使用顶点属性.uniform和采样器来完成这一任务了.然而,除此之外,GLSL还定义了另外几个以gl_为前缀的变量,它们能提供给我们更 ...
- Unity Shader:细分着色器(Tessellation Shader)在Unity顶点着色器中的写法以及各参数变量解释
图1:在Unity内将sphere细分后 图2:在Unity内将sphere细分后 Unity官网关于细分着色器的资料比较少,只有在Surface Shader中使用的例子.我看了下Surface S ...
- Learn OpenGL(三)——顶点着色器(Vertext Shader)
顶点着色器是几个着色器中的一个, 它是可编程的. 现代OpenGL需要我们至少设置一个顶点着色器和一个片段着色器, 如果我们打算做渲染的话. 我们会简要介绍一下着色器以及配置两个非常简单的着色器来绘制 ...
- D3D12渲染技术之编译Shader
很多人只知道写Shader,但是并不了解DX或者OpenGL是如何编译Shader的,我们写的Shader是一种文本文件,它可以被DX或者OpenGL读取,说明它们提供了接口编译Shader.3D引擎 ...
最新文章
- asp.net访问被拒绝,程序集无法加载原因与解决方法[摘录]
- 半编译半解释的Java语言和C++、Python等语言的区别
- 字符串匹配算法(二):BM(BoyerMoore)算法、坏字符规则,好后缀规则
- php 将字符串打乱,PHP内部实现打乱字符串顺序函数str_shuffle的方法
- java代码块是对象吗_面向对象(Java中普通代码块,构造代码块,静态代码块区别及代码示例)...
- Spark源码分析之Master资源调度算法原理
- 响应式布局技术:App如何适配不同尺寸的设备
- 11-7 无底洞问题
- 《Effective Java 3rd》读书笔记——对于所有对象都通用的方法
- JavaScript:typeof的用法以及undefined和null的区别
- jbox弹窗_关于使用 jBox 对话框的提交不能弹出问题解决方法
- 计算机设置调整吃鸡,绝地求生韦神托马斯主播的电脑画面设置灵敏度_绝地求生主播的电脑画面设置和灵敏度介绍_游戏吧...
- 6款办公软件,文案人员常用到
- 时间字符串转中国标准时间转时间戳转年月日格式
- app软件系统开发好后有哪些盈利方式?
- centos安装minikube
- 使用Visual Studio调试BGFX的Shader
- 《20个月赚30个亿-陈士骏自传》读后感
- js网页导出excel表格文件
- 小波变换 wavelet 2
热门文章
- bzoj4455UOJ185 [Zjoi2016]小星星(树形DP+容斥原理)
- 多层感知器的基本特征
- photoshop ps 美白 去污 磨皮 方法
- Android_微信分享时提示“签名不对,请检查签名是否与开放平台上填写的一致。”
- Mac上解决外接magic Mouse 2等鼠标移动速度慢的问题
- apple magic mouse 鼠标 windows 下如何设置滚轮方向 使其 和 mac 一致
- 福禄克FLUKE FTK1475,FTK1450,FTK1375等配件和功能区别分析
- Python读取上证指数csv
- vbs(Visual Basic Script) 笔记
- 安卓开发开发规范手册V1.0