Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

[Impeller] Add Impeller scene #37694

Merged
merged 9 commits into from
Nov 17, 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
15 changes: 15 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1576,6 +1576,21 @@ FILE: ../../../flutter/impeller/runtime_stage/runtime_stage_playground.h
FILE: ../../../flutter/impeller/runtime_stage/runtime_stage_unittests.cc
FILE: ../../../flutter/impeller/runtime_stage/runtime_types.cc
FILE: ../../../flutter/impeller/runtime_stage/runtime_types.h
FILE: ../../../flutter/impeller/scene/camera.cc
FILE: ../../../flutter/impeller/scene/camera.h
FILE: ../../../flutter/impeller/scene/geometry.cc
FILE: ../../../flutter/impeller/scene/geometry.h
FILE: ../../../flutter/impeller/scene/material.cc
FILE: ../../../flutter/impeller/scene/material.h
FILE: ../../../flutter/impeller/scene/scene.cc
FILE: ../../../flutter/impeller/scene/scene.h
FILE: ../../../flutter/impeller/scene/scene_encoder.cc
FILE: ../../../flutter/impeller/scene/scene_encoder.h
FILE: ../../../flutter/impeller/scene/scene_entity.cc
FILE: ../../../flutter/impeller/scene/scene_entity.h
FILE: ../../../flutter/impeller/scene/scene_unittests.cc
FILE: ../../../flutter/impeller/scene/static_mesh_entity.cc
FILE: ../../../flutter/impeller/scene/static_mesh_entity.h
FILE: ../../../flutter/impeller/tessellator/c/tessellator.cc
FILE: ../../../flutter/impeller/tessellator/c/tessellator.h
FILE: ../../../flutter/impeller/tessellator/dart/lib/tessellator.dart
Expand Down
1 change: 1 addition & 0 deletions impeller/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ impeller_component("impeller_unittests") {
"image:image_unittests",
"playground",
"renderer:renderer_unittests",
"scene:scene_unittests",
"typographer:typographer_unittests",
]
}
Expand Down
43 changes: 43 additions & 0 deletions impeller/scene/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Copyright 2013 The Flutter Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//flutter/impeller/tools/impeller.gni")

impeller_component("scene") {
sources = [
"camera.cc",
"camera.h",
"geometry.cc",
"geometry.h",
"material.cc",
"material.h",
"scene.cc",
"scene.h",
"scene_encoder.cc",
"scene_encoder.h",
"scene_entity.cc",
"scene_entity.h",
"static_mesh_entity.cc",
"static_mesh_entity.h",
]

public_deps = [ "../renderer" ]

deps = [ "//flutter/fml" ]
}

impeller_component("scene_unittests") {
testonly = true

sources = [ "scene_unittests.cc" ]

deps = [
":scene",
"../fixtures",
"../playground:playground_test",
"//flutter/testing:testing_lib",

#"//third_party/tinygltf",
]
}
140 changes: 140 additions & 0 deletions impeller/scene/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
## ⚠️ **Experimental:** Do not use in production! ⚠️

# Impeller Scene

Impeller Scene is an experimental realtime 3D renderer powered by Impeller's
render layer with the following design priorities:

* Ease of use.
* Suitability for mobile.
* Common case scalability.

The aim is to create a familiar and flexible scene graph capable of building
complex dynamic scenes for games and beyond.

## Example

