void EarthHemsiphere::Render(IDeviceContext* pContext, const RenderingParams &NewParams, const float3 &vCameraPosition, const float4x4 &CameraViewProjMatrix, ITextureView *pShadowMapSRV, ITextureView *pPrecomputedNetDensitySRV, ITextureView *pAmbientSkylightSRV, bool bZOnlyPass) { if( m_Params.m_iNumShadowCascades != NewParams.m_iNumShadowCascades || m_Params.m_bBestCascadeSearch != NewParams.m_bBestCascadeSearch || m_Params.m_bSmoothShadows != NewParams.m_bSmoothShadows || m_Params.DstRTVFormat != NewParams.DstRTVFormat ) { m_pHemispherePS.Release(); } m_Params = NewParams; #if 0 if( GetAsyncKeyState(VK_F9) ) { m_RenderEarthHemisphereTech.Release(); } #endif if( !m_pHemispherePS ) { ShaderCreationAttribs Attrs; Attrs.FilePath = "HemispherePS.fx"; Attrs.EntryPoint = "HemispherePS"; Attrs.Desc.ShaderType = SHADER_TYPE_PIXEL; Attrs.Desc.Name = "HemispherePS"; ShaderVariableDesc ShaderVars[] = { {"g_tex2DShadowMap", SHADER_VARIABLE_TYPE_DYNAMIC}, }; Attrs.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL; BasicShaderSourceStreamFactory BasicSSSFactory("shaders;shaders\\terrain;"); Attrs.pShaderSourceStreamFactory = &BasicSSSFactory; StaticSamplerDesc StaticSamplers[5]; StaticSamplers[0].TextureName = "g_tex2DTileDiffuse"; StaticSamplers[0].Desc.AddressU = TEXTURE_ADDRESS_WRAP; StaticSamplers[0].Desc.AddressV = TEXTURE_ADDRESS_WRAP; StaticSamplers[0].Desc.AddressW = TEXTURE_ADDRESS_WRAP; StaticSamplers[1].TextureName = "g_tex2DTileNM"; StaticSamplers[1].Desc = StaticSamplers[0].Desc; StaticSamplers[2].TextureName = "g_tex2DNormalMap"; StaticSamplers[2].Desc.AddressU = TEXTURE_ADDRESS_MIRROR; StaticSamplers[2].Desc.AddressV = TEXTURE_ADDRESS_MIRROR; StaticSamplers[2].Desc.AddressW = TEXTURE_ADDRESS_MIRROR; StaticSamplers[3].TextureName = "g_tex2DMtrlMap"; StaticSamplers[3].Desc = StaticSamplers[2].Desc; StaticSamplers[4].TextureName = "g_tex2DShadowMap"; StaticSamplers[4].Desc.MinFilter = FILTER_TYPE_COMPARISON_LINEAR; StaticSamplers[4].Desc.MagFilter = FILTER_TYPE_COMPARISON_LINEAR; StaticSamplers[4].Desc.MipFilter = FILTER_TYPE_COMPARISON_LINEAR; StaticSamplers[4].Desc.ComparisonFunc = COMPARISON_FUNC_LESS; Attrs.Desc.StaticSamplers = StaticSamplers; Attrs.Desc.NumStaticSamplers = _countof(StaticSamplers); ShaderMacroHelper Macros; Macros.AddShaderMacro("TEXTURING_MODE", m_Params.m_TexturingMode); Macros.AddShaderMacro("NUM_TILE_TEXTURES", NUM_TILE_TEXTURES); Macros.AddShaderMacro("NUM_SHADOW_CASCADES", m_Params.m_iNumShadowCascades); Macros.AddShaderMacro("BEST_CASCADE_SEARCH", m_Params.m_bBestCascadeSearch ? true : false); Macros.AddShaderMacro("SMOOTH_SHADOWS", m_Params.m_bSmoothShadows ? true : false); Macros.Finalize(); Attrs.Macros = Macros; Attrs.Desc.VariableDesc = ShaderVars; Attrs.Desc.NumVariables = _countof(ShaderVars); m_pDevice->CreateShader( Attrs, &m_pHemispherePS ); m_pTerrainScript->Run( "SetHemispherePS", m_pHemispherePS, GetTextureFormatAttribs(m_Params.DstRTVFormat).Name ); } ViewFrustumExt ViewFrustum; auto DevType = m_pDevice->GetDeviceCaps().DevType; ExtractViewFrustumPlanesFromMatrix(CameraViewProjMatrix, ViewFrustum, DevType == DeviceType::D3D11 || DevType == DeviceType::D3D12); { MapHelper<TerrainAttribs> TerrainAttribs( pContext, m_pcbTerrainAttribs, MAP_WRITE, MAP_FLAG_DISCARD ); *TerrainAttribs = m_Params.m_TerrainAttribs; } #if 0 ID3D11ShaderResourceView *pSRVs[3 + 2*NUM_TILE_TEXTURES] = { m_ptex2DNormalMapSRV, m_ptex2DMtrlMaskSRV, pShadowMapSRV }; for(int iTileTex = 0; iTileTex < NUM_TILE_TEXTURES; iTileTex++) { pSRVs[3+iTileTex] = m_ptex2DTilesSRV[iTileTex]; pSRVs[3+NUM_TILE_TEXTURES+iTileTex] = m_ptex2DTilNormalMapsSRV[iTileTex]; } pd3dImmediateContext->PSSetShaderResources(1, _countof(pSRVs), pSRVs); pSRVs[0] = pPrecomputedNetDensitySRV; pSRVs[1] = pAmbientSkylightSRV; pd3dImmediateContext->VSSetShaderResources(0, 2, pSRVs); ID3D11SamplerState *pSamplers[] = {m_psamLinearMirror, m_psamLinearWrap, m_psamComaprison, m_psamLinearClamp}; pd3dImmediateContext->VSSetSamplers(0, _countof(pSamplers), pSamplers); pd3dImmediateContext->PSSetSamplers(0, _countof(pSamplers), pSamplers); #endif Uint32 offset[1] = { 0 }; Uint32 stride[1] = { sizeof(HemisphereVertex) }; IBuffer* ppBuffers[1] = { m_pVertBuff }; pContext->SetVertexBuffers( 0, 1, ppBuffers, stride, offset, SET_VERTEX_BUFFERS_FLAG_RESET); if( bZOnlyPass ) m_pTerrainScript->Run( pContext, "RenderHemisphereShadow" ); else { pShadowMapSRV->SetSampler( m_pComparisonSampler ); m_pTerrainScript->Run( pContext, "RenderHemisphere", pPrecomputedNetDensitySRV, pAmbientSkylightSRV, pShadowMapSRV ); } for(auto MeshIt = m_SphereMeshes.begin(); MeshIt != m_SphereMeshes.end(); ++MeshIt) { if(GetBoxVisibility<false>(ViewFrustum, MeshIt->BndBox) != BoxVisibility::Invisible) { pContext->SetIndexBuffer(MeshIt->pIndBuff, 0); DrawAttribs DrawAttrs; DrawAttrs.Topology = PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; DrawAttrs.IndexType = VT_UINT32; DrawAttrs.NumIndices = MeshIt->uiNumIndices; DrawAttrs.IsIndexed = true; pContext->Draw(DrawAttrs); } } pContext->SetIndexBuffer(m_pStitchIndBuff, 0); DrawAttribs DrawAttrs; DrawAttrs.Topology = PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; DrawAttrs.IndexType = VT_UINT32; DrawAttrs.NumIndices = m_uiNumStitchIndices; DrawAttrs.IsIndexed = true; pContext->Draw(DrawAttrs); }
void Tutorial08_Tessellation::Initialize(IRenderDevice *pDevice, IDeviceContext **ppContexts, Uint32 NumDeferredCtx, ISwapChain *pSwapChain) { const auto& deviceCaps = pDevice->GetDeviceCaps(); if(!deviceCaps.bTessellationSupported) { throw std::runtime_error("Hardware tessellation is not supported"); } SampleBase::Initialize(pDevice, ppContexts, NumDeferredCtx, pSwapChain); ShaderMacroHelper MacroHelper; { // Pipeline state object encompasses configuration of all GPU stages PipelineStateDesc PSODesc; // Pipeline state name is used by the engine to report issues // It is always a good idea to give objects descriptive names PSODesc.Name = "Terrain PSO"; // This is a graphics pipeline PSODesc.IsComputePipeline = false; // This tutorial will render to a single render target PSODesc.GraphicsPipeline.NumRenderTargets = 1; // Set render target format which is the format of the swap chain's color buffer PSODesc.GraphicsPipeline.RTVFormats[0] = pSwapChain->GetDesc().ColorBufferFormat; // Set depth buffer format which is the format of the swap chain's back buffer PSODesc.GraphicsPipeline.DSVFormat = pSwapChain->GetDesc().DepthBufferFormat; // Primitive topology type defines what kind of primitives will be rendered by this pipeline state PSODesc.GraphicsPipeline.PrimitiveTopologyType = PRIMITIVE_TOPOLOGY_TYPE_PATCH; // Cull back faces PSODesc.GraphicsPipeline.RasterizerDesc.CullMode = CULL_MODE_BACK; // Enable depth testing PSODesc.GraphicsPipeline.DepthStencilDesc.DepthEnable = True; // Create dynamic uniform buffer that will store shader constants CreateUniformBuffer(pDevice, sizeof(GlobalConstants), "Global shader constants CB", &m_ShaderConstants); ShaderCreationAttribs CreationAttribs; // Tell the system that the shader source code is in HLSL. // For OpenGL, the engine will convert this into GLSL behind the scene CreationAttribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL; // In this tutorial, we will load shaders from file. To be able to do that, // we need to create a shader source stream factory BasicShaderSourceStreamFactory BasicSSSFactory; CreationAttribs.pShaderSourceStreamFactory = &BasicSSSFactory; // Define variable type that will be used by default CreationAttribs.Desc.DefaultVariableType = SHADER_VARIABLE_TYPE_STATIC; // Create vertex shader RefCntAutoPtr<IShader> pVS; { CreationAttribs.Desc.ShaderType = SHADER_TYPE_VERTEX; CreationAttribs.EntryPoint = "TerrainVS"; CreationAttribs.Desc.Name = "Terrain VS"; CreationAttribs.FilePath = "terrain.vsh"; pDevice->CreateShader(CreationAttribs, &pVS); pVS->GetShaderVariable("VSConstants")->Set(m_ShaderConstants); } // Create geometry shader RefCntAutoPtr<IShader> pGS; { CreationAttribs.Desc.ShaderType = SHADER_TYPE_GEOMETRY; CreationAttribs.EntryPoint = "TerrainGS"; CreationAttribs.Desc.Name = "Terrain GS"; CreationAttribs.FilePath = "terrain.gsh"; pDevice->CreateShader(CreationAttribs, &pGS); pGS->GetShaderVariable("GSConstants")->Set(m_ShaderConstants); } // Create hull shader RefCntAutoPtr<IShader> pHS; { CreationAttribs.Desc.ShaderType = SHADER_TYPE_HULL; CreationAttribs.EntryPoint = "TerrainHS"; CreationAttribs.Desc.Name = "Terrain HS"; CreationAttribs.FilePath = "terrain.hsh"; ShaderVariableDesc Vars[] = { {"g_HeightMap", SHADER_VARIABLE_TYPE_MUTABLE} }; CreationAttribs.Desc.VariableDesc = Vars; CreationAttribs.Desc.NumVariables = _countof(Vars); // Define static sampler for g_Texture. Static samplers should be used whenever possible SamplerDesc SamLinearClampDesc( FILTER_TYPE_LINEAR, FILTER_TYPE_LINEAR, FILTER_TYPE_LINEAR, TEXTURE_ADDRESS_CLAMP, TEXTURE_ADDRESS_CLAMP, TEXTURE_ADDRESS_CLAMP); StaticSamplerDesc StaticSamplers[] = { {"g_HeightMap", SamLinearClampDesc} }; CreationAttribs.Desc.StaticSamplers = StaticSamplers; CreationAttribs.Desc.NumStaticSamplers = _countof(StaticSamplers); MacroHelper.AddShaderMacro("BLOCK_SIZE", m_BlockSize); CreationAttribs.Macros = MacroHelper; pDevice->CreateShader(CreationAttribs, &pHS); pHS->GetShaderVariable("HSConstants")->Set(m_ShaderConstants); } // Create domain shader RefCntAutoPtr<IShader> pDS; { CreationAttribs.Desc.ShaderType = SHADER_TYPE_DOMAIN; CreationAttribs.EntryPoint = "TerrainDS"; CreationAttribs.Desc.Name = "Terrain DS"; CreationAttribs.FilePath = "terrain.dsh"; CreationAttribs.Macros = nullptr; pDevice->CreateShader(CreationAttribs, &pDS); pDS->GetShaderVariable("DSConstants")->Set(m_ShaderConstants); } // Create pixel shader RefCntAutoPtr<IShader> pPS, pWirePS; { CreationAttribs.Desc.ShaderType = SHADER_TYPE_PIXEL; CreationAttribs.EntryPoint = "TerrainPS"; CreationAttribs.Desc.Name = "Terrain PS"; CreationAttribs.FilePath = "terrain.psh"; // Shader variables should typically be mutable, which means they are expected // to change on a per-instance basis ShaderVariableDesc Vars[] = { {"g_Texture", SHADER_VARIABLE_TYPE_MUTABLE} }; CreationAttribs.Desc.VariableDesc = Vars; CreationAttribs.Desc.NumVariables = _countof(Vars); // Define static sampler for g_Texture. Static samplers should be used whenever possible SamplerDesc SamLinearClampDesc( FILTER_TYPE_LINEAR, FILTER_TYPE_LINEAR, FILTER_TYPE_LINEAR, TEXTURE_ADDRESS_CLAMP, TEXTURE_ADDRESS_CLAMP, TEXTURE_ADDRESS_CLAMP); StaticSamplerDesc StaticSamplers[] = { {"g_Texture", SamLinearClampDesc} }; CreationAttribs.Desc.StaticSamplers = StaticSamplers; CreationAttribs.Desc.NumStaticSamplers = _countof(StaticSamplers); pDevice->CreateShader(CreationAttribs, &pPS); CreationAttribs.EntryPoint = "WireTerrainPS"; CreationAttribs.Desc.Name = "Wireframe Terrain PS"; CreationAttribs.FilePath = "terrain_wire.psh"; pDevice->CreateShader(CreationAttribs, &pWirePS); pWirePS->GetShaderVariable("PSConstants")->Set(m_ShaderConstants); } PSODesc.GraphicsPipeline.pVS = pVS; PSODesc.GraphicsPipeline.pHS = pHS; PSODesc.GraphicsPipeline.pDS = pDS; PSODesc.GraphicsPipeline.pPS = pPS; pDevice->CreatePipelineState(PSODesc, &m_pPSO[0]); PSODesc.GraphicsPipeline.pGS = pGS; PSODesc.GraphicsPipeline.pPS = pWirePS; pDevice->CreatePipelineState(PSODesc, &m_pPSO[1]); } { // Load texture TextureLoadInfo loadInfo; loadInfo.IsSRGB = false; loadInfo.Name = "Terrain height map"; RefCntAutoPtr<ITexture> HeightMap; CreateTextureFromFile("ps_height_1k.png", loadInfo, m_pDevice, &HeightMap); const auto HMDesc = HeightMap->GetDesc(); m_HeightMapWidth = HMDesc.Width; m_HeightMapHeight = HMDesc.Height; // Get shader resource view from the texture m_HeightMapSRV = HeightMap->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE); } { TextureLoadInfo loadInfo; loadInfo.IsSRGB = true; loadInfo.Name = "Terrain color map"; RefCntAutoPtr<ITexture> ColorMap; CreateTextureFromFile("ps_texture_2k.png", loadInfo, m_pDevice, &ColorMap); // Get shader resource view from the texture m_ColorMapSRV = ColorMap->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE); } // Since we are using mutable variable, we must create shader resource binding object // http://diligentgraphics.com/2016/03/23/resource-binding-model-in-diligent-engine-2-0/ for(size_t i=0; i < _countof(m_pPSO); ++i) { m_pPSO[i]->CreateShaderResourceBinding(&m_SRB[i]); // Set texture SRV in the SRB m_SRB[i]->GetVariable(SHADER_TYPE_PIXEL, "g_Texture")->Set(m_ColorMapSRV); m_SRB[i]->GetVariable(SHADER_TYPE_DOMAIN, "g_HeightMap")->Set(m_HeightMapSRV); m_SRB[i]->GetVariable(SHADER_TYPE_HULL, "g_HeightMap")->Set(m_HeightMapSRV); } // Create a tweak bar TwBar *bar = TwNewBar("Settings"); int barSize[2] = {224 * m_UIScale, 120 * m_UIScale}; TwSetParam(bar, NULL, "size", TW_PARAM_INT32, 2, barSize); // Add grid size control TwAddVarRW(bar, "Animate", TW_TYPE_BOOLCPP, &m_Animate, ""); TwAddVarRW(bar, "Adaptive tessellation", TW_TYPE_BOOLCPP, &m_AdaptiveTessellation, ""); TwAddVarRW(bar, "Wireframe", TW_TYPE_BOOLCPP, &m_Wireframe, ""); TwAddVarRW(bar, "Tess density", TW_TYPE_FLOAT, &m_TessDensity, "min=1 max=32 step=0.1"); TwAddVarRW(bar, "Distance", TW_TYPE_FLOAT, &m_Distance, "min=1 max=20 step=0.1"); }