Unreal中针对Instance物体获取位置
最近帮忙解决了一个很奇怪的问题:在材质球里如何获得Instance模型(譬如Foliage)的坐标,其实也就是Foliage instance position in Material editor。TA需要的是模型原点的世界坐标。
解决方法非常简单粗暴:
Try passing object position through custom UVs
我是用VertexInterpolator来实现(其实意思一样),这样能得到正确结果的原因是::对于Instance物体 在VS里计算世界坐标是对的,而PS里是错的。
下面来看下具体的原因:对于非Instance的物体,两者除了经过一次v2f插值之外没什么区别;但是对于Instance的物体,那么PS里计算的时候数据是不够的(没有InstanceLocalToWorld)。当PS里世界空间坐标是错误的情况下,肯定就不能指望了。
ps. 仔细观察可以发现UE4内置的不少节点其实都是实现了两个版本(Vertex/Pixel),区分的地方其实就是第一个参数是FMaterialVertexParameters
还是FMaterialPixelParameters
。
/** Transforms a vector from local space to world space (VS version) */ |
顺便提一句常见的几个位置区别Coordinates Expressions:
- ActorPositionWS: Actor位置(逻辑概念)
- ObjectPositionWS: 包围盒中心(和网格有关)
- TransformPosition(float4(0,0,0,0))是获取的模型坐标系零点对应的世界坐标
如果一定要获取准确Instance物体的LocalPosition,可以参考TransformLocalVectorToWorld来个CustomExpression自定义一发
这里我自定义扩展了一个材质节点,把Pixel和Vertex分开输入(防止编译错误)。最后生成的代码就是
MaterialFloat3 CustomExpression0(FMaterialPixelParameters Parameters) |
ps. UE4里扩展材质球节点比我想象中简单很多,直接在插件里实现一个UMaterialExpression
的子类,核心代码是virtual int32 Compile(class FMaterialCompiler* Compiler, int32 OutputIndex)
函数生成最后的HLSL。具体生成逻辑参考HLSLMaterialTranslator.h
里的FHLSLMaterialTranslator
实现即可