mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	Rasterizer: Pre-divide vertex attributes by W
Execute the division-by-W for perspective-correct interpolation of values in the clipper, moving them out of the rasterization inner loop.
This commit is contained in:
		
							parent
							
								
									fe186d3a59
								
							
						
					
					
						commit
						8369ee5803
					
				| @ -91,10 +91,17 @@ static void InitScreenCoordinates(OutputVertex& vtx) | |||||||
|     viewport.zscale     = float24::FromRawFloat24(registers.viewport_depth_range); |     viewport.zscale     = float24::FromRawFloat24(registers.viewport_depth_range); | ||||||
|     viewport.offset_z   = float24::FromRawFloat24(registers.viewport_depth_far_plane); |     viewport.offset_z   = float24::FromRawFloat24(registers.viewport_depth_far_plane); | ||||||
| 
 | 
 | ||||||
|  |     float24 inv_w = float24::FromFloat32(1.f) / vtx.pos.w; | ||||||
|  |     vtx.color *= inv_w; | ||||||
|  |     vtx.tc0 *= inv_w; | ||||||
|  |     vtx.tc1 *= inv_w; | ||||||
|  |     vtx.tc2 *= inv_w; | ||||||
|  |     vtx.pos.w = inv_w; | ||||||
|  | 
 | ||||||
|     // TODO: Not sure why the viewport width needs to be divided by 2 but the viewport height does not
 |     // TODO: Not sure why the viewport width needs to be divided by 2 but the viewport height does not
 | ||||||
|     vtx.screenpos[0] = (vtx.pos.x / vtx.pos.w + float24::FromFloat32(1.0)) * viewport.halfsize_x + viewport.offset_x; |     vtx.screenpos[0] = (vtx.pos.x * inv_w + float24::FromFloat32(1.0)) * viewport.halfsize_x + viewport.offset_x; | ||||||
|     vtx.screenpos[1] = (vtx.pos.y / vtx.pos.w + float24::FromFloat32(1.0)) * viewport.halfsize_y + viewport.offset_y; |     vtx.screenpos[1] = (vtx.pos.y * inv_w + float24::FromFloat32(1.0)) * viewport.halfsize_y + viewport.offset_y; | ||||||
|     vtx.screenpos[2] = viewport.offset_z - vtx.pos.z / vtx.pos.w * viewport.zscale; |     vtx.screenpos[2] = viewport.offset_z - vtx.pos.z * inv_w * viewport.zscale; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ProcessTriangle(OutputVertex &v0, OutputVertex &v1, OutputVertex &v2) { | void ProcessTriangle(OutputVertex &v0, OutputVertex &v1, OutputVertex &v2) { | ||||||
|  | |||||||
| @ -757,6 +757,26 @@ struct float24 { | |||||||
|         return float24::FromFloat32(ToFloat32() - flt.ToFloat32()); |         return float24::FromFloat32(ToFloat32() - flt.ToFloat32()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     float24& operator *= (const float24& flt) { | ||||||
|  |         value *= flt.ToFloat32(); | ||||||
|  |         return *this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     float24& operator /= (const float24& flt) { | ||||||
|  |         value /= flt.ToFloat32(); | ||||||
|  |         return *this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     float24& operator += (const float24& flt) { | ||||||
|  |         value += flt.ToFloat32(); | ||||||
|  |         return *this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     float24& operator -= (const float24& flt) { | ||||||
|  |         value -= flt.ToFloat32(); | ||||||
|  |         return *this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     float24 operator - () const { |     float24 operator - () const { | ||||||
|         return float24::FromFloat32(-ToFloat32()); |         return float24::FromFloat32(-ToFloat32()); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -106,10 +106,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||||||
|     int bias1 = IsRightSideOrFlatBottomEdge(vtxpos[1].xy(), vtxpos[2].xy(), vtxpos[0].xy()) ? -1 : 0; |     int bias1 = IsRightSideOrFlatBottomEdge(vtxpos[1].xy(), vtxpos[2].xy(), vtxpos[0].xy()) ? -1 : 0; | ||||||
|     int bias2 = IsRightSideOrFlatBottomEdge(vtxpos[2].xy(), vtxpos[0].xy(), vtxpos[1].xy()) ? -1 : 0; |     int bias2 = IsRightSideOrFlatBottomEdge(vtxpos[2].xy(), vtxpos[0].xy(), vtxpos[1].xy()) ? -1 : 0; | ||||||
| 
 | 
 | ||||||
|     const Math::Vec3<float24> w_inverse = Math::MakeVec( |     auto w_inverse = Math::MakeVec(v0.pos.w, v1.pos.w, v2.pos.w); | ||||||
|             float24::FromFloat32(1.0f) / v0.pos.w, |  | ||||||
|             float24::FromFloat32(1.0f) / v1.pos.w, |  | ||||||
|             float24::FromFloat32(1.0f) / v2.pos.w); |  | ||||||
| 
 | 
 | ||||||
|     auto textures = registers.GetTextures(); |     auto textures = registers.GetTextures(); | ||||||
|     auto tev_stages = registers.GetTevStages(); |     auto tev_stages = registers.GetTevStages(); | ||||||
| @ -158,7 +155,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||||||
|             //
 |             //
 | ||||||
|             // The generalization to three vertices is straightforward in baricentric coordinates.
 |             // The generalization to three vertices is straightforward in baricentric coordinates.
 | ||||||
|             auto GetInterpolatedAttribute = [&](float24 attr0, float24 attr1, float24 attr2) { |             auto GetInterpolatedAttribute = [&](float24 attr0, float24 attr1, float24 attr2) { | ||||||
|                 auto attr_over_w = Math::MakeVec(attr0, attr1, attr2) * w_inverse; |                 auto attr_over_w = Math::MakeVec(attr0, attr1, attr2); | ||||||
|                 float24 interpolated_attr_over_w = Math::Dot(attr_over_w, baricentric_coordinates); |                 float24 interpolated_attr_over_w = Math::Dot(attr_over_w, baricentric_coordinates); | ||||||
|                 return interpolated_attr_over_w * interpolated_w_inverse; |                 return interpolated_attr_over_w * interpolated_w_inverse; | ||||||
|             }; |             }; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Yuri Kunde Schlesner
						Yuri Kunde Schlesner