Skip to content

Commit

Permalink
Traktor: Clouds are rendered to a unwrapped texture and temporarily f…
Browse files Browse the repository at this point in the history
…iltered.
  • Loading branch information
apistol78 committed Feb 20, 2024
1 parent 6f841e1 commit a240763
Show file tree
Hide file tree
Showing 16 changed files with 1,327 additions and 179 deletions.
2 changes: 2 additions & 0 deletions code/Weather/Editor/WeatherPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ bool WeatherPipeline::buildDependencies(
{
const Guid c_shaderClouds2D(L"{9F52BE0A-0C1A-4928-91D9-9D32296CB8F3}");
const Guid c_shaderClouds3D(L"{EF88CE37-0917-4402-B2D1-6E3F2D3CCCCF}");
const Guid c_shaderCloudsDome(L"{151F822B-B85F-6349-B536-7663C95C43B8}");

pipelineDepends->addDependency(skyComponentData->getShader(), editor::PdfBuild | editor::PdfResource);
pipelineDepends->addDependency(skyComponentData->getTexture(), editor::PdfBuild | editor::PdfResource);
pipelineDepends->addDependency(c_shaderClouds2D, editor::PdfBuild | editor::PdfResource);
pipelineDepends->addDependency(c_shaderClouds3D, editor::PdfBuild | editor::PdfResource);
pipelineDepends->addDependency(c_shaderCloudsDome, editor::PdfBuild | editor::PdfResource);
}
return true;
}
Expand Down
80 changes: 74 additions & 6 deletions code/Weather/Sky/SkyComponent.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* TRAKTOR
* Copyright (c) 2022-2023 Anders Pistol.
* Copyright (c) 2022-2024 Anders Pistol.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
Expand All @@ -11,6 +11,7 @@
#include "Core/Misc/SafeDestroy.h"
#include "Render/Buffer.h"
#include "Render/IRenderSystem.h"
#include "Render/IRenderTargetSet.h"
#include "Render/ITexture.h"
#include "Render/VertexElement.h"
#include "Render/Context/RenderContext.h"
Expand All @@ -30,6 +31,7 @@ namespace traktor::weather

const resource::Id< render::Shader > c_shaderClouds2D(Guid(L"{9F52BE0A-0C1A-4928-91D9-9D32296CB8F3}"));
const resource::Id< render::Shader > c_shaderClouds3D(Guid(L"{EF88CE37-0917-4402-B2D1-6E3F2D3CCCCF}"));
const resource::Id< render::Shader > c_shaderCloudsDome(Guid(L"{151F822B-B85F-6349-B536-7663C95C43B8}"));

const render::Handle s_handleWeather_SkyRadius(L"Weather_SkyRadius");
const render::Handle s_handleWeather_SkyRotation(L"Weather_SkyRotation");
Expand All @@ -40,6 +42,7 @@ const render::Handle s_handleWeather_SkyIntensity(L"Weather_SkyIntensity");
const render::Handle s_handleWeather_SkySunDirection(L"Weather_SkySunDirection");
const render::Handle s_handleWeather_SkySunColor(L"Weather_SkySunColor");
const render::Handle s_handleWeather_SkyEyePosition(L"Weather_SkyEyePosition");
const render::Handle s_handleWeather_SkyCloudTexture(L"Weather_SkyCloudTexture");

