gpt4 book ai didi

c++ - 无法从 Direct3D 获取抗锯齿图片

转载 作者:行者123 更新时间:2023-11-30 04:57:56 24 4
gpt4 key购买 nike

我正在迈出使用 Direct3D 进行编程的第一步。我有一个非常基本的管道设置,我想从中得到的只是一个抗锯齿的平滑图像。但我明白了:

screenshot首先,尽管我的管道中已经启用了 4x MSAA(DXGI_SAMPLE_DESC::Count 为 4,Quality 为 0),但我无法摆脱阶梯效应: stairs

其次,尽管我在采样器状态下生成了 mipmap 并设置了 LINEAR 过滤,但我还是得到了这种嘈杂的纹理。 noisy texturing

我是否遗漏了什么或做错了什么?

这是我的代码:

1) 渲染器类:

#include "Scene.h" // Custom class that contains vertex and index buffer contents for every rendered mesh.
#include "Camera.h" // Custom class that contains camera position and fov.

#include <wrl/client.h>
using Microsoft::WRL::ComPtr;

#include <DirectXMath.h>
using namespace DirectX;

#include <map>

#include "generated\VertexShader.h"
#include "generated\PixelShader.h"

class Renderer
{
public:
Renderer(HWND hWnd, int wndWidth, int wndHeight, const Scene& scene, const Camera& camera);

void Render();

void SwitchToWireframe();
void SwitchToSolid();

protected:
void CreateDeviceAndSwapChain();
void CreateDepthStencil();
void CreateInputLayout();
void CreateVertexShader();
void CreatePixelShader();
void CreateRasterizerStates();
void CreateBlendState();
void CreateSamplerState();
void CreateBuffer(ID3D11Buffer** buffer,
D3D11_USAGE usage, D3D11_BIND_FLAG bindFlags,
UINT cpuAccessFlags, UINT miscFlags,
UINT sizeOfBuffer, UINT sizeOfBufferElement, const void* initialData);
void CreateTexture2DAndSRV(const Scene::Texture& texture, ID3D11ShaderResourceView** view);
void CreateTexturesAndViews();
void GenerateMips();

protected:
const Scene& m_scene;

const Camera& m_camera;
DWORD m_cameraLastUpdateTickCount;

HWND m_windowHandle;
int m_windowWidth;
int m_windowHeight;

DXGI_SAMPLE_DESC m_sampleDesc;

ComPtr<IDXGISwapChain> m_swapChain;
ComPtr<ID3D11Texture2D> m_swapChainBuffer;
ComPtr<ID3D11RenderTargetView> m_swapChainBufferRTV;
ComPtr<ID3D11Device> m_device;
ComPtr<ID3D11DeviceContext> m_deviceContext;
ComPtr<ID3D11Debug> m_debugger;
ComPtr<ID3D11Texture2D> m_depthStencilTexture;
ComPtr<ID3D11DepthStencilState> m_depthStencilState;
ComPtr<ID3D11DepthStencilView> m_depthStencilView;
ComPtr<ID3D11InputLayout> m_inputLayout;
ComPtr<ID3D11VertexShader> m_vertexShader;
ComPtr<ID3D11PixelShader> m_pixelShader;
ComPtr<ID3D11RasterizerState> m_solidRasterizerState;
ComPtr<ID3D11RasterizerState> m_wireframeRasterizerState;
ComPtr<ID3D11BlendState> m_blendState;
ComPtr<ID3D11SamplerState> m_linearSamplerState;

std::map<std::string, ComPtr<ID3D11ShaderResourceView>> m_diffuseMapViews;
std::map<std::string, ComPtr<ID3D11ShaderResourceView>> m_normalMapViews;

XMMATRIX m_worldViewMatrix;

ID3D11RasterizerState* m_currentRasterizerState;
};

