Fix transforms in custom shaders using large FVF

In small batches using hardware transform, vertices would be drawn in incorrect positions due to the item transform being applied twice - once in the transform uniform, and once from the transform passed as a vertex attribute.

This PR alters the shader to ignore uniform transforms when using large FVF.
This commit is contained in:
lawnjelly 2020-10-24 17:36:07 +01:00
parent a03af876d1
commit f4cb88e232
5 changed files with 20 additions and 4 deletions

View file

@ -2176,7 +2176,9 @@ void RasterizerCanvasGLES2::render_joined_item(const BItemJoined &p_bij, RenderI
}
}
// using software transform
// using software transform?
// (i.e. don't send the transform matrix, send identity, and either use baked verts,
// or large fvf where the transform is done in the shader from transform stored in the fvf.)
if (!p_bij.use_hardware_transform()) {
state.uniforms.modelview_matrix = Transform2D();
// final_modulate will be baked per item ref so the final_modulate can be an identity color

View file

@ -203,13 +203,16 @@ VERTEX_SHADER_CODE
temp += translate_attrib;
outvec.xy = temp;
#endif
#else
// transform is in uniforms
#if !defined(SKIP_TRANSFORM_USED)
outvec = extra_matrix_instance * outvec;
outvec = modelview_matrix * outvec;
#endif
#endif // not large integer
color_interp = color;
#ifdef USE_PIXEL_SNAP

View file

@ -1439,7 +1439,9 @@ void RasterizerCanvasGLES3::render_joined_item(const BItemJoined &p_bij, RenderI
// state.final_transform = p_ci->final_transform;
// state.extra_matrix = Transform2D();
// using software transform
// using software transform?
// (i.e. don't send the transform matrix, send identity, and either use baked verts,
// or large fvf where the transform is done in the shader from transform stored in the fvf.)
if (!p_bij.use_hardware_transform()) {
state.final_transform = Transform2D();
// final_modulate will be baked per item ref so the final_modulate can be an identity color

View file

@ -208,13 +208,17 @@ VERTEX_SHADER_CODE
temp += translate_attrib;
outvec.xy = temp;
#endif
#else
// transform is in uniforms
#if !defined(SKIP_TRANSFORM_USED)
outvec = extra_matrix * outvec;
outvec = modelview_matrix * outvec;
#endif
#endif // not large integer
#undef extra_matrix
color_interp = color;

View file

@ -2068,6 +2068,11 @@ PREAMBLE(bool)::prefill_joined_item(FillState &r_fill_state, int &r_command_star
// break this extra matrix software path (as we don't want to unset it on the GPU etc)
if (r_fill_state.extra_matrix_sent) {
_prefill_default_batch(r_fill_state, command_num, *p_item);
// keep track of the combined matrix on the CPU in parallel, in case we use large vertex format
RasterizerCanvas::Item::CommandTransform *transform = static_cast<RasterizerCanvas::Item::CommandTransform *>(command);
const Transform2D &extra_matrix = transform->xform;
r_fill_state.transform_combined = p_item->final_transform * extra_matrix;
} else {
// Extra matrix fast path.
// Instead of sending the command immediately, we store the modified transform (in combined)