PooledTextureRef ImageBasedLensFlare::Setup(const Ptr<Texture> & brightPassTex) { auto setupTexRef = TexturePool::Instance().FindFree({ TEXTURE_2D, brightPassTex->GetDesc() }); auto setupTex = setupTexRef->Get()->Cast<Texture>(); Global::GetRenderEngine()->GetRenderContext()->ClearRenderTarget(setupTex->GetRenderTargetView(0, 0, 1), 0.0f); auto ps = Shader::FindOrCreate<LensFlareSetupPS>(); Global::GetRenderEngine()->GetRenderContext()->SetBlendState( BlendStateTemplate<false, false, true, BLEND_PARAM_ONE, BLEND_PARAM_ONE, BLEND_OP_ADD>::Get()); int2 texSize = int2(setupTex->GetDesc().width / 2, setupTex->GetDesc().height / 2); int2 center = texSize; for (int i = 0; i < 3; ++i) { int2 xy = center - texSize / 2; ps->SetSRV("brightPassTex", brightPassTex->GetShaderResourceView()); ps->SetSampler("linearSampler", SamplerTemplate<>::Get()); ps->Flush(); DrawQuad({ setupTex->GetRenderTargetView(0, 0, 1) }, (float)xy.x(), (float)xy.y(), (float)texSize.x(), (float)texSize.y()); texSize /= 2; } for (int i = 0; i < 5; ++i) { int2 xy = center - texSize / 2; ps->SetSRV("brightPassTex", brightPassTex->GetShaderResourceView()); ps->SetSampler("linearSampler", SamplerTemplate<>::Get()); ps->Flush(); DrawQuad({ setupTex->GetRenderTargetView(0, 0, 1) }, (float)xy.x(), (float)xy.y(), (float)texSize.x(), (float)texSize.y(), 1.0f, 1.0f, -1.0f, -1.0f); texSize *= 2; } Global::GetRenderEngine()->GetRenderContext()->SetBlendState(nullptr); return setupTexRef; }
String ShininessToRoughnessTex(const String & path) { auto roughnessTexPath = path.substr(0, path.rfind('.')) + "_roughness" + TextureAsset::GetExtension(); if (Global::GetPlatform()->FileExists(roughnessTexPath)) return roughnessTexPath; auto shininessTexAsset = Asset::Find<TextureAsset>(path); if (!shininessTexAsset->IsInit()) { shininessTexAsset->Init(); auto roughnessTexDesc = shininessTexAsset->GetTexture()->GetDesc(); roughnessTexDesc.bindFlag = TEXTURE_BIND_SHADER_RESOURCE | TEXTURE_BIND_RENDER_TARGET | TEXTURE_BIND_GENERATE_MIPS; roughnessTexDesc.mipLevels = 0; auto roughnessTex = Global::GetRenderEngine()->GetRenderFactory()->CreateTexture(TEXTURE_2D); roughnessTex->SetDesc(roughnessTexDesc); roughnessTex->Init(); auto ps = Shader::FindOrCreate<ShininessToRoughnessPS>(); ps->SetSRV("shininessTex", shininessTexAsset->GetTexture()->GetShaderResourceView(0, 1, 0, 1)); ps->SetSampler("pointSampler", SamplerTemplate<FILTER_MIN_MAG_MIP_POINT>::Get()); ps->Flush(); DrawQuad({ roughnessTex->GetRenderTargetView(0, 0, 1) }); auto roughnessTexAsset = std::make_shared<TextureAsset>(); roughnessTexAsset->SetPath(roughnessTexPath); roughnessTexAsset->Register(); roughnessTexAsset->Save(); } return roughnessTexPath; }
Ptr<Texture> HeightToBumpTex(const Ptr<Texture> & heightTex, float scale) { auto bumpTexDesc = heightTex->GetDesc(); bumpTexDesc.format = RENDER_FORMAT_R8G8B8A8_UNORM; bumpTexDesc.bindFlag = TEXTURE_BIND_SHADER_RESOURCE | TEXTURE_BIND_RENDER_TARGET | TEXTURE_BIND_GENERATE_MIPS; bumpTexDesc.mipLevels = 0; auto bumpTex = Global::GetRenderEngine()->GetRenderFactory()->CreateTexture(TEXTURE_2D); bumpTex->SetDesc(bumpTexDesc); bumpTex->Init(); auto ps = Shader::FindOrCreate<HeightToBumpPS>(); ps->SetScalar("texSize", heightTex->GetTexSize()); ps->SetScalar("scale", scale); ps->SetSRV("heightTex", heightTex->GetShaderResourceView()); ps->SetSampler("pointSampler", SamplerTemplate<FILTER_MIN_MAG_MIP_POINT>::Get()); ps->Flush(); DrawQuad({ bumpTex->GetRenderTargetView(0, 0, 1) }); bumpTex->GenerateMips(); return bumpTex; }
PooledTextureRef SSR::SSRNeighborShare( const Ptr<RenderView> & view, const Ptr<Texture> & ssrResult, const Ptr<Texture> & gbuffer1, const Ptr<Texture> & depthTex, const Ptr<Texture> & ssrStencilMask) { auto resultTexRef = TexturePool::Instance().FindFree({ TEXTURE_2D, ssrResult->GetDesc() }); auto resultTex = resultTexRef->Get()->Cast<Texture>(); auto ps = Shader::FindOrCreate<SSRNeighborSharePS>(); view->BindShaderParams(ps); ps->SetScalar("texSize", ssrResult->GetTexSize()); ps->SetSRV("ssrTex", ssrResult->GetShaderResourceView()); ps->SetSRV("gbuffer1", gbuffer1->GetShaderResourceView()); ps->SetSRV("depthTex", depthTex->GetShaderResourceView(0, 0, 0, 0, false, RENDER_FORMAT_R24_UNORM_X8_TYPELESS)); ps->SetSampler("pointClampSampler", SamplerTemplate<FILTER_MIN_MAG_MIP_POINT>::Get()); ps->Flush(); DrawQuad({ resultTex->GetRenderTargetView(0, 0, 1) }, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, ssrStencilMask->GetDepthStencilView(0, 0, 1, RENDER_FORMAT_D24_UNORM_S8_UINT)); return resultTexRef; }
void BeginSceneCommand::run(ICommandContext* context) { auto device = context->GetDevice(); auto graphicsContext = device->GetContext(); graphicsContext->ClearRenderTargetView( device->GetRenderTargetView(), reinterpret_cast<const float*>(&Math::Color::Grey) ); graphicsContext->ClearDepthStencilView( device->GetDepthStencilView(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0, 0 ); }
PooledTextureRef SSR::BuildHZB(const Ptr<Texture> & depthTex) { auto texDesc = depthTex->GetDesc(); texDesc.format = RENDER_FORMAT_R16_FLOAT; texDesc.bindFlag = TEXTURE_BIND_SHADER_RESOURCE | TEXTURE_BIND_RENDER_TARGET; texDesc.mipLevels = 0; auto hzb0Ref = TexturePool::Instance().FindFree({ TEXTURE_2D, texDesc }); auto hzb1Ref = TexturePool::Instance().FindFree({ TEXTURE_2D, texDesc }); auto hzb0 = hzb0Ref->Get()->Cast<Texture>(); auto hzb1 = hzb1Ref->Get()->Cast<Texture>(); Transform( depthTex->GetShaderResourceView(0, 1, 0, 1, false, RENDER_FORMAT_R24_UNORM_X8_TYPELESS), hzb0Ref->Get()->Cast<Texture>()->GetRenderTargetView(0, 0, 1)); auto rc = Global::GetRenderEngine()->GetRenderContext(); auto ps = Shader::FindOrCreate<HZBBuildPS>(); for (int32_t mipLevel = 1; mipLevel < hzb0->GetDesc().mipLevels; ++mipLevel) { auto & mipSize = hzb0->GetMipSize(mipLevel - 1); auto w = mipSize.x(); auto h = mipSize.y(); float4 screenSize = float4((float)w, (float)h, 1.0f / (float)w, 1.0f / (float)h); ps->SetScalar("screenSize", screenSize); ps->SetScalar("mipLevel", (float)(mipLevel - 1)); ps->SetSRV("depthTex", hzb0->GetShaderResourceView()); ps->SetSampler("pointSampler", SamplerTemplate<FILTER_MIN_MAG_MIP_POINT>::Get()); ps->Flush(); auto & targetMipSize = hzb0->GetMipSize(mipLevel); DrawQuad({ hzb1->GetRenderTargetView(mipLevel, 0, 1) }); hzb1->CopyTo(hzb0, mipLevel, 0, 0, 0, 0, mipLevel, 0); } return hzb0Ref; }
void PostProcessVolumetricLight::Render(const Ptr<RenderView> & view) { if (!_light) return; auto sceneTex = view->GetViewRenderContext()->GetSharedTexture("RenderResult"); auto sceneLinearClipDepth = view->GetViewRenderContext()->GetSharedTexture("SceneLinearClipDepth"); auto radialBlurInTexRef = Setup(sceneTex, sceneLinearClipDepth); auto radialBlurInTex = radialBlurInTexRef->Get()->Cast<Texture>(); auto lightPosH = _light->GetClipSpacePos(view->GetCamera()); auto lightPosUV = lightPosH * float2(0.5f, -0.5f) + float2(0.5f, 0.5f); auto volumetricLightTexRef = RenderVolumetricLight(lightPosUV, radialBlurInTex); auto volumetricLightTex = volumetricLightTexRef->Get()->Cast<Texture>(); BlurVolumetricLight(lightPosUV, sceneLinearClipDepth, volumetricLightTex, sceneTex->GetRenderTargetView(0, 0, 1)); }
PooledTextureRef PostProcessVolumetricLight::Setup(const Ptr<Texture> & sceneTex, const Ptr<Texture> & linearDepthTex) { auto texDesc = sceneTex->GetDesc(); texDesc.width /= 2; texDesc.height /= 2; auto resultTexRef = TexturePool::Instance().FindFree({ TEXTURE_2D, texDesc }); auto resultTex = resultTexRef->Get()->Cast<Texture>(); auto ps = Shader::FindOrCreate<PPVolumeSetupPS>(); ps->SetSRV("sceneTex", sceneTex->GetShaderResourceView()); ps->SetSRV("linearDepthTex", linearDepthTex->GetShaderResourceView()); ps->SetSampler("pointSampler", SamplerTemplate<FILTER_MIN_MAG_MIP_POINT>::Get()); ps->Flush(); DrawQuad({ resultTex->GetRenderTargetView(0, 0, 1) }); return resultTexRef; }
PooledTextureRef ToneMapping::BrightPass(const Ptr<Texture> & sceneTex, const Ptr<Texture> & adaptedExposureScale) { auto texDesc = sceneTex->GetDesc(); texDesc.mipLevels = 1; texDesc.format = RENDER_FORMAT_R11G11B10_FLOAT; texDesc.bindFlag = TEXTURE_BIND_SHADER_RESOURCE | TEXTURE_BIND_RENDER_TARGET | TEXTURE_BIND_GENERATE_MIPS; auto brightPassTexRef = TexturePool::Instance().FindFree({ TEXTURE_2D, texDesc }); auto brightPassTex = brightPassTexRef->Get()->Cast<Texture>(); auto ps = Shader::FindOrCreate<BrightPassPS>(); ps->SetScalar("brightPassThreshold", _brightPassThreshold); ps->SetSRV("sceneTex", sceneTex->GetShaderResourceView()); ps->SetSRV("adaptedExposureScale", adaptedExposureScale->GetShaderResourceView()); ps->SetSampler("pointSampler", SamplerTemplate<FILTER_MIN_MAG_MIP_POINT>::Get()); ps->Flush(); DrawQuad({ brightPassTex->GetRenderTargetView(0, 0, 1) }); return brightPassTexRef; }
PooledTextureRef PostProcessVolumetricLight::RenderVolumetricLight(const float2 & lightPosUV, const Ptr<Texture> & setupTex) { auto resultTexRef = TexturePool::Instance().FindFree({ TEXTURE_2D, setupTex->GetDesc() }); auto resultTex = resultTexRef->Get()->Cast<Texture>(); auto ps = Shader::FindOrCreate<RadialBlurPS>(); ps->SetScalar("lightPosUV", lightPosUV); ps->SetScalar("density", _density); ps->SetScalar("intensity", _intensity); ps->SetScalar("decay", _decay); ps->SetScalar("frameCount", (uint32_t)Global::GetInfo()->frameCount); ps->SetSRV("sceneTex", setupTex->GetShaderResourceView()); ps->SetSampler("linearSampler", SamplerTemplate<>::Get()); ps->Flush(); DrawQuad({ resultTex->GetRenderTargetView(0, 0, 1) }); return resultTexRef; }
void ToneMapping::BloomBlur(const Ptr<Texture> & inTex, float blurRadius) { TextureDesc texDesc = inTex->GetDesc(); auto tmpTexRef = TexturePool::Instance().FindFree({ TEXTURE_2D, texDesc }); auto tmpTex = tmpTexRef->Get()->Cast<Texture>(); { int32_t tableSize = (int32_t)blurRadius * 2 + 1; auto & gaussTable = GetGaussTable(tableSize); int32_t sampleIndex = 0; float weightSum = 0.0f; std::vector<float2> offsets; std::vector<float> weights; for (; sampleIndex < tableSize - 1; sampleIndex += 2) { float offsetStart = (float)sampleIndex - blurRadius; float weight0 = gaussTable[sampleIndex]; float weight1 = gaussTable[sampleIndex + 1]; weights.push_back(weight0 + weight1); offsets.push_back(float2(1.0f, 0.0f) * (offsetStart + weight1 / weights.back())); weightSum += weights.back(); } weights.push_back(gaussTable.back()); offsets.push_back(float2(1.0f, 0.0f) * blurRadius); for (auto & w : weights) w /= weightSum; for (auto & offset : offsets) offset /= float2((float)inTex->GetDesc().width, (float)inTex->GetDesc().height); TextureFilter(inTex->GetShaderResourceView(), tmpTex->GetRenderTargetView(0, 0, 1), offsets, weights, SamplerTemplate<FILTER_MIN_MAG_MIP_LINEAR>::Get()); } { int32_t tableSize = (int32_t)blurRadius * 2 + 1; auto & gaussTable = GetGaussTable(tableSize); int32_t sampleIndex = 0; float weightSum = 0.0f; std::vector<float2> offsets; std::vector<float> weights; for (; sampleIndex < tableSize - 1; sampleIndex += 2) { float offsetStart = (float)sampleIndex - blurRadius; float weight0 = gaussTable[sampleIndex]; float weight1 = gaussTable[sampleIndex + 1]; weights.push_back(weight0 + weight1); offsets.push_back(float2(0.0f, 1.0f) * (offsetStart + weight1 / weights.back())); weightSum += weights.back(); } weights.push_back(gaussTable.back()); offsets.push_back(float2(0.0f, 1.0f) * blurRadius); for (auto & w : weights) w /= weightSum; for (auto & offset : offsets) offset /= float2((float)inTex->GetDesc().width, (float)inTex->GetDesc().height); TextureFilter(tmpTex->GetShaderResourceView(), inTex->GetRenderTargetView(0, 0, 1), offsets, weights, SamplerTemplate<FILTER_MIN_MAG_MIP_LINEAR>::Get()); } }
void SSR::Render(const Ptr<RenderView> & view) { auto sceneTex = view->GetViewRenderContext()->GetSharedTexture("RenderResult"); auto sceneClipDepth = view->GetViewRenderContext()->GetSharedTexture("SceneClipDepth"); auto gbuffer0 = view->GetViewRenderContext()->GetSharedTexture("GBuffer0"); auto gbuffer1 = view->GetViewRenderContext()->GetSharedTexture("GBuffer1"); TextureDesc ssrDesc = sceneTex->GetDesc(); ssrDesc.format = RENDER_FORMAT_R16G16B16A16_FLOAT; auto ssrResultTexRef = TexturePool::Instance().FindFree({ TEXTURE_2D, ssrDesc }); auto ssrResult = ssrResultTexRef->Get()->Cast<Texture>(); auto tmpDepthTexRef = TexturePool::Instance().FindFree({ TEXTURE_2D, sceneClipDepth->GetDesc() }); auto tmpDepthTex = tmpDepthTexRef->Get()->Cast<Texture>(); sceneClipDepth->CopyTo(tmpDepthTex, 0, 0, 0, 0, 0, 0, 0); auto ps = Shader::FindOrCreate<ScreenSpaceReflectionPS>(); view->BindShaderParams(ps); ps->SetScalar("frameCount", Global::GetInfo()->frameCount); ps->SetScalar("ssrMaxRoughness", _ssrMaxRoughness); ps->SetScalar("ssrIntensity", _ssrIntensity); ps->SetSRV("sceneTex", sceneTex->GetShaderResourceView()); ps->SetSRV("depthTex", tmpDepthTex->GetShaderResourceView(0, 0, 0, 0, false, RENDER_FORMAT_R24_UNORM_X8_TYPELESS)); ps->SetSRV("gbuffer0", gbuffer0->GetShaderResourceView()); ps->SetSRV("gbuffer1", gbuffer1->GetShaderResourceView()); ps->SetSampler("pointClampSampler", SamplerTemplate<FILTER_MIN_MAG_MIP_POINT>::Get()); ps->SetSampler("linearSampler", SamplerTemplate<>::Get()); ps->Flush(); auto rc = Global::GetRenderEngine()->GetRenderContext(); rc->SetDepthStencilState( DepthStencilStateTemplate< false, DEPTH_WRITE_ZERO, COMPARISON_LESS, true, 0xff, 0xff, STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP, COMPARISON_NOT_EQUAL>::Get(), 0); DrawQuad( { ssrResult->GetRenderTargetView(0, 0, 1) }, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, sceneClipDepth->GetDepthStencilView(0, 0, 1, RENDER_FORMAT_D24_UNORM_S8_UINT)); auto ssrSharedRef = SSRNeighborShare(view, ssrResult, gbuffer1, tmpDepthTex, sceneClipDepth); auto ssrShared = ssrSharedRef->Get()->Cast<Texture>(); // Temporal AA for SSR auto ssrAAedResultTexRef = TexturePool::Instance().FindFree({ TEXTURE_2D, sceneTex->GetDesc() }); auto ssrAAedResultTex = ssrAAedResultTexRef->Get()->Cast<Texture>(); { auto adaptedExposureScale = view->GetViewRenderContext()->GetSharedTexture("AdaptedExposureScale"); float2 offsets[5] = { float2(0.0f, 0.0f), float2(-1.0f, 0.0f), float2(1.0f, 0.0f), float2(0.0f, -1.0f), float2(0.0f, 1.0f), }; float filterWeights[5]; float weightsSum = 0.0f; for (int i = 0; i < 5; ++i) { float2 offset = offsets[i] - float2(0.5f, -0.5f) * view->temporalAAJitter; //filterWeights[i] = CatmullRom(offset.x()) * CatmullRom(offset.y()); offset.x() *= 1.0f + 0.0f * 0.5f; offset.y() *= 1.0f + 0.0f * 0.5f; filterWeights[i] = exp(-2.29f * (offset.x() * offset.x() + offset.y() * offset.y())); weightsSum += filterWeights[i]; } for (auto & i : filterWeights) i /= weightsSum; std::map<String, String> macros; macros["TAA_DYNAMIC"] = "0"; macros["TAA_HISTORY_BICUBIC"] = "0"; auto ps = Shader::FindOrCreate<TemporalAAPS>(macros); view->BindShaderParams(ps); ps->SetScalar("texSize", ssrResult->GetTexSize()); ps->SetScalar("neighborFilterWeights", filterWeights, (int)sizeof(float) * 5); ps->SetScalar("frameCount", (uint32_t)Global::GetInfo()->frameCount); ps->SetScalar("lerpFactor", 0.125f); //ps->SetSRV("linearDepth", sceneLinearClipDepth->GetShaderResourceView()); ps->SetSRV("sceneDepth", sceneClipDepth->GetShaderResourceView(0, 0, 0, 0, false, RENDER_FORMAT_R24_UNORM_X8_TYPELESS)); ps->SetSRV("sceneTex", ssrShared->GetShaderResourceView()); //ps->SetSRV("velocityTex", velocityTex->GetShaderResourceView()); //ps->SetSRV("adaptedExposureScale", adaptedExposureScale->GetShaderResourceView()); if (_preSSRResultRef) ps->SetSRV("historyTex", _preSSRResultRef->Get()->Cast<Texture>()->GetShaderResourceView()); else ps->SetSRV("historyTex", nullptr); ps->SetSampler("pointSampler", SamplerTemplate<FILTER_MIN_MAG_MIP_POINT>::Get()); ps->SetSampler("linearSampler", SamplerTemplate<>::Get()); ps->Flush(); DrawQuad( { ssrAAedResultTex->GetRenderTargetView(0, 0, 1) }, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, sceneClipDepth->GetDepthStencilView(0, 0, 1, RENDER_FORMAT_D24_UNORM_S8_UINT)); _preSSRResultRef = ssrResultTexRef; } /*rc->SetBlendState( BlendStateTemplate<false, false, true, BLEND_PARAM_ONE, BLEND_PARAM_ONE, BLEND_OP_ADD>::Get()); rc->SetDepthStencil(sceneClipDepth->GetDepthStencilView(0, 0, 1, RENDER_FORMAT_D24_UNORM_S8_UINT)); Transform( ssrAAedResultTex->GetShaderResourceView(), sceneTex->GetRenderTargetView(0, 0, 1), { COLOR_WRITE_R, COLOR_WRITE_G ,COLOR_WRITE_B ,COLOR_WRITE_A }, 0.0f, 0.0f, nullptr, sceneClipDepth->GetDepthStencilView(0, 0, 1, RENDER_FORMAT_D24_UNORM_S8_UINT));*/ rc->SetBlendState(nullptr); rc->SetDepthStencilState(nullptr); view->GetViewRenderContext()->SetSharedResource("SSR", ssrAAedResultTexRef); }