void Renderer::CreateDeviceAndSwapChain()
{
HRESULT hr;

DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
swapChainDesc.BufferDesc.Width = m_windowWidth;
swapChainDesc.BufferDesc.Height = m_windowHeight;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 1;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 60;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;
swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED;
swapChainDesc.SampleDesc = m_sampleDesc;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 1;
swapChainDesc.OutputWindow = m_windowHandle;
swapChainDesc.Windowed = TRUE;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

D3D_FEATURE_LEVEL desiredFeatureLevels[] = { D3D_FEATURE_LEVEL_10_1 };
D3D_FEATURE_LEVEL featureLevel;

hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL,
D3D11_CREATE_DEVICE_DEBUG | D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
desiredFeatureLevels, 1, D3D11_SDK_VERSION, &swapChainDesc,
m_swapChain.GetAddressOf(), m_device.GetAddressOf(), &featureLevel,
m_deviceContext.GetAddressOf());

if (FAILED(hr))
{
hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_WARP, NULL,
D3D11_CREATE_DEVICE_DEBUG | D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
desiredFeatureLevels, 1, D3D11_SDK_VERSION, &swapChainDesc,
m_swapChain.GetAddressOf(), m_device.GetAddressOf(), &featureLevel,
m_deviceContext.GetAddressOf());
}

if (FAILED(hr))
throw std::exception("Failed to create device or swap chain");

hr = m_device->QueryInterface(m_debugger.GetAddressOf());

if (FAILED(hr))
throw std::exception("Failed to get debugger interface");

hr = m_swapChain->GetBuffer(0, __uuidof(m_swapChainBuffer),
(void**)m_swapChainBuffer.GetAddressOf());

if (FAILED(hr))
throw std::exception("Failed to get swap chain buffer");

hr = m_device->CreateRenderTargetView(m_swapChainBuffer.Get(), NULL,
m_swapChainBufferRTV.GetAddressOf());

if (FAILED(hr))
throw std::exception("Failed to create RTV for swap chain buffer");
}

void Renderer::CreateDepthStencil()
{
HRESULT hr;

D3D11_TEXTURE2D_DESC tdesc;
tdesc.Width = m_windowWidth;
tdesc.Height = m_windowHeight;
tdesc.MipLevels = 1;
tdesc.ArraySize = 1;
tdesc.Format = DXGI_FORMAT_D16_UNORM;
tdesc.SampleDesc = m_sampleDesc;
tdesc.Usage = D3D11_USAGE_DEFAULT;
tdesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
tdesc.CPUAccessFlags = 0;
tdesc.MiscFlags = 0;

hr = m_device->CreateTexture2D(&tdesc, NULL, m_depthStencilTexture.GetAddressOf());

if (FAILED(hr))
throw std::exception("Failed to create depth stencil texture");

D3D11_DEPTH_STENCIL_VIEW_DESC dsvdesc;
dsvdesc.Format = DXGI_FORMAT_D16_UNORM;
dsvdesc.ViewDimension = m_sampleDesc.Count > 1
? D3D11_DSV_DIMENSION_TEXTURE2DMS
: D3D11_DSV_DIMENSION_TEXTURE2D;
dsvdesc.Flags = 0;
dsvdesc.Texture2D.MipSlice = 0;

hr = m_device->CreateDepthStencilView(m_depthStencilTexture.Get(), &dsvdesc,
m_depthStencilView.GetAddressOf());

if (FAILED(hr))
throw std::exception("Failed to create depth stencil view");

D3D11_DEPTH_STENCIL_DESC dsdesc;
dsdesc.DepthEnable = TRUE;
dsdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
dsdesc.DepthFunc = D3D11_COMPARISON_LESS;
dsdesc.StencilEnable = FALSE;
dsdesc.StencilReadMask = 0;
dsdesc.StencilWriteMask = 0;
dsdesc.FrontFace = {};
dsdesc.BackFace = {};

hr = m_device->CreateDepthStencilState(&dsdesc, m_depthStencilState.GetAddressOf());

if (FAILED(hr))
throw std::exception("Failed to create depth stencil state");
}

