So I got my hands on the terrain shader, and after studying it, I've figured out exactly what parameters it takes. This should making deciphering the htres a lot easier.
The texture maps it consumes:
WorldTexture
SrmTexture
NormalTexture
AlbedoTexture
MaterialIndicesTexture
MaterialSelectMapTexture
TileMapTexture
HeightMapTexture
The bolded ones are the new discoveries. The first few are all normal ftx texture that are assigned in the terrain's fox2. The heightmap we already knew was encoded in the htre, but I don't know anything about where the bolded ones are. My guess is that they're somewhere in the htre. The MaterialIndicesTexture is probably what the htre calls materialIDs. I'm guessing it specifies what terrain materials go where.
The heightmap is read as a float in the shader, so that confirms that the height is encoded in a 32-bit format. Interestingly, MaterialIndices, MaterialSelectMap, MaterialWeightMap, and TileMap are each read in as half4's, so they're probably encoded in a 16-bit format. For MaterialIndicesMap and the heightmap, only the r channel of the texture is read, so each value is probably only stored as one channel (makes sense for the heightmap, no idea what that says about the material IDs, though). Interestingly, though, the others seem to use four channels, so I'd expect to see them encoded as a 16-bit RGBA. That should help a lot in tracking the data down.
Here's a snippet from the shader that shows how the maps are used:
Code: Select all
float4 materialAndWeight = (float4( materialLists * 1.0h/256.0h ) + float4( floor( materialWeights * 256.0h ) ));
materialAndWeight.xy = materialAndWeight.x > materialAndWeight.y ? materialAndWeight.xy : materialAndWeight.yx ;
materialAndWeight.zw = materialAndWeight.z > materialAndWeight.w ? materialAndWeight.zw : materialAndWeight.wz ;
materialAndWeight.xz = materialAndWeight.x > materialAndWeight.z ? materialAndWeight.xz : materialAndWeight.zx ;
materialAndWeight.yw = materialAndWeight.y > materialAndWeight.w ? materialAndWeight.yw : materialAndWeight.wy ;
materialAndWeight.yz = materialAndWeight.y > materialAndWeight.z ? materialAndWeight.yz : materialAndWeight.zy ;
outMaterialIndex = (half4)frac( materialAndWeight ) * 256.0h ;
outMaterialWeight = (half4)floor( materialAndWeight ) / 256.0h ;
half2 materialSelectTableUvParam = half2( 1.0h/16.0h, 0.5h/16.0h );
half2 materialSelectTableUv = half2( outMaterialIndex.x * materialSelectTableUvParam.x + materialSelectTableUvParam.y, 0 );
outTopMaterialIndex = (half)TFetch2DH( inMaterialIndicesTexture, SamplerPoint, materialSelectTableUv ).x ;