Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Impeller Scene] Depth attachment; baked lighting example #38118

Merged
merged 4 commits into from
Dec 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions impeller/fixtures/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ test_fixtures("file_fixtures") {
"boston.jpg",
"embarcadero.jpg",
"flutter_logo.glb",
"flutter_logo_baked.png",
"kalimba.jpg",
"multiple_stages.hlsl",
"resources_limit.vert",
Expand Down
Binary file added impeller/fixtures/flutter_logo_baked.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion impeller/playground/backend/gles/playground_impl_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ PlaygroundImplGLES::PlaygroundImplGLES()
::glfwWindowHint(GLFW_GREEN_BITS, 8);
::glfwWindowHint(GLFW_BLUE_BITS, 8);
::glfwWindowHint(GLFW_ALPHA_BITS, 8);
::glfwWindowHint(GLFW_DEPTH_BITS, 0); // no depth buffer
::glfwWindowHint(GLFW_DEPTH_BITS, 32); // 32 bit depth buffer
::glfwWindowHint(GLFW_STENCIL_BITS, 8); // 8 bit stencil buffer
::glfwWindowHint(GLFW_SAMPLES, 4); // 4xMSAA

Expand Down
31 changes: 2 additions & 29 deletions impeller/playground/playground.cc
Original file line number Diff line number Diff line change
Expand Up @@ -263,35 +263,8 @@ bool Playground::OpenPlaygroundHere(
}
render_target.SetColorAttachment(color0, 0);

#ifndef IMPELLER_ENABLE_VULKAN
{
TextureDescriptor stencil0_tex;
stencil0_tex.storage_mode = StorageMode::kDeviceTransient;
stencil0_tex.type = TextureType::kTexture2D;
stencil0_tex.sample_count = SampleCount::kCount1;
stencil0_tex.format = PixelFormat::kDefaultStencil;
stencil0_tex.size = color0.texture->GetSize();
stencil0_tex.usage =
static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
auto stencil_texture =
renderer->GetContext()->GetResourceAllocator()->CreateTexture(
stencil0_tex);

if (!stencil_texture) {
VALIDATION_LOG << "Could not create stencil texture.";
return false;
}
stencil_texture->SetLabel("ImguiStencil");

StencilAttachment stencil0;
stencil0.texture = stencil_texture;
stencil0.clear_stencil = 0;
stencil0.load_action = LoadAction::kClear;
stencil0.store_action = StoreAction::kDontCare;

render_target.SetStencilAttachment(stencil0);
}
#endif
render_target.SetStencilAttachment(std::nullopt);
render_target.SetDepthAttachment(std::nullopt);

auto pass = buffer->CreateRenderPass(render_target);
if (!pass) {
Expand Down
9 changes: 4 additions & 5 deletions impeller/renderer/backend/gles/texture_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ struct TexImage2DData {
break;
case PixelFormat::kUnknown:
case PixelFormat::kS8UInt:
case PixelFormat::kD32FloatS8UInt:
case PixelFormat::kR8UNormInt:
case PixelFormat::kR8G8UNormInt:
return;
Expand Down Expand Up @@ -136,15 +137,11 @@ struct TexImage2DData {
break;
}
case PixelFormat::kR8G8B8A8UNormIntSRGB:
return;
case PixelFormat::kB8G8R8A8UNormInt:
return;
case PixelFormat::kB8G8R8A8UNormIntSRGB:
return;
case PixelFormat::kS8UInt:
return;
case PixelFormat::kD32FloatS8UInt:
case PixelFormat::kR8UNormInt:
return;
case PixelFormat::kR8G8UNormInt:
return;
}
Expand Down Expand Up @@ -279,6 +276,8 @@ static std::optional<GLenum> ToRenderBufferFormat(PixelFormat format) {
return GL_RGBA4;
case PixelFormat::kS8UInt:
return GL_STENCIL_INDEX8;
case PixelFormat::kD32FloatS8UInt:
return GL_DEPTH32F_STENCIL8;
case PixelFormat::kUnknown:
case PixelFormat::kA8UNormInt:
case PixelFormat::kR8UNormInt:
Expand Down
12 changes: 8 additions & 4 deletions impeller/renderer/backend/metal/formats_mtl.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ constexpr PixelFormat FromMTLPixelFormat(MTLPixelFormat format) {
return PixelFormat::kB8G8R8A8UNormIntSRGB;
case MTLPixelFormatRGBA8Unorm:
return PixelFormat::kR8G8B8A8UNormInt;
case MTLPixelFormatStencil8:
return PixelFormat::kS8UInt;
case MTLPixelFormatRGBA8Unorm_sRGB:
return PixelFormat::kR8G8B8A8UNormIntSRGB;
case MTLPixelFormatStencil8:
return PixelFormat::kS8UInt;
case MTLPixelFormatDepth32Float_Stencil8:
return PixelFormat::kD32FloatS8UInt;
default:
return PixelFormat::kUnknown;
}
Expand All @@ -53,10 +55,12 @@ constexpr MTLPixelFormat ToMTLPixelFormat(PixelFormat format) {
return MTLPixelFormatBGRA8Unorm_sRGB;
case PixelFormat::kR8G8B8A8UNormInt:
return MTLPixelFormatRGBA8Unorm;
case PixelFormat::kS8UInt:
return MTLPixelFormatStencil8;
case PixelFormat::kR8G8B8A8UNormIntSRGB:
return MTLPixelFormatRGBA8Unorm_sRGB;
case PixelFormat::kS8UInt:
return MTLPixelFormatStencil8;
case PixelFormat::kD32FloatS8UInt:
return MTLPixelFormatDepth32Float_Stencil8;
}
return MTLPixelFormatInvalid;
};
Expand Down
5 changes: 5 additions & 0 deletions impeller/renderer/backend/vulkan/formats_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ constexpr vk::Format ToVKImageFormat(PixelFormat format) {
return vk::Format::eB8G8R8A8Srgb;
case PixelFormat::kS8UInt:
return vk::Format::eS8Uint;
case PixelFormat::kD32FloatS8UInt:
return vk::Format::eD32SfloatS8Uint;
case PixelFormat::kR8UNormInt:
return vk::Format::eR8Unorm;
case PixelFormat::kR8G8UNormInt:
Expand Down Expand Up @@ -179,6 +181,9 @@ constexpr PixelFormat ToPixelFormat(vk::Format format) {
case vk::Format::eS8Uint:
return PixelFormat::kS8UInt;

case vk::Format::eD32SfloatS8Uint:
return PixelFormat::kD32FloatS8UInt;

case vk::Format::eR8Unorm:
return PixelFormat::kR8UNormInt;

Expand Down
5 changes: 5 additions & 0 deletions impeller/renderer/formats.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ enum class PixelFormat {
kR8G8B8A8UNormIntSRGB,
kB8G8R8A8UNormInt,
kB8G8R8A8UNormIntSRGB,

// Depth and stencil formats.
kS8UInt,
kD32FloatS8UInt,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol, I didn't realize we didn't have one of these already.

Copy link
Member Author

@bdero bdero Dec 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I never noticed either. For the depth in impeller-cmake I literally used B8G8R8A8 because it's GLES only right now and the attachments have no affect on the surface framebuffer. 😄


// Defaults. If you don't know which ones to use, these are usually a safe
// bet.
Expand Down Expand Up @@ -285,6 +288,8 @@ constexpr size_t BytesPerPixelForPixelFormat(PixelFormat format) {
case PixelFormat::kB8G8R8A8UNormInt:
case PixelFormat::kB8G8R8A8UNormIntSRGB:
return 4u;
case PixelFormat::kD32FloatS8UInt:
return 5u;
}
return 0u;
}
Expand Down
14 changes: 10 additions & 4 deletions impeller/renderer/render_target.cc
Original file line number Diff line number Diff line change
Expand Up @@ -149,15 +149,21 @@ RenderTarget& RenderTarget::SetColorAttachment(
return *this;
}

RenderTarget& RenderTarget::SetDepthAttachment(DepthAttachment attachment) {
if (attachment.IsValid()) {
RenderTarget& RenderTarget::SetDepthAttachment(
std::optional<DepthAttachment> attachment) {
if (!attachment.has_value()) {
depth_ = std::nullopt;
} else if (attachment->IsValid()) {
depth_ = std::move(attachment);
}
return *this;
}

RenderTarget& RenderTarget::SetStencilAttachment(StencilAttachment attachment) {
if (attachment.IsValid()) {
RenderTarget& RenderTarget::SetStencilAttachment(
std::optional<StencilAttachment> attachment) {
if (!attachment.has_value()) {
stencil_ = std::nullopt;
} else if (attachment->IsValid()) {
stencil_ = std::move(attachment);
}
return *this;
Expand Down
5 changes: 3 additions & 2 deletions impeller/renderer/render_target.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ class RenderTarget {
RenderTarget& SetColorAttachment(const ColorAttachment& attachment,
size_t index);

RenderTarget& SetDepthAttachment(DepthAttachment attachment);
RenderTarget& SetDepthAttachment(std::optional<DepthAttachment> attachment);

RenderTarget& SetStencilAttachment(StencilAttachment attachment);
RenderTarget& SetStencilAttachment(
std::optional<StencilAttachment> attachment);

const std::map<size_t, ColorAttachment>& GetColorAttachments() const;

Expand Down
5 changes: 5 additions & 0 deletions impeller/scene/material.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ void UnlitMaterial::SetColorTexture(std::shared_ptr<Texture> color_texture) {
color_texture_ = std::move(color_texture);
}

void UnlitMaterial::SetVertexColorWeight(Scalar weight) {
vertex_color_weight_ = weight;
}

// |Material|
std::shared_ptr<Pipeline<PipelineDescriptor>> UnlitMaterial::GetPipeline(
const SceneContext& scene_context,
Expand All @@ -69,6 +73,7 @@ void UnlitMaterial::BindToCommand(const SceneContext& scene_context,
// Uniform buffer.
UnlitPipeline::FragmentShader::FragInfo info;
info.color = color_;
info.vertex_color_weight = vertex_color_weight_;
UnlitPipeline::FragmentShader::BindFragInfo(command,
buffer.EmplaceUniform(info));

Expand Down
3 changes: 3 additions & 0 deletions impeller/scene/material.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ class UnlitMaterial final : public Material {

void SetColorTexture(std::shared_ptr<Texture> color_texture);

void SetVertexColorWeight(Scalar weight);

// |Material|
std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
const SceneContext& scene_context,
Expand All @@ -79,6 +81,7 @@ class UnlitMaterial final : public Material {
private:
Color color_ = Color::White();
std::shared_ptr<Texture> color_texture_;
Scalar vertex_color_weight_ = 1;
};

class StandardMaterial final : public Material {
Expand Down
12 changes: 12 additions & 0 deletions impeller/scene/scene_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ namespace scene {

void SceneContextOptions::ApplyToPipelineDescriptor(
PipelineDescriptor& desc) const {
DepthAttachmentDescriptor depth;
depth.depth_compare = CompareFunction::kLess;
depth.depth_write_enabled = true;
desc.SetDepthStencilAttachmentDescriptor(depth);
desc.SetDepthPixelFormat(PixelFormat::kD32FloatS8UInt);

StencilAttachmentDescriptor stencil;
stencil.stencil_compare = CompareFunction::kAlways;
stencil.depth_stencil_pass = StencilOperation::kKeep;
desc.SetStencilAttachmentDescriptors(stencil);
desc.SetStencilPixelFormat(PixelFormat::kD32FloatS8UInt);

desc.SetSampleCount(sample_count);
desc.SetPrimitiveType(primitive_type);
}
Expand Down
32 changes: 31 additions & 1 deletion impeller/scene/scene_encoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,37 @@ static void EncodeCommand(const SceneContext& scene_context,
std::shared_ptr<CommandBuffer> SceneEncoder::BuildSceneCommandBuffer(
const SceneContext& scene_context,
const Camera& camera,
const RenderTarget& render_target) const {
RenderTarget render_target) const {
{
TextureDescriptor ds_texture;
ds_texture.type = TextureType::kTexture2DMultisample;
ds_texture.format = PixelFormat::kD32FloatS8UInt;
ds_texture.size = render_target.GetRenderTargetSize();
ds_texture.usage =
static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
ds_texture.sample_count = SampleCount::kCount4;
ds_texture.storage_mode = StorageMode::kDeviceTransient;
auto texture =
scene_context.GetContext()->GetResourceAllocator()->CreateTexture(
ds_texture);

DepthAttachment depth;
depth.load_action = LoadAction::kClear;
depth.store_action = StoreAction::kDontCare;
depth.clear_depth = 1.0;
depth.texture = texture;
render_target.SetDepthAttachment(depth);

// The stencil and depth buffers must be the same texture for MacOS ARM
// and Vulkan.
StencilAttachment stencil;
stencil.load_action = LoadAction::kClear;
stencil.store_action = StoreAction::kDontCare;
stencil.clear_stencil = 0u;
stencil.texture = texture;
render_target.SetStencilAttachment(stencil);
}

auto command_buffer = scene_context.GetContext()->CreateCommandBuffer();
if (!command_buffer) {
FML_LOG(ERROR) << "Failed to create command buffer.";
Expand Down
2 changes: 1 addition & 1 deletion impeller/scene/scene_encoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class SceneEncoder {
std::shared_ptr<CommandBuffer> BuildSceneCommandBuffer(
const SceneContext& scene_context,
const Camera& camera,
const RenderTarget& render_target) const;
RenderTarget render_target) const;

std::vector<SceneCommand> commands_;

Expand Down
20 changes: 17 additions & 3 deletions impeller/scene/scene_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <cmath>
#include <memory>

#include "flutter/testing/testing.h"
#include "impeller/geometry/color.h"
#include "impeller/geometry/constants.h"
#include "impeller/geometry/matrix.h"
#include "impeller/geometry/quaternion.h"
#include "impeller/geometry/vector.h"
#include "impeller/playground/playground.h"
#include "impeller/playground/playground_test.h"
#include "impeller/renderer/formats.h"
#include "impeller/scene/camera.h"
#include "impeller/scene/geometry.h"
#include "impeller/scene/importer/scene_flatbuffers.h"
Expand Down Expand Up @@ -80,18 +85,27 @@ TEST_P(SceneTest, GLTFScene) {
auto geometry = Geometry::MakeFromFBMesh(*fb_mesh, *allocator);
ASSERT_NE(geometry, nullptr);

std::shared_ptr<UnlitMaterial> material = Material::MakeUnlit();
auto bridge = CreateTextureForFixture("flutter_logo_baked.png");
material->SetColorTexture(bridge);
material->SetVertexColorWeight(0);

Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
auto scene = Scene(GetContext());

auto mesh = SceneEntity::MakeStaticMesh();
mesh->SetMaterial(Material::MakeUnlit());
mesh->SetMaterial(material);
mesh->SetGeometry(geometry);
mesh->SetLocalTransform(Matrix::MakeScale({3, 3, 3}));
scene.Add(mesh);

Quaternion rotation({0, 1, 0}, -GetSecondsElapsed() * 0.5);
Vector3 start_position(-1, -1.5, -5);

// Face towards the +Z direction (+X right, +Y up).
auto camera = Camera::MakePerspective(
/* fov */ Radians(kPiOver4),
/* position */ {2, 2, -5})
/* fov */ Degrees(60),
/* position */ rotation * start_position)
.LookAt(
/* target */ Vector3(),
/* up */ {0, 1, 0});
Expand Down
6 changes: 4 additions & 2 deletions impeller/scene/shaders/unlit.frag
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

uniform FragInfo {
vec4 color;
float vertex_color_weight;
}
frag_info;

Expand All @@ -17,6 +18,7 @@ in vec4 v_color;
out vec4 frag_color;

void main() {
frag_color =
texture(base_color_texture, v_texture_coords) * v_color * frag_info.color;
vec4 vertex_color = mix(vec4(1), v_color, frag_info.vertex_color_weight);
frag_color = texture(base_color_texture, v_texture_coords) * vertex_color *
frag_info.color;
}