Skip to content

Conversation

@StarryThrone
Copy link
Collaborator

@StarryThrone StarryThrone commented Sep 18, 2025

1、新增Transform3DImageFilter,支持设置44矩阵和Size类型视口大小对输入图像应用3D投影变换。
2、从DrawOp派生Rect3DDrawOp实现渲染任务。使用Transform3DGeometryProcessor实现顶点处理逻辑。
3、接口层暴露Vector和Matrix3D用于构建4
4变换矩阵。

/**
* A geometry processor for rendering 3D transformed quads with optional per-edge anti-aliasing.
*/
class QuadPerEdgeAA3DGeometryProcessor : public GeometryProcessor {
Copy link
Collaborator

Choose a reason for hiding this comment

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

建议和滤镜同名:Transform3DGeometryProcessor

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

已经修改。

@domchen domchen changed the title Provide perspective filters for applying perspective projection effects on the canvas (Paint) and on layers. Add a Transform3DImageFilter to apply perspective projection effects. Sep 19, 2025
return;
}

constexpr auto loadOp = LoadAction::Clear;
Copy link
Collaborator

Choose a reason for hiding this comment

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

这个声明一个变量的意义是什么?

Copy link
Collaborator Author

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);
Copy link
Collaborator

Choose a reason for hiding this comment

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

这个类没有看到任何调用深度缓冲和模板缓冲的代码,是不是没有必要单独写个RenderTask,走公共的RectDrawOp就可以了?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

按最新意见,整个Transform3DRenderTask已经重构,直接使用实现Rect3DDrawOp。

* @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);
Copy link
Collaborator

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,容易让人误解

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

我把NDC坐标最后做视口变换的那一步看成是映射到一个窗口,所有注释这么写了。参数我改成viewportsize,这样和GL的接口glViewport一致,更容易理解。

* 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};
Copy link
Collaborator

Choose a reason for hiding this comment

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

s需要防止被0除

Copy link
Collaborator Author

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) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

按4行4列书写,禁用clang-format,方便阅读

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

已经修改,通过注释的方式增加可读性

return this->mapPoint(v.x, v.y, v.z, v.w);
}

float values[16];
Copy link
Collaborator

Choose a reason for hiding this comment

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

初始化下

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

已经修改。

dst[15] = src[15];
}

static bool Invert4x4Matrix(const float inMat[16], float outMat[16]) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

把概念统一一下,要么统一叫Matrix44,要么统一叫Matrix3D,不要混用

Copy link
Collaborator Author

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());
Copy link
Collaborator

Choose a reason for hiding this comment

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

这些const都可以删除掉

Copy link
Collaborator Author

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,
Copy link
Collaborator

Choose a reason for hiding this comment

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

transform 和 matrix很多时候是等价的概念

Copy link
Collaborator Author

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;
Copy link
Collaborator

Choose a reason for hiding this comment

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

const都去掉

Copy link
Collaborator Author

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;
Copy link
Collaborator

Choose a reason for hiding this comment

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

成员变量都初始化下

Copy link
Collaborator Author

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 };
Copy link
Collaborator

Choose a reason for hiding this comment

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

这里支持吃了Rect做3D变换吗?RRect、Shape呢

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

是的。PRect和Shape还没有支持,但理论上都可以通过一个投影矩阵和视口大小实现3D投影的。这里先暂时满足需求应该就好了。

Copy link
Collaborator

Choose a reason for hiding this comment

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

vec2、vec3、vec4的逻辑都是一样的,看能否合并,内部的实现逻辑都转成vec4的,这样就避免有大量重复代码

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

如果优化需要使用匿名结构体,这个属于非标准的CPP用法。

namespace tgfx {
class TextureProxy;
enum class SrcRectConstraint;
struct PerspectiveInfo;
Copy link
Collaborator

Choose a reason for hiding this comment

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

这个前向声明应该删除吧

Copy link
Collaborator Author

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";
Copy link
Collaborator

Choose a reason for hiding this comment

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

这个名字和类名保持一致

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

已经修改。

values[i + 12] = v.w;
}

void setCol(int i, const Vec4& v) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

setColumn写全称吧

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

已经修改。

Comment on lines 77 to 78
const Vec2 scale2(drawArgs.viewportSize.width / static_cast<float>(renderTarget->width()),
drawArgs.viewportSize.height / static_cast<float>(renderTarget->height()));
Copy link
Collaborator

Choose a reason for hiding this comment

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

宽高的有效性检查下,防止除以0

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

已加DEBUG_ASSERT。

shlzxjp
shlzxjp previously approved these changes Sep 25, 2025
Copy link
Collaborator

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文件的前面。

Copy link
Collaborator Author

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(
Copy link
Collaborator

@domchen domchen Sep 25, 2025

Choose a reason for hiding this comment

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

这个方法里没有实现args.drawScale的缩放优化吧?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

已经补充,同时补充了单测用例。

Comment on lines 23 to 25
#define UNIFORM_TRANSFORM_MATRIX_NAME "transformMatrix"
#define UNIFORM_NDC_SCALE_NAME "ndcScale"
#define UNIFORM_NDC_OFFSET_NAME "ndcOffset"
Copy link
Collaborator

@domchen domchen Sep 25, 2025

Choose a reason for hiding this comment

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

我们尽量避免使用#define, 缺少作用域,都改成static constexpr char*

Copy link
Collaborator Author

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);
Copy link
Collaborator

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

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

已经修改。

Comment on lines 23 to 25
static constexpr const char* UniformTransformMatrixName = "transformMatrix";
static constexpr const char* UniformNdcScaleName = "ndcScale";
static constexpr const char* UniformNdcOffsetName = "ndcOffset";
Copy link
Collaborator

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[] =

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

已经修改。

@domchen domchen merged commit aa5de9f into main Sep 26, 2025
9 checks passed
@domchen domchen deleted the feature/jasonrjchen_3D_render branch September 26, 2025 04:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants