如何在Google Filament中用1x1白色像素实现间接光
解决Filament纯色天空盒与间接光的实现问题
你的问题出在立方体贴图的像素数据填充上:Filament的立方体贴图包含6个面,每个面都需要独立的像素数据,而你只提供了1个像素(3字节)的buffer,导致仅部分面被正确填充,其余面无数据显示为黑色。另外你尝试的faceOffsets参数用错了——它代表字节偏移量而非面索引,所以设置0-5会导致读取buffer时越界抛出异常。
下面给出两种可行的实现方案:
方案1:使用单个Buffer填充所有6个面
创建包含6个白色RGB像素的Buffer(共6×3=18字节),并设置正确的字节偏移量:
// 创建包含6个白色RGB像素的字节数组(每个像素3字节) val whiteCubePixels = byteArrayOf( 0xFF.toByte(), 0xFF.toByte(), 0xFF.toByte(), // +X面 0xFF.toByte(), 0xFF.toByte(), 0xFF.toByte(), // -X面 0xFF.toByte(), 0xFF.toByte(), 0xFF.toByte(), // +Y面 0xFF.toByte(), 0xFF.toByte(), 0xFF.toByte(), // -Y面 0xFF.toByte(), 0xFF.toByte(), 0xFF.toByte(), // +Z面 0xFF.toByte(), 0xFF.toByte(), 0xFF.toByte() // -Z面 ) val whitePixelBuffer = Texture.PixelBufferDescriptor( ByteBuffer.wrap(whiteCubePixels), Texture.Format.RGB, Texture.Type.UBYTE ) // 每个面的字节偏移量:每个面占3字节,依次累加 val faceOffsets = intArrayOf(0, 3, 6, 9, 12, 15) val indirectLightCube = Texture.Builder() .width(1) .height(1) .sampler(Texture.Sampler.SAMPLER_CUBEMAP) .format(Texture.InternalFormat.RGB8) .build(engine) .also { texture -> texture.setImage(engine, 0, whitePixelBuffer, faceOffsets) } val indirectLight = IndirectLight.Builder() .reflections(indirectLightCube) .intensity(1.0f) // 可根据需求调整亮度 .build(engine)
方案2:逐个面填充像素数据
这种方式更直观,避免偏移量计算错误:
val oneWhitePixel = ByteBuffer.wrap(byteArrayOf(0xFF.toByte(), 0xFF.toByte(), 0xFF.toByte())) val whitePixelBuffer = Texture.PixelBufferDescriptor( oneWhitePixel, Texture.Format.RGB, Texture.Type.UBYTE ) val indirectLightCube = Texture.Builder() .width(1) .height(1) .sampler(Texture.Sampler.SAMPLER_CUBEMAP) .format(Texture.InternalFormat.RGB8) .build(engine) .also { texture -> // 为立方体贴图的6个面分别设置白色像素 Texture.CubemapFace.values().forEach { face -> texture.setImage(engine, face, 0, whitePixelBuffer) } } val indirectLight = IndirectLight.Builder() .reflections(indirectLightCube) .intensity(1.0f) .build(engine)
两种方案都能让立方体贴图的6个面全部填充白色,从而实现均匀的纯色间接光效果。
内容的提问来源于stack exchange,提问作者Wilfred
相关产品推荐
相关产品推荐

