最近在用UE4的Instancing, 发现限制很多。
Unity有instancing的attribute array (uniform/constant buffer),通过InstanceID来访问每个instance的数据,实现每个实例的不同的参数(通常的一种做法)。
然而Unreal没有这样的功能,只有一些instancing的vertex buffer。
shader:
1 #if USE_INSTANCING && !USE_INSTANCING_EMULATED 2 float4 InstanceOrigin : ATTRIBUTE8; // per-instance random in w 3 half4 InstanceTransform1 : ATTRIBUTE9; // hitproxy.r + 256 * selected in .w 4 half4 InstanceTransform2 : ATTRIBUTE10; // hitproxy.g in .w 5 half4 InstanceTransform3 : ATTRIBUTE11; // hitproxy.b in .w 6 #endif // USE_INSTANCING && !USE_INSTANCING_EMULATED
C++:
1 template <class FloatType> 2 struct FInstanceStream 3 { 4 FVector4 InstanceOrigin; // per-instance random in w 5 FloatType InstanceTransform1[4]; // hitproxy.r + 256 * selected in .w 6 FloatType InstanceTransform2[4]; // hitproxy.g in .w 7 FloatType InstanceTransform3[4]; // hitproxy.b in .w 8 int16 InstanceLightmapAndShadowMapUVBias[4]; 9 ... 10 };
在不改动引擎代码的前提下(不熟悉,风险大), 总结了以下workaround:
其中第一种是简单的颜色映射。
后面的几种是为了解决多个参数的方式,因为只有一个随机值,导致随机化不理想。比如一个实例有两个随机颜色,用PerInstanceRandom去查两个颜色表【蓝,黄,绿】和【黑,白,灰】那么第一个颜色是蓝色的时候,第二个颜色一定是黑色,而实际需求的很可能是两个颜色也要随机搭配。
解决方法是把一个随机值映射为多个。前两种比较类似,一个用随机函数,一个用纹理采样。最后一种是hack, 取每一位的数字就不一样。虽然hack,但是目前用起来还算可以。
note: instance‘s AbsoluteWorldPosition could be used to generate attribute variations.
[工作积累] Tricks with UE4 PerInstanceRandom
原文:http://www.cnblogs.com/crazii/p/7161594.html