Skip to content
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

[原生] 3D摄像机的 rect 属性在原生平台无效. #17863

Closed
finscn opened this issue Nov 15, 2024 · 42 comments
Closed

[原生] 3D摄像机的 rect 属性在原生平台无效. #17863

finscn opened this issue Nov 15, 2024 · 42 comments
Assignees
Labels
Bug Env: Native General issue on all native platforms including iOS, Android, MacOS, Windows
Milestone

Comments

@finscn
Copy link
Contributor

finscn commented Nov 15, 2024

Cocos Creator version

3.8.4

System information

all

Issue description

在 小游戏 和 web中 设置 3d camera 的 rect 有效, 同样的代码 在 原生ios 和安卓平台 无效 (也不会报错)

Relevant error log output

No response

Steps to reproduce

如上

Minimal reproduction project

No response

@finscn finscn added Bug Needs Triage Needs to be assigned by the team labels Nov 15, 2024
@finscn
Copy link
Contributor Author

finscn commented Nov 15, 2024

补充下 , 游戏是横屏的, 我是通过代码调整的rect. 类似这种:

camera3D.rect = cc.rect(.....)

@finscn
Copy link
Contributor Author

finscn commented Nov 15, 2024

论坛好像有人提过类似的问题: https://forum.cocos.org/t/topic/155850

@finscn
Copy link
Contributor Author

finscn commented Nov 17, 2024

补充 : "新渲染管线" 和 "原渲染管线" 都试了, 都不行 . 一样的问题.

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024

有demo吗?

@finscn
Copy link
Contributor Author

finscn commented Nov 18, 2024

有demo吗?

目前没有 , 等我抽空写一个. 周一事情有点多, 晚些时候的.

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024

在这个pr里修复了:#17871

@finscn
Copy link
Contributor Author

finscn commented Nov 18, 2024

在这个pr里修复了:#17871

@star-e 试了, 还是不行. 宽高修复了, 但是 x y 还是 一直是 0, 0 .

在提供demo前 我可以提供一点线索.
我在代码里 设置了 3d摄像机的 rect, 但是 3d摄像机的 viewport 的 x, y 还是 0,0 .

camera3D.rect = cc.rect(0.0, 0.5, 1, 1.5);
const {x, y, width, height} = camera3D.camera.viewport;
console.log('camera.viewport : ', x, y, width, height);  // 此时打印的 viewport 是 ( 0, 0, 1, 1.5) , 错误的.

在你这个 pr 之前 , viewport 的 宽高 也是错的, 仍然都是 1. 所以 这个pr 修复了 宽高, 没有修复 x y.

你看我上面发的论坛的帖子, 那个人遇到的也是 x y 的问题

image

我猜是不是 有些地方 left, top , x , y 相关的逻辑有问题.
我看你们的原生代码 viewport 一会是 left top 一会儿x y 的. 是不是你们自己也被搞懵了, 于是出现了一些bug.
比如 :

  • 该用 x y 的地方, 用了 left , top
  • 该用 left top 的地方, 用了 x y
  • 更新了x y , 忘了更新 left top
  • 更新了left top , 忘了更新 x y
  • ...... 等等

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024 via email

@finscn
Copy link
Contributor Author

finscn commented Nov 18, 2024

@star-e 我发现 我上面举的例子不对.
我实际项目使用的 rect 是 cc.rect(0, -0.25, 1 , 1.25) , (y 减了 0.25, height增加了0.25) :
在 web和小游戏环境 log的结果都是一致的, 正确的:

camera.rect :  0, -0.25, 1, 1.25
camera.viewport :  0, -0.25, 1, 1.25

但是在 原生就不对了, 变成了

camera.rect :  0, -0.25, 1, 1.25
camera.viewport :  0, 0, 1, 1.25

大概率是这行代码有bug, 而且 ts 和 cpp 都有bug :

ts的 Camera

 const y = this._device.capabilities.screenSpaceSignY < 0 ? 1 - val.y - height : val.y;

cpp的 Camera :

 const auto y = _device->getCapabilities().screenSpaceSignY < 0 ? 1.F - val.y - height : val.y;

