国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Direct3D 12——模板——平面鏡效果

這篇具有很好參考價值的文章主要介紹了Direct3D 12——模板——平面鏡效果。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1.將實物照常渲染到后臺緩沖區(qū)內(nèi)(不包括鏡子)。注意,此步驟不修改模 板緩沖區(qū)。

2.清理模板緩沖區(qū),將其整體置零。
Direct3D 12——模板——平面鏡效果
將實物都繪制到后臺緩沖區(qū)中,并將模板緩沖區(qū)清理為0 (用淺灰色來表示)。
繪制在模板緩沖區(qū)中的黑色輪廊線條反映的是:后臺緩沖區(qū)與模板緩沖區(qū)中像素之間的對照關(guān)系,而并非模板緩沖區(qū)中所繪的實際數(shù)據(jù)。

3.僅將鏡面渲染到模板緩沖區(qū)中。若要禁止其他顏色數(shù)據(jù)寫入到后臺緩沖區(qū),可用下列設(shè)置所創(chuàng) 建的混合狀態(tài):
D3D12_RENDER_TARGET_BLEND_DESC::RenderTargetWriteMask = 0;
再通過以下配置來禁止向深度緩沖區(qū)的寫操作:
D3D12_DEPTH_STENCIL_DESC::DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;

在向模板緩沖區(qū)渲染鏡面的時候,我將模板測試設(shè)置為每次都成功(D3D12_COMPARISON_ALWAYS), 并且在通過測試時用1 ( StencilRef模板參考值)來替換(通過D3D12_STENCIL_OP_REPLACE來 設(shè)置)模板緩沖區(qū)元素。如果深度測試失敗,則應(yīng)當(dāng)采用枚舉項D3D12_STENCIL_OP_KEEP,使模板緩沖區(qū)中的對應(yīng)像素保持不變。由于僅向模板緩沖區(qū)繪制了鏡面,因此在模板緩沖區(qū)內(nèi),除了鏡面可見部分的對應(yīng)像素為1,其他像素皆為0。圖下所示的即為更新后的模板緩沖區(qū)。換言之,我們其實就是在模板緩沖區(qū)中標(biāo)記了鏡面的可見像素而已。
Direct3D 12——模板——平面鏡效果
圖把鏡面渲染到模板緩沖區(qū)中,其實就是在模板緩沖區(qū)中標(biāo)記出鏡面可視部分的對應(yīng)像素。
模板緩沖區(qū)中實心黑色區(qū)域的模板元素取值為1。但請注意,由于被立方體擋住部分的深度測試會失敗,所以在模板緩沖區(qū)中的這一范圍內(nèi),元素的取值并不為1
(立方體與黑色鏡面重合的部分,也就是立方體位于鏡面前方的這一部分)

保證先繪制實物,后將鏡面渲染至模板緩沖區(qū)的順序是很重要的。這樣一來,深度 測試的失敗會令鏡面的像素被實物的像素所遮擋,因而也就不必再對模板緩沖區(qū)進 行二次修改了。我們并不希望把模板緩沖區(qū)中鏡面被遮擋部分的值設(shè)為1,那樣將導(dǎo)致在實物位于鏡面前方的范圍內(nèi)也能顯示出鏡面內(nèi)容。

4.現(xiàn)在我們來將實物的鏡像渲染至后臺緩沖區(qū)及模板緩沖區(qū)中。前面曾提到,只有通過模板測 試的像素才能渲染至后臺緩沖區(qū)。對此,我們便將其設(shè)置為:僅當(dāng)模板緩沖區(qū)中的值為1時, 才能通過模板測試。這可以通過令StencilRef為1,且模板運算符為D3D12_COMPARISON_ FUNC_EQUAL來實現(xiàn)。如此一來,只有模板緩沖區(qū)中元素數(shù)值為1的實物鏡像部分才能得以 渲染。由于只有鏡面可見部分所對應(yīng)的模板緩沖區(qū)中元素數(shù)值為1,所以僅有這一范圍內(nèi)的實物鏡像才能被渲染出來。

