DeferredShading: Add bloom
This commit is contained in:
parent
7bbe879d2f
commit
9ee3a0d6be
|
|
@ -0,0 +1,69 @@
|
||||||
|
[layout(std140)]
|
||||||
|
struct ViewerData
|
||||||
|
{
|
||||||
|
projectionMatrix: mat4<f32>,
|
||||||
|
invProjectionMatrix: mat4<f32>,
|
||||||
|
viewMatrix: mat4<f32>,
|
||||||
|
invViewMatrix: mat4<f32>,
|
||||||
|
viewProjMatrix: mat4<f32>,
|
||||||
|
invViewProjMatrix: mat4<f32>,
|
||||||
|
renderTargetSize: vec2<f32>,
|
||||||
|
invRenderTargetSize: vec2<f32>,
|
||||||
|
eyePosition: vec3<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
external
|
||||||
|
{
|
||||||
|
[binding(0)] colorTexture: sampler2D<f32>,
|
||||||
|
[binding(1)] viewerData: uniform<ViewerData>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FragIn
|
||||||
|
{
|
||||||
|
[builtin(fragcoord)] fragcoord: vec4<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FragOut
|
||||||
|
{
|
||||||
|
[location(0)] color: vec4<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VertIn
|
||||||
|
{
|
||||||
|
[location(0)] pos: vec3<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VertOut
|
||||||
|
{
|
||||||
|
[builtin(position)] position: vec4<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
[entry(frag)]
|
||||||
|
fn main(input: FragIn) -> FragOut
|
||||||
|
{
|
||||||
|
let BrightLuminance = 0.6;
|
||||||
|
let BrightMiddleGrey = 0.5;
|
||||||
|
let BrightThreshold = 0.7;
|
||||||
|
|
||||||
|
let fragcoord = input.fragcoord.xy * viewerData.invRenderTargetSize * 10.0;
|
||||||
|
|
||||||
|
let color = colorTexture.Sample(fragcoord).rgb;
|
||||||
|
color = color * (BrightMiddleGrey/BrightLuminance);
|
||||||
|
color = color * (vec3<f32>(1.0, 1.0, 1.0) + (color / (BrightThreshold*BrightThreshold)));
|
||||||
|
color = color - vec3<f32>(0.5, 0.5, 0.5);
|
||||||
|
color = color / (vec3<f32>(1.0, 1.0, 1.0) + color);
|
||||||
|
|
||||||
|
let output: FragOut;
|
||||||
|
output.color = vec4<f32>(color, 1.0);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
[entry(vert)]
|
||||||
|
fn main(input: VertIn) -> VertOut
|
||||||
|
{
|
||||||
|
let output: VertOut;
|
||||||
|
output.position = vec4<f32>(input.pos, 1.0);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
[layout(std140)]
|
||||||
|
struct ViewerData
|
||||||
|
{
|
||||||
|
projectionMatrix: mat4<f32>,
|
||||||
|
invProjectionMatrix: mat4<f32>,
|
||||||
|
viewMatrix: mat4<f32>,
|
||||||
|
invViewMatrix: mat4<f32>,
|
||||||
|
viewProjMatrix: mat4<f32>,
|
||||||
|
invViewProjMatrix: mat4<f32>,
|
||||||
|
renderTargetSize: vec2<f32>,
|
||||||
|
invRenderTargetSize: vec2<f32>,
|
||||||
|
eyePosition: vec3<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
external
|
||||||
|
{
|
||||||
|
[binding(0)] colorTexture: sampler2D<f32>,
|
||||||
|
[binding(1)] bloomTexture: sampler2D<f32>,
|
||||||
|
[binding(2)] viewerData: uniform<ViewerData>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FragIn
|
||||||
|
{
|
||||||
|
[builtin(fragcoord)] fragcoord: vec4<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FragOut
|
||||||
|
{
|
||||||
|
[location(0)] color: vec4<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VertIn
|
||||||
|
{
|
||||||
|
[location(0)] pos: vec3<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VertOut
|
||||||
|
{
|
||||||
|
[builtin(position)] position: vec4<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
[entry(frag)]
|
||||||
|
fn main(input: FragIn) -> FragOut
|
||||||
|
{
|
||||||
|
let fragcoord = input.fragcoord.xy * viewerData.invRenderTargetSize;
|
||||||
|
|
||||||
|
let output: FragOut;
|
||||||
|
output.color = colorTexture.Sample(fragcoord) + bloomTexture.Sample(fragcoord);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
[entry(vert)]
|
||||||
|
fn main(input: VertIn) -> VertOut
|
||||||
|
{
|
||||||
|
let output: VertOut;
|
||||||
|
output.position = vec4<f32>(input.pos, 1.0);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
[layout(std140)]
|
||||||
|
struct ViewerData
|
||||||
|
{
|
||||||
|
projectionMatrix: mat4<f32>,
|
||||||
|
invProjectionMatrix: mat4<f32>,
|
||||||
|
viewMatrix: mat4<f32>,
|
||||||
|
invViewMatrix: mat4<f32>,
|
||||||
|
viewProjMatrix: mat4<f32>,
|
||||||
|
invViewProjMatrix: mat4<f32>,
|
||||||
|
renderTargetSize: vec2<f32>,
|
||||||
|
invRenderTargetSize: vec2<f32>,
|
||||||
|
eyePosition: vec3<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
external
|
||||||
|
{
|
||||||
|
[binding(0)] colorTexture: sampler2D<f32>,
|
||||||
|
[binding(1)] viewerData: uniform<ViewerData>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FragIn
|
||||||
|
{
|
||||||
|
[builtin(fragcoord)] fragcoord: vec4<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FragOut
|
||||||
|
{
|
||||||
|
[location(0)] color: vec4<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VertIn
|
||||||
|
{
|
||||||
|
[location(0)] pos: vec3<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VertOut
|
||||||
|
{
|
||||||
|
[builtin(position)] position: vec4<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
[entry(frag)]
|
||||||
|
fn main(input: FragIn) -> FragOut
|
||||||
|
{
|
||||||
|
let invTargetSize = viewerData.invRenderTargetSize * 10.0;
|
||||||
|
let fragcoord = input.fragcoord.xy * invTargetSize;
|
||||||
|
|
||||||
|
let color = colorTexture.Sample(fragcoord).rgb * 0.2270270270;
|
||||||
|
|
||||||
|
let filter = vec2<f32>(1.0, 0.0);
|
||||||
|
|
||||||
|
color = color + colorTexture.Sample(fragcoord + filter * 1.3846153846 * invTargetSize).rgb * 0.3162162162;
|
||||||
|
color = color + colorTexture.Sample(fragcoord - filter * 1.3846153846 * invTargetSize).rgb * 0.3162162162;
|
||||||
|
|
||||||
|
color = color + colorTexture.Sample(fragcoord + filter * 3.2307692308 * invTargetSize).rgb * 0.0702702703;
|
||||||
|
color = color + colorTexture.Sample(fragcoord - filter * 3.2307692308 * invTargetSize).rgb * 0.0702702703;
|
||||||
|
|
||||||
|
filter = vec2<f32>(0.0, 1.0);
|
||||||
|
|
||||||
|
color = color + colorTexture.Sample(fragcoord + filter * 1.3846153846 * invTargetSize).rgb * 0.3162162162;
|
||||||
|
color = color + colorTexture.Sample(fragcoord - filter * 1.3846153846 * invTargetSize).rgb * 0.3162162162;
|
||||||
|
|
||||||
|
color = color + colorTexture.Sample(fragcoord + filter * 3.2307692308 * invTargetSize).rgb * 0.0702702703;
|
||||||
|
color = color + colorTexture.Sample(fragcoord - filter * 3.2307692308 * invTargetSize).rgb * 0.0702702703;
|
||||||
|
|
||||||
|
let output: FragOut;
|
||||||
|
output.color = vec4<f32>(color, 1.0);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
[entry(vert)]
|
||||||
|
fn main(input: VertIn) -> VertOut
|
||||||
|
{
|
||||||
|
let output: VertOut;
|
||||||
|
output.position = vec4<f32>(input.pos, 1.0);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
@ -55,6 +55,7 @@ fn main(input: VertIn) -> VertOut
|
||||||
{
|
{
|
||||||
// Set translation part to zero
|
// Set translation part to zero
|
||||||
let rotationMat = viewerData.viewMatrix;
|
let rotationMat = viewerData.viewMatrix;
|
||||||
|
// rotationMat[3].xyz = vec3<f32>(0.0, 0.0, 0.0); // Requires SPIRV generator to handle swizzle for store expressions
|
||||||
rotationMat[3][0] = 0.0;
|
rotationMat[3][0] = 0.0;
|
||||||
rotationMat[3][1] = 0.0;
|
rotationMat[3][1] = 0.0;
|
||||||
rotationMat[3][2] = 0.0;
|
rotationMat[3][2] = 0.0;
|
||||||
|
|
|
||||||
|
|
@ -351,20 +351,88 @@ int main()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::shared_ptr<const Nz::VertexDeclaration>& vertexDeclaration = Nz::VertexDeclaration::Get(Nz::VertexLayout::XYZ_UV);
|
const std::shared_ptr<const Nz::VertexDeclaration>& fullscreenVertexDeclaration = Nz::VertexDeclaration::Get(Nz::VertexLayout::XYZ_UV);
|
||||||
|
|
||||||
|
|
||||||
unsigned int offscreenWidth = window.GetSize().x;
|
unsigned int offscreenWidth = window.GetSize().x;
|
||||||
unsigned int offscreenHeight = window.GetSize().y;
|
unsigned int offscreenHeight = window.GetSize().y;
|
||||||
|
|
||||||
|
// Bloom data
|
||||||
|
|
||||||
|
Nz::RenderPipelineLayoutInfo bloomPipelineLayoutInfo;
|
||||||
|
bloomPipelineLayoutInfo.bindings.push_back({
|
||||||
|
Nz::ShaderBindingType::Texture,
|
||||||
|
Nz::ShaderStageType::Fragment,
|
||||||
|
0
|
||||||
|
});
|
||||||
|
|
||||||
|
bloomPipelineLayoutInfo.bindings.push_back({
|
||||||
|
Nz::ShaderBindingType::UniformBuffer,
|
||||||
|
Nz::ShaderStageType::Fragment,
|
||||||
|
1
|
||||||
|
});
|
||||||
|
|
||||||
|
Nz::RenderPipelineLayoutInfo bloomBlendPipelineLayoutInfo;
|
||||||
|
bloomBlendPipelineLayoutInfo.bindings.push_back({
|
||||||
|
Nz::ShaderBindingType::Texture,
|
||||||
|
Nz::ShaderStageType::Fragment,
|
||||||
|
0
|
||||||
|
});
|
||||||
|
|
||||||
|
bloomBlendPipelineLayoutInfo.bindings.push_back({
|
||||||
|
Nz::ShaderBindingType::Texture,
|
||||||
|
Nz::ShaderStageType::Fragment,
|
||||||
|
1
|
||||||
|
});
|
||||||
|
|
||||||
|
bloomBlendPipelineLayoutInfo.bindings.push_back({
|
||||||
|
Nz::ShaderBindingType::UniformBuffer,
|
||||||
|
Nz::ShaderStageType::Fragment,
|
||||||
|
2
|
||||||
|
});
|
||||||
|
|
||||||
|
Nz::RenderPipelineInfo bloomPipelineInfo;
|
||||||
|
bloomPipelineInfo.primitiveMode = Nz::PrimitiveMode::TriangleList;
|
||||||
|
bloomPipelineInfo.pipelineLayout = device->InstantiateRenderPipelineLayout(bloomPipelineLayoutInfo);
|
||||||
|
bloomPipelineInfo.vertexBuffers.push_back({
|
||||||
|
0,
|
||||||
|
fullscreenVertexDeclaration
|
||||||
|
});
|
||||||
|
|
||||||
|
bloomPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "bloom_bright.nzsl", {}));
|
||||||
|
|
||||||
|
std::shared_ptr<Nz::ShaderBinding> bloomBrightShaderBinding = bloomPipelineInfo.pipelineLayout->AllocateShaderBinding();
|
||||||
|
std::shared_ptr<Nz::ShaderBinding> gaussianBlurShaderBinding = bloomPipelineInfo.pipelineLayout->AllocateShaderBinding();
|
||||||
|
|
||||||
|
std::shared_ptr<Nz::RenderPipeline> bloomBrightPipeline = device->InstantiateRenderPipeline(bloomPipelineInfo);
|
||||||
|
|
||||||
|
bloomPipelineInfo.shaderModules.clear();
|
||||||
|
bloomPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "gaussian_blur.nzsl", {}));
|
||||||
|
|
||||||
|
std::shared_ptr<Nz::RenderPipeline> gaussianBlurPipeline = device->InstantiateRenderPipeline(bloomPipelineInfo);
|
||||||
|
|
||||||
|
Nz::RenderPipelineInfo bloomBlendPipelineInfo;
|
||||||
|
bloomBlendPipelineInfo.primitiveMode = Nz::PrimitiveMode::TriangleList;
|
||||||
|
bloomBlendPipelineInfo.pipelineLayout = device->InstantiateRenderPipelineLayout(bloomBlendPipelineLayoutInfo);
|
||||||
|
bloomBlendPipelineInfo.vertexBuffers.push_back({
|
||||||
|
0,
|
||||||
|
fullscreenVertexDeclaration
|
||||||
|
});
|
||||||
|
|
||||||
|
bloomBlendPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "bloom_final.nzsl", {}));
|
||||||
|
|
||||||
|
std::shared_ptr<Nz::RenderPipeline> bloomBlendPipeline = device->InstantiateRenderPipeline(bloomBlendPipelineInfo);
|
||||||
|
|
||||||
|
std::shared_ptr<Nz::ShaderBinding> bloomBlendShaderBinding = bloomBlendPipelineInfo.pipelineLayout->AllocateShaderBinding();
|
||||||
|
|
||||||
// Fullscreen data
|
// Fullscreen data
|
||||||
|
|
||||||
Nz::RenderPipelineInfo fullscreenPipelineInfo;
|
Nz::RenderPipelineInfo fullscreenPipelineInfo;
|
||||||
fullscreenPipelineInfo.primitiveMode = Nz::PrimitiveMode::TriangleStrip;
|
fullscreenPipelineInfo.primitiveMode = Nz::PrimitiveMode::TriangleList;
|
||||||
fullscreenPipelineInfo.pipelineLayout = device->InstantiateRenderPipelineLayout(fullscreenPipelineLayoutInfo);
|
fullscreenPipelineInfo.pipelineLayout = device->InstantiateRenderPipelineLayout(fullscreenPipelineLayoutInfo);
|
||||||
fullscreenPipelineInfo.vertexBuffers.push_back({
|
fullscreenPipelineInfo.vertexBuffers.push_back({
|
||||||
0,
|
0,
|
||||||
vertexDeclaration
|
fullscreenVertexDeclaration
|
||||||
});
|
});
|
||||||
|
|
||||||
fullscreenPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(Nz::ShaderStageType::Fragment, Nz::ShaderLanguage::NazaraBinary, resourceDir / "fullscreen.frag.shader", {}));
|
fullscreenPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(Nz::ShaderStageType::Fragment, Nz::ShaderLanguage::NazaraBinary, resourceDir / "fullscreen.frag.shader", {}));
|
||||||
|
|
@ -461,21 +529,15 @@ int main()
|
||||||
}
|
}
|
||||||
};*/
|
};*/
|
||||||
|
|
||||||
std::shared_ptr<Nz::AbstractBuffer> vertexBuffer = device->InstantiateBuffer(Nz::BufferType::Vertex);
|
std::shared_ptr<Nz::AbstractBuffer> fullscreenVertexBuffer = device->InstantiateBuffer(Nz::BufferType::Vertex);
|
||||||
if (!vertexBuffer->Initialize(vertexDeclaration->GetStride() * vertexData.size(), Nz::BufferUsage::DeviceLocal))
|
if (!fullscreenVertexBuffer->Initialize(fullscreenVertexDeclaration->GetStride() * vertexData.size(), Nz::BufferUsage::DeviceLocal))
|
||||||
return __LINE__;
|
return __LINE__;
|
||||||
|
|
||||||
if (!vertexBuffer->Fill(vertexData.data(), 0, vertexBuffer->GetSize()))
|
if (!fullscreenVertexBuffer->Fill(vertexData.data(), 0, fullscreenVertexBuffer->GetSize()))
|
||||||
return __LINE__;
|
return __LINE__;
|
||||||
|
|
||||||
std::shared_ptr<Nz::ShaderBinding> finalBlitBinding = fullscreenPipelineInfo.pipelineLayout->AllocateShaderBinding();
|
std::shared_ptr<Nz::ShaderBinding> finalBlitBinding = fullscreenPipelineInfo.pipelineLayout->AllocateShaderBinding();
|
||||||
|
|
||||||
std::size_t colorTexture;
|
|
||||||
std::size_t normalTexture;
|
|
||||||
std::size_t positionTexture;
|
|
||||||
std::size_t depthBuffer;
|
|
||||||
std::size_t backbuffer;
|
|
||||||
|
|
||||||
bool viewerUboUpdate = true;
|
bool viewerUboUpdate = true;
|
||||||
bool lightUpdate = true;
|
bool lightUpdate = true;
|
||||||
|
|
||||||
|
|
@ -499,9 +561,19 @@ int main()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
bool bloomEnabled = true;
|
||||||
bool forwardEnabled = true;
|
bool forwardEnabled = true;
|
||||||
bool lightAnimation = true;
|
bool lightAnimation = true;
|
||||||
|
|
||||||
|
std::size_t colorTexture;
|
||||||
|
std::size_t normalTexture;
|
||||||
|
std::size_t positionTexture;
|
||||||
|
std::size_t depthBuffer;
|
||||||
|
std::size_t backbuffer;
|
||||||
|
std::size_t bloomTextureA;
|
||||||
|
std::size_t bloomTextureB;
|
||||||
|
std::size_t lightOutput;
|
||||||
|
|
||||||
Nz::BakedFrameGraph bakedGraph = [&]
|
Nz::BakedFrameGraph bakedGraph = [&]
|
||||||
{
|
{
|
||||||
Nz::FrameGraph graph;
|
Nz::FrameGraph graph;
|
||||||
|
|
@ -526,11 +598,30 @@ int main()
|
||||||
Nz::PixelFormat::Depth24Stencil8
|
Nz::PixelFormat::Depth24Stencil8
|
||||||
});
|
});
|
||||||
|
|
||||||
|
lightOutput = graph.AddAttachment({
|
||||||
|
"Light output",
|
||||||
|
Nz::PixelFormat::RGBA8
|
||||||
|
});
|
||||||
|
|
||||||
backbuffer = graph.AddAttachment({
|
backbuffer = graph.AddAttachment({
|
||||||
"Backbuffer",
|
"Backbuffer",
|
||||||
Nz::PixelFormat::RGBA8
|
Nz::PixelFormat::RGBA8
|
||||||
});
|
});
|
||||||
|
|
||||||
|
bloomTextureA = graph.AddAttachment({
|
||||||
|
"Bloom texture A",
|
||||||
|
Nz::PixelFormat::RGBA8,
|
||||||
|
10'000,
|
||||||
|
10'000
|
||||||
|
});
|
||||||
|
|
||||||
|
bloomTextureB = graph.AddAttachment({
|
||||||
|
"Bloom texture B",
|
||||||
|
Nz::PixelFormat::RGBA8,
|
||||||
|
10'000,
|
||||||
|
10'000
|
||||||
|
});
|
||||||
|
|
||||||
Nz::FramePass& gbufferPass = graph.AddPass("GBuffer");
|
Nz::FramePass& gbufferPass = graph.AddPass("GBuffer");
|
||||||
|
|
||||||
std::size_t geometryAlbedo = gbufferPass.AddOutput(colorTexture);
|
std::size_t geometryAlbedo = gbufferPass.AddOutput(colorTexture);
|
||||||
|
|
@ -608,7 +699,7 @@ int main()
|
||||||
lightingPass.AddInput(colorTexture);
|
lightingPass.AddInput(colorTexture);
|
||||||
lightingPass.AddInput(normalTexture);
|
lightingPass.AddInput(normalTexture);
|
||||||
lightingPass.AddInput(positionTexture);
|
lightingPass.AddInput(positionTexture);
|
||||||
lightingPass.SetClearColor(lightingPass.AddOutput(backbuffer), Nz::Color::Black);
|
lightingPass.SetClearColor(lightingPass.AddOutput(lightOutput), Nz::Color::Black);
|
||||||
lightingPass.SetDepthStencilInput(depthBuffer);
|
lightingPass.SetDepthStencilInput(depthBuffer);
|
||||||
lightingPass.SetDepthStencilOutput(depthBuffer);
|
lightingPass.SetDepthStencilOutput(depthBuffer);
|
||||||
|
|
||||||
|
|
@ -631,11 +722,73 @@ int main()
|
||||||
return (forwardEnabled) ? Nz::FramePassExecution::Execute : Nz::FramePassExecution::Skip;
|
return (forwardEnabled) ? Nz::FramePassExecution::Execute : Nz::FramePassExecution::Skip;
|
||||||
});
|
});
|
||||||
|
|
||||||
forwardPass.AddInput(backbuffer);
|
forwardPass.AddInput(lightOutput);
|
||||||
forwardPass.AddOutput(backbuffer);
|
forwardPass.AddOutput(lightOutput);
|
||||||
forwardPass.SetDepthStencilInput(depthBuffer);
|
forwardPass.SetDepthStencilInput(depthBuffer);
|
||||||
forwardPass.SetDepthStencilOutput(depthBuffer);
|
forwardPass.SetDepthStencilOutput(depthBuffer);
|
||||||
|
|
||||||
|
|
||||||
|
Nz::FramePass& bloomBrightPass = graph.AddPass("Bloom pass - extract bright pixels");
|
||||||
|
bloomBrightPass.SetCommandCallback([&](Nz::CommandBufferBuilder& builder)
|
||||||
|
{
|
||||||
|
builder.SetScissor(Nz::Recti{ 0, 0, int(offscreenWidth) / 10, int(offscreenHeight) / 10 });
|
||||||
|
builder.SetViewport(Nz::Recti{ 0, 0, int(offscreenWidth) / 10, int(offscreenHeight) / 10 });
|
||||||
|
|
||||||
|
builder.BindShaderBinding(*bloomBrightShaderBinding);
|
||||||
|
builder.BindPipeline(*bloomBrightPipeline);
|
||||||
|
builder.BindVertexBuffer(0, fullscreenVertexBuffer.get());
|
||||||
|
|
||||||
|
builder.Draw(3);
|
||||||
|
});
|
||||||
|
bloomBrightPass.SetExecutionCallback([&]
|
||||||
|
{
|
||||||
|
return (bloomEnabled) ? Nz::FramePassExecution::Execute : Nz::FramePassExecution::Skip;
|
||||||
|
});
|
||||||
|
|
||||||
|
bloomBrightPass.AddInput(lightOutput);
|
||||||
|
bloomBrightPass.AddOutput(bloomTextureA);
|
||||||
|
|
||||||
|
Nz::FramePass& bloomBlurPass = graph.AddPass("Bloom pass - gaussian blur");
|
||||||
|
bloomBlurPass.SetCommandCallback([&](Nz::CommandBufferBuilder& builder)
|
||||||
|
{
|
||||||
|
builder.SetScissor(Nz::Recti{ 0, 0, int(offscreenWidth) / 10, int(offscreenHeight) / 10 });
|
||||||
|
builder.SetViewport(Nz::Recti{ 0, 0, int(offscreenWidth) / 10, int(offscreenHeight) / 10 });
|
||||||
|
|
||||||
|
builder.BindShaderBinding(*gaussianBlurShaderBinding);
|
||||||
|
builder.BindPipeline(*gaussianBlurPipeline);
|
||||||
|
builder.BindVertexBuffer(0, fullscreenVertexBuffer.get());
|
||||||
|
|
||||||
|
builder.Draw(3);
|
||||||
|
});
|
||||||
|
bloomBlurPass.SetExecutionCallback([&]
|
||||||
|
{
|
||||||
|
return (bloomEnabled) ? Nz::FramePassExecution::Execute : Nz::FramePassExecution::Skip;
|
||||||
|
});
|
||||||
|
|
||||||
|
bloomBlurPass.AddInput(bloomTextureA);
|
||||||
|
bloomBlurPass.AddOutput(bloomTextureB);
|
||||||
|
|
||||||
|
Nz::FramePass& bloomBlendPass = graph.AddPass("Bloom pass - blend");
|
||||||
|
bloomBlendPass.SetCommandCallback([&](Nz::CommandBufferBuilder& builder)
|
||||||
|
{
|
||||||
|
builder.SetScissor(Nz::Recti{ 0, 0, int(offscreenWidth), int(offscreenHeight) });
|
||||||
|
builder.SetViewport(Nz::Recti{ 0, 0, int(offscreenWidth), int(offscreenHeight) });
|
||||||
|
|
||||||
|
builder.BindShaderBinding(*bloomBlendShaderBinding);
|
||||||
|
builder.BindPipeline(*bloomBlendPipeline);
|
||||||
|
builder.BindVertexBuffer(0, fullscreenVertexBuffer.get());
|
||||||
|
|
||||||
|
builder.Draw(3);
|
||||||
|
});
|
||||||
|
bloomBlendPass.SetExecutionCallback([&]
|
||||||
|
{
|
||||||
|
return (bloomEnabled) ? Nz::FramePassExecution::Execute : Nz::FramePassExecution::Skip;
|
||||||
|
});
|
||||||
|
|
||||||
|
bloomBlendPass.AddInput(lightOutput);
|
||||||
|
bloomBlendPass.AddInput(bloomTextureB);
|
||||||
|
bloomBlendPass.AddOutput(backbuffer);
|
||||||
|
|
||||||
graph.SetBackbufferOutput(backbuffer);
|
graph.SetBackbufferOutput(backbuffer);
|
||||||
|
|
||||||
return graph.Bake();
|
return graph.Bake();
|
||||||
|
|
@ -688,6 +841,64 @@ int main()
|
||||||
lightingShaderBindings.emplace_back(std::move(lightingShaderBinding));
|
lightingShaderBindings.emplace_back(std::move(lightingShaderBinding));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bloomBrightShaderBinding->Update({
|
||||||
|
{
|
||||||
|
0,
|
||||||
|
Nz::ShaderBinding::TextureBinding {
|
||||||
|
bakedGraph.GetAttachmentTexture(lightOutput).get(),
|
||||||
|
textureSampler.get()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
1,
|
||||||
|
Nz::ShaderBinding::UniformBufferBinding {
|
||||||
|
viewerDataUBO.get(),
|
||||||
|
0, viewerDataUBO->GetSize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
gaussianBlurShaderBinding->Update({
|
||||||
|
{
|
||||||
|
0,
|
||||||
|
Nz::ShaderBinding::TextureBinding {
|
||||||
|
bakedGraph.GetAttachmentTexture(bloomTextureA).get(),
|
||||||
|
textureSampler.get()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
1,
|
||||||
|
Nz::ShaderBinding::UniformBufferBinding {
|
||||||
|
viewerDataUBO.get(),
|
||||||
|
0, viewerDataUBO->GetSize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bloomBlendShaderBinding->Update({
|
||||||
|
{
|
||||||
|
0,
|
||||||
|
Nz::ShaderBinding::TextureBinding {
|
||||||
|
bakedGraph.GetAttachmentTexture(lightOutput).get(),
|
||||||
|
textureSampler.get()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
1,
|
||||||
|
Nz::ShaderBinding::TextureBinding {
|
||||||
|
bakedGraph.GetAttachmentTexture(bloomTextureB).get(),
|
||||||
|
textureSampler.get()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
2,
|
||||||
|
Nz::ShaderBinding::UniformBufferBinding {
|
||||||
|
viewerDataUBO.get(),
|
||||||
|
0, viewerDataUBO->GetSize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
finalBlitBinding->Update({
|
finalBlitBinding->Update({
|
||||||
{
|
{
|
||||||
0,
|
0,
|
||||||
|
|
@ -719,7 +930,7 @@ int main()
|
||||||
|
|
||||||
builder.BindShaderBinding(*finalBlitBinding);
|
builder.BindShaderBinding(*finalBlitBinding);
|
||||||
builder.BindPipeline(*fullscreenPipeline);
|
builder.BindPipeline(*fullscreenPipeline);
|
||||||
builder.BindVertexBuffer(0, vertexBuffer.get());
|
builder.BindVertexBuffer(0, fullscreenVertexBuffer.get());
|
||||||
builder.Draw(3);
|
builder.Draw(3);
|
||||||
}
|
}
|
||||||
builder.EndRenderPass();
|
builder.EndRenderPass();
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ namespace Nz
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
PixelFormat format;
|
PixelFormat format;
|
||||||
|
unsigned int width = 100'000;
|
||||||
|
unsigned int height = 100'000;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -172,8 +172,8 @@ namespace Nz
|
||||||
|
|
||||||
TextureData& data = m_pending.textures.emplace_back();
|
TextureData& data = m_pending.textures.emplace_back();
|
||||||
data.format = m_attachments[attachmentIndex].format;
|
data.format = m_attachments[attachmentIndex].format;
|
||||||
data.width = 100'000;
|
data.width = m_attachments[attachmentIndex].width;
|
||||||
data.height = 100'000;
|
data.height = m_attachments[attachmentIndex].height;
|
||||||
|
|
||||||
return textureId;
|
return textureId;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -338,7 +338,7 @@ namespace Nz
|
||||||
|
|
||||||
rightOperand = rightAsVec;
|
rightOperand = rightAsVec;
|
||||||
}
|
}
|
||||||
else if (!IsPrimitiveType(leftType) || !IsPrimitiveType(rightType))
|
else if (leftType != rightType)
|
||||||
throw std::runtime_error("unexpected division operands");
|
throw std::runtime_error("unexpected division operands");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ void VecValue<ComponentCount>::BuildNodeEdition(QFormLayout* layout)
|
||||||
|
|
||||||
connect(spinbox, qOverload<double>(&QDoubleSpinBox::valueChanged), [=](double)
|
connect(spinbox, qOverload<double>(&QDoubleSpinBox::valueChanged), [=](double)
|
||||||
{
|
{
|
||||||
m_value[i] = spinbox->value();
|
m_value[i] = float(spinbox->value());
|
||||||
Q_EMIT dataUpdated(0);
|
Q_EMIT dataUpdated(0);
|
||||||
|
|
||||||
UpdatePreview();
|
UpdatePreview();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue