Előadást letölteni
Az előadás letöltése folymat van. Kérjük, várjon
1
Direct3D DirectCompute
Szécsi László 3D Grafikus Rendszerek 5. labor
2
Keret Visual Studio 2015 project DirectXTex Egg lib modulok
App – alapinfrastuktúra, App osztály eseménykezelő metódusokkal Cam – kamera Enum – típusbiztos enum és flag kezelés Math – vektor- és mátrixműveletek, pl. float3, float4x4 Mesh – geometria- és anyagrendszer AssImp modellfile-betöltővel
3
gr005-ToneMap project Game osztály eseménykezelő metódusok
egy 3D objektum Egg::Mesh::ShadedP shadedMesh – ugyanaz mint a WebGL-ben a Mesh volt kirajzoláshoz trafók beállítása kézzel perObjectConstantBuffer, perFrameConstantBuffer feltöltése GameObject nincs a keretben (így is elég nagy, nemhogy még színtérkezeléssel) háttér quad ugyanaz minden, mint WebGL-ben volt shaderek trafo.hlsli, vsTrafo.hlsl, fsEnvMapped.hlsl quad.hlsli, vsQuad.hlsl, fsBackground.hlsl
4
Hova dolgozunk? új erőforrások a Game.h-ba tagváltozóként
létrehozásuk/felszabadításuk a Game.cpp megfelelő eseményfigyelőiben használatuk rajzoláshoz a Game::render-ben shaderek a Shaders folderbe properties-ben állítsuk be a shader típusát
5
Munkaterv tone mapping manuálisan textúrába renderelés
legyen egy per-frame shader konstans (uniform) szorzó gombnyomással változtatható textúrába renderelés 128x128-as textúra létrehozása usage: render target és shader resource RTV és SVR nézetobjektumok létrehozása színtér rajzolása a textúrába render target ellenőrzése: kész textúra megjelenítése compute shaderrel a 128x128 pixel átlagolása tone mapping az átlag alapján extra
6
Manuális tone mapping új elem a perFrame-ben: float4 toneScale
createResources-ban buffer méretét módosítani psEnvMapped és psBackground shaderekben a kimenet szorzása toneScale.x-lel Game-ben float toneScale tagváltozó Game::processMessage-ben változtatható uMsg == WM_KEYDOWN wParam == 'G': toneScale *= 0.8f wParam == 'T': toneScale *= 1.25f render-ben a konstant buffer feltöltésének kiegészítése
7
Várt eredmény
8
Erőforrás-pointerek Microsoft::WRL::ComPtr<ID3D11Texture2D> sampleTexture; Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> sampleSrv; Microsoft::WRL::ComPtr<ID3D11RenderTargetView> sampleRtv; sampleDepthTexture; Microsoft::WRL::ComPtr<ID3D11DepthStencilView> sampleDsv;
9
Erőforrások létrehozása - sampleTexture
CD3D11_TEXTURE2D_DESC sampleTextureDesc( DXGI_FORMAT_R32G32B32A32_FLOAT, 128, 128); sampleTextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; sampleTextureDesc.MipLevels = 1; device->CreateTexture2D( &sampleTextureDesc, NULL, sampleTexture.GetAddressOf());
10
Erőforrások létrehozása - sampleRtv
CD3D11_RENDER_TARGET_VIEW_DESC sampleRtvDesc; sampleRtvDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; sampleRtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; sampleRtvDesc.Texture2D.MipSlice = 0; device->CreateRenderTargetView( sampleTexture.Get(), &sampleRtvDesc, sampleRtv.GetAddressOf());
11
Erőforrások létrehozása - sampleSrv
CD3D11_SHADER_RESOURCE_VIEW_DESC sampleSrvDesc; sampleSrvDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; sampleSrvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; sampleSrvDesc.Texture2D.MipLevels = 1; sampleSrvDesc.Texture2D.MostDetailedMip = 0; device->CreateShaderResourceView( sampleTexture.Get(), &sampleSrvDesc, sampleSrv.GetAddressOf());
12
Erőforrások létrehozása - sampleDepthTexture
CD3D11_TEXTURE2D_DESC sampleDepthTextureDesc( DXGI_FORMAT_D24_UNORM_S8_UINT, 128, 128); sampleDepthTextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; sampleDepthTextureDesc.MipLevels = 1; HRESULT hr = device->CreateTexture2D( &sampleDepthTextureDesc, NULL, sampleDepthTexture.GetAddressOf());
13
Erőforrások létrehozása - sampleDsv
CD3D11_DEPTH_STENCIL_VIEW_DESC sampleDsvDesc; sampleDsvDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; sampleDsvDesc.Flags = 0; sampleDsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; sampleDsvDesc.Texture2D.MipSlice = 0; device->CreateDepthStencilView( sampleDepthTexture.Get(), &sampleDsvDesc, sampleDsv.GetAddressOf());
14
Erőforrások felszabadítása
mindegyikre: .Reset(); nullázza a pointert, elveszíti a referenciát
15
Rajzoljuk a hátteret + zsiráfot a textúrába
render target váltás (lásd köv. dia) rtv/dsv törlés dolgok rajzolása render target visszaállítás default rtv/dsv törlés ide is rajzolhatjuk a színteret a render target textúra megmutatása is ide kerülhet
16
Render target váltás context->OMSetRenderTargets( 1, sampleRtv.GetAddressOf(), sampleDsv.Get()); D3D11_VIEWPORT vp; vp.TopLeftX = 0; vp.TopLeftY = 0; vp.Height = 128; vp.Width = 128; vp.MinDepth = 0; vp.MaxDepth = 1; context->RSSetViewports(1, &vp);
17
Render target visszaállítás
context->OMSetRenderTargets( 1, defaultRenderTargetView.GetAddressOf(), defaultDepthStencilView.Get()); vp.TopLeftX = 0; vp.TopLeftY = 0; vp.Height = swapChainDesc.Height; vp.Width = swapChainDesc.Width; vp.MinDepth = 0; vp.MaxDepth = 1; context->RSSetViewports(1, &vp);
18
Render texture megmutatása
teljes képernyős quad új pixel shaderrel backgroundMesh mintájára: showMesh új PS, showMaterial gyártása belőle, inputBinder-rel inputLayout kérése, shaded mesh létrehozása psShow.hlsl quad input mint a psBackground-ban 2D textúrából olvas, input.tex koordinátákkal az anyagnak a 2d textúra sample SRV-t beállítani (lásd köv dia)
19
Textúra SRV bekötése showMaterial->setShaderResource( "showTexture", sampleSrv);
20
Minden kikötése (hogy ne sírjon)
context->ClearState();
21
Várt eredmény (128x128)
22
Jöhet a compute koncepció: 1. menet 2. menet végül
extra Jöhet a compute koncepció: 1. menet minden szálcsoport egy sort ad össze a képből 128 szálcsoportot indítunk, 64 szál per csoport minden szálcsoport első szála a végén kiírja az eredményt egy output buffer megfelelő elemébe 2. menet egyetlen szálcsoportot indítunk, aki összeadja az 128 számot végül a kapott számmal osztunk a megjelenítéskor
23
Összeadás algoritmusa
minden szál beolvas két adatot, összeadja, shared tömbbe tárolja szinkronizáció, megvárjuk, hogy bejöjjön az adat ezután a második felét hozzáadjuk az első feléhez már csak 32 szál végez értelmes munkát aztán ezt ismételjük feleakkora méretben szinkronizáció nem kell, mert az összes szál egy warpben van (egyszerre hajtódnak végre ténylegesen) a végén a shared memória nulladik eleme az összeg
24
Buffer, UAV pointerek, shaderek
Microsoft::WRL::ComPtr<ID3D11Buffer> reduceBuffer1; Microsoft::WRL::ComPtr<ID3D11UnorderedAccessView> reduceUav1; reduceBuffer2; reduceUav2; Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> reduceSrv2; Egg::Mesh::ShaderP csReduceHorizontal; Egg::Mesh::ShaderP csReduceVertical;
25
Bufferek, UAVok létrehozása
CD3D11_BUFFER_DESC reduceBuffer1Desc(sizeof(float) * 128, D3D11_BIND_UNORDERED_ACCESS); device->CreateBuffer(&reduceBuffer1Desc, NULL, reduceBuffer1.GetAddressOf()); CD3D11_UNORDERED_ACCESS_VIEW_DESC reduceUav1Desc(D3D11_UAV_DIMENSION_BUFFER, DXGI_FORMAT_R32_FLOAT, 0, 128); device->CreateUnorderedAccessView( reduceBuffer1.Get(), &reduceUav1Desc, reduceUav1.GetAddressOf()); // A másik hasonlóan. Mekkora legyen?
26
SRV létrehozása CD3D11_SHADER_RESOURCE_VIEW_DESC reduceSrv2Desc( D3D11_SRV_DIMENSION_BUFFER, DXGI_FORMAT_R32_FLOAT, 0, 1); device->CreateShaderResourceView( reduceBuffer2.Get(), &reduceSrv2Desc, reduceSrv2.GetAddressOf());
27
Shaderek betöltése mint korábban
28
Felszabadítás ne feledkezzünk meg róla
29
be- és kimenetek, shared memória tömb (csReduceHorizontal.hlsl)
Texture2D inputTexture; RWBuffer<float> inputData; RWBuffer<float> outputData; #define groupSize 64 groupshared float sdata[groupSize];
30
csReduceHorizontal eleje, adatbeolvasás
[numthreads( groupSize, 1, 1)] void csReduceHorizontal(uint tid : SV_GroupIndex, uint3 groupIdx : SV_GroupID ) { sdata[tid] = inputTexture.Load(uint3(tid*2 , groupIdx.x, 0)) + inputTexture.Load(uint3(tid*2+1, groupIdx.x, 0)); GroupMemoryBarrierWithGroupSync();
31
csReduceHorizontal vége, összeadás
if (tid < 32) sdata[tid] += sdata[tid + 32]; if (tid < 16) sdata[tid] += sdata[tid + 16]; if (tid < 8) sdata[tid] += sdata[tid + 8]; if (tid < 4) sdata[tid] += sdata[tid + 4]; if (tid < 2) sdata[tid] += sdata[tid + 2]; if (tid < 1) sdata[tid] += sdata[tid + 1]; if (tid == 0) outputData[groupIdx.x] = sdata[0] / 128.0; }
32
csReduceVertical megírása
128 sorösszeg összegzése csak egy szálcsoportot fogunk indítani beolvasás nem textúrából, hanem adatbufferből sima tömbindexeléssel olvasható különben ugyanaz
33
Compute shaderek futtatása
uint zeros[2] = { 0, 0 }; ID3D11UnorderedAccessView* nulls[2] = { nullptr, nullptr }; context->CSSetShader( csReduceHorizontal->as<ID3D11ComputeShader>().Get(), nullptr, 0); context->CSSetUnorderedAccessViews(0, 1, reduceUav1.GetAddressOf(), zeros); context->CSSetShaderResources(0, 1, sampleSrv.GetAddressOf()); context->Dispatch(128, 1, 1); // másik ugyanígy, csak két buffer van, és 1 csoport
34
Tone mapping a számolt összeg alapján
show PS-ben osszunk az eredményt tartalmazó adatbufferből kiolvasott eredménnyel kell a shaderbe egy Buffer<float> nem RWBuffer mezei shader resource, a végeredmény-buffer SRV-jét kell rákötni, simán materialon keresztül mehet, pl: showMaterial->setShaderResource("toneData", reduceSrv2);
35
5. házi feladat sok áttetsző plakát megjelenítése
geometry shaderrel alpha blending, rajzolás hátulról előre mozogniuk nem feltétlenül kell, de legalább a kamerát lehessen mozgatni szorgalmi: rendezés a GPU-n compute shaderrel brick sort (a.k.a. even-odd transposition sort) egy frameben elég 1-2 rendezési lépést megtenni majdnem rendezett a tömb úgyis ha mozgatjuk a részecskéket, azt is a compute shader csinálja sohasem olvassuk vagy írjuk a buffert a CPU-ról
Hasonló előadás
© 2024 SlidePlayer.hu Inc.
All rights reserved.