5.最后,我們像往常那樣將鏡面渲染到后臺緩沖區(qū)中。但是,為了能“透過”鏡面觀察實物的 鏡像(它實際位于鏡子的背面。雖說展現(xiàn)的是鏡面內(nèi)的鏡像,但實際上是鏡面背后的反射實物 與鏡面透明混合所得到的效果),我們就需要運用透明混合技術(shù)來渲染鏡面。若非如此,則由于 實物鏡像的深度值小于鏡面的深度值,理所當(dāng)然地會致使實物鏡像被鏡子擋住。為此,我 們只需為鏡面定義一個新的材質(zhì)配置實例:將其漫反射alpha通道分量設(shè)為0.3,使鏡子的不透 明度達(dá)到30%,

	auto icemirror = std::make_unique<Material>();
	icemirror->Name = "icemirror";
	icemirror->MatCBIndex = 2;
	icemirror->DiffuseSrvHeapIndex = 2;
	icemirror->DiffuseAlbedo = XMFLOAT4(1.0f, 1.0f, 1.0f, 0.3f);
	icemirror->FresnelR0 = XMFLOAT3(0.1f, 0.1f, 0.1f);
	icemirror->Roughness = 0.5f;

假設(shè)已經(jīng)將實物鏡像的像素置于后臺緩沖區(qū)內(nèi),那么,此時我們所看到的鏡像顏色30%來自鏡子 (源像素),70%出自實物鏡像(目標(biāo)像素)。

定義鏡像的深度/模板狀態(tài)

為了實現(xiàn)上述算法,我們要用到兩個PSO對象。第一個用于在繪制鏡面時標(biāo)記模板緩沖區(qū)內(nèi)鏡面部 分的像素,第二個則用于繪制鏡面可見部分(即不被前側(cè)實物所遮擋部分)內(nèi)的實物鏡像。

	//
	//
	// PSO for marking stencil mirrors.禁止對渲染目標(biāo)的寫操作
	//

	CD3DX12_BLEND_DESC mirrorBlendState(D3D12_DEFAULT);
	mirrorBlendState.RenderTarget[0].RenderTargetWriteMask = 0; //禁止對渲染目標(biāo)的寫操作

	D3D12_DEPTH_STENCIL_DESC mirrorDSS;
	mirrorDSS.DepthEnable = true;
	mirrorDSS.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;//禁止對渲染目標(biāo)的寫操作
	mirrorDSS.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
	mirrorDSS.StencilEnable = true;
	mirrorDSS.StencilReadMask = 0xff;
	mirrorDSS.StencilWriteMask = 0xff;
	
	mirrorDSS.FrontFace.StencilFailOp = D3D12_STENCIL_OP_KEEP;
	mirrorDSS.FrontFace.StencilDepthFailOp = D3D12_STENCIL_OP_KEEP;
	mirrorDSS.FrontFace.StencilPassOp = D3D12_STENCIL_OP_REPLACE;
	mirrorDSS.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS;
	

	//我們不渲染背面朝向的多邊形,因而對這些參數(shù)血置并不關(guān)心
	// We are not rendering backfacing polygons, so these settings do not matter.]

	mirrorDSS.BackFace.StencilFailOp = D3D12_STENCIL_OP_KEEP;
	mirrorDSS.BackFace.StencilDepthFailOp = D3D12_STENCIL_OP_KEEP;
	mirrorDSS.BackFace.StencilPassOp = D3D12_STENCIL_OP_REPLACE;
	mirrorDSS.BackFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS;

	D3D12_GRAPHICS_PIPELINE_STATE_DESC markMirrorsPsoDesc = opaquePsoDesc;
	markMirrorsPsoDesc.BlendState = mirrorBlendState;
	markMirrorsPsoDesc.DepthStencilState = mirrorDSS;
	ThrowIfFailed(md3dDevice->CreateGraphicsPipelineState(&markMirrorsPsoDesc, IID_PPV_ARGS(&mPSOs["markStencilMirrors"])));

	//
	// PSO for stencil reflections.用于渲染模板緩沖區(qū)中反射鏡像的PSO
	//

	D3D12_DEPTH_STENCIL_DESC reflectionsDSS;
	reflectionsDSS.DepthEnable = true;
	reflectionsDSS.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
	reflectionsDSS.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
	reflectionsDSS.StencilEnable = true;
	reflectionsDSS.StencilReadMask = 0xff;
	reflectionsDSS.StencilWriteMask = 0xff;

	reflectionsDSS.FrontFace.StencilFailOp = D3D12_STENCIL_OP_KEEP;
	reflectionsDSS.FrontFace.StencilDepthFailOp = D3D12_STENCIL_OP_KEEP;
	reflectionsDSS.FrontFace.StencilPassOp = D3D12_STENCIL_OP_KEEP;
	reflectionsDSS.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_EQUAL;

	// We are not rendering backfacing polygons, so these settings do not matter.
	reflectionsDSS.BackFace.StencilFailOp = D3D12_STENCIL_OP_KEEP;
	reflectionsDSS.BackFace.StencilDepthFailOp = D3D12_STENCIL_OP_KEEP;
	reflectionsDSS.BackFace.StencilPassOp = D3D12_STENCIL_OP_KEEP;
	reflectionsDSS.BackFace.StencilFunc = D3D12_COMPARISON_FUNC_EQUAL;

	D3D12_GRAPHICS_PIPELINE_STATE_DESC drawReflectionsPsoDesc = opaquePsoDesc;
	drawReflectionsPsoDesc.DepthStencilState = reflectionsDSS;
	drawReflectionsPsoDesc.RasterizerState.CullMode = D3D12_CULL_MODE_BACK;
	drawReflectionsPsoDesc.RasterizerState.FrontCounterClockwise = true;
	ThrowIfFailed(md3dDevice->CreateGraphicsPipelineState(&drawReflectionsPsoDesc, IID_PPV_ARGS(&mPSOs["drawStencilReflections"])));

