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

[BUG]: mode=pixel时,PickFire对于visibleMap的meshID读取存在误差 #420

Open
bestsamsg opened this issue Jul 18, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@bestsamsg
Copy link

Bug描述

我在实现一个拾取功能,但在测试中,PickFire返回的meshID经常错误,从而找不到对应的ColliderComponent,最终导致拾取不到物体

Bug复现流程

通过以下步骤产生bug:

  1. orillusion\src\loader\parser\gltf\GLTFSubParserConverter.ts中的convertprimitives方法,给类型为Object3D的model添加ColliderComponent
model.addComponent(ColliderComponent);
  1. 给PickCompute.ts添加log对比
 public getPickMeshID(): number {
    var meshID = this._outBuffer.outFloat32Array[0];
    const result = Math.floor(meshID + 0.1);
    console.log(meshID, result, 'DDDDDDDDDDDDD')
    return result;
}
  1. 给PickFire.ts添加测试拾取的方法

PickFire

public pickMeshId(){
  this._pickCompute.compute(this._view);
  const meshId = this._pickCompute.getPickMeshID();
  const collider = this.mouseEnableMap.get(meshId);

  //collider经常出现undefined
  if(collider) {
     return meshId;
  }
}
  1. 在demo中对POINTER_CLICK进行监听,并主动触发PickFire.pickMeshId
    demo.ts
Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_CLICK, e=>{
    const id= view.pickFire.pickMeshId();
    console.log(id);
}, this)

期待的结果

PickFire要拾取到准确的meshId

报错截图

测试引擎版本:

本地运行出错的Orillusion引擎版本v0.7.2

本机系统 (请填写完整):

  • OS: win10
  • Browser: chrome
  • Version: 120

本机配置

  • CPU: i7
  • Graphics Card: 1660 Ti

代码示例

其他信息

meshID可能存在小数点,然后又使用Math.floor读取(假设visibleMap返回meshID结果为324.75, 那么即使加上0.1,经过floor后结果也是324,实际上325才是对的meshID),这是一种情况,可能还有其他原因。

@bestsamsg bestsamsg added the bug Something isn't working label Jul 18, 2024
@bestsamsg bestsamsg changed the title [BUG]: PickFire对于visibleMap的meshID读取存在误差 [BUG]: mode=pixel时,PickFire对于visibleMap的meshID读取存在误差 Jul 18, 2024
@orillusion-admin
Copy link
Contributor

能不能提供一下案例?现在不太好确定问题~

按道理说是不会出现324.75这种meshID的情况的~

@bestsamsg
Copy link
Author

能不能提供一下案例?现在不太好确定问题~

按道理说是不会出现324.75这种meshID的情况的~

我这边确实出现过很多次这种情况,因修改了不少源码,不好给案例。

不过,昨天通过将f32的meshId转4个uint8,存在materialMap.rgba中(pick_cs新增此sampler, 并读取存于原来的pick_Tangent中),在PickCompute.ts中unpack为float32,可以拿到一个误差在0.001内的数,通过Math.round就能拿到准确的meshId。

目前还没出现过点击失败的情况,算是一个方案吧。

大概代码
orillusion\src\assets\shader\lighting\BxDF_frag.ts

//sam-add-begin
fn float32ToUint8(value: f32) -> vec4<u32> {
	var intRep = bitcast<u32>(value);
	let byte0 = intRep & 0xFFu;
	let byte1 = (intRep >> 8) & 0xFFu;
	let byte2 = (intRep >> 16) & 0xFFu;
	let byte3 = (intRep >> 24) & 0xFFu;
	return vec4<u32>(byte0, byte1, byte2, byte3);
}
//sam-add-end

fn BxDFShading(){
	...
	//sam-replace-begin
	#if USE_BATCHID
	//ORI_FragmentOutput.material = vec4<f32>(1.0,fragData.Roughness,fragData.Metallic,1.0);
	//sam-replace-to

	//材质贴图添加meshId输出
	let uint8Values = float32ToUint8(ORI_VertexVarying.index);

	// 将 uint8 转换为 [0.0, 1.0] 范围内的 f32
	let r = f32(uint8Values.x) / 255.0;
	let g = f32(uint8Values.y) / 255.0;
	let b = f32(uint8Values.z) / 255.0;
	let a = f32(uint8Values.w) / 255.0;

	ORI_FragmentOutput.material = vec4<f32>(r, g, b, a);
	#endif
	//sam-replace-end
	...
}

orillusion\src\io\picker\PickCompute.ts

public getPickMeshID(): number {

	//sam-replace-begin
	//结果返回错误
	// var meshID = this._outBuffer.outFloat32Array[0] + 0.1;
	// return Math.floor(meshID);
	//sam-replace-to
	const byte0 = this._outBuffer.outFloat32Array[12] * 255;
	const byte1 = this._outBuffer.outFloat32Array[13] * 255;
	const byte2 = this._outBuffer.outFloat32Array[14] * 255;
	const byte3 = this._outBuffer.outFloat32Array[15] * 255;
	const uint32Value =  (byte3 << 24) | (byte2 << 16) | (byte1 << 8) | byte0
	const float32Array = new Float32Array(new Uint32Array([uint32Value]).buffer);
	const restoredValue = float32Array[0];
	
	console.log(restoredValue, 'd')

	if(window['startDebug']){
		debugger
	}
	return Math.round(restoredValue);
	//sam-replace-end
}

后续如果有其他的问题再反馈,感谢回复。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants