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; }
void PostProcessVolumetricLight::BlurVolumetricLight( const float2 & lightPosUV, const Ptr<Texture> & linearDepthTex, const Ptr<Texture> & volumetricLightTex, const Ptr<RenderTargetView> & target) { auto ps = Shader::FindOrCreate<BlurVolumetricLightPS>(); ps->SetScalar("lightPosUV", lightPosUV); ps->SetScalar("texSize", volumetricLightTex->GetTexSize()); ps->SetSRV("volumetricLightTex", volumetricLightTex->GetShaderResourceView()); ps->SetSRV("linearDepthTex", linearDepthTex->GetShaderResourceView()); ps->SetSampler("pointSampler", SamplerTemplate<FILTER_MIN_MAG_MIP_POINT>::Get()); ps->SetSampler("linearSampler", SamplerTemplate<>::Get()); ps->Flush(); Global::GetRenderEngine()->GetRenderContext()->SetBlendState(BlendStateTemplate<false, false, true, BLEND_PARAM_ONE, BLEND_PARAM_ONE, BLEND_OP_ADD>::Get()); DrawQuad({ target }); Global::GetRenderEngine()->GetRenderContext()->SetBlendState(nullptr); }
PooledTextureRef ToneMapping::ComputeToneMappingLUT() { TextureDesc lutTexDesc; lutTexDesc.width = lutTexDesc.height = lutTexDesc.depth = 32; lutTexDesc.arraySize = 1; lutTexDesc.bCube = false; lutTexDesc.bindFlag = TEXTURE_BIND_RENDER_TARGET | TEXTURE_BIND_SHADER_RESOURCE; lutTexDesc.cpuAccess = 0; lutTexDesc.format = RENDER_FORMAT_R11G11B10_FLOAT; lutTexDesc.mipLevels = 1; lutTexDesc.sampleCount = 1; lutTexDesc.sampleQuality = 0; auto lutTexRef = TexturePool::Instance().FindFree({ TEXTURE_3D, lutTexDesc }); auto lutTex = lutTexRef->Get()->Cast<Texture>(); float WhiteTemp = 6500.0f; float WhiteTint = 0.0f; float3 ColorSaturation = 1.0f; float3 ColorContrast = 1.0f; float3 ColorGamma = 1.0f; float3 ColorGain = 1.0f; float3 ColorOffset = 0.0f; float FilmSlope = 0.88f; float FilmToe = 0.55f; float FilmShoulder = 0.26f; float FilmBlackClip = 0.0f; float FilmWhiteClip = 0.04f; auto ps = Shader::FindOrCreate<ToneMappingLUTPS>(); ps->SetScalar("WhiteTemp", WhiteTemp); ps->SetScalar("WhiteTint", WhiteTint); ps->SetScalar("ColorSaturation", ColorSaturation); ps->SetScalar("ColorContrast", ColorContrast); ps->SetScalar("ColorGamma", ColorGamma); ps->SetScalar("ColorGain", ColorGain); ps->SetScalar("ColorOffset", ColorOffset); ps->SetScalar("FilmSlope", FilmSlope); ps->SetScalar("FilmToe", FilmToe); ps->SetScalar("FilmShoulder", FilmShoulder); ps->SetScalar("FilmBlackClip", FilmBlackClip); ps->SetScalar("FilmWhiteClip", FilmWhiteClip); ps->Flush(); RenderToVolumeTexture(lutTex); return lutTexRef; }
int WindowEntry::SetThreshold(const char *threshold) { int r = 0; dtrace("\"%s\"", threshold); SetScalar(0, threshold); if (D != NULL) { r = gd_alter_entry(D->D, E.field, &E, 0); if (!r) { switch(E.u.window.windop) { case GD_WINDOP_EQ: case GD_WINDOP_NE: r = gd_get_constant(D->D, threshold, GD_INT64, &E.u.window.threshold.i); break; case GD_WINDOP_SET: case GD_WINDOP_CLR: r = gd_get_constant(D->D, threshold, GD_UINT64, &E.u.window.threshold.u); break; default: r = gd_get_constant(D->D, threshold, GD_FLOAT64, &E.u.window.threshold.r); break; } } } dreturn("%i", r); return r; }
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 ReplaceMaterialParam(const Palleon::MaterialPtr& material, const char* paramName, float newParamValue) { auto param = material->GetEffectParameter(paramName); float paramValue = param.GetScalar(); paramValue = (newParamValue == 1000.f) ? paramValue : newParamValue; param.SetScalar(paramValue); material->SetEffectParameter(paramName, param); }
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 TextureFilter( const Ptr<ShaderResourceView> & src, const Ptr<RenderTargetView> & dst, const std::vector<float2> & uvOffsets, const std::vector<float> & weights, const Ptr<class Sampler> & sampler) { ToyGE_ASSERT(uvOffsets.size() == weights.size()); ToyGE_ASSERT(src); ToyGE_ASSERT(dst); int32_t numSamples = (int32_t)uvOffsets.size(); if (numSamples <= 0) return; auto rc = Global::GetRenderEngine()->GetRenderContext(); rc->SetViewport(GetTextureQuadViewport(dst->GetResource()->Cast<Texture>())); auto filterVS = Shader::FindOrCreate<FilterVS>({ { "NUM_SAMPLES", std::to_string(numSamples) } }); auto filterPS = Shader::FindOrCreate<FilterPS>({ { "NUM_SAMPLES", std::to_string(numSamples) } }); filterVS->SetScalar("samplesOffsets", &uvOffsets[0], (int32_t)(sizeof(uvOffsets[0]) * uvOffsets.size())); filterVS->Flush(); filterPS->SetScalar("samplesWeights", &weights[0], (int32_t)(sizeof(weights[0]) * weights.size())); filterPS->SetSRV("filterTex", src); filterPS->SetSampler("filterSampler", sampler ? sampler : SamplerTemplate<>::Get()); filterPS->Flush(); rc->SetRenderTargets({ dst }); rc->SetDepthStencil(nullptr); rc->SetDepthStencilState(DepthStencilStateTemplate<false>::Get()); rc->SetVertexBuffer({ GetQuadVBs()[0] }); rc->SetIndexBuffer(GetQuadIB()); rc->SetPrimitiveTopology(PRIMITIVE_TOPOLOGY_TRIANGLELIST); rc->DrawIndexed(0, 0); }
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 BilateralUpSampling( const Ptr<ShaderResourceView> & src, const Ptr<RenderTargetView> & dst, const Ptr<ShaderResourceView> & lowResDepthTex, const Ptr<ShaderResourceView> & highResDepthTex, float depthDiffThreshold) { auto srcTex = src->GetResource()->Cast<Texture>(); auto ps = Shader::FindOrCreate<BilateralUpSamplingPS>(); ps->SetScalar("texSize", srcTex->GetTexSize()); ps->SetScalar("depthDiffThreshold", depthDiffThreshold); ps->SetSRV("lowResDepthTex", lowResDepthTex); ps->SetSRV("highResDepthTex", highResDepthTex); ps->SetSRV("upSamplingInTex", src); ps->SetSampler("pointSampler", SamplerTemplate<FILTER_MIN_MAG_MIP_POINT>::Get()); ps->Flush(); DrawQuad({ dst }); }
int BitEntry::SetFirstBit(const char *first_bit) { int r = 0; SetScalar(0, first_bit); if (D != NULL) { r = gd_alter_entry(D->D, E.field, &E, 0); if (!r) r = gd_get_constant(D->D, first_bit, GD_INT16, &E.u.bit.bitnum); } return r; }
PooledTextureRef ImageBasedLensFlare::BrightPass(const Ptr<Texture> & sceneTex) { auto brightPassTexRef = TexturePool::Instance().FindFree({ TEXTURE_2D, sceneTex->GetDesc() }); auto ps = Shader::FindOrCreate<LensBlurBrightPassPS>(); ps->SetScalar("brightPassThreshold", _brightPassThreshold); ps->SetSRV("sceneTex", sceneTex->GetShaderResourceView()); ps->SetSampler("pointSampler", SamplerTemplate<FILTER_MIN_MAG_MIP_POINT>::Get()); ps->Flush(); DrawQuad({ brightPassTexRef->Get()->Cast<Texture>()->GetRenderTargetView(0, 0, 1) }); return brightPassTexRef; }
int BitEntry::SetNumBits(const char *num_bits) { int r = 0; SetScalar(1, num_bits); E.scalar[1] = strdup(num_bits); if (D != NULL) { r = gd_alter_entry(D->D, E.field, &E, 0); if (!r) r = gd_get_constant(D->D, num_bits, GD_INT16, &E.u.bit.numbits); } return r; }
void Fill( const float4 & color, const std::vector< Ptr<class RenderTargetView> > & rtvs, float topLeftX, float topLeftY, float width, float height, float topLeftU, float topLeftV, float uvWidth, float uvHeight, const Ptr<class DepthStencilView> & dsv) { auto ps = Shader::FindOrCreate<FillPS>(); ps->SetScalar("fillColor", color); ps->Flush(); DrawQuad(rtvs, topLeftX, topLeftY, width, height, topLeftU, topLeftV, uvWidth, uvHeight, dsv); }
void ToneMapping::DoToneMapping( const Ptr<Texture> & scene, const Ptr<Texture> & bloomTex, const Ptr<Texture> & adaptedExposureScale, const Ptr<Texture> & lut, const Ptr<RenderTargetView> & target) { auto ps = Shader::FindOrCreate<ToneMappingPS>(); ps->SetScalar("gamma", Global::GetRenderEngine()->GetGamma()); ps->SetSRV("sceneTex", scene->GetShaderResourceView()); ps->SetSRV("bloomTex", bloomTex->GetShaderResourceView()); ps->SetSRV("adaptedExposureScale", adaptedExposureScale->GetShaderResourceView()); ps->SetSRV("toneMappingLUT", lut->GetShaderResourceView()); ps->SetSampler("pointSampler", SamplerTemplate<FILTER_MIN_MAG_MIP_POINT>::Get()); ps->SetSampler("linearSampler", SamplerTemplate<>::Get()); ps->Flush(); DrawQuad({ target }); }
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; }
void SkyBox::Render(const Ptr<RenderTargetView> & target, const Ptr<DepthStencilView> & dsv, const Ptr<RenderView> & view) { if (!_tex) return; auto rc = Global::GetRenderEngine()->GetRenderContext(); auto translationMat = translation(view->GetCamera()->GetPos()); auto transformMat = mul(translationMat, view->GetCamera()->GetViewProjMatrix()); auto vs = Shader::FindOrCreate<SkyBoxVS>(); auto ps = Shader::FindOrCreate<SkyBoxPS>(); vs->SetScalar("transform", transformMat); ps->SetSRV("skyBoxTex", _tex->GetShaderResourceView(0, 0, 0, 0, true)); ps->SetSampler("linearSampler", SamplerTemplate<>::Get()); vs->Flush(); ps->Flush(); rc->SetViewport(GetTextureQuadViewport(target->GetResource()->Cast<Texture>())); rc->SetRenderTargets({ target }); rc->SetDepthStencil(dsv); rc->SetRasterizerState(RasterizerStateTemplate<FILL_SOLID, CULL_NONE>::Get()); rc->SetDepthStencilState(DepthStencilStateTemplate<true, DEPTH_WRITE_ZERO, COMPARISON_LESS_EQUAL>::Get()); rc->SetVertexBuffer(_sphereMesh->GetRenderData()->GetMeshElements()[0]->GetVertexBuffer()); rc->SetIndexBuffer(_sphereMesh->GetRenderData()->GetMeshElements()[0]->GetIndexBuffer()); rc->SetPrimitiveTopology(PRIMITIVE_TOPOLOGY_TRIANGLELIST); rc->DrawIndexed(0, 0); rc->SetRasterizerState(nullptr); rc->SetDepthStencilState(nullptr); }
void BilateralBlur( const Ptr<ShaderResourceView> & src, const Ptr<RenderTargetView> & dst, const Ptr<ShaderResourceView> & depthTex, const std::vector<float> & weights, float depthDiffThreshold) { auto srcTex = src->GetResource()->Cast<Texture>(); auto tmpTexDesc = dst->GetResource()->Cast<Texture>()->GetDesc(); auto tmpTexRef = TexturePool::Instance().FindFree({ TEXTURE_2D, tmpTexDesc }); { auto ps = Shader::FindOrCreate<BilateralBlurXPS>(); ps->SetScalar("bilateralBlurWeights", &weights[0], (int32_t)(sizeof(float) * weights.size())); ps->SetScalar("texSize", srcTex->GetTexSize()); ps->SetScalar("depthDiffThreshold", depthDiffThreshold); ps->SetSRV("bilateralDepthTex", depthTex); ps->SetSRV("bilateralBlurInTex", src); ps->SetSampler("pointSampler", SamplerTemplate<FILTER_MIN_MAG_MIP_POINT>::Get()); ps->Flush(); DrawQuad({ tmpTexRef->Get()->Cast<Texture>()->GetRenderTargetView(0, 0, 1) }); } { auto ps = Shader::FindOrCreate<BilateralBlurYPS>(); ps->SetScalar("bilateralBlurWeights", &weights[0], (int32_t)(sizeof(float) * weights.size())); ps->SetScalar("texSize", srcTex->GetTexSize()); ps->SetScalar("depthDiffThreshold", depthDiffThreshold); ps->SetSRV("bilateralDepthTex", depthTex); ps->SetSRV("bilateralBlurInTex", tmpTexRef->Get()->Cast<Texture>()->GetShaderResourceView()); ps->SetSampler("pointSampler", SamplerTemplate<FILTER_MIN_MAG_MIP_POINT>::Get()); ps->Flush(); DrawQuad({ dst }); } }
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); }
void ImageBasedLensFlare::LensBlur(const Ptr<Texture> & setupTex, const Ptr<Texture> & target) { int32_t tileSize = 9; //Extract Sprite Points int32_t extractWidth = (setupTex->GetDesc().width + tileSize - 1) / tileSize; int32_t extractHeight = (setupTex->GetDesc().height + tileSize - 1) / tileSize; RenderBufferDesc spPointsBufDesc; spPointsBufDesc.bindFlag = BUFFER_BIND_SHADER_RESOURCE | BUFFER_BIND_UNORDERED_ACCESS; spPointsBufDesc.elementSize = sizeof(float2) + sizeof(float3); spPointsBufDesc.numElements = extractWidth * extractHeight; spPointsBufDesc.cpuAccess = 0; spPointsBufDesc.bStructured = true; auto spPointsBufRef = BufferPool::Instance().FindFree(spPointsBufDesc); auto spPointsBuf = spPointsBufRef->Get()->Cast<RenderBuffer>(); { auto ps = Shader::FindOrCreate<ExtractSpritePointsPS>(); ps->SetScalar("spriteThreshold", _spriteThreshold); ps->SetSRV("setupTex", setupTex->GetShaderResourceView()); ps->SetUAV("spPointsBuf", spPointsBuf->GetUnorderedAccessView(0, 0, RENDER_FORMAT_UNKNOWN, BUFFER_UAV_APPEND)); ps->Flush(); DrawQuad({}, 0.0f, 0.0f, (float)extractWidth, (float)extractHeight); } //Render Sprites if (!_indirectAgsBuf) { RenderBufferDesc indirectArgsBufDesc; indirectArgsBufDesc.bindFlag = BUFFER_BIND_INDIRECT_ARGS; indirectArgsBufDesc.elementSize = 16; indirectArgsBufDesc.numElements = 1; indirectArgsBufDesc.cpuAccess = 0; indirectArgsBufDesc.bStructured = false; uint32_t initData[] = { 0, 1, 0, 0 }; _indirectAgsBuf = Global::GetRenderEngine()->GetRenderFactory()->CreateBuffer(); _indirectAgsBuf->SetDesc(indirectArgsBufDesc); _indirectAgsBuf->Init(initData); } spPointsBuf->CopyStructureCountTo(_indirectAgsBuf, 0, 0, spPointsBuf->GetDesc().numElements, RENDER_FORMAT_UNKNOWN, BUFFER_UAV_APPEND); { auto vs = Shader::FindOrCreate<LensBlurVS>(); auto gs = Shader::FindOrCreate<LensBlurGS>(); auto ps = Shader::FindOrCreate<LensBlurPS>(); vs->SetScalar("texSize", target->GetTexSize()); gs->SetScalar("texSize", target->GetTexSize()); gs->SetScalar("flareIntensity", _flareIntensity); vs->SetSRV("spPointsRenderBuf", spPointsBuf->GetShaderResourceView(0, 0, RENDER_FORMAT_UNKNOWN)); auto lensTexAsset = Asset::Find<TextureAsset>("Textures/Bokeh_Circle.dds"); if (!lensTexAsset->IsInit()) lensTexAsset->Init(); auto lensTex = lensTexAsset->GetTexture(); ps->SetSRV("lensTex", lensTex->GetShaderResourceView()); ps->SetSampler("linearSampler", SamplerTemplate<>::Get()); vs->Flush(); gs->Flush(); ps->Flush(); auto rc = Global::GetRenderEngine()->GetRenderContext(); rc->SetVertexBuffer({}); rc->SetIndexBuffer(nullptr); rc->SetPrimitiveTopology(PRIMITIVE_TOPOLOGY_POINTLIST); rc->SetViewport(GetTextureQuadViewport(target)); rc->SetRenderTargets({ target->GetRenderTargetView(0, 0, 1) }); rc->SetDepthStencil(nullptr); rc->SetDepthStencilState(DepthStencilStateTemplate<false>::Get()); rc->SetBlendState(BlendStateTemplate<false, false, true, BLEND_PARAM_SRC_ALPHA, BLEND_PARAM_ONE, BLEND_OP_ADD>::Get()); rc->DrawInstancedIndirect(_indirectAgsBuf, 0); rc->ResetShader(SHADER_GS); rc->SetBlendState(nullptr); } }
void FFT::FFT2DRadix2( const Ptr<Texture> & src, int32_t srcMipLevel, int32_t srcArrayOffset, const Ptr<Texture> & dst, int32_t dstMipLevel, int32_t dstArrayOffset, bool bInverse, bool bIFFTScale) { auto mipSize = src->GetMipSize(srcMipLevel); TextureDesc texDesc; texDesc.width = mipSize.x(); texDesc.height = mipSize.y(); texDesc.depth = 1; texDesc.bindFlag = TEXTURE_BIND_SHADER_RESOURCE | TEXTURE_BIND_RENDER_TARGET | TEXTURE_BIND_UNORDERED_ACCESS; texDesc.cpuAccess = 0; texDesc.format = RENDER_FORMAT_R32G32_FLOAT; texDesc.mipLevels = 1; texDesc.arraySize = 1; texDesc.bCube = false; texDesc.sampleCount = 1; texDesc.sampleQuality = 0; PooledTextureRef bfSrcRef; Ptr<Texture> bfSrc; int32_t bfSrcMipLevel = 0; int32_t bfSrcArrayOffset = 0; /*if (!bInverse) { bfSrcRef = TexturePool::Instance().FindFree({ TEXTURE_2D, texDesc }); bfSrc = bfSrcRef->Get()->Cast<Texture>(); FFT::FFTSetup(src, srcMipLevel, srcArrayOffset, bfSrc, 0, 0); } else*/ { bfSrc = src; bfSrcMipLevel = srcMipLevel; bfSrcArrayOffset = srcArrayOffset; } PooledTextureRef bfDstRef; Ptr<Texture> bfDst; int32_t bfDstMipLevel = 0; int32_t bfDstArrayOffset = 0; if (dst->GetDesc().bindFlag & TEXTURE_BIND_UNORDERED_ACCESS && dst->GetDesc().format == RENDER_FORMAT_R32G32_FLOAT) { bfDst = dst; bfDstMipLevel = dstMipLevel; bfDstArrayOffset = dstArrayOffset; } else { bfDstRef = TexturePool::Instance().FindFree({ TEXTURE_2D, texDesc }); bfDst = bfDstRef->Get()->Cast<Texture>(); } std::map<String, String> macros; macros["FFT_2D"] = ""; if (bInverse) { macros["FFT_INVERSE"] = ""; if (bIFFTScale) macros["FFT_INVERSE_SCALE"] = ""; } static int fftGroupSize = 64; macros["FFT_GROUP_SIZE"] = std::to_string(fftGroupSize); auto fftXCS = Shader::FindOrCreate<FFTRadix2_2D_XCS>(macros); auto fftYCS = Shader::FindOrCreate<FFTRadix2_2D_YCS>(macros); auto ifftScalePS = Shader::FindOrCreate<IFFTScalePS>(); float4 dataSize = float4((float)mipSize.x(), (float)mipSize.y(), 1.0f / (float)mipSize.x(), 1.0f / (float)mipSize.y()); auto rc = Global::GetRenderEngine()->GetRenderContext(); //Butterfly X { uint32_t numGroups = std::max<uint32_t>(1, texDesc.width / fftGroupSize / 2); uint32_t bfLen = 2; while (bfLen <= static_cast<uint32_t>(texDesc.width)) { fftXCS->SetScalar("dataSize", dataSize); fftXCS->SetScalar("butterflyLength", bfLen); fftXCS->SetSRV("srcTex", bfSrc->GetShaderResourceView(bfSrcMipLevel, 1, bfSrcArrayOffset, 1)); fftXCS->SetUAV("dstTex", bfDst->GetUnorderedAccessView(bfDstMipLevel, bfDstArrayOffset, 1)); fftXCS->Flush(); rc->Compute(numGroups, texDesc.height, 1); std::swap(bfSrc, bfDst); std::swap(bfSrcMipLevel, bfDstMipLevel); std::swap(bfSrcArrayOffset, bfDstArrayOffset); bfLen = bfLen << 1; } rc->ResetShader(SHADER_CS); if (bInverse && bIFFTScale) { float ifftScale = 1.0f / (float)texDesc.width; ifftScalePS->SetScalar("ifftScale", ifftScale); ifftScalePS->SetSRV("srcTex", bfSrc->GetShaderResourceView(bfSrcMipLevel, 1, bfSrcArrayOffset, 1)); ifftScalePS->SetSampler("pointSampler", SamplerTemplate<FILTER_MIN_MAG_MIP_POINT>::Get()); ifftScalePS->Flush(); DrawQuad({ bfDst->GetRenderTargetView(dstMipLevel, dstArrayOffset, 1) }); std::swap(bfSrc, bfDst); std::swap(bfSrcMipLevel, bfDstMipLevel); std::swap(bfSrcArrayOffset, bfDstArrayOffset); } } //Butterfly Y { uint32_t numGroups = std::max<uint32_t>(1, texDesc.height / fftGroupSize / 2); uint32_t bfLen = 2; while (bfLen <= static_cast<uint32_t>(texDesc.height)) { fftYCS->SetScalar("dataSize", dataSize); fftYCS->SetScalar("butterflyLength", bfLen); fftYCS->SetSRV("srcTex", bfSrc->GetShaderResourceView(bfSrcMipLevel, 1, bfSrcArrayOffset, 1)); fftYCS->SetUAV("dstTex", bfDst->GetUnorderedAccessView(bfDstMipLevel, bfDstArrayOffset, 1)); fftYCS->Flush(); rc->Compute(numGroups, texDesc.width, 1); std::swap(bfSrc, bfDst); std::swap(bfSrcMipLevel, bfDstMipLevel); std::swap(bfSrcArrayOffset, bfDstArrayOffset); bfLen = bfLen << 1; } rc->ResetShader(SHADER_CS); if (bInverse && bIFFTScale) { float ifftScale = 1.0f / texDesc.height; ifftScalePS->SetScalar("ifftScale", ifftScale); ifftScalePS->SetSRV("srcTex", bfSrc->GetShaderResourceView(bfSrcMipLevel, 1, bfSrcArrayOffset, 1)); ifftScalePS->SetSampler("pointSampler", SamplerTemplate<FILTER_MIN_MAG_MIP_POINT>::Get()); ifftScalePS->Flush(); DrawQuad({ bfDst->GetRenderTargetView(dstMipLevel, dstArrayOffset, 1) }); std::swap(bfSrc, bfDst); std::swap(bfSrcMipLevel, bfDstMipLevel); std::swap(bfSrcArrayOffset, bfDstArrayOffset); } } //Clear if (bfSrc != dst) //dst is result { bfSrc->CopyTo(dst, dstMipLevel, dstArrayOffset, 0, 0, 0, 0, 0); } }
void FFT::FFT2DRadix8( const Ptr<Texture> & src, int32_t srcMipLevel, int32_t srcArrayOffset, const Ptr<Texture> & dst, int32_t dstMipLevel, int32_t dstArrayOffset, bool bInverse, bool bIFFTScale) { auto mipSize = src->GetMipSize(srcMipLevel); TextureDesc texDesc; texDesc.width = mipSize.x(); texDesc.height = mipSize.y(); texDesc.depth = 1; texDesc.bindFlag = TEXTURE_BIND_SHADER_RESOURCE | TEXTURE_BIND_RENDER_TARGET | TEXTURE_BIND_UNORDERED_ACCESS; texDesc.cpuAccess = 0; texDesc.format = RENDER_FORMAT_R32G32_FLOAT; texDesc.mipLevels = 1; texDesc.arraySize = 1; texDesc.bCube = false; texDesc.sampleCount = 1; texDesc.sampleQuality = 0; PooledTextureRef bfSrcRef; Ptr<Texture> bfSrc; int32_t bfSrcMipLevel = 0; int32_t bfSrcArrayOffset = 0; //if (!bInverse) //{ // bfSrcRef = TexturePool::Instance().FindFree({ TEXTURE_2D, texDesc }); // bfSrc = bfSrcRef->Get()->Cast<Texture>(); // FFT::FFTSetup(src, srcMipLevel, srcArrayOffset, bfSrc, 0, 0); //} //else { bfSrc = src; bfSrcMipLevel = srcMipLevel; bfSrcArrayOffset = srcArrayOffset; } PooledTextureRef bfDstRef; Ptr<Texture> bfDst; int32_t bfDstMipLevel = 0; int32_t bfDstArrayOffset = 0; if (dst->GetDesc().bindFlag & TEXTURE_BIND_UNORDERED_ACCESS && dst->GetDesc().format == RENDER_FORMAT_R32G32_FLOAT) { bfDst = dst; bfDstMipLevel = dstMipLevel; bfDstArrayOffset = dstArrayOffset; } else { bfDstRef = TexturePool::Instance().FindFree({ TEXTURE_2D, texDesc }); bfDst = bfDstRef->Get()->Cast<Texture>(); } std::map<String, String> macros; macros["FFT_2D"] = ""; if (bInverse) { macros["FFT_INVERSE"] = ""; if(bIFFTScale) macros["FFT_INVERSE_SCALE"] = ""; } static int fftGroupSize = 64; macros["FFT_GROUP_SIZE"] = std::to_string(fftGroupSize); auto fftXCS = Shader::FindOrCreate<FFTRadix8_2D_XCS>(macros); auto fftXFinalCS = Shader::FindOrCreate<FFTRadix8_2D_X_FinalCS>(macros); auto fftYCS = Shader::FindOrCreate<FFTRadix8_2D_YCS>(macros); auto fftYFinalCS = Shader::FindOrCreate<FFTRadix8_2D_Y_FinalCS>(macros); auto ifftScalePS = Shader::FindOrCreate<IFFTScalePS>(); float4 dataSize = float4((float)mipSize.x(), (float)mipSize.y(), 1.0f / (float)mipSize.x(), 1.0f / (float)mipSize.y()); auto rc = Global::GetRenderEngine()->GetRenderContext(); //FFT X { uint32_t numGroups = texDesc.width / fftGroupSize / 8; uint32_t threadCount = texDesc.width / 8; uint32_t ostride = threadCount; uint32_t istride = threadCount; float phaseBase = -PI2 / texDesc.width; if (bInverse) phaseBase *= -1.0f; while (istride > 0) { if (istride > 1) { fftXCS->SetScalar("dataSize", dataSize); fftXCS->SetScalar("threadCount", threadCount); fftXCS->SetScalar("ostride", ostride); fftXCS->SetScalar("istride", istride); fftXCS->SetScalar("phaseBase", phaseBase); fftXCS->SetSRV("srcTex", bfSrc->GetShaderResourceView(bfSrcMipLevel, 1, bfSrcArrayOffset, 1)); fftXCS->SetUAV("dstTex", bfDst->GetUnorderedAccessView(bfDstMipLevel, bfDstArrayOffset, 1)); fftXCS->Flush(); rc->Compute(numGroups, texDesc.height, 1); } else { fftXFinalCS->SetScalar("dataSize", dataSize); fftXFinalCS->SetScalar("threadCount", threadCount); fftXFinalCS->SetScalar("ostride", ostride); fftXFinalCS->SetScalar("istride", istride); fftXFinalCS->SetSRV("srcTex", bfSrc->GetShaderResourceView(bfSrcMipLevel, 1, bfSrcArrayOffset, 1)); fftXFinalCS->SetUAV("dstTex", bfDst->GetUnorderedAccessView(bfDstMipLevel, bfDstArrayOffset, 1)); fftXFinalCS->Flush(); rc->Compute(numGroups, texDesc.height, 1); } std::swap(bfSrc, bfDst); std::swap(bfSrcMipLevel, bfDstMipLevel); std::swap(bfSrcArrayOffset, bfDstArrayOffset); istride /= 8; phaseBase *= 8.0f; } } //FFT Y { uint32_t numGroups = texDesc.height / fftGroupSize / 8; uint32_t threadCount = texDesc.height / 8; uint32_t ostride = threadCount; uint32_t istride = threadCount; float phaseBase = -PI2 / texDesc.height; if (bInverse) phaseBase *= -1.0f; while (istride > 0) { if (istride > 1) { fftYCS->SetScalar("dataSize", dataSize); fftYCS->SetScalar("threadCount", threadCount); fftYCS->SetScalar("ostride", ostride); fftYCS->SetScalar("istride", istride); fftYCS->SetScalar("phaseBase", phaseBase); fftYCS->SetSRV("srcTex", bfSrc->GetShaderResourceView(bfSrcMipLevel, 1, bfSrcArrayOffset, 1)); fftYCS->SetUAV("dstTex", bfDst->GetUnorderedAccessView(bfDstMipLevel, bfDstArrayOffset, 1)); fftYCS->Flush(); rc->Compute(numGroups, texDesc.width, 1); } else { fftYFinalCS->SetScalar("dataSize", dataSize); fftYFinalCS->SetScalar("threadCount", threadCount); fftYFinalCS->SetScalar("ostride", ostride); fftYFinalCS->SetScalar("istride", istride); fftYFinalCS->SetSRV("srcTex", bfSrc->GetShaderResourceView(bfSrcMipLevel, 1, bfSrcArrayOffset, 1)); fftYFinalCS->SetUAV("dstTex", bfDst->GetUnorderedAccessView(bfDstMipLevel, bfDstArrayOffset, 1)); fftYFinalCS->Flush(); rc->Compute(numGroups, texDesc.width, 1); } std::swap(bfSrc, bfDst); std::swap(bfSrcMipLevel, bfDstMipLevel); std::swap(bfSrcArrayOffset, bfDstArrayOffset); istride /= 8; phaseBase *= 8.0f; } } rc->ResetShader(SHADER_CS); //Clear if (bfSrc != dst) //dst is result { bfSrc->CopyTo(dst, dstMipLevel, dstArrayOffset, 0, 0, 0, 0, 0); } }