web和小程序正确, 是因为他们没有走 screenSpaceSignY< 0 的分支.
只要走了 screenSpaceSignY<0的分支 , 值就不对了.

比如这个值: cc.rect(0, -0.25, 1 , 1.25)
当 screenSpaceSignY < 0 时, 1-(-0.25)-1.25 = 0 , 所以 就会出现 viewport 的 y 一直是 0 的情况.

screenSpaceSignY < 0 时, 应该只需要 1 - val.y 就可以了 (无论cpp 还是 ts).
- height 的操作 下面的 switch 分支里有做.

无视我这段修改建议, 都是瞎猜的. 但是问题肯定是出在 screenSpaceSignY<0 的时候

@finscn
Copy link
Contributor Author

finscn commented Nov 18, 2024

@star-e 你那边把 rect 按照我这个 cc.rect(0, -0.25, 1 , 1.25) 设置应该就能测试出来bug了. 如果还不行 我再弄demo.

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024 via email

@star-e star-e mentioned this issue Nov 18, 2024
6 tasks
@minggo minggo removed the Needs Triage Needs to be assigned by the team label Nov 18, 2024
@minggo minggo added this to the 3.8.5 milestone Nov 18, 2024
@minggo minggo added the Env: Native General issue on all native platforms including iOS, Android, MacOS, Windows label Nov 18, 2024
@minggo minggo closed this as completed Nov 18, 2024
@finscn
Copy link
Contributor Author

finscn commented Nov 18, 2024

@minggo 问题并没有解决.
我看到 @star-e 在15分钟前又更新了pr, 但是我整合了最新的内容, 还是不行

@star-e star-e reopened this Nov 18, 2024
@star-e
Copy link
Contributor

star-e commented Nov 18, 2024

修复了原生viewport的问题。还有screenSpaceSignY相关问题正在验证。

@finscn
Copy link
Contributor Author

finscn commented Nov 18, 2024

@star-e 这里提供了一个demo.

change-camera.zip

另外麻烦看一下 demo里的 ts 文件中我写的注释.

注释除了一些说明, 还阐述了我有 "改变rect" 这个需求的原因.
更重要的是, 还有一个问题 我一直无法解决, 所以特意来求助.

麻烦了, 谢谢.

image

这个问题我曾经在论坛和 cocos的技术群里 咨询过, 没有得到答案.

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024

@star-e 我发现 我上面举的例子不对. 我实际项目使用的 rect 是 cc.rect(0, -0.25, 1 , 1.25) , (y 减了 0.25, height增加了0.25) : 在 web和小游戏环境 log的结果都是一致的, 正确的:

我看下来结果是正确的。Component的Rect,坐标原点在左下角,y=-0.25, height = 1时,图片往下移:
image

当screenSpaceSignY>0时,坐标原点在左下角。这个时候viewport为(0, -0.25, 1, 1.25),转换到800x600的图片坐标(原点左上角),为(0, 0, 800, 750)
当screenSpaceSignY<0时,坐标原点在左上角。这个时候viewport为(0, 0, 1, 1.25),转换到800x600的图片坐标(原点左上角),也是(0, 0, 800, 750)

@finscn
Copy link
Contributor Author

finscn commented Nov 18, 2024

@star-e 我提供了一个demo 你可以看下

@finscn
Copy link
Contributor Author

finscn commented Nov 18, 2024

@star-e 我发现 我上面举的例子不对. 我实际项目使用的 rect 是 cc.rect(0, -0.25, 1 , 1.25) , (y 减了 0.25, height增加了0.25) : 在 web和小游戏环境 log的结果都是一致的, 正确的:

我看下来结果是正确的。Component的Rect,坐标原点在左下角,y=-0.25, height = 1时,图片往下移: image

当screenSpaceSignY>0时,坐标原点在左下角。这个时候viewport为(0, -0.25, 1, 1.25),转换到800x600的图片坐标(原点左上角),为(0, 0, 800, 750) 当screenSpaceSignY<0时,坐标原点在左上角。这个时候viewport为(0, 0, 1, 1.25),转换到800x600的图片坐标(原点左上角),也是(0, 0, 800, 750)