void Renderer::CreateInputLayout()
{
HRESULT hr;

D3D11_INPUT_ELEMENT_DESC iedescs[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};

hr = m_device->CreateInputLayout(iedescs, 3,
g_vertexShader, sizeof(g_vertexShader),
m_inputLayout.GetAddressOf());

if (FAILED(hr))
throw std::exception("Failed to create input layout");
}

void Renderer::CreateVertexShader()
{
HRESULT hr;

hr = m_device->CreateVertexShader(g_vertexShader, sizeof(g_vertexShader),
NULL, m_vertexShader.GetAddressOf());

if (FAILED(hr))
throw std::exception("Failed to create vertex shader");
}

void Renderer::CreatePixelShader()
{
HRESULT hr;

hr = m_device->CreatePixelShader(g_pixelShader, sizeof(g_pixelShader),
NULL, m_pixelShader.GetAddressOf());

if (FAILED(hr))
throw std::exception("Failed to create pixel shader");
}

void Renderer::CreateRasterizerStates()
{
HRESULT hr;

D3D11_RASTERIZER_DESC rdesc;
rdesc.FillMode = D3D11_FILL_SOLID;
rdesc.CullMode = D3D11_CULL_FRONT;
rdesc.FrontCounterClockwise = FALSE;
rdesc.DepthBias = 0;
rdesc.DepthBiasClamp = 0.0f;
rdesc.SlopeScaledDepthBias = 0.0f;
rdesc.DepthClipEnable = TRUE;
rdesc.ScissorEnable = FALSE;
rdesc.MultisampleEnable = m_sampleDesc.Count > 1 ? TRUE : FALSE;
rdesc.AntialiasedLineEnable = m_sampleDesc.Count > 1 ? TRUE : FALSE;

hr = m_device->CreateRasterizerState(&rdesc, m_solidRasterizerState.GetAddressOf());

if (FAILED(hr))
throw std::exception("Failed to create rasterizer state");

rdesc.FillMode = D3D11_FILL_WIREFRAME;

hr = m_device->CreateRasterizerState(&rdesc, m_wireframeRasterizerState.GetAddressOf());

if (FAILED(hr))
throw std::exception("Failed to create rasterizer state");

m_currentRasterizerState = m_solidRasterizerState.Get();
}

void Renderer::CreateSamplerState()
{
HRESULT hr;

D3D11_SAMPLER_DESC smdesc;
smdesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
smdesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
smdesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
smdesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
smdesc.MipLODBias = 0.0f;
smdesc.MaxAnisotropy = 0;
smdesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
smdesc.BorderColor[4] = {};
FLOAT MinLOD = 0.0;
FLOAT MaxLOD = 0.0;

hr = m_device->CreateSamplerState(&smdesc, m_linearSamplerState.GetAddressOf());

if (FAILED(hr))
throw new std::exception("Failed to create sampler state");
}

void Renderer::CreateBlendState()
{
HRESULT hr;

D3D11_BLEND_DESC bdesc;
bdesc.AlphaToCoverageEnable = FALSE;
bdesc.IndependentBlendEnable = FALSE;
bdesc.RenderTarget[0].BlendEnable = FALSE;
bdesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
bdesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
bdesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
bdesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
bdesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
bdesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
bdesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;

hr = m_device->CreateBlendState(&bdesc, m_blendState.GetAddressOf());

if (FAILED(hr))
throw std::exception("Failed to create blend state");
}

void Renderer::CreateBuffer(ID3D11Buffer** buffer,
D3D11_USAGE usage, D3D11_BIND_FLAG bindFlags,
UINT cpuAccessFlags, UINT miscFlags,
UINT sizeOfBuffer, UINT sizeOfBufferElement, const void* initialData)
{
HRESULT hr;

D3D11_BUFFER_DESC bdesc;
bdesc.ByteWidth = sizeOfBuffer;
bdesc.Usage = usage;
bdesc.BindFlags = bindFlags;
bdesc.CPUAccessFlags = cpuAccessFlags;
bdesc.MiscFlags = miscFlags;
bdesc.StructureByteStride = sizeOfBufferElement;

D3D11_SUBRESOURCE_DATA bdata;
bdata.pSysMem = initialData;
bdata.SysMemPitch = 0;
bdata.SysMemSlicePitch = 0;

hr = m_device->CreateBuffer(&bdesc, &bdata, buffer);

if (FAILED(hr))
throw std::exception("Failed to create buffer");
}

