diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 6f860fc248..0b85f5bee6 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -1485,7 +1485,7 @@ vec4 secondary_fragment_color = vec4(0.0); out += "vec4 combiner_buffer = vec4(0.0);\n" "vec4 next_combiner_buffer = tev_combiner_buffer_color;\n" - "vec4 last_tex_env_out = vec4(0.0);\n"; + "vec4 last_tex_env_out = rounded_primary_color;\n"; for (std::size_t index = 0; index < state.tev_stages.size(); ++index) { WriteTevStage(out, config, static_cast(index)); diff --git a/src/video_core/renderer_software/sw_rasterizer.cpp b/src/video_core/renderer_software/sw_rasterizer.cpp index 52d172e6ef..8b3d6bfee9 100644 --- a/src/video_core/renderer_software/sw_rasterizer.cpp +++ b/src/video_core/renderer_software/sw_rasterizer.cpp @@ -422,8 +422,8 @@ void RasterizerSoftware::ProcessTriangle(const Vertex& v0, const Vertex& v1, con } // Write the TEV stages. - WriteTevConfig(texture_color, tev_stages, primary_color, primary_fragment_color, - secondary_fragment_color); + auto combiner_output = WriteTevConfig(texture_color, tev_stages, primary_color, + primary_fragment_color, secondary_fragment_color); const auto& output_merger = regs.framebuffer.output_merger; if (output_merger.fragment_operation_mode == @@ -663,7 +663,7 @@ Common::Vec4 RasterizerSoftware::PixelColor(u16 x, u16 y, return result; } -void RasterizerSoftware::WriteTevConfig( +Common::Vec4 RasterizerSoftware::WriteTevConfig( std::span, 4> texture_color, std::span tev_stages, Common::Vec4 primary_color, Common::Vec4 primary_fragment_color, @@ -676,6 +676,7 @@ void RasterizerSoftware::WriteTevConfig( * with some basic arithmetic. Alpha combiners can be configured separately but work * analogously. **/ + Common::Vec4 combiner_output = primary_color; Common::Vec4 combiner_buffer = {0, 0, 0, 0}; Common::Vec4 next_combiner_buffer = Common::MakeVec(regs.texturing.tev_combiner_buffer_color.r.Value(), @@ -766,6 +767,8 @@ void RasterizerSoftware::WriteTevConfig( next_combiner_buffer.a() = combiner_output.a(); } } + + return combiner_output; } void RasterizerSoftware::WriteFog(Common::Vec4& combiner_output, float depth) const { diff --git a/src/video_core/renderer_software/sw_rasterizer.h b/src/video_core/renderer_software/sw_rasterizer.h index 919d862fcd..40f7ce7811 100644 --- a/src/video_core/renderer_software/sw_rasterizer.h +++ b/src/video_core/renderer_software/sw_rasterizer.h @@ -55,10 +55,11 @@ private: Common::Vec4 PixelColor(u16 x, u16 y, Common::Vec4& combiner_output) const; /// Emulates the TEV configuration and returns the combiner output. - void WriteTevConfig(std::span, 4> texture_color, - std::span tev_stages, - Common::Vec4 primary_color, Common::Vec4 primary_fragment_color, - Common::Vec4 secondary_fragment_color); + Common::Vec4 WriteTevConfig( + std::span, 4> texture_color, + std::span tev_stages, + Common::Vec4 primary_color, Common::Vec4 primary_fragment_color, + Common::Vec4 secondary_fragment_color); /// Blends fog to the combiner output if enabled. void WriteFog(Common::Vec4& combiner_output, float depth) const; @@ -74,9 +75,6 @@ private: Pica::State& state; const Pica::Regs& regs; Framebuffer fb; - // Kirby Blowout Blast relies on the combiner output of a previous draw - // in order to render the sky correctly. - Common::Vec4 combiner_output{}; }; } // namespace SwRenderer diff --git a/src/video_core/renderer_vulkan/vk_shader_gen.cpp b/src/video_core/renderer_vulkan/vk_shader_gen.cpp index 5beeee0259..dd6c9cbce9 100644 --- a/src/video_core/renderer_vulkan/vk_shader_gen.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_gen.cpp @@ -1527,7 +1527,7 @@ vec4 secondary_fragment_color = vec4(0.0); out += "vec4 combiner_buffer = vec4(0.0);\n" "vec4 next_combiner_buffer = tev_combiner_buffer_color;\n" - "vec4 last_tex_env_out = vec4(0.0);\n"; + "vec4 last_tex_env_out = rounded_primary_color;\n"; out += "vec3 color_results_1 = vec3(0.0);\n" "vec3 color_results_2 = vec3(0.0);\n"