diff options
| author | Jason Maskell <[email protected]> | 2016-05-09 10:39:54 +0200 |
|---|---|---|
| committer | Jason Maskell <[email protected]> | 2016-05-09 10:39:54 +0200 |
| commit | 79b3462799c28af8ba586349bd671b1b56e72353 (patch) | |
| tree | 3b06e36c390254c0dc7f3733a0d32af213d87293 /demo/ocean_psm.cpp | |
| download | waveworks_archive-79b3462799c28af8ba586349bd671b1b56e72353.tar.xz waveworks_archive-79b3462799c28af8ba586349bd671b1b56e72353.zip | |
Initial commit with PS4 and XBone stuff trimmed.
Diffstat (limited to 'demo/ocean_psm.cpp')
| -rw-r--r-- | demo/ocean_psm.cpp | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/demo/ocean_psm.cpp b/demo/ocean_psm.cpp new file mode 100644 index 0000000..a213ad0 --- /dev/null +++ b/demo/ocean_psm.cpp @@ -0,0 +1,243 @@ +// This code contains NVIDIA Confidential Information and is disclosed +// under the Mutual Non-Disclosure Agreement. +// +// Notice +// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES +// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless +// expressly authorized by NVIDIA. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright � 2008- 2013 NVIDIA Corporation. All rights reserved. +// +// NVIDIA Corporation and its licensors retain all intellectual property and proprietary +// rights in and to this software and related documentation and any modifications thereto. +// Any use, reproduction, disclosure or distribution of this software and related +// documentation without an express license agreement from NVIDIA Corporation is +// strictly prohibited. +// + +#include "DXUT.h" +#include "ocean_psm.h" + +#include "ocean_shader_common.h" + +extern HRESULT LoadFile(LPCTSTR FileName, ID3DXBuffer** ppBuffer); + +namespace { + + enum { kPSMLayersPerSlice = 2 }; +} + +OceanPSM::OceanPSM() +{ + m_pFX = NULL; + m_pPropagatePSMTechnique = NULL; + m_pRenderPSMToUITechnique = NULL; + + m_pPSMPropagationMapUAVVariable = NULL; + m_pPSMMapVariable = NULL; + + m_pd3dDevice = DXUTGetD3D11Device(); + m_pPSMSRV = NULL; + m_pPSMUAV = NULL; + m_pPSMRTV = NULL; + + m_PSM_w = 0; + m_PSM_h = 0; + m_PSM_d = 0; + m_PSM_num_slices = 0; + + m_PsmBoundsMax = D3DXVECTOR3(1.f,1.f,1.f); + m_PsmBoundsMin = D3DXVECTOR3(-1.f,-1.f,-1.f); + + D3DXMatrixIdentity(&m_matPSMView); + D3DXMatrixIdentity(&m_matPSMProj); + D3DXMatrixIdentity(&m_matWorldToPSMUV); +} + +OceanPSM::~OceanPSM() +{ + SAFE_RELEASE(m_pFX); + + SAFE_RELEASE(m_pPSMSRV); + SAFE_RELEASE(m_pPSMUAV); + SAFE_RELEASE(m_pPSMRTV); +} + +HRESULT OceanPSM::init( const D3DXVECTOR3& psm_bounds_min, + const D3DXVECTOR3& psm_bounds_max, + int nominal_res + ) +{ + HRESULT hr; + + m_PsmBoundsMin = psm_bounds_min; + m_PsmBoundsMax = psm_bounds_max; + + const D3DXVECTOR3 psm_bounds_extents = psm_bounds_max - psm_bounds_min; + const float world_volume_of_psm_bounds = psm_bounds_extents.x * psm_bounds_extents.y * psm_bounds_extents.z; + const float voxel_volume = world_volume_of_psm_bounds / float(nominal_res*nominal_res*nominal_res); + const float voxel_length = powf(voxel_volume,1/3.f); + + m_PSM_w = (int)ceilf(psm_bounds_extents.x/voxel_length); + m_PSM_h = (int)ceilf(psm_bounds_extents.y/voxel_length); + m_PSM_d = (int)ceilf(psm_bounds_extents.z/voxel_length); + m_PSM_num_slices = (m_PSM_d/kPSMLayersPerSlice)-1; + + SAFE_RELEASE(m_pFX); + ID3DXBuffer* pEffectBuffer = NULL; + V_RETURN(LoadFile(TEXT(".\\Media\\ocean_psm_d3d11.fxo"), &pEffectBuffer)); + V_RETURN(D3DX11CreateEffectFromMemory(pEffectBuffer->GetBufferPointer(), pEffectBuffer->GetBufferSize(), 0, m_pd3dDevice, &m_pFX)); + pEffectBuffer->Release(); + + m_pPropagatePSMTechnique = m_pFX->GetTechniqueByName("PropagatePSMTech"); + m_pRenderPSMToUITechnique = m_pFX->GetTechniqueByName("RenderPSMToUITech"); + + m_pPSMPropagationMapUAVVariable = m_pFX->GetVariableByName("g_PSMPropagationMapUAV")->AsUnorderedAccessView(); + m_pPSMMapVariable = m_pFX->GetVariableByName("g_PSMMap")->AsShaderResource(); + + // Create PSM texture + { + D3D11_TEXTURE3D_DESC texDesc; + texDesc.Format = DXGI_FORMAT_R16G16_TYPELESS; + texDesc.Width = m_PSM_w; + texDesc.Height = m_PSM_h; + texDesc.MipLevels = 1; + texDesc.Depth = m_PSM_d/kPSMLayersPerSlice; + // texDesc.SampleDesc.Count = 1; + // texDesc.SampleDesc.Quality = 0; + texDesc.Usage = D3D11_USAGE_DEFAULT; + texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET | D3D11_BIND_UNORDERED_ACCESS; + texDesc.CPUAccessFlags = 0; + texDesc.MiscFlags = 0; + + ID3D11Texture3D* pTex = NULL; + V_RETURN(m_pd3dDevice->CreateTexture3D(&texDesc, NULL, &pTex)); + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + srvDesc.Texture3D.MostDetailedMip = 0; + srvDesc.Texture3D.MipLevels = texDesc.MipLevels; + srvDesc.Format = DXGI_FORMAT_R16G16_UNORM; + V_RETURN(m_pd3dDevice->CreateShaderResourceView(pTex, &srvDesc, &m_pPSMSRV) ); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = 0; + rtvDesc.Texture3D.FirstWSlice = 0; + rtvDesc.Texture3D.WSize = texDesc.Depth; + rtvDesc.Format = DXGI_FORMAT_R16G16_UNORM; + V_RETURN(m_pd3dDevice->CreateRenderTargetView(pTex, &rtvDesc, &m_pPSMRTV) ); + + D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; + uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D; + uavDesc.Texture3D.MipSlice = 0; + uavDesc.Texture3D.FirstWSlice = 0; + uavDesc.Texture3D.WSize = texDesc.Depth; + uavDesc.Format = DXGI_FORMAT_R32_UINT; + V_RETURN(m_pd3dDevice->CreateUnorderedAccessView(pTex, &uavDesc, &m_pPSMUAV) ); + + SAFE_RELEASE(pTex); + } + + return S_OK; +} + +void OceanPSM::beginRenderToPSM(const D3DXMATRIX& matPSM, ID3D11DeviceContext* pDC) +{ + D3DXMatrixInverse(&m_matPSMView,NULL,&matPSM); + + // We use proj to scale and translate to PSM from local space + const D3DXVECTOR4 PSM_centre_local = 0.5f * (m_PsmBoundsMax + m_PsmBoundsMin); + const D3DXVECTOR4 PSM_extents_local = m_PsmBoundsMax - m_PsmBoundsMin; + D3DXMATRIX TranslationComponent, ScalingComponent; + D3DXMatrixTranslation(&TranslationComponent, -PSM_centre_local.x, -PSM_centre_local.y, m_PsmBoundsMax.z); // Using z-max because effective light-dir is pointing down + D3DXMatrixScaling(&ScalingComponent, 2.f/PSM_extents_local.x, 2.f/PSM_extents_local.y, 1.f/PSM_extents_local.z); + m_matPSMProj = TranslationComponent * ScalingComponent; + + D3DXMATRIX matProjToUV; + D3DXMatrixTranslation(&matProjToUV,0.5f,0.5f,0.f); + matProjToUV._11 = 0.5f; + matProjToUV._22 = -0.5f; + m_matWorldToPSMUV = m_matPSMView * m_matPSMProj * matProjToUV; + + // Save rt setup to restore shortly... + m_num_saved_viewports = sizeof(m_saved_viewports)/sizeof(m_saved_viewports[0]); + pDC->RSGetViewports( &m_num_saved_viewports, m_saved_viewports); + + pDC->OMSetRenderTargets(1, &m_pPSMRTV, NULL); + const D3D11_VIEWPORT opacityViewport = {0.f, 0.f, FLOAT(m_PSM_w), FLOAT(m_PSM_h), 0.f, 1.f }; + pDC->RSSetViewports(1, &opacityViewport); + + const D3DXVECTOR4 PSMClearColor(1.f,1.f,1.f,1.f); + pDC->ClearRenderTargetView(m_pPSMRTV, (FLOAT*)&PSMClearColor); +} + +void OceanPSM::endRenderToPSM(ID3D11DeviceContext* pDC) +{ + // Restore original viewports + pDC->RSSetViewports(m_num_saved_viewports, m_saved_viewports); + + // Release RTV + ID3D11RenderTargetView* pNullRTV = NULL; + pDC->OMSetRenderTargets(1, &pNullRTV, NULL); + + // Propagate opacity + m_pPSMPropagationMapUAVVariable->SetUnorderedAccessView(m_pPSMUAV); + m_pPropagatePSMTechnique->GetPassByIndex(0)->Apply(0, pDC); + + const int num_groups_w = 1 + (m_PSM_w-1)/PSMPropagationCSBlockSize; + const int num_groups_h = 1 + (m_PSM_h-1)/PSMPropagationCSBlockSize; + pDC->Dispatch(num_groups_w,num_groups_h,1); + + // Release inputs + m_pPSMPropagationMapUAVVariable->SetUnorderedAccessView(NULL); + m_pPropagatePSMTechnique->GetPassByIndex(0)->Apply(0, pDC); +} + +void OceanPSM::renderToUI(ID3D11DeviceContext* pDC) +{ + m_pPSMMapVariable->SetResource(m_pPSMSRV); + m_pRenderPSMToUITechnique->GetPassByIndex(0)->Apply(0, pDC); + + pDC->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + pDC->IASetInputLayout(NULL); + pDC->Draw(4,0); + + m_pPSMMapVariable->SetResource(NULL); + m_pRenderPSMToUITechnique->GetPassByIndex(0)->Apply(0, pDC); +} + +void OceanPSM::setWriteParams(const OceanPSMParams& params) +{ + params.m_pPSMSlicesVariable->SetFloat(float(m_PSM_num_slices)); +} + +void OceanPSM::setReadParams(const OceanPSMParams& params, const D3DXVECTOR3& tint_color) +{ + params.m_pPSMTintVariable->SetFloatVector((FLOAT*)&tint_color); + params.m_pPSMSlicesVariable->SetFloat(float(m_PSM_num_slices)); + params.m_pPSMMapVariable->SetResource(m_pPSMSRV); +} + +OceanPSMParams::OceanPSMParams(ID3DX11Effect* pFX) +{ + m_pPSMMapVariable = pFX->GetVariableByName("g_PSMMap")->AsShaderResource(); + m_pPSMSlicesVariable = pFX->GetVariableByName("g_PSMSlices")->AsScalar(); + m_pPSMTintVariable = pFX->GetVariableByName("g_PSMTint")->AsVector(); +} + +void OceanPSM::clearReadParams(const OceanPSMParams& params) +{ + params.m_pPSMMapVariable->SetResource(NULL); +} |