void Renderer::CreateTexture2DAndSRV(const Scene::Texture& sceneTexture, ID3D11ShaderResourceView** view)
{
HRESULT hr;

constexpr DXGI_FORMAT texformat = DXGI_FORMAT_R32G32B32A32_FLOAT;

D3D11_TEXTURE2D_DESC tdesc;
tdesc.Width = sceneTexture.width;
tdesc.Height = sceneTexture.height;
tdesc.MipLevels = 0;
tdesc.ArraySize = 1;
tdesc.Format = texformat;
tdesc.SampleDesc.Count = 1;
tdesc.SampleDesc.Quality = 0;
tdesc.Usage = D3D11_USAGE_DEFAULT;
tdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
tdesc.CPUAccessFlags = 0;
tdesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;

ComPtr<ID3D11Texture2D> texture2d;

hr = m_device->CreateTexture2D(&tdesc, NULL, texture2d.GetAddressOf());

if (FAILED(hr))
throw std::exception("Failed to create texture");


D3D11_SUBRESOURCE_DATA srdata;
srdata.pSysMem = sceneTexture.data;
srdata.SysMemPitch = sceneTexture.width * sizeof(float) * 4;
srdata.SysMemSlicePitch = 0;

m_deviceContext->UpdateSubresource(texture2d.Get(), 0, NULL,
srdata.pSysMem, srdata.SysMemPitch, srdata.SysMemSlicePitch);


D3D11_SHADER_RESOURCE_VIEW_DESC srvdesc;
srvdesc.Format = texformat;
srvdesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvdesc.Texture2D.MostDetailedMip = 0;
srvdesc.Texture2D.MipLevels = -1;

ComPtr<ID3D11ShaderResourceView> shaderResourceView;

hr = m_device->CreateShaderResourceView(texture2d.Get(), &srvdesc, view);

if (FAILED(hr))
throw std::exception("Failed to create shader resource view");
}

void Renderer::CreateTexturesAndViews()
{
for (auto it = m_scene.materials.cbegin(); it != m_scene.materials.cend(); it++)
{
//don't know what's the problem but if I don't place initialized ComPtr<...> instance into a map
//then further .GetAddessOf() fails.
m_diffuseMapViews.emplace(it->first, ComPtr<ID3D11ShaderResourceView>());
m_normalMapViews.emplace(it->first, ComPtr<ID3D11ShaderResourceView>());

CreateTexture2DAndSRV(it->second.diffuseMap, m_diffuseMapViews[it->first].GetAddressOf());
CreateTexture2DAndSRV(it->second.normalMap, m_normalMapViews[it->first].GetAddressOf());
}
}

void Renderer::GenerateMips()
{
for (auto it = m_diffuseMapViews.begin(); it != m_diffuseMapViews.end(); it++)
m_deviceContext->GenerateMips(it->second.Get());
for (auto it = m_normalMapViews.begin(); it != m_normalMapViews.end(); it++)
m_deviceContext->GenerateMips(it->second.Get());
}

