[Impeller Scene] Wire up camera (flutter/engine#38053)

* [Impeller Scene] Wire up camera

* Resolve view transform once
This commit is contained in:
Brandon DeRosier 2022-12-03 15:11:21 -08:00 committed by GitHub
parent ab78871b66
commit cfccb9ed0b
10 changed files with 29 additions and 24 deletions

View File

@ -7,7 +7,7 @@
namespace impeller {
namespace scene {
Camera Camera::MakePerspective(Scalar fov_y, Vector3 position) {
Camera Camera::MakePerspective(Radians fov_y, Vector3 position) {
Camera camera;
camera.fov_y_ = fov_y;
camera.position_ = position;
@ -26,9 +26,8 @@ Matrix Camera::GetTransform(ISize target_size) const {
return transform_.value();
}
transform_ =
Matrix::MakePerspective(Radians(fov_y_), target_size, z_near_, z_far_) *
Matrix::MakeLookAt(position_, target_, up_).Invert();
transform_ = Matrix::MakePerspective(fov_y_, target_size, z_near_, z_far_) *
Matrix::MakeLookAt(position_, target_, up_);
return transform_.value();
}

View File

@ -13,14 +13,14 @@ namespace scene {
class Camera {
public:
static Camera MakePerspective(Scalar fov_y, Vector3 position);
static Camera MakePerspective(Radians 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;
Radians fov_y_ = Degrees(60);
Vector3 position_ = Vector3();
Vector3 target_ = Vector3(0, 0, -1);
Vector3 up_ = Vector3(0, -1, 0);

View File

@ -26,7 +26,7 @@ bool Scene::Render(const RenderTarget& render_target,
const Camera& camera) const {
// Collect the render commands from the scene.
SceneEncoder encoder;
if (!root_.Render(encoder, camera)) {
if (!root_.Render(encoder)) {
FML_LOG(ERROR) << "Failed to render frame.";
return false;
}
@ -34,7 +34,7 @@ bool Scene::Render(const RenderTarget& render_target,
// Encode the commands.
std::shared_ptr<CommandBuffer> command_buffer =
encoder.BuildSceneCommandBuffer(*scene_context_, render_target);
encoder.BuildSceneCommandBuffer(*scene_context_, camera, render_target);
// TODO(bdero): Do post processing.

View File

@ -22,6 +22,7 @@ void SceneEncoder::Add(const SceneCommand& command) {
}
static void EncodeCommand(const SceneContext& scene_context,
const Matrix& view_transform,
RenderPass& render_pass,
const SceneCommand& scene_command) {
auto& host_buffer = render_pass.GetTransientsBuffer();
@ -39,7 +40,7 @@ static void EncodeCommand(const SceneContext& scene_context,
scene_command.material->BindToCommand(scene_context, host_buffer, cmd);
GeometryVertexShader::VertInfo info;
info.mvp = scene_command.transform;
info.mvp = view_transform * scene_command.transform;
GeometryVertexShader::BindVertInfo(cmd, host_buffer.EmplaceUniform(info));
render_pass.AddCommand(std::move(cmd));
@ -47,6 +48,7 @@ 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 {
auto command_buffer = scene_context.GetContext()->CreateCommandBuffer();
if (!command_buffer) {
@ -61,7 +63,9 @@ std::shared_ptr<CommandBuffer> SceneEncoder::BuildSceneCommandBuffer(
}
for (auto& command : commands_) {
EncodeCommand(scene_context, *render_pass, command);
Matrix view_transform =
camera.GetTransform(render_pass->GetRenderTargetSize());
EncodeCommand(scene_context, view_transform, *render_pass, command);
}
if (!render_pass->EncodeCommands()) {

View File

@ -10,6 +10,7 @@
#include "flutter/fml/macros.h"
#include "impeller/renderer/command_buffer.h"
#include "impeller/scene/camera.h"
#include "impeller/scene/geometry.h"
#include "impeller/scene/material.h"
@ -34,6 +35,7 @@ class SceneEncoder {
std::shared_ptr<CommandBuffer> BuildSceneCommandBuffer(
const SceneContext& scene_context,
const Camera& camera,
const RenderTarget& render_target) const;
std::vector<SceneCommand> commands_;

View File

@ -56,17 +56,17 @@ bool SceneEntity::Add(const std::shared_ptr<SceneEntity>& child) {
return true;
}
bool SceneEntity::Render(SceneEncoder& encoder, const Camera& camera) const {
OnRender(encoder, camera);
bool SceneEntity::Render(SceneEncoder& encoder) const {
OnRender(encoder);
for (auto& child : children_) {
if (!child->Render(encoder, camera)) {
if (!child->Render(encoder)) {
return false;
}
}
return true;
}
bool SceneEntity::OnRender(SceneEncoder& encoder, const Camera& camera) const {
bool SceneEntity::OnRender(SceneEncoder& encoder) const {
return true;
}

View File

@ -34,13 +34,13 @@ class SceneEntity {
bool Add(const std::shared_ptr<SceneEntity>& child);
bool Render(SceneEncoder& encoder, const Camera& camera) const;
bool Render(SceneEncoder& encoder) const;
protected:
Matrix local_transform_;
private:
virtual bool OnRender(SceneEncoder& encoder, const Camera& camera) const;
virtual bool OnRender(SceneEncoder& encoder) const;
SceneEntity* parent_ = nullptr;
std::vector<std::shared_ptr<SceneEntity>> children_;

View File

@ -37,20 +37,21 @@ TEST_P(SceneTest, CuboidUnlit) {
material->SetColor(Color::Red());
mesh->SetMaterial(std::move(material));
Vector3 size(1, 2, 3);
Vector3 size(1, 1, 0);
mesh->SetGeometry(Geometry::MakeCuboid(size));
mesh->SetLocalTransform(Matrix::MakeTranslation(size / 2));
mesh->SetLocalTransform(Matrix::MakeTranslation(-size / 2));
scene.Add(mesh);
}
// Face towards the +Z direction (+X right, +Y up).
auto camera = Camera::MakePerspective(
/* fov */ kPiOver4,
/* position */ {50, -30, 50})
/* fov */ Radians(kPiOver4),
/* position */ {2, 2, -5})
.LookAt(
/* target */ Vector3(),
/* up */ {0, -1, 0});
/* up */ {0, 1, 0});
scene.Render(render_target, camera);
return true;

View File

@ -24,8 +24,7 @@ void StaticMeshEntity::SetMaterial(std::shared_ptr<Material> material) {
}
// |SceneEntity|
bool StaticMeshEntity::OnRender(SceneEncoder& encoder,
const Camera& camera) const {
bool StaticMeshEntity::OnRender(SceneEncoder& encoder) const {
SceneCommand command = {
.label = "Static Mesh",
.transform = GetGlobalTransform(),

View File

@ -25,7 +25,7 @@ class StaticMeshEntity final : public SceneEntity {
private:
// |SceneEntity|
bool OnRender(SceneEncoder& encoder, const Camera& camera) const override;
bool OnRender(SceneEncoder& encoder) const override;
std::shared_ptr<Material> material_;
std::shared_ptr<Geometry> geometry_;