web和小游戏里 log 出来的 viewport 和 rect 是一致的, 都是 (0, -0.25, 1, 1.25) , 但是原生平台的 不一致, viewport是(0, 0, 1, 1.25), 这个是正常的吗?

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024

web和小游戏里 log 出来的 viewport 和 rect 是一致的, 都是 (0, -0.25, 1, 1.25) , 但是原生平台的 不一致, viewport是(0, 0, 1, 1.25), 这个是正常的吗?

vulkan、metal后端是(0, 0, 1, 1.25)
gles后端是(0, -0.25, 1, 1.25)

vulkan、metal y轴是朝下的。gles、webgl y轴朝上。

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024

你想要的这个效果,感觉没法通过调整viewport的位置实现。
viewport中的内容始终是camera视锥中的内容,viewport相当于把相机内容平移缩放到屏幕别的位置。无法显示相机视锥外的内容。
实际想要的是在保持相机位置不变(投影关系不变)的情况下,显示视锥外内容,这需要特殊的投影矩阵才能做到。

@finscn
Copy link
Contributor Author

finscn commented Nov 18, 2024

@star-e 谢谢答疑解惑.
回到这个 issue最初的问题. 我合并了你的最新代码, 但是我这边还是有 web和微信小游戏 视窗起点正确, native起点不正确的问题. 你那边能重现吗?

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024

@star-e 谢谢答疑解惑. 回到这个 issue最初的问题. 我合并了你的最新代码, 但是我这边还是有 web和微信小游戏 视窗起点正确, native起点不正确的问题. 你那边能重现吗?

我这里不能重现,我现在按照-0.25,1.25,效果和webgl是相同的。windows版本。
我理解下来,起点就是指y=-0.25,画面确实往下移了。

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024

@star-e 谢谢答疑解惑. 回到这个 issue最初的问题. 我合并了你的最新代码, 但是我这边还是有 web和微信小游戏 视窗起点正确, native起点不正确的问题. 你那边能重现吗?

可能需要选择正确的自定义引擎

@finscn
Copy link
Contributor Author

finscn commented Nov 18, 2024

@star-e 谢谢答疑解惑. 回到这个 issue最初的问题. 我合并了你的最新代码, 但是我这边还是有 web和微信小游戏 视窗起点正确, native起点不正确的问题. 你那边能重现吗?

可能需要选择正确的自定义引擎

我用的就是自定义引擎. 而且我自己尝试随便修改一些代码的数值, 也能看到错误的结果(说明自定义引擎生效了)

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024

关于off-center perspective projection matrix,可以参考这个回答:
https://stackoverflow.com/questions/36758294/asymmetric-projection-matrix

相关方法在:
https://learn.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectiveoffcenterrh

注意这里是d3d的投影矩阵,放在cocos里需要些调整。

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024

@star-e 谢谢答疑解惑. 回到这个 issue最初的问题. 我合并了你的最新代码, 但是我这边还是有 web和微信小游戏 视窗起点正确, native起点不正确的问题. 你那边能重现吗?

可能需要选择正确的自定义引擎

我用的就是自定义引擎. 而且我自己尝试随便修改一些代码的数值, 也能看到错误的结果(说明自定义引擎生效了)

注意scene.Camera的viewport是平台相关的,和camera component的rect不一样。
用scene.Camera的viewport,代码需要做调整的。

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024

https://computergraphics.stackexchange.com/questions/5054/render-with-camera-perspective-off-center
W7GLv
3bVXX

@finscn
Copy link
Contributor Author

finscn commented Nov 18, 2024

@star-e 其实我并没有用到 viewport . 刚才给你的demo 可能有点复杂了, 有很多无用干扰项.
我重新发一个只包含主贴 issue 的demo. 你看看你那边 web/小游戏 和 native的效果一样吗

change-camera-rect.zip

@finscn
Copy link
Contributor Author

finscn commented Nov 18, 2024

https://computergraphics.stackexchange.com/questions/5054/render-with-camera-perspective-off-center W7GLv 3bVXX

感谢分享. 看来我把这个问题想简单了. 这个小需求居然实现起来还挺复杂 .
不过目前我们的游戏里 只需要向下移动一小段固定的距离 .
这么做主要是为了适配pad, 游戏是横屏的. 主要操控区域偏下, 所以ipad上要整体往下移动, 上面补充一些内容.
类似下图:
image

