zoukankan      html  css  js  c++  java
  • processTexturemapping之setuptextureMapping

    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等信息并且检测会不会重叠,重叠的话,会进行偏移。

  • 相关阅读:
    中国首个 SaaS 模式的云告警平台安卓版 APP 上线
    Cloud Insight 和 BearyChat 第一次合体,好紧张!
    安卓 DevOps:从一次推送命令到生产
    Jmeter 使用笔记之 html 报告扩展(一)
    10大常见的安全漏洞!你知道吗?
    iOS 并发:NSOperation 与调度队列入门(1)
    欺诈网站都注重用户体验!你,还在等什么?!
    你知道在深圳一个月花多少钱吗?
    找不到编译器:wepy-compiler-less
    wepy项目的学习
  • 原文地址:https://www.cnblogs.com/Shaojunping/p/14479674.html
Copyright © 2011-2022 走看看