繪制場景

	//繪制不透明的物體
	// Draw opaque items--floors, walls, skull.
	auto passCB = mCurrFrameResource->PassCB->Resource();
	mCommandList->SetGraphicsRootConstantBufferView(2, passCB->GetGPUVirtualAddress());
    DrawRenderItems(mCommandList.Get(), mRitemLayer[(int)RenderLayer::Opaque]);
	
	//將模板緩沖區(qū)中可見的鏡面像素標(biāo)記為1
	 Mark the visible mirror pixels in the stencil buffer with the value 1
	mCommandList->OMSetStencilRef(1);
	mCommandList->SetPipelineState(mPSOs["markStencilMirrors"].Get());
	DrawRenderItems(mCommandList.Get(), mRitemLayer[(int)RenderLayer::Mirrors]);

	//只繪制鏡子范圍內(nèi)的鏡像(即僅繪制模板緩沖區(qū)中標(biāo)記為1的像素)
   //注意,我們必須使用兩個單獨的渲染過程常量緩沖區(qū)(per-pass constant buffer)來完成此工作,
   //一個存儲物體鏡像,另一個保存光照鏡像
	// Draw the reflection into the mirror only (only for pixels where the stencil buffer is 1).
	// Note that we must supply a different per-pass constant buffer--one with the lights reflected.
	mCommandList->SetGraphicsRootConstantBufferView(2, passCB->GetGPUVirtualAddress() + 1 * passCBByteSize);
	mCommandList->SetPipelineState(mPSOs["drawStencilReflections"].Get());
	DrawRenderItems(mCommandList.Get(), mRitemLayer[(int)RenderLayer::Reflected]);

	//恢復(fù)主渲染過程常量數(shù)據(jù)以及模板參考值 
	// Restore main pass constants and stencil ref.
	mCommandList->SetGraphicsRootConstantBufferView(2, passCB->GetGPUVirtualAddress());
	mCommandList->OMSetStencilRef(0);

	//繪制透明的鏡面,使鏡像可以與之混合
	// Draw mirror with transparency so reflection blends through.
	mCommandList->SetPipelineState(mPSOs["transparent"].Get());
	DrawRenderItems(mCommandList.Get(), mRitemLayer[(int)RenderLayer::Transparent]);

關(guān)于以上代碼還有一點需要注意,即在繪制RenderLayer: :Reflected層的時候如何來修改其渲染過程常量緩沖區(qū)。這是因為在繪制物體鏡像的同時,還涉及場景中光照的鏡像(即,物體的鏡像也 要有與之對應(yīng)的光照)。光源本存于渲染過程常量緩沖區(qū)中,因此我們可以再額外創(chuàng)建一個渲染過程常量 緩沖區(qū),用以存儲場景中光照的鏡像。該常量緩沖區(qū)的設(shè)置方法如下:

  PassConstants mMainPassCB;
  PassConstants mReflectedPassCB;