Renderer::Renderer(HWND hWnd, int windowWidth, int windowHeight,
const Scene& scene, const Camera& camera)
: m_scene(scene)
, m_camera(camera)
, m_cameraLastUpdateTickCount(0)
, m_windowHandle(hWnd)
, m_windowWidth(windowWidth)
, m_windowHeight(windowHeight)
{
m_sampleDesc.Count = 4;
m_sampleDesc.Quality = 0;

CreateDeviceAndSwapChain();
CreateDepthStencil();
CreateInputLayout();
CreateVertexShader();
CreatePixelShader();
CreateRasterizerStates();
CreateBlendState();
CreateSamplerState();
CreateTexturesAndViews();
GenerateMips();

// Setting up IA stage

m_deviceContext->IASetPrimitiveTopology(
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

m_deviceContext->IASetInputLayout(m_inputLayout.Get());

// Setting up VS stage

m_deviceContext->VSSetShader(m_vertexShader.Get(), 0, 0);

// Setting up RS stage

D3D11_VIEWPORT viewport;
viewport.TopLeftX = 0.0f;
viewport.TopLeftY = 0.0f;
viewport.Width = static_cast<FLOAT>(m_windowWidth);
viewport.Height = static_cast<FLOAT>(m_windowHeight);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;

m_deviceContext->RSSetViewports(1, &viewport);

// Setting up PS stage

m_deviceContext->PSSetSamplers(0, 1, m_linearSamplerState.GetAddressOf());
m_deviceContext->PSSetShader(m_pixelShader.Get(), 0, 0);

// Setting up OM stage

m_deviceContext->OMSetBlendState(m_blendState.Get(), NULL, 0xffffffff);
m_deviceContext->OMSetDepthStencilState(m_depthStencilState.Get(), 0);
m_deviceContext->OMSetRenderTargets(1, m_swapChainBufferRTV.GetAddressOf(), m_depthStencilView.Get());
}

void Renderer::Render()
{
constexpr float background[4] = { 0.047f, 0.0487f, 0.066f, 1.0f };

// Setting up view matix

if (m_cameraLastUpdateTickCount
!= m_camera.GetLastUpdateTickCount())
{
const Float3& camFrom = m_camera.GetFrom();
const Float3& camAt = m_camera.GetAt();
const Float3& camUp = m_camera.GetUp();

m_cameraLastUpdateTickCount = m_camera.GetLastUpdateTickCount();

FXMVECTOR from = XMVectorSet(camFrom.x, camFrom.y, camFrom.z, 1.0f);
FXMVECTOR at = XMVectorSet(camAt.x, camAt.y, camAt.z, 1.0f);
FXMVECTOR up = XMVectorSet(camUp.x, camUp.y, camUp.z, 0.0f);

FXMVECTOR dir = XMVectorSubtract(at, from);

FXMVECTOR x = XMVector3Cross(dir, up);
FXMVECTOR up2 = XMVector3Cross(x, dir);

XMMATRIX lookTo = XMMatrixLookToRH(from, dir, up2);

float scalef = 1.0f / XMVectorGetByIndex(XMVector3Length(dir), 0);

XMMATRIX scale = XMMatrixScaling(scalef, scalef, scalef);

float aspect = float(m_windowWidth) / m_windowHeight;
float fov = m_camera.GetFov() / 180.0f * 3.14f;

XMMATRIX persp = XMMatrixPerspectiveFovRH(fov, aspect, 0.1f, 1000.0f);

m_worldViewMatrix = XMMatrixMultiply(XMMatrixMultiply(lookTo, scale), persp);
}
else
{
return;
}

m_deviceContext->ClearDepthStencilView(m_depthStencilView.Get(), D3D11_CLEAR_DEPTH, 1.0f, 0);
m_deviceContext->ClearRenderTargetView(m_swapChainBufferRTV.Get(), background);

for (auto imesh = m_scene.meshes.cbegin(); imesh != m_scene.meshes.cend(); imesh++)
{
// Creating vertex buffer

ComPtr<ID3D11Buffer> vertexBuffer;

CreateBuffer(vertexBuffer.GetAddressOf(),
D3D11_USAGE_DEFAULT, D3D11_BIND_VERTEX_BUFFER, 0, 0,
sizeof(Scene::Vertex) * imesh->vertices.size(), sizeof(Scene::Vertex),
imesh->vertices.data());

// Creating index buffer

ComPtr<ID3D11Buffer> indexBuffer;

CreateBuffer(indexBuffer.GetAddressOf(),
D3D11_USAGE_DEFAULT, D3D11_BIND_INDEX_BUFFER, 0, 0,
sizeof(unsigned int) * imesh->indices.size(), sizeof(unsigned int),
imesh->indices.data());

// Creating constant buffer

ComPtr<ID3D11Buffer> constantBuffer;

CreateBuffer(constantBuffer.GetAddressOf(),
D3D11_USAGE_IMMUTABLE, D3D11_BIND_CONSTANT_BUFFER, 0, 0,
sizeof(XMMATRIX), sizeof(XMMATRIX),
&m_worldViewMatrix);

// Setting up IA stage

ID3D11Buffer* vertexBuffers[8] = { vertexBuffer.Get() };
unsigned int vertexBufferStrides[8] = { sizeof(Scene::Vertex) };
unsigned int vertexBufferOffsets[8] = { 0 };

m_deviceContext->IASetVertexBuffers(0, 8,
vertexBuffers, vertexBufferStrides, vertexBufferOffsets);

m_deviceContext->IASetIndexBuffer(indexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);

// Setting up VS stage

m_deviceContext->VSSetConstantBuffers(0, 1, constantBuffer.GetAddressOf());

// Setting up RS stage

m_deviceContext->RSSetState(m_currentRasterizerState);

// Setting up PS stage

ID3D11ShaderResourceView* srvs[2] = { };
srvs[0] = m_diffuseMapViews.at(imesh->material).Get();
srvs[1] = m_normalMapViews.at(imesh->material).Get();

m_deviceContext->PSSetShaderResources(0, 2, srvs);

// Drawing

m_deviceContext->DrawIndexed(imesh->indices.size(), 0, 0);
}

m_swapChain->Present(0, 0);
}

void Renderer::SwitchToWireframe()
{
m_currentRasterizerState = m_wireframeRasterizerState.Get();
m_camera.UpdateLastUpdateTickCount();
}

void Renderer::SwitchToSolid()
{
m_currentRasterizerState = m_solidRasterizerState.Get();
m_camera.UpdateLastUpdateTickCount();
}

2) 顶点着色器