const int32_t c_longitudes = 16;
const int32_t c_latitudes = 24;
Expand Down Expand Up @@ -147,13 +150,24 @@ bool SkyComponent::create(resource::IResourceManager* resourceManager, render::I
vtcd.shaderStorage = true;
m_cloudTextures[1] = renderSystem->createVolumeTexture(vtcd, T_FILE_LINE_W);

//render::SimpleTextureCreateDesc stcd = {};
stcd.width = 2048;
stcd.height = 512;
stcd.mipCount = 1;
stcd.format = render::TfR32G32B32A32F;
stcd.shaderStorage = true;
m_cloudDomeTexture[0] = renderSystem->createSimpleTexture(stcd, T_FILE_LINE_W);
m_cloudDomeTexture[1] = renderSystem->createSimpleTexture(stcd, T_FILE_LINE_W);

if (!m_cloudTextures[0] || !m_cloudTextures[1])
return false;

if (!resourceManager->bind(c_shaderClouds2D, m_shaderClouds2D))
return false;
if (!resourceManager->bind(c_shaderClouds3D, m_shaderClouds3D))
return false;
if (!resourceManager->bind(c_shaderCloudsDome, m_shaderCloudsDome))
return false;

return true;
}
Expand Down Expand Up @@ -200,7 +214,9 @@ void SkyComponent::setup(
const world::WorldRenderView& worldRenderView
)
{
const static render::Handle s_handleInputTexture(L"Weather_InputTexture");
const static render::Handle s_handleOutputTexture(L"Weather_OutputTexture");
render::RenderGraph& renderGraph = context.getRenderGraph();

if (m_shaderClouds2D.changed() || m_shaderClouds3D.changed())
{
Expand All @@ -211,7 +227,7 @@ void SkyComponent::setup(

if (m_dirty)
{
Ref< render::RenderPass > rp = new render::RenderPass(L"Sky compute clouds");
Ref< render::RenderPass > rp = new render::RenderPass(L"Sky compute clouds noise");
rp->addBuild([=](const render::RenderGraph&, render::RenderContext* renderContext) {
{
auto renderBlock = renderContext->allocNamed< render::ComputeRenderBlock >(L"Sky clouds 2D");
Expand All @@ -226,7 +242,7 @@ void SkyComponent::setup(
renderBlock->programParams->endParameters(renderContext);

renderContext->compute(renderBlock);
renderContext->compute< render::BarrierRenderBlock >(render::Stage::Compute, render::Stage::Fragment);
renderContext->compute< render::BarrierRenderBlock >(render::Stage::Compute, render::Stage::Compute);
}
{
auto renderBlock = renderContext->allocNamed< render::ComputeRenderBlock >(L"Sky clouds 3D");
Expand All @@ -241,13 +257,60 @@ void SkyComponent::setup(
renderBlock->programParams->endParameters(renderContext);

renderContext->compute(renderBlock);
renderContext->compute< render::BarrierRenderBlock >(render::Stage::Compute, render::Stage::Fragment);
renderContext->compute< render::BarrierRenderBlock >(render::Stage::Compute, render::Stage::Compute);
}
});
context.getRenderGraph().addPass(rp);
renderGraph.addPass(rp);

m_dirty = false;
}

// Generate dome projected cloud layer.
if (worldRenderView.getIndex() == 0)
{
render::ITexture* input = m_cloudDomeTexture[m_count & 1];
render::ITexture* output = m_cloudDomeTexture[(m_count + 1) & 1];

// Get sun from directional light in same entity as sky component.
Vector4 sunDirection = m_transform.axisY();
Vector4 sunColor = Vector4(1.0f, 0.9f, 0.85f) * 1.8_simd;
if (m_owner != nullptr)
{
auto lightComponent = m_owner->getComponent< world::LightComponent >();
if (lightComponent)
sunColor = lightComponent->getColor();
}

Ref< render::RenderPass > rp = new render::RenderPass(L"Sky compute clouds dome");
rp->addBuild([=](const render::RenderGraph&, render::RenderContext* renderContext) {
auto renderBlock = renderContext->allocNamed< render::ComputeRenderBlock >(L"Sky clouds dome");
renderBlock->program = m_shaderCloudsDome->getProgram().program;
renderBlock->workSize[0] = 2048;
renderBlock->workSize[1] = 512;
renderBlock->workSize[2] = 1;

renderBlock->programParams = renderContext->alloc< render::ProgramParameters >();
renderBlock->programParams->beginParameters(renderContext);

renderBlock->programParams->setImageViewParameter(s_handleInputTexture, input, 0);
renderBlock->programParams->setImageViewParameter(s_handleOutputTexture, output, 0);

renderBlock->programParams->setTextureParameter(s_handleWeather_SkyCloud2D, m_cloudTextures[0]);
renderBlock->programParams->setTextureParameter(s_handleWeather_SkyCloud3D, m_cloudTextures[1]);
renderBlock->programParams->setFloatParameter(s_handleWeather_SkyRadius, worldRenderView.getViewFrustum().getFarZ() - 10.0f);
renderBlock->programParams->setVectorParameter(s_handleWeather_SkySunColor, sunColor);
renderBlock->programParams->setVectorParameter(s_handleWeather_SkySunDirection, sunDirection);
renderBlock->programParams->setFloatParameter(render::getParameterHandle(L"World_Time"), worldRenderView.getTime());

renderBlock->programParams->endParameters(renderContext);

renderContext->compute(renderBlock);
renderContext->compute< render::BarrierRenderBlock >(render::Stage::Compute, render::Stage::Fragment);
});
renderGraph.addPass(rp);

m_count++;
}
}

void SkyComponent::build(
Expand All @@ -256,7 +319,8 @@ void SkyComponent::build(
const world::IWorldRenderPass& worldRenderPass
)
{
auto sp = worldRenderPass.getProgram(m_shader);
auto perm = worldRenderPass.getPermutation(m_shader);
auto sp = m_shader->getProgram(perm);
if (!sp)
return;

Expand All @@ -273,6 +337,8 @@ void SkyComponent::build(
const Vector4 eyePosition = worldRenderView.getEyePosition();
const float rotation = m_transform.rotation().toEulerAngles().x();

render::ITexture* cloudDomeTexture = m_cloudDomeTexture[m_count & 1];

auto renderBlock = renderContext->allocNamed< render::SimpleRenderBlock >(L"Sky");

// Render sky after all opaques but before of all alpha blended.
Expand Down Expand Up @@ -301,6 +367,8 @@ void SkyComponent::build(
renderBlock->programParams->setTextureParameter(s_handleWeather_SkyCloud2D, m_cloudTextures[0]);
renderBlock->programParams->setTextureParameter(s_handleWeather_SkyCloud3D, m_cloudTextures[1]);

renderBlock->programParams->setTextureParameter(s_handleWeather_SkyCloudTexture, cloudDomeTexture);

renderBlock->programParams->endParameters(renderContext);

renderContext->draw(sp.priority, renderBlock);
Expand Down
5 changes: 5 additions & 0 deletions code/Weather/Sky/SkyComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ class T_DLLCLASS SkyComponent : public world::IEntityComponent
Transform m_transform;
float m_intensity = 1.0f;
bool m_dirty = true;

resource::Proxy< render::Shader > m_shaderCloudsDome;
Ref< render::ITexture > m_cloudDomeTexture[2];

int32_t m_count = 0;
};

}
4 changes: 3 additions & 1 deletion code/World/Deferred/WorldRendererDeferred.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ void WorldRendererDeferred::setup(
// Add additional passes by entity renderers.
{
T_PROFILER_SCOPE(L"WorldRendererDeferred setup extra passes");
WorldSetupContext context(world, m_entityRenderers, m_irradianceGrid, renderGraph);
WorldSetupContext context(world, m_entityRenderers, m_irradianceGrid, renderGraph, m_visualAttachments);

for (auto r : m_gatheredView.renderables)
r.renderer->setup(context, worldRenderView, r.renderable);
Expand Down Expand Up @@ -216,6 +216,8 @@ void WorldRendererDeferred::setupVisualPass(
// rp->addInput(contactShadowsTargetSetId);
rp->addInput(reflectionsTargetSetId);
rp->addInput(shadowMapAtlasTargetSetId);
for (auto attachment : m_visualAttachments)
rp->addInput(attachment);

render::Clear clear;
clear.mask = render::CfColor;
Expand Down
5 changes: 4 additions & 1 deletion code/World/Forward/WorldRendererForward.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ void WorldRendererForward::setup(
// Add additional passes by entity renderers.
{
T_PROFILER_SCOPE(L"WorldRendererForward setup extra passes");
WorldSetupContext context(world, m_entityRenderers, m_irradianceGrid, renderGraph);
WorldSetupContext context(world, m_entityRenderers, m_irradianceGrid, renderGraph, m_visualAttachments);

for (auto r : m_gatheredView.renderables)
r.renderer->setup(context, worldRenderView, r.renderable);
Expand Down Expand Up @@ -208,6 +208,9 @@ void WorldRendererForward::setupVisualPass(
rp->addInput(reflectionsTargetSetId);
if (shadowsEnable)
rp->addInput(shadowMapAtlasTargetSetId);

for (auto attachment : m_visualAttachments)
rp->addInput(attachment);

render::Clear clear;
clear.mask = render::CfColor;
Expand Down
1 change: 1 addition & 0 deletions code/World/Shared/WorldRendererShared.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class T_DLLCLASS WorldRendererShared : public IWorldRenderer
Ref< Packer > m_shadowAtlasPacker;

GatherView m_gatheredView;
AlignedVector< render::handle_t > m_visualAttachments;

struct State
{
Expand Down
5 changes: 4 additions & 1 deletion code/World/Simple/WorldRendererSimple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ void WorldRendererSimple::setup(
// Add additional passes by entity renderers.
{
T_PROFILER_SCOPE(L"WorldRendererSimple setup extra passes");
const WorldSetupContext context(world, m_entityRenderers, nullptr, renderGraph);
const WorldSetupContext context(world, m_entityRenderers, nullptr, renderGraph, m_visualAttachments);

for (auto gathered : m_gathered)
gathered.entityRenderer->setup(context, worldRenderView, gathered.renderable);
Expand All @@ -116,6 +116,9 @@ void WorldRendererSimple::setup(
cl.depth = 1.0f;
rp->setOutput(outputTargetSetId, cl, render::TfNone, render::TfAll);

for (auto attachment : m_visualAttachments)
rp->addInput(attachment);

rp->addBuild(
[=](const render::RenderGraph& renderGraph, render::RenderContext* renderContext)
{
Expand Down
1 change: 1 addition & 0 deletions code/World/Simple/WorldRendererSimple.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class T_DLLCLASS WorldRendererSimple : public IWorldRenderer
Ref< WorldEntityRenderers > m_entityRenderers;
Ref< render::ITexture > m_depthTexture;
AlignedVector< Gather > m_gathered;
AlignedVector< render::handle_t > m_visualAttachments;
};

}
10 changes: 9 additions & 1 deletion code/World/WorldSetupContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,20 @@ namespace traktor::world

T_IMPLEMENT_RTTI_CLASS(L"traktor.world.WorldSetupContext", WorldSetupContext, Object)

WorldSetupContext::WorldSetupContext(const World* world, const WorldEntityRenderers* entityRenderers, const IrradianceGrid* irradianceGrid, render::RenderGraph& renderGraph)
WorldSetupContext::WorldSetupContext(
const World* world,
const WorldEntityRenderers* entityRenderers,
const IrradianceGrid* irradianceGrid,
render::RenderGraph& renderGraph,
AlignedVector< render::handle_t >& visualAttachments
)
: m_world(world)
, m_entityRenderers(entityRenderers)
, m_irradianceGrid(irradianceGrid)
, m_renderGraph(renderGraph)
, m_visualAttachments(visualAttachments)
{
m_visualAttachments.resize(0);
}

}
11 changes: 10 additions & 1 deletion code/World/WorldSetupContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,13 @@ class T_DLLCLASS WorldSetupContext : public Object
T_RTTI_CLASS;

public:
explicit WorldSetupContext(const World* world, const WorldEntityRenderers* entityRenderers, const IrradianceGrid* irradianceGrid, render::RenderGraph& renderGraph);
explicit WorldSetupContext(
const World* world,
const WorldEntityRenderers* entityRenderers,
const IrradianceGrid* irradianceGrid,
render::RenderGraph& renderGraph,
AlignedVector< render::handle_t >& visualAttachments
);

const World* getWorld() const { return m_world; }

Expand All @@ -52,11 +58,14 @@ class T_DLLCLASS WorldSetupContext : public Object

render::RenderGraph& getRenderGraph() const { return m_renderGraph; }

AlignedVector< render::handle_t >& getVisualAttachments() const { return m_visualAttachments; }

private:
const World* m_world;
const WorldEntityRenderers* m_entityRenderers;
const IrradianceGrid* m_irradianceGrid;
render::RenderGraph& m_renderGraph;
AlignedVector< render::handle_t >& m_visualAttachments;
};

}
31 changes: 31 additions & 0 deletions data/Source/System/Weather/Sky/Modules/Polar.xdi
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<object type="traktor.render.ShaderModule">
<text>
<![CDATA[
#define PI 3.142f
#define TWO_PI (PI * 2.0f)
#define HALF_PI (PI / 2.0f)
vec3 TexCoordToDirection(in vec2 texCoord)
{
float theta = texCoord.x * TWO_PI;
float radius = texCoord.y; // cos(texCoord.y * HALF_PI);
return vec3(
cos(theta) * radius,
1.0f - radius,
sin(theta) * radius
);
}
vec2 DirectionToTexCoord(in vec3 direction)
{
float phi = direction.y; // acos(direction.y) / HALF_PI;
float theta = atan(direction.z, direction.x) / TWO_PI + 0.5f;
return vec2( theta, 1 - phi);
}
]]>
</text>
</object>
6 changes: 6 additions & 0 deletions data/Source/System/Weather/Sky/Modules/Polar.xdm
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<object type="traktor.db.LocalInstanceMeta" version="2">
<guid>{055423F4-A0F5-4840-8020-D5C93F97F8E5}</guid>
<primaryType>traktor.render.ShaderModule</primaryType>
<blobs/>
</object>
Loading

0 comments on commit a240763

Please sign in to comment.