void StencilApp::UpdateReflectedPassCB(const GameTimer& gt)
{
	mReflectedPassCB = mMainPassCB;

	XMVECTOR mirrorPlane = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f); // xy plane
	XMMATRIX R = XMMatrixReflect(mirrorPlane);

	// 光照鏡像
	for(int i = 0; i < 3; ++i)
	{
		XMVECTOR lightDir = XMLoadFloat3(&mMainPassCB.Lights[i].Direction);
		XMVECTOR reflectedLightDir = XMVector3TransformNormal(lightDir, R);
		XMStoreFloat3(&mReflectedPassCB.Lights[i].Direction, reflectedLightDir);
	}

	// 將光照鏡像的渲染過程常量數(shù)據(jù)存于渲染過程常量緩沖區(qū)中索引1的位置
	auto currPassCB = mCurrFrameResource->PassCB.get();
	currPassCB->CopyData(1, mReflectedPassCB);
}

繞序與鏡像

當(dāng)一個三角形被反射到某個平面上時(也就是此三角形在這一平面上的鏡像),其繞序(winding order ) 并不會發(fā)生改變,正因如此,其平面法線的方向同樣保持不變。所以,實際物體的外向法線在鏡像中則變?yōu)?了內(nèi)向法線。此時,為了糾正這一點,我們會告知Direct3D將逆時針繞序的三角形看作是正面 朝向,而將順時針繞序的三角形看作背面朝向。這實際上 是對法線的方向也進行了 “反射”,以此使鏡像成為外向朝向。我們可以通過設(shè)置下列PSO光柵化屬性來改 變繞序的約定:

drawReflectionsPsoDesc.RasterizerState.FrontCounterClockwise = true;

Direct3D 12——模板——平面鏡效果文章來源地址http://www.zghlxwxcb.cn/news/detail-420766.html

多邊形的法線不會隨著反射操作而調(diào)轉(zhuǎn)過來,這使得鏡像的法線都變?yōu)閮?nèi)向朝向