```cpp
std::shared_ptr<impeller::Context> context =
/* Create the backend-specific Impeller context */;

auto allocator = context->GetResourceAllocator();

/// Load resources.

auto dash_gltf = impeller::scene::LoadGLTF(allocator, "models/dash.glb");
auto environment_hdri =
impeller::scene::LoadHDRI(allocator, "environment/table_mountain.hdr");

/// Construct a scene.

auto scene = impeller::scene::Scene(context);

scene.Add(dash_gltf.scene);

auto& dash_player = dash_gltf.scene.CreateAnimationPlayer();
auto& walk_action = dash_player.CreateClipAction(dash_gltf.GetClip("Walk"));
walk_action.SetLoop(impeller::scene::AnimationAction::kLoopForever);
walk_action.SetWeight(0.7f);
walk_action.Seek(0.0f);
walk_action.Play();
auto& run_action = dash_player.CreateClipAction(dash_gltf.GetClip("Run"));
run_action.SetLoop(impeller::scene::AnimationAction::kLoopForever);
run_action.SetWeight(0.3f);
run_action.Play();

scene.Add(
impeller::scene::DirectionalLight(
/* color */ impeller::Color::AntiqueWhite(),
/* intensity */ 5,
/* direction */ {2, 3, 4}));

impeller::scene::StaticMeshEntity sphere_entity;
sphere_entity.SetGlobalTransform(
Matrix::MakeRotationEuler({kPiOver4, kPiOver4, 0}));
sphere_entity.SetCullingMode(impeller::scene::CullingMode::kFrustum);

std::unique_ptr<impeller::scene::SphereGeometry> sphere =
impeller::scene::Geometry::MakeSphere(allocator, /* radius */ 2);

sphere_entity.SetGeometry(sphere);

auto material = impeller::scene::Material::MakeStandard();
material.SetAlbedo(impeller::Color::Red());
material.SetRoughness(0.4);
material.SetMetallic(0.2);
// Common properties shared by all materials.
material.SetEnvironmentMap(environment_hdri);
material.SetFlatShaded(true);
material.SetBlendConfig({
impeller::BlendOperation::kAdd, // color_op
impeller::BlendFactor::kOne, // source_color_factor
impeller::BlendFactor::kOneMinusSourceAlpha, // destination_color_factor
impeller::BlendOperation::kAdd, // alpha_op
impeller::BlendFactor::kOne, // source_alpha_factor
impeller::BlendFactor::kOneMinusSourceAlpha, // destination_alpha_factor
});
material.SetStencilConfig({
impeller::StencilOperation::kIncrementClamp, // operation
impeller::CompareFunction::kAlways, // compare
});

sphere_entity->SetMaterials({material});


impeller::scene::StaticMeshEntity cube_entity;
cube_entity.GetGeometry(
impeller::scene::Geometry::MakeCube(allocator, {4, 4, 4}));
cube_entity.SetMaterials({material});

cube_entity.SetLocalTransform(Matrix::MakeTranslation({4, 0, 0}));

sphere_entity->Add(sube_entity);
scene.Add(sphere_entity);

/// Post processing.

auto dof = impeller::scene::PostProcessingEffect::MakeBokeh(
/* aperture_size */ 0.2,
/* focus_plane_distance */ 50);
scene.SetPostProcessing({dof});

/// Render the scene.

auto renderer = impeller::Renderer(context);

while(true) {
std::unique_ptr<impeller::Surface> surface = /* Wrap the window surface */;

renderer->Render(surface, [&scene](RenderTarget& render_target) {
/// Render a perspective view.

auto camera =
impeller::Camera::MakePerspective(
/* fov */ kPiOver4,
/* position */ {50, -30, 50})
.LookAt(
/* target */ impeller::Vector3::Zero,
/* up */ {0, -1, 0});

scene.Render(render_target, camera);

/// Render an overhead view on the bottom right corner of the screen.

auto size = render_target.GetRenderTargetSize();
auto minimap_camera =
impeller::Camera::MakeOrthographic(
/* view */ Rect::MakeLTRB(-100, -100, 100, 100),
/* position */ {0, -50, 0})
.LookAt(
/* target */ impeller::Vector3::Zero,
/* up */ {0, 0, 1})
.WithViewport(IRect::MakeXYWH(size.width / 4, size.height / 4,
size.height / 5, size.height / 5));

scene.Render(render_target, minimap_camera);

return true;
});
}
```
37 changes: 37 additions & 0 deletions impeller/scene/camera.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "impeller/scene/camera.h"

namespace impeller {
namespace scene {

Camera Camera::MakePerspective(Scalar fov_y, Vector3 position) {
Camera camera;
camera.fov_y_ = fov_y;
camera.position_ = position;
return camera;
}

Camera Camera::LookAt(Vector3 target, Vector3 up) const {
Camera camera = *this;
camera.target_ = target;
camera.up_ = up;
return camera;
}

Matrix Camera::GetTransform(ISize target_size) const {
if (transform_.has_value()) {
return transform_.value();
}

transform_ =
Matrix::MakePerspective(Radians(fov_y_), target_size, z_near_, z_far_) *
Matrix::MakeLookAt(position_, target_, up_).Invert();

return transform_.value();
}

} // namespace scene
} // namespace impeller
34 changes: 34 additions & 0 deletions impeller/scene/camera.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include <optional>

#include "impeller/geometry/matrix.h"

namespace impeller {
namespace scene {

class Camera {
public:
static Camera MakePerspective(Scalar fov_y, Vector3 position);

Camera LookAt(Vector3 target, Vector3 up = Vector3(0, -1, 0)) const;

Matrix GetTransform(ISize target_size) const;

private:
Scalar fov_y_ = 60;
Vector3 position_ = Vector3();
Vector3 target_ = Vector3(0, 0, -1);
Vector3 up_ = Vector3(0, -1, 0);
Scalar z_near_ = 0.1;
Scalar z_far_ = 1000;

mutable std::optional<Matrix> transform_;
};

} // namespace scene
} // namespace impeller
36 changes: 36 additions & 0 deletions impeller/scene/geometry.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "impeller/scene/geometry.h"

#include <memory>

namespace impeller {
namespace scene {

//------------------------------------------------------------------------------
/// Geometry
///

std::shared_ptr<CuboidGeometry> Geometry::MakeCuboid(Vector3 size) {
auto result = std::make_shared<CuboidGeometry>();
result->SetSize(size);
return result;
}

//------------------------------------------------------------------------------
/// CuboidGeometry
///

void CuboidGeometry::SetSize(Vector3 size) {
size_ = size;
}

VertexBuffer CuboidGeometry::GetVertexBuffer(
std::shared_ptr<Allocator>& allocator) const {
return {};
}

} // namespace scene
} // namespace impeller
39 changes: 39 additions & 0 deletions impeller/scene/geometry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include <memory>

#include "impeller/geometry/vector.h"
#include "impeller/renderer/allocator.h"
#include "impeller/renderer/vertex_buffer.h"

namespace impeller {
namespace scene {

class CuboidGeometry;

class Geometry {
public:
static std::shared_ptr<CuboidGeometry> MakeCuboid(Vector3 size);

private:
virtual VertexBuffer GetVertexBuffer(
std::shared_ptr<Allocator>& allocator) const = 0;
};

class CuboidGeometry final : public Geometry {
public:
void SetSize(Vector3 size);

private:
VertexBuffer GetVertexBuffer(
std::shared_ptr<Allocator>& allocator) const override;

Vector3 size_;
};

} // namespace scene
} // namespace impeller
Loading