所以我用 rect 在web和小游戏里目前能满足需求 ( cc.rect(0, -0.25, 1 , 1.25) 中的那个 0.25 就是计算出来的偏移量)
但是目前原生就遇到了我主贴里提到的问题.

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024

image
image
Windows(Vulkan、GLES)是一致的。上图是Vulkan的结果,GLES结果类似我就不贴了。

@finscn
Copy link
Contributor Author

finscn commented Nov 18, 2024

image image Windows(Vulkan、GLES)是一致的。上图是Vulkan的结果,GLES结果类似我就不贴了。

我这边 xcode 和 android studio 的模拟器里就有问题. ios和安卓的真机上原生也有类似问题.
微信小游戏 web 都没有问题.

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024

这么做主要是为了适配pad, 游戏是横屏的. 主要操控区域偏下, 所以ipad上要整体往下移动, 上面补充一些内容.

这个需求,可以通过改变fov做到。ipad屏幕接近4:3,所以fov(一般指y轴fov)需要更大些。
但最好还是要off center perspective projection matrix。

@finscn
Copy link
Contributor Author

finscn commented Nov 18, 2024

这么做主要是为了适配pad, 游戏是横屏的. 主要操控区域偏下, 所以ipad上要整体往下移动, 上面补充一些内容.

这个需求,可以通过改变fov做到。ipad屏幕接近4:3,所以fov(一般指y轴fov)需要更大些。 但最好还是要off center perspective projection matrix。

其实我们第一个方案用的就是 fov, 但是实际情况其实比我说的复杂, 比如 很多手机 其实左右也要补充内容, ipad是上面补充内容. 某些安卓pad 左右和上方都要补充内容. fov 和 fovAxis 都要调整. 各种计算.
最后结果总是会有一些差异 还有一些光照等. 所以最后想的是用 rect. 目前看来可能确实 off center perspective projection matrix 更好. 但是感觉这个实现起来有点复杂 要自定义好多 cocos的东西. 而且native部分我也不熟 不敢轻易碰.

如果rect能解决 尽量用rect.

你那边 ios 和 安卓真机 也无法重现我遇到的问题吗?

.

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024 via email

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024

Screenshot_2024-11-18-16-54-00-072_com cocos viewport
Android看起来是对的。小米8

@finscn
Copy link
Contributor Author

finscn commented Nov 18, 2024

Screenshot_2024-11-18-16-54-00-072_com cocos viewport Android看起来是对的。小米8

你能把你生成的 apk包发我下吗 我在我们的安卓设备上测试下, 顺便问一下 你使用的新管线 还是老管线?

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024

Screenshot_2024-11-18-16-54-00-072_com cocos viewport Android看起来是对的。小米8

你能把你生成的 apk包发我下吗 我在我们的安卓设备上测试下, 顺便问一下 你使用的新管线 还是老管线?

我用的新管线

@finscn
Copy link
Contributor Author

finscn commented Nov 18, 2024

@star-e 我用新管线也ok了, 非常感谢. 那你们还打算修复老管线的问题吗? 因为我们小游戏线上版本一直用的老管线. 担心切换到新管线会有其他新问题.

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024 via email

@star-e
Copy link
Contributor

star-e commented Nov 18, 2024

#17875
修复了老管线的viewport问题。

@finscn
Copy link
Contributor Author

finscn commented Nov 18, 2024

#17875 修复了老管线的viewport问题。

谢谢! 必须加薪!

@finscn
Copy link
Contributor Author

finscn commented Nov 18, 2024

#17875 修复了老管线的viewport问题。

测试了下老管线 , 也ok了. 这个问题应该可以close了.

@finscn finscn closed this as completed Nov 18, 2024
@star-e
Copy link
Contributor

star-e commented Nov 18, 2024

Fixed Rect bug in Camera component on native platform for both legacy-pipeline and builtin-pipeline.
#17871
#17875

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Env: Native General issue on all native platforms including iOS, Android, MacOS, Windows
Projects
None yet
Development

No branches or pull requests

3 participants