到了這里,關(guān)于Direct3D 12——模板——平面鏡效果的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • DirectX12_Windows_GameDevelop_3:Direct3D的初始化

    DirectX12_Windows_GameDevelop_3:Direct3D的初始化

    查看龍書時發(fā)現(xiàn), 第四章介紹預(yù)備知識的代碼不太利于學(xué)習(xí) 。因為它不像是LearnOpenGL那樣從頭開始一步一步教你敲代碼,導(dǎo)致你沒有一種整體感。 如果你把它當(dāng)作某一塊的代碼進行學(xué)習(xí),你跟著敲會發(fā)現(xiàn),總有幾個變量是沒有定義的。這是因為書上的代碼都是把框架里的某

    2024年02月08日
    瀏覽(28)
  • Direct3D光照

    Direct3D光照

    光照的組成 環(huán)境光:這種類型的光經(jīng)其他表面反射到達(dá)物體表面,并照亮整個場景,要想以較低代價粗略模擬這類反射光,環(huán)境光是一個很好的選擇 漫射光:這種類型光沿著特定的方向傳播。當(dāng)它到達(dá)某一表面時,將沿著各個方向均勻反射,無論從哪個方位觀察,表面亮度

    2024年02月09日
    瀏覽(20)
  • Direct3D融合技術(shù)

    該技術(shù)能使我們將當(dāng)前要進行光柵化的像素的顏色與先前已已光柵化并處于同一位置的像素的顏色進行合成,即將正在處理的圖元顏色值與存儲在后臺緩存中的像素顏色值進行合成(混合),利用該技術(shù)我們可得到各種各樣的效果,尤其是透明效果。 在融合運算時需要遵循:首

    2024年02月07日
    瀏覽(28)
  • Direct3D繪制旋轉(zhuǎn)立方體例程

    Direct3D繪制旋轉(zhuǎn)立方體例程

    初始化文件見Direct3D的初始化_direct3dcreate9_寂寂寂寂寂蝶丶的博客-CSDN博客 D3DPractice.cpp 運行結(jié)果

    2024年02月09日
    瀏覽(18)
  • Character Animation With Direct3D 讀書筆記

    2D動畫:循環(huán)播放多張圖片 3D動畫: 骨骼動畫、變形動畫 Win32 應(yīng)用程序 Application類:處理主程序循環(huán),圖形設(shè)備的初始化 Init:加載資源并創(chuàng)建圖形設(shè)備 Update:更新游戲世界,移動對象,更新物理引擎 Render:渲染所有對象,并將結(jié)果呈現(xiàn)給屏幕 Quit Cleanup DirectX 渲染循環(huán):

    2024年02月12日
    瀏覽(21)
  • 三維引擎基礎(chǔ)概述(Direct3D、OpenGL、UE、U3D、threejs等)

    三維引擎基礎(chǔ)概述(Direct3D、OpenGL、UE、U3D、threejs等)

    一般而言,三維引擎是在三維底層圖形技術(shù)的基礎(chǔ)上,封裝硬件操作與三維圖形算法,形成普遍意義上的三維交互引擎,提供給開發(fā)者一個簡單易用、功能豐富的三維圖形環(huán)境,在此基礎(chǔ)上進行虛擬現(xiàn)實、三維交互、可視化管理平臺二次開發(fā)等,極大提高開發(fā)效率。 【底層圖

    2024年02月11日
    瀏覽(31)
  • web3D三維引擎(Direct3D、OpenGL、UE、U3D、threejs)基礎(chǔ)掃盲

    web3D三維引擎(Direct3D、OpenGL、UE、U3D、threejs)基礎(chǔ)掃盲

    三維引擎是指用于創(chuàng)建和渲染三維圖形的軟件框架。它們通常提供了圖形處理、物理模擬、光照、碰撞檢測等功能,幫助開發(fā)者構(gòu)建逼真的三維場景和交互體驗。在這里,我將為您詳細(xì)介紹一些常見的三維引擎,包括Direct3D、OpenGL、Unreal Engine、Unity3D和Three.js。 Direct3D是由微軟

    2024年02月11日
    瀏覽(22)
  • 【C/C++】使用C++和Direct3D (d3d)獲取屏幕截圖并根據(jù)傳入分辨率進行縮放圖片大小

    【C/C++】使用C++和Direct3D (d3d)獲取屏幕截圖并根據(jù)傳入分辨率進行縮放圖片大小

    目錄 一,函數(shù)清單 1.Direct3DCreate9?函數(shù) 2.IDirect3D9::CreateDevice 方法 3.IDirect3DDevice9::GetDisplayMode?方法 4.IDirect3DDevice9::CreateOffscreenPlainSurface?方法 5.IDirect3DDevice9::GetFrontBufferData?方法 6.IDirect3DDevice9::D3DXLoadSurfaceFromSurface 方法 7.?D3DXSaveSurfaceToFile 函數(shù) 二,關(guān)鍵代碼實現(xiàn) 三,最終實現(xiàn)

    2024年01月18日
    瀏覽(30)
  • 在direct3D中,透明度處理和D2D1_ALPHA_MODE_PREMULTIPLIED含義?

    D2D1_ALPHA_MODE_PREMULTIPLIED 是 Direct2D 中定義的一種 Alpha 模式,用于描述像素顏色值和其 Alpha 通道(透明度)之間的關(guān)系。 在非預(yù)乘 Alpha (Straight or Unpremultiplied Alpha) 圖像中,每個顏色分量(紅、綠、藍(lán))是獨立于 Alpha 值的。而在預(yù)乘 Alpha 圖像中,每個顏色分量已經(jīng)被其對應(yīng)的

    2024年01月25日
    瀏覽(27)
  • direct3d-msaa-抗鋸齒算法-教程-涉及概念解析

    交換鏈(Swap Chain)在計算機圖形學(xué)和窗口系統(tǒng)中是一個核心概念,它主要用于管理一組緩沖區(qū)(通常是幀緩沖區(qū)),這些緩沖區(qū)用于存儲渲染的圖像,并且有序地與屏幕顯示進行交替更新。 窗口系統(tǒng)中的交換鏈: 在Windows、Linux等操作系統(tǒng)上的窗口環(huán)境中,交換鏈與圖形API(

    2024年01月24日
    瀏覽(17)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包