本文是DirectX11 With Windows SDK--09 纹理映射与采样器状态的课后作业
答案仅供参考
原文链接:DirectX11 With Windows SDK--09 纹理映射与采样器状态
自己动手将过滤器修改为常量插值法、线性插值法、各向异性过滤,观察立方体盒的效果
按照要求修改即可
尝试在使用Geometry::MeshData创建的立方体网格数据(不能对其修改)的基础上,让立方体的六个面使用不同的纹理来绘制,可以使用魔方项目里的纹理
//1. GameApp.h 中添加 std::vector<ComPtr<ID3D11ShaderResourceView>> m_pWoodCrates; // //2. InitResource() 函数中添加 纹理集 m_pWoodCrates.resize(6); for (int i = 1; i <= 6; ++i) { wsprintf(strFile, L"..\\Texture\\FireAnim\\Fire%03d.bmp", i); HR(CreateWICTextureFromFile(m_pd3dDevice.Get(), strFile, nullptr, m_pWoodCrates[static_cast<size_t>(i) - 1].GetAddressOf())); } //3. 在DrawScene() 中添加 for (int j = 0; j < 6; j++) { m_pd3dImmediateContext->PSSetShaderResources(0, 1, m_pWoodCrates[j].GetAddressOf()); m_pd3dImmediateContext->DrawIndexed(j*6+6, 0, 0); }
使用教程项目第26章Texture文件夹中的flare.dds和flarealpha.dds,在着色器中通过分量乘法实现
//1. GameApp.h 中添加 ComPtr<ID3D11ShaderResourceView> m_pFlare; // 旋转纹理 ComPtr<ID3D11ShaderResourceView> m_pFlarealpha; // 修改 VSConstantBuffer struct VSConstantBuffer { DirectX::XMMATRIX world; DirectX::XMMATRIX view; DirectX::XMMATRIX proj; DirectX::XMMATRIX worldInvTranspose; DirectX::XMMATRIX Tex; }; //2.InitResource() 中添加 // 初始化旋转纹理 HR(CreateDDSTextureFromFile(m_pd3dDevice.Get(), L"..\\Texture\\flare.dds", nullptr, m_pFlare.GetAddressOf())); HR(CreateDDSTextureFromFile(m_pd3dDevice.Get(), L"..\\Texture\\flarealpha.dds", nullptr, m_pFlarealpha.GetAddressOf())); // 在设置采样器的时候添加 m_pd3dImmediateContext->PSSetSamplers(1, 1, m_pSamplerState.GetAddressOf()); //3. 在UpdateScene() 更新缓冲区添加 m_VSConstantBuffer.Tex = XMMatrixTranspose(XMMatrixRotationZ(phi)); //4. DrawScene 中添加 设置 纹理 m_pd3dImmediateContext->PSSetShaderResources(0, 1, m_pFlare.GetAddressOf()); m_pd3dImmediateContext->PSSetShaderResources(1, 1, m_pFlarealpha.GetAddressOf()); //5. 修改着色器 //Basic.hlsli中修改 VSConstantBuffer cbuffer VSConstantBuffer : register(b0) { matrix g_World; matrix g_View; matrix g_Proj; matrix g_WorldInvTranspose; // 纹理旋转 matrix Tex; } //添加 Texture2D g_Tex1 : register(t1); SamplerState g_SamLinear1 : register(s1); //Basic_VS_3D.hlsl 中添加 vOut.Tex = mul(float4(vIn.Tex.x - 0.5f, vIn.Tex.y - 0.5f, 1.0f, 1.0f),Tex).xy; vOut.Tex += 0.5f; // 修改Basic_PS_3D.hlsl中的return return g_Tex.Sample(g_SamLinear, pIn.Tex) * g_Tex1.Sample(g_SamLinear1, pIn.Tex);
如果你阅读过"深入理解与使用2D纹理资源"这篇,那么尝试用一个纹理数组存储所有的火焰纹理,在HLSL中使用Texture2DArray
//1. GameApp.h 中添加 ComPtr<ID3D11ShaderResourceView> m_pFire; // 火焰纹理集 // 2.修改代码片段 // 初始化火焰纹理 WCHAR strFile[40]; std::vector<std::wstring> fileNames; fileNames.resize(120); m_pFireAnims.resize(120); for (int i = 1; i <= 120; ++i) { if (i <10) { fileNames[i - 1] = L"..\\Texture\\FireAnim\\Fire00" + std::to_wstring(i) + L".bmp"; } else if (i >= 10 && i < 100) { fileNames[i - 1] = L"..\\Texture\\FireAnim\\Fire0" + std::to_wstring(i) + L".bmp"; } else { fileNames[i - 1] = L"..\\Texture\\FireAnim\\Fire" + std::to_wstring(i) + L".bmp"; } wsprintf(strFile, L"..\\Texture\\FireAnim\\Fire%03d.bmp", i); HR(CreateWICTextureFromFile(m_pd3dDevice.Get(), strFile, nullptr, m_pFireAnims[static_cast<size_t>(i) - 1].GetAddressOf())); } // 要先在util.h .cpp 中添加相应的方法 HR(CreateTexture2DArrayFromFile(m_pd3dDevice.Get(), m_pd3dImmediateContext.Get(), fileNames, nullptr, m_pFire.GetAddressOf())); //3.修改代码片段 else if (m_CurrMode == ShowMode::FireAnim) { // 用于限制在1秒60帧 static float totDeltaTime = 0; totDeltaTime += dt; if (totDeltaTime > 1.0f / 60) { totDeltaTime -= 1.0f / 60; m_CurrFrame = (m_CurrFrame + 1) % 120; //m_pd3dImmediateContext->PSSetShaderResources(1, 1, m_pFire.GetAddressOf()); // 利用多余的变量pad进行传参 m_PSConstantBuffer.pad = m_CurrFrame; D3D11_MAPPED_SUBRESOURCE mappedData; HR(m_pd3dImmediateContext->Map(m_pConstantBuffers[1].Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedData)); memcpy_s(mappedData.pData, sizeof(m_PSConstantBuffer), &m_PSConstantBuffer, sizeof(m_PSConstantBuffer)); m_pd3dImmediateContext->Unmap(m_pConstantBuffers[1].Get(), 0); } } //4.shader中修改 Texture2DArray gTexArray : register(t1);//basic.hlsli // basic_PS_3D.hlsl float4 texColor = gTexArray.Sample(g_SamLinear1, float3(pIn.Tex, pad)); return texColor;