Batching - use FINAL_MODULATE_ALIAS in shaders
As part of the improvements to batch more cases, batching can store final_modulate as an attribute in the vertex format rather than sending as a uniform. This allows draw calls with different final_modulate to be batched together. However custom shader code was reading from only the final_modulate uniform, and not the attribute when it was in use. This was leading to visual errors. This is tricky to solve, because we cannot use the same name for the attribute in the vertex and fragment shaders, because one is an attribute and one a varying, whereas a uniform is accessible anywhere. To get around this, a macro is used which can translate to the most appropriate variable depending on whether uniform or attribute or varying is required.
This commit is contained in:
parent
9952a5039a
commit
5ed0fd067d
|
@ -911,7 +911,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
|
|||
actions[VS::SHADER_CANVAS_ITEM].renames["INSTANCE_CUSTOM"] = "instance_custom";
|
||||
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["COLOR"] = "color";
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["MODULATE"] = "final_modulate";
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["MODULATE"] = "final_modulate_alias";
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["NORMAL"] = "normal";
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["NORMALMAP"] = "normal_map";
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["NORMALMAP_DEPTH"] = "normal_depth";
|
||||
|
|
|
@ -31,6 +31,17 @@ attribute vec2 uv_attrib; // attrib:4
|
|||
attribute highp vec4 modulate_attrib; // attrib:5
|
||||
#endif
|
||||
|
||||
// Usually, final_modulate is passed as a uniform. However during batching
|
||||
// If larger fvfs are used, final_modulate is passed as an attribute.
|
||||
// we need to read from the attribute in custom vertex shader
|
||||
// rather than the uniform. We do this by specifying final_modulate_alias
|
||||
// in shaders rather than final_modulate directly.
|
||||
#ifdef USE_ATTRIB_MODULATE
|
||||
#define final_modulate_alias modulate_attrib
|
||||
#else
|
||||
#define final_modulate_alias final_modulate
|
||||
#endif
|
||||
|
||||
#ifdef USE_ATTRIB_LARGE_VERTEX
|
||||
// shared with skeleton attributes, not used in batched shader
|
||||
attribute highp vec2 translate_attrib; // attrib:6
|
||||
|
@ -469,6 +480,18 @@ void main() {
|
|||
normal_used = true;
|
||||
#endif
|
||||
|
||||
// If larger fvfs are used, final_modulate is passed as an attribute.
|
||||
// we need to read from this in custom fragment shaders or applying in the post step,
|
||||
// rather than using final_modulate directly.
|
||||
#if defined(final_modulate_alias)
|
||||
#undef final_modulate_alias
|
||||
#endif
|
||||
#ifdef USE_ATTRIB_MODULATE
|
||||
#define final_modulate_alias modulate_interp
|
||||
#else
|
||||
#define final_modulate_alias final_modulate
|
||||
#endif
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
FRAGMENT_SHADER_CODE
|
||||
|
@ -481,11 +504,7 @@ FRAGMENT_SHADER_CODE
|
|||
}
|
||||
|
||||
#if !defined(MODULATE_USED)
|
||||
#ifdef USE_ATTRIB_MODULATE
|
||||
color *= modulate_interp;
|
||||
#else
|
||||
color *= final_modulate;
|
||||
#endif
|
||||
color *= final_modulate_alias;
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIGHTING
|
||||
|
|
|
@ -891,7 +891,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
|
|||
actions[VS::SHADER_CANVAS_ITEM].renames["INSTANCE_CUSTOM"] = "instance_custom";
|
||||
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["COLOR"] = "color";
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["MODULATE"] = "final_modulate";
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["MODULATE"] = "final_modulate_alias";
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["NORMAL"] = "normal";
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["NORMALMAP"] = "normal_map";
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["NORMALMAP_DEPTH"] = "normal_depth";
|
||||
|
|
|
@ -14,6 +14,17 @@ layout(location = 3) in vec4 color_attrib;
|
|||
layout(location = 5) in vec4 modulate_attrib; // attrib:5
|
||||
#endif
|
||||
|
||||
// Usually, final_modulate is passed as a uniform. However during batching
|
||||
// If larger fvfs are used, final_modulate is passed as an attribute.
|
||||
// we need to read from the attribute in custom vertex shader
|
||||
// rather than the uniform. We do this by specifying final_modulate_alias
|
||||
// in shaders rather than final_modulate directly.
|
||||
#ifdef USE_ATTRIB_MODULATE
|
||||
#define final_modulate_alias modulate_attrib
|
||||
#else
|
||||
#define final_modulate_alias final_modulate
|
||||
#endif
|
||||
|
||||
#ifdef USE_ATTRIB_LARGE_VERTEX
|
||||
// shared with skeleton attributes, not used in batched shader
|
||||
layout(location = 6) in vec2 translate_attrib; // attrib:6
|
||||
|
@ -567,6 +578,18 @@ void main() {
|
|||
normal_used = true;
|
||||
#endif
|
||||
|
||||
// If larger fvfs are used, final_modulate is passed as an attribute.
|
||||
// we need to read from this in custom fragment shaders or applying in the post step,
|
||||
// rather than using final_modulate directly.
|
||||
#if defined(final_modulate_alias)
|
||||
#undef final_modulate_alias
|
||||
#endif
|
||||
#ifdef USE_ATTRIB_MODULATE
|
||||
#define final_modulate_alias modulate_interp
|
||||
#else
|
||||
#define final_modulate_alias final_modulate
|
||||
#endif
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
FRAGMENT_SHADER_CODE
|
||||
|
@ -582,12 +605,8 @@ FRAGMENT_SHADER_CODE
|
|||
color = vec4(vec3(enc32), 1.0);
|
||||
#endif
|
||||
|
||||
#ifdef USE_ATTRIB_MODULATE
|
||||
color *= modulate_interp;
|
||||
#else
|
||||
#if !defined(MODULATE_USED)
|
||||
color *= final_modulate;
|
||||
#endif
|
||||
color *= final_modulate_alias;
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIGHTING
|
||||
|
|
Loading…
Reference in New Issue