processTexturemapping之setuptextureMapping
2021-03-04 13:09 kk20161206 阅读(142) 评论(0) 收藏 举报1. setuptextureMapping函数里会calculateTexelCorners,这个函数会光栅化每个三角形里的每个corner,
// Rasterize each triangle offset by the corner offsets
for (int32 CornerIndex = 0; CornerIndex < NumTexelCorners; CornerIndex++)
{
FTriangleRasterizer<FTexelCornerRasterPolicy> TexelCornerRasterizer(FTexelCornerRasterPolicy(
Scene,
TexelToCornersMap,
CornerIndex,
bDebugThisMapping
));
TexelCornerRasterizer.DrawTriangle(
V0,
V1,
V2,
V0.TextureCoordinates[UVIndex] * FVector2D(TexelToCornersMap.GetSizeX(), TexelToCornersMap.GetSizeY()) + CornerOffsets[CornerIndex],
V1.TextureCoordinates[UVIndex] * FVector2D(TexelToCornersMap.GetSizeX(), TexelToCornersMap.GetSizeY()) + CornerOffsets[CornerIndex],
V2.TextureCoordinates[UVIndex] * FVector2D(TexelToCornersMap.GetSizeX(), TexelToCornersMap.GetSizeY()) + CornerOffsets[CornerIndex],
false
);
}
注意这里光栅化的时候会设置texeltocorner为valid,而且得到位置、切线等信息:
void FTexelCornerRasterPolicy::ProcessPixel(int32 X, int32 Y, const InterpolantType& Vertex, bool BackFacing)
{
FTexelToCorners& TexelToCorners = TexelToCornersMap(X, Y);
#if ALLOW_LIGHTMAP_SAMPLE_DEBUGGING
if (bDebugThisMapping
&& X == Scene.DebugInput.LocalX
&& Y == Scene.DebugInput.LocalY)
{
int32 TempBreak = 0;
}
#endif
TexelToCorners.Corners[CornerIndex].WorldPosition = Vertex.WorldPosition;
TexelToCorners.WorldTangentX = Vertex.WorldTangentX;
TexelToCorners.WorldTangentY = Vertex.WorldTangentY;
TexelToCorners.WorldTangentZ = Vertex.WorldTangentZ;
TexelToCorners.bValid[CornerIndex] = true;
}
2. 设置是否用保守的纹素光栅化,同时贴图映射为双线性滤波,
为true,则 会遍历每个三角形,x,y双重循环1到7,计算sampleOffset及sample权重然后会通过staticLightingRasterpolicy计算图素对应的顶点sample,
FTriangleRasterizer<FStaticLightingRasterPolicy> TexelMappingRasterizer(FStaticLightingRasterPolicy( Scene, TexelToVertexMap, SampleWeight, TriangleNormal, bDebugThisMapping, GeneralSettings.bUseMaxWeight )); TexelMappingRasterizer.DrawTriangle( V0, V1, V2, UV0 + FVector2D(SampleXOffset, SampleYOffset), UV1 + FVector2D(SampleXOffset, SampleYOffset), UV2 + FVector2D(SampleXOffset, SampleYOffset), false );
光栅化得到texelTOVertex数据
void FStaticLightingRasterPolicy::ProcessPixel(int32 X,int32 Y,const InterpolantType& Interpolant,bool BackFacing)
{
FTexelToVertex& TexelToVertex = TexelToVertexMap(X,Y);
bool bDebugThisTexel = false;
#if ALLOW_LIGHTMAP_SAMPLE_DEBUGGING
if (bDebugThisMapping
&& X == Scene.DebugInput.LocalX
&& Y == Scene.DebugInput.LocalY)
{
bDebugThisTexel = true;
}
#endif
if (bUseMaxWeight)
{
if (SampleWeight > TexelToVertex.MaxSampleWeight)
{
// Use the sample with the largest weight.
// This has the disadvantage compared averaging based on weight that it won't be well centered for texels on a UV seam,
// But it has the advantage that the final position is guaranteed to be valid (ie actually on a triangle),
// Even for split texels which are mapped to triangles in different parts of the mesh.
TexelToVertex.MaxSampleWeight = SampleWeight;
TexelToVertex.WorldPosition = Interpolant.Vertex.WorldPosition;
TexelToVertex.ElementIndex = Interpolant.ElementIndex;
for( int32 CurCoordIndex = 0; CurCoordIndex < MAX_TEXCOORDS; ++CurCoordIndex )
{
TexelToVertex.TextureCoordinates[ CurCoordIndex ] = Interpolant.Vertex.TextureCoordinates[ CurCoordIndex ];
}
}
// Weighted average of normal, improves the case where the position chosen by the max weight has a different normal than the rest of the texel
// Eg, small extrusions from an otherwise flat surface, and the texel center lies on the perpendicular extrusion
//@todo - only average normals within the texel radius to improve the split texel case?
TexelToVertex.WorldTangentX += Interpolant.Vertex.WorldTangentX * SampleWeight;
TexelToVertex.WorldTangentY += Interpolant.Vertex.WorldTangentY * SampleWeight;
TexelToVertex.WorldTangentZ += Interpolant.Vertex.WorldTangentZ * SampleWeight;
checkSlow(!TriangleNormal.ContainsNaN());
TexelToVertex.TriangleNormal += TriangleNormal * SampleWeight;
TexelToVertex.TotalSampleWeight += SampleWeight;
}
else if (!bUseMaxWeight)
{
// Update the sample weight, and compute the scales used to update the sample's averages.
const float NewTotalSampleWeight = TexelToVertex.TotalSampleWeight + SampleWeight;
const float OldSampleWeight = TexelToVertex.TotalSampleWeight / NewTotalSampleWeight;
const float NewSampleWeight = SampleWeight / NewTotalSampleWeight;
TexelToVertex.TotalSampleWeight = NewTotalSampleWeight;
// Add this sample to the mapping.
TexelToVertex.WorldPosition = TexelToVertex.WorldPosition * OldSampleWeight + Interpolant.Vertex.WorldPosition * NewSampleWeight;
TexelToVertex.WorldTangentX = FVector4(TexelToVertex.WorldTangentX) * OldSampleWeight + Interpolant.Vertex.WorldTangentX * NewSampleWeight;
TexelToVertex.WorldTangentY = FVector4(TexelToVertex.WorldTangentY) * OldSampleWeight + Interpolant.Vertex.WorldTangentY * NewSampleWeight;
TexelToVertex.WorldTangentZ = FVector4(TexelToVertex.WorldTangentZ) * OldSampleWeight + Interpolant.Vertex.WorldTangentZ * NewSampleWeight;
TexelToVertex.TriangleNormal = TriangleNormal;
TexelToVertex.ElementIndex = Interpolant.ElementIndex;
for( int32 CurCoordIndex = 0; CurCoordIndex < MAX_TEXCOORDS; ++CurCoordIndex )
{
TexelToVertex.TextureCoordinates[ CurCoordIndex ] = TexelToVertex.TextureCoordinates[ CurCoordIndex ] * OldSampleWeight + Interpolant.Vertex.TextureCoordinates[ CurCoordIndex ] * NewSampleWeight;
}
}
}
如果为false,则只是在纹素中心光栅化,不用考虑权重混合。如果中心不在三角形内则纹素不会被映射。
3. 最后这个函数AdjustRepresentativeSurfelForTexelsTextureMapping会设置lightmapData为是否映射,
if (LightMapData != nullptr)
{
// Mark the texel as mapped to some geometry in the scene
FGatheredLightMapSample& CurrentLightSample = (*LightMapData)(X, Y);
CurrentLightSample.bIsMapped = true;
}
会重新计算调整texelToVertex的坐标、tangent等信息并且检测会不会重叠,重叠的话,会进行偏移。
浙公网安备 33010602011771号