Directx11教程二十七之Tessellation(曲面细分)
2016-10-27 01:18
288 查看
先看看本节教程的结构吧
这里看此放出D3D11的3D渲染管线图:
看红色画圈部分的都属于“Tessellation(曲面细分阶段)”,分别为:HullShader(HS) Stage,TessellatorStage,DomainShader(DS)Stage,
D3D11程序普通情况下渲染管线的流程是:
加入曲面细分后,渲染流程变为:
放出Shader代码:
ColorShader.fx
说说上面HullShader和DomainShader关键字
(1) domain:补丁类型(the patch type),实参可以是tri,quad,或者isoline
(2)partitioning:指定曲面细分的细分模式,实参可以是integer,fractional_even,fractional_odd
(3)outputtopology:通过曲面细分新创建的三角形的绕线方向
(a) triangle_cw:顺时针绕线方向
(b)triangle_ccw:逆时针绕线方向
(c)line: 线性曲面细分
(4) outputcontrolpoints:HullShader(外壳着色器)执行的次数,每次输出一个控制点.系统值SV_OutputControlPointID给予了一个下标值,这个下标值标识了HullShader(外壳着色器)正在处理的输出控制点(0utputControlpoint)
(5)patchconstantfunc(补丁常量函数):HullShader常量函数的函数名字,为一个字符串
(6)maxtessfactor:驱动的控制线索指定了你的着色器可以使用的最大的曲面细分因子。如果知道这个值的上限,可以通过硬件进行潜在的优化,因此这个因子指明了曲面细分需要使用多少资源。被D3D11硬件支持最大的曲面细分因子为64.
三角形补丁曲面细分的例子(Triangle Patch Tessellation examples):
四边形补丁曲面细分的例子(Quad Patch Tessellation examples):
创建VertexShader,PixelShader,HullShader,DomainShader
设定VertexShader,PixelShader,HullShader,DomainShader
这里我的EdgeTess和InsideTess都是4
程序运行图:
下面放出我的源代码链接:
http://download.csdn.net/detail/qq_29523119/9665102
一,曲面细分的介绍。
这里先链接一篇关于曲面细分的文章 http://blog.csdn.net/qq_29523119/article/details/52914370,算是对曲面细分大概的科普吧.这里看此放出D3D11的3D渲染管线图:
看红色画圈部分的都属于“Tessellation(曲面细分阶段)”,分别为:HullShader(HS) Stage,TessellatorStage,DomainShader(DS)Stage,
D3D11程序普通情况下渲染管线的流程是:
加入曲面细分后,渲染流程变为:
放出Shader代码:
ColorShader.fx
/*-------------常量缓存---------------------*/ cbuffer CBMatrix:register(b0) { matrix World; matrix View; matrix Proj; }; cbuffer CBTessellation:register(b1) { float TessellationAmount; float3 pad; }; /*--------------各个阶段输入输出的结构体--------------------*/ //从IA阶段输出的 struct VertexIn { float3 Pos:POSITION; float4 color:COLOR; }; //从VertexShader输出的 struct HullIn { float3 Pos:POSITION; float4 color:COLOR; }; //从HullShader输出的 struct DomainIn { float3 Pos:POSITION; float4 color:COLOR; }; //从DomainShader输出的 struct PixelIn { float4 Pos:SV_POSITION; float4 color:COLOR; }; /*--------------各个Shader阶段的函数--------------------*/ /*VertexShader*/ HullIn VS(VertexIn ina) { HullIn outa; outa.Pos = ina.Pos; outa.color = ina.color; return outa; } /*HullShader */ //HullShader用到的从补丁常量函数输出的值 三角形 struct ConstantOutputType { float edges[3] : SV_TessFactor; float inside : SV_InsideTessFactor; }; //HullShader补丁常量缓存函数 ConstantOutputType ColorPathConstantFunction(InputPatch<HullIn, 3> inputPatch, uint patchId : SV_PrimitiveID) { ConstantOutputType outa; //设置三角形三条边的曲面细分因子 outa.edges[0] = TessellationAmount; outa.edges[1] = TessellationAmount; outa.edges[2] = TessellationAmount; //设置三角形里面的曲面细分因子 outa.inside = TessellationAmount; return outa; } [domain("tri")] //三角形 [partitioning("integer")] //整数 [outputtopology("triangle_cw")] //顺时针 [outputcontrolpoints(3)] //三个控制点 [patchconstantfunc("ColorPathConstantFunction")] // 补丁常量缓存函数名 DomainIn HS(InputPatch<HullIn, 3> patch, uint pointId : SV_OutputControlPointID, uint patchId : SV_PrimitiveID) { DomainIn outa; //设置HullShader输出的顶点坐标 outa.Pos = patch[pointId].Pos; //设置HullShader输出的颜色 outa.color = patch[pointId].color; return outa; } /*DomainShader*/ [domain("tri")] PixelIn DS(ConstantOutputType input, float3 uvwCoord : SV_DomainLocation, const OutputPatch<DomainIn, 3> patch) { PixelIn outa; float3 vertexPosition; //获取新顶点的位置 vertexPosition = uvwCoord.x * patch[0].Pos + uvwCoord.y * patch[1].Pos + uvwCoord.z * patch[2].Pos; //将坐标变到齐次裁剪空间 outa.Pos = mul(float4(vertexPosition, 1.0f), World); outa.Pos = mul(outa.Pos, View); outa.Pos = mul(outa.Pos, Proj); outa.color = patch[0].color; return outa; } /*PixelShader*/ float4 PS(PixelIn outa) : SV_Target { return outa.color; }
说说上面HullShader和DomainShader关键字
(1) domain:补丁类型(the patch type),实参可以是tri,quad,或者isoline
(2)partitioning:指定曲面细分的细分模式,实参可以是integer,fractional_even,fractional_odd
(3)outputtopology:通过曲面细分新创建的三角形的绕线方向
(a) triangle_cw:顺时针绕线方向
(b)triangle_ccw:逆时针绕线方向
(c)line: 线性曲面细分
(4) outputcontrolpoints:HullShader(外壳着色器)执行的次数,每次输出一个控制点.系统值SV_OutputControlPointID给予了一个下标值,这个下标值标识了HullShader(外壳着色器)正在处理的输出控制点(0utputControlpoint)
(5)patchconstantfunc(补丁常量函数):HullShader常量函数的函数名字,为一个字符串
(6)maxtessfactor:驱动的控制线索指定了你的着色器可以使用的最大的曲面细分因子。如果知道这个值的上限,可以通过硬件进行潜在的优化,因此这个因子指明了曲面细分需要使用多少资源。被D3D11硬件支持最大的曲面细分因子为64.
三角形补丁曲面细分的例子(Triangle Patch Tessellation examples):
四边形补丁曲面细分的例子(Quad Patch Tessellation examples):
创建VertexShader,PixelShader,HullShader,DomainShader
bool ColorShaderClass::InitializeShader(ID3D11Device* d3dDevice, HWND hwnd, WCHAR* VSFileName, WCHAR* PSFileName, WCHAR* HSFileName, WCHAR* DSFileName) { HRESULT result; ID3D10Blob* errorMessage; ID3D10Blob* VertexShaderBuffer; ID3D10Blob* PixelShaderBuffer; ID3D10Blob* HullShaderBuffer; ID3D10Blob* DomainShaderBuffer; //第一,初始化参数 errorMessage = NULL; VertexShaderBuffer=NULL; PixelShaderBuffer=NULL; //第二,编译VertexShader代码,并创建VertexShader result = D3DX11CompileFromFile(VSFileName, NULL, NULL, "VS", "vs_5_0", D3DCOMPILE_ENABLE_STRICTNESS, 0, NULL, &VertexShaderBuffer, &errorMessage, NULL); if (FAILED(result)) { //存在错误信息 if (errorMessage) { OutputShaderErrorMessage(errorMessage, hwnd, VSFileName); } //不存在错误信息,也就是没有找到Shader文件 else { MessageBox(hwnd, L"can not find VS file", L"error", MB_OK); } } HR(d3dDevice->CreateVertexShader(VertexShaderBuffer->GetBufferPointer(),VertexShaderBuffer->GetBufferSize(),NULL,&md3dVertexShader)); //第三,编译HullShader,并创建HullShader result = D3DX11CompileFromFile(HSFileName, NULL, NULL, "HS", "hs_5_0", D3DCOMPILE_ENABLE_STRICTNESS, 0, NULL, &HullShaderBuffer, &errorMessage, NULL); if (FAILED(result)) { //存在错误信息 if (errorMessage) { OutputShaderErrorMessage(errorMessage, hwnd, HSFileName); } //不存在错误信息,也就是没有找到Shader文件 else { MessageBox(hwnd, L"can not find HS file", L"error", MB_OK); } } HR(d3dDevice->CreateHullShader(HullShaderBuffer->GetBufferPointer(), HullShaderBuffer->GetBufferSize(), NULL, &md3dHullShader)); //第四,编译HullShader,并创建DomainShader result = D3DX11CompileFromFile(DSFileName, NULL, NULL, "DS", "ds_5_0", D3DCOMPILE_ENABLE_STRICTNESS, 0, NULL, &DomainShaderBuffer, &errorMessage, NULL); if (FAILED(result)) { //存在错误信息 if (errorMessage) { OutputShaderErrorMessage(errorMessage, hwnd, DSFileName); } //不存在错误信息,也就是没有找到Shader文件 else { MessageBox(hwnd, L"can not find DS file", L"error", MB_OK); } } HR(d3dDevice->CreateDomainShader(DomainShaderBuffer->GetBufferPointer(), DomainShaderBuffer->GetBufferSize(), NULL, &md3dDomainShader)); //第五,编译PixelShader,并创建PixelShader result = D3DX11CompileFromFile(PSFileName, NULL, NULL, "PS", "ps_5_0", D3DCOMPILE_ENABLE_STRICTNESS, 0, NULL, &PixelShaderBuffer, &errorMessage, NULL); if (FAILED(result)) { //存在错误信息 if (errorMessage) { OutputShaderErrorMessage(errorMessage, hwnd, PSFileName); } //不存在错误信息,也就是没有找到Shader文件 else { MessageBox(hwnd, L"can not find PS file", L"error", MB_OK); } } HR(d3dDevice->CreatePixelShader(PixelShaderBuffer->GetBufferPointer(), PixelShaderBuffer->GetBufferSize(), NULL, &md3dPixelShader)) //第六,填充输入布局形容结构体,创建输入布局 D3D11_INPUT_ELEMENT_DESC VertexInputLayout[] = { { "POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0 }, // 96位即12个字节 { "COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0 }, }; unsigned int numElements = sizeof(VertexInputLayout) / sizeof(VertexInputLayout[0]); //布局数量 HR(d3dDevice->CreateInputLayout(VertexInputLayout, numElements, VertexShaderBuffer->GetBufferPointer(), VertexShaderBuffer->GetBufferSize(), &md3dInputLayout)); //第七,释放VertexShaderBuffer和PixelShaderBuffer VertexShaderBuffer->Release(); VertexShaderBuffer = NULL; PixelShaderBuffer->Release(); PixelShaderBuffer = NULL; //第八,设置矩阵(常量)缓存形容结构体,并创建矩阵常量缓存 D3D11_BUFFER_DESC matrixBufferDesc; ZeroMemory(&matrixBufferDesc, sizeof(matrixBufferDesc)); matrixBufferDesc.Usage = D3D11_USAGE_DEFAULT; matrixBufferDesc.ByteWidth = sizeof(CBMatrix); //结构体大小,必须为16字节倍数 matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; matrixBufferDesc.CPUAccessFlags = 0; HR(d3dDevice->CreateBuffer(&matrixBufferDesc, NULL, &mCBMatrixBuffer)); //第九,设置曲面细分(常量)缓存形容结构体,并创建曲面细分常量缓存 D3D11_BUFFER_DESC TesselationBufferDesc; ZeroMemory(&TesselationBufferDesc, sizeof(TesselationBufferDesc)); TesselationBufferDesc.Usage = D3D11_USAGE_DEFAULT; TesselationBufferDesc.ByteWidth = sizeof(CBTessellation); //结构体大小,必须为16字节倍数 TesselationBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; TesselationBufferDesc.CPUAccessFlags = 0; HR(d3dDevice->CreateBuffer(&TesselationBufferDesc, NULL, &mCBTessellationBuffer)); return true; }
设定VertexShader,PixelShader,HullShader,DomainShader
void ColorShaderClass::RenderShader(ID3D11DeviceContext* deviceContext, int indexCount) { //设置顶点输入布局 deviceContext->IASetInputLayout(md3dInputLayout); //设置VertexShader,PixelShader,hullShader,DomainShader deviceContext->VSSetShader(md3dVertexShader, NULL, 0); deviceContext->PSSetShader(md3dPixelShader, NULL, 0); deviceContext->HSSetShader(md3dHullShader, NULL, 0); deviceContext->DSSetShader(md3dDomainShader, NULL, 0); //渲染三角形 deviceContext->DrawIndexed(indexCount, 0, 0); }
这里我的EdgeTess和InsideTess都是4
程序运行图:
下面放出我的源代码链接:
http://download.csdn.net/detail/qq_29523119/9665102
相关文章推荐
- Directx11教程(62) tessellation学习(4)
- Directx11教程(60) tessellation学习(2)
- DirectX11 Tessellation曲面细分实现动态增加模型细节
- Directx11教程(64) tessellation学习(6)-PN Triangles
- Directx11教程(59) tessellation学习(1)
- Directx11教程(61) tessellation学习(3)
- Directx11教程(63) tessellation学习(5)
- Directx11教程九之多重纹理和纹理数组
- Directx11教程(20) 一个简单的水面
- Redis学习记录之集群教程(二十七)
- Directx11教程(14) D3D11管线(3)
- DirectX 11 Tessellation (曲面细分)—什么是 Tessellation (曲面细分) ?它为什么能够起到如此重要的作用?
- Directx11教程(53) D3D11管线(8) GS的调度执行
- Android Studio 使用教程(二十七)之Android Studio 进阶详细配置
- Directx11教程二十一之Water(水的实现)
- Android高手进阶教程(二十七)之---基于ViewFlipper实现的自定义新手指引控件.
- Directx11教程(56) 建立一个skydome
- Directx11教程三十四之ProjectiveLightMap(投影光照图)
- Directx11教程四十四之CascadeShadowMap(层级阴影)(上)
- 史上最简单的 MySQL 教程(二十七)「连接查询(下)」