mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller Scene] Depth attachment; baked lighting example (flutter/engine#38118)
* [Impeller Scene] Depth buffer; baked lighting example * vk formats * Remove kD24UNormS8UInt * Address comments
This commit is contained in:
parent
0fab2ea52d
commit
5ad4bcdd38
@ -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",
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -109,6 +109,7 @@ struct TexImage2DData {
|
||||
break;
|
||||
case PixelFormat::kUnknown:
|
||||
case PixelFormat::kS8UInt:
|
||||
case PixelFormat::kD32FloatS8UInt:
|
||||
case PixelFormat::kR8UNormInt:
|
||||
case PixelFormat::kR8G8UNormInt:
|
||||
return;
|
||||
@ -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;
|
||||
}
|
||||
@ -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:
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
};
|
||||
|
||||
@ -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:
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -87,7 +87,10 @@ enum class PixelFormat {
|
||||
kR8G8B8A8UNormIntSRGB,
|
||||
kB8G8R8A8UNormInt,
|
||||
kB8G8R8A8UNormIntSRGB,
|
||||
|
||||
// Depth and stencil formats.
|
||||
kS8UInt,
|
||||
kD32FloatS8UInt,
|
||||
|
||||
// Defaults. If you don't know which ones to use, these are usually a safe
|
||||
// bet.
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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,
|
||||
@ -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));
|
||||
|
||||
|
||||
@ -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,
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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.";
|
||||
|
||||
@ -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_;
|
||||
|
||||
|
||||
@ -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"
|
||||
@ -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});
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
uniform FragInfo {
|
||||
vec4 color;
|
||||
float vertex_color_weight;
|
||||
}
|
||||
frag_info;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user