struct VS_INPUT
{
float3 position : POSITION;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD;
};

struct VS_OUTPUT
{
float4 position : SV_POSITION;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD;
};

cbuffer Matrices
{
matrix worldViewMatrix;
}

VS_OUTPUT main(VS_INPUT input)
{
VS_OUTPUT output;

output.position = mul(worldViewMatrix, float4(input.position.xyz, 1.0));
output.normal = input.normal;
output.texcoord = input.texcoord;

return output;
}

3) 像素着色器

Texture2D DiffuseMap : register(t0);
Texture2D NormalMap: register(t1);

SamplerState LinearSampler : register(s0);

float4 main(VS_OUTPUT input) : SV_TARGET
{
float3 light = normalize(float3(2.87, -0.36, 1.68));

float3 diffuseColor = DiffuseMap.Sample(LinearSampler, input.texcoord);
float3 normalDisplace = float3(0.0, 0.0, 1.0) - NormalMap.Sample(LinearSampler, input.texcoord);

float illumination = clamp(dot(light, input.normal + normalDisplace), 0.2, 1.0);

return float4(mul(diffuseColor, illumination), 1.0);
}

最佳答案

好的,我刚刚弄清楚了这个楼梯效果的原因:

enter image description here

原因是我为 CreateWindow WinApi 函数和 DXGI_SWAP_CHAIN_DESC::BufferDesc 传递了相同的宽度和高度值。同时,这些应该是不同的,因为 CreateWindow 需要创建一个窗口的外部宽度和高度(窗口矩形),而 BufferDesc 应该接收内部值(窗口客户区域矩形)。由于屏幕上的实际区域小于 交换链缓冲区,渲染结果可能会重新采样以适合矩形,这在应用 MSAA 后引入了锯齿。

解决问题后得到了更清晰的结果(此处应用了 4x MSAA):

enter image description here

但是纹理混叠的问题仍然悬而未决:

enter image description here

关于c++ - 无法从 Direct3D 获取抗锯齿图片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51865096/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com