-
Notifications
You must be signed in to change notification settings - Fork 103
Add a Transform3DImageFilter to apply perspective projection effects. #938
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
Conversation
| /** | ||
| * A geometry processor for rendering 3D transformed quads with optional per-edge anti-aliasing. | ||
| */ | ||
| class QuadPerEdgeAA3DGeometryProcessor : public GeometryProcessor { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
建议和滤镜同名:Transform3DGeometryProcessor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
已经修改。
| return; | ||
| } | ||
|
|
||
| constexpr auto loadOp = LoadAction::Clear; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个声明一个变量的意义是什么?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个变量声明确实多余了。另外按最新意见,整个Transform3DRenderTask已经重构。
| constexpr auto loadOp = LoadAction::Clear; | ||
| const RenderPassDescriptor descriptor(rt->getRenderTexture(), loadOp, StoreAction::Store, | ||
| Color::Transparent(), nullptr); | ||
| const auto renderPass = encoder->beginRenderPass(descriptor); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个类没有看到任何调用深度缓冲和模板缓冲的代码,是不是没有必要单独写个RenderTask,走公共的RectDrawOp就可以了?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
按最新意见,整个Transform3DRenderTask已经重构,直接使用实现Rect3DDrawOp。
include/tgfx/core/ImageFilter.h
Outdated
| * @param matrix 3D transformation matrix used to convert model coordinates to clip space. | ||
| * @param viewSize Window view size, used to map NDC coordinates to window coordinates. | ||
| */ | ||
| static std::shared_ptr<ImageFilter> Transform3D(const Matrix3D& matrix, const Size& viewSize); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
viewSize 不是 Rect的大小吗?这里注释写是Window view size,容易让人误解
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
我把NDC坐标最后做视口变换的那一步看成是映射到一个窗口,所有注释这么写了。参数我改成viewportsize,这样和GL的接口glViewport一致,更容易理解。
include/tgfx/core/MathVector.h
Outdated
| * Returns the quotient of this vector and a scalar, computed as (v.x / s, v.y / s). | ||
| */ | ||
| friend Vec2 operator/(const Vec2& v, float s) { | ||
| return {v.x / s, v.y / s}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s需要防止被0除
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
只增加DEBUG_ASSERT(!FloatNearlyZero(s));判断,不错额外处理,因为除以0并不会直接crash,会得到NaN,这个异常值可以返回给使用者,引擎内部隐藏错误可能不太好,
| /** | ||
| * Creates a Matrix3D set to the identity matrix. | ||
| */ | ||
| constexpr Matrix3D() : Matrix3D(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
按4行4列书写,禁用clang-format,方便阅读
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
已经修改,通过注释的方式增加可读性
include/tgfx/core/Matrix3D.h
Outdated
| return this->mapPoint(v.x, v.y, v.z, v.w); | ||
| } | ||
|
|
||
| float values[16]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
初始化下
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
已经修改。
src/core/Matrix3D.cpp
Outdated
| dst[15] = src[15]; | ||
| } | ||
|
|
||
| static bool Invert4x4Matrix(const float inMat[16], float outMat[16]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
把概念统一一下,要么统一叫Matrix44,要么统一叫Matrix3D,不要混用
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
已经修改。
| source->isAlphaOnly(), 1, args.mipmapped, ImageOrigin::TopLeft, args.backingFit); | ||
| auto sourceTextureProxy = source->lockTextureProxy(args); | ||
|
|
||
| const auto srcW = static_cast<float>(source->width()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这些const都可以删除掉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
已经修改。
| #define UNIFORM_NDC_OFFSET_NAME "ndcOffset" | ||
|
|
||
| PlacementPtr<Transform3DGeometryProcessor> Transform3DGeometryProcessor::Make( | ||
| BlockBuffer* buffer, AAType aa, const Matrix3D& transformMatrix, const Vec2& ndcScale, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
transform 和 matrix很多时候是等价的概念
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
已经修改。
| } | ||
|
|
||
| void GLSLQuadPerEdgeAA3DGeometryProcessor::emitCode(EmitArgs& args) const { | ||
| const auto vertBuilder = args.vertBuilder; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const都去掉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
已经修改。
|
|
||
| void onComputeProcessorKey(BytesKey* bytesKey) const override; | ||
|
|
||
| Attribute position; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
成员变量都初始化下
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
已经修改。
| class DrawOp { | ||
| public: | ||
| enum class Type { RectDrawOp, RRectDrawOp, ShapeDrawOp, AtlasTextOp }; | ||
| enum class Type { RectDrawOp, RRectDrawOp, ShapeDrawOp, AtlasTextOp, Rect3DDrawOp }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里支持吃了Rect做3D变换吗?RRect、Shape呢
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
是的。PRect和Shape还没有支持,但理论上都可以通过一个投影矩阵和视口大小实现3D投影的。这里先暂时满足需求应该就好了。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vec2、vec3、vec4的逻辑都是一样的,看能否合并,内部的实现逻辑都转成vec4的,这样就避免有大量重复代码
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
如果优化需要使用匿名结构体,这个属于非标准的CPP用法。
include/tgfx/core/ImageFilter.h
Outdated
| namespace tgfx { | ||
| class TextureProxy; | ||
| enum class SrcRectConstraint; | ||
| struct PerspectiveInfo; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个前向声明应该删除吧
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
已经修改。
| const Vec2& ndcOffset); | ||
|
|
||
| std::string name() const override { | ||
| return "QuadPerEdgeAA3DGeometryProcessor"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个名字和类名保持一致
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
已经修改。
include/tgfx/core/Matrix3D.h
Outdated
| values[i + 12] = v.w; | ||
| } | ||
|
|
||
| void setCol(int i, const Vec4& v) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setColumn写全称吧
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
已经修改。
src/gpu/ops/Rect3DDrawOp.cpp
Outdated
| const Vec2 scale2(drawArgs.viewportSize.width / static_cast<float>(renderTarget->width()), | ||
| drawArgs.viewportSize.height / static_cast<float>(renderTarget->height())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
宽高的有效性检查下,防止除以0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
已加DEBUG_ASSERT。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个文件要么命名为Vec.h和内容保持一致。要么和Skia一样,把里面的内容都放到Matrix3D.h文件的前面。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
已经改名。
| return result; | ||
| } | ||
|
|
||
| std::shared_ptr<TextureProxy> Transform3DImageFilter::lockTextureProxy( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个方法里没有实现args.drawScale的缩放优化吧?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
已经补充,同时补充了单测用例。
| #define UNIFORM_TRANSFORM_MATRIX_NAME "transformMatrix" | ||
| #define UNIFORM_NDC_SCALE_NAME "ndcScale" | ||
| #define UNIFORM_NDC_OFFSET_NAME "ndcOffset" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
我们尽量避免使用#define, 缺少作用域,都改成static constexpr char*
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
已经修改。
| std::shared_ptr<Image> source, const Rect& renderBounds, const TPArgs& args) const { | ||
| float dstDrawWidth = renderBounds.width(); | ||
| float dstDrawHeight = renderBounds.height(); | ||
| const float tmpDrawScale = std::max(0.f, args.drawScale); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个变量如果不允许小于0,直接DEBUG_ASSERT(args.drawScale>0.0f),不用赋值给一个大于等于零的临时变量再DEBUG_ASSERT
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
已经修改。
| static constexpr const char* UniformTransformMatrixName = "transformMatrix"; | ||
| static constexpr const char* UniformNdcScaleName = "ndcScale"; | ||
| static constexpr const char* UniformNdcOffsetName = "ndcOffset"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
改成这种写法:static constexpr const char UniformTransformMatrixName[] =
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
已经修改。
1、新增Transform3DImageFilter,支持设置44矩阵和Size类型视口大小对输入图像应用3D投影变换。
2、从DrawOp派生Rect3DDrawOp实现渲染任务。使用Transform3DGeometryProcessor实现顶点处理逻辑。
3、接口层暴露Vector和Matrix3D用于构建44变换矩阵。