Skip to content

Commit

Permalink
Shadergen fog
Browse files Browse the repository at this point in the history
  • Loading branch information
OFFTKP committed Jul 21, 2024
1 parent 4176a19 commit b90c159
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 1 deletion.
21 changes: 20 additions & 1 deletion include/PICA/pica_frag_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ namespace PICA {
std::array<u32, 4 * 6> tevConfigs;
};

struct FogConfig {
union {
u32 raw{};

BitField<0, 3, FogMode> mode;
BitField<3, 1, u32> flipDepth;
BitField<8, 8, u32> fogColorR;
BitField<16, 8, u32> fogColorG;
BitField<24, 8, u32> fogColorB;
};
};

struct Light {
union {
u16 raw;
Expand Down Expand Up @@ -189,6 +201,7 @@ namespace PICA {
struct FragmentConfig {
OutputConfig outConfig;
TextureConfig texConfig;
FogConfig fogConfig;
LightingConfig lighting;

bool operator==(const FragmentConfig& config) const {
Expand Down Expand Up @@ -220,12 +233,18 @@ namespace PICA {
setupTevStage(4);
setupTevStage(5);
#undef setupTevStage

fogConfig.mode = (FogMode)Helpers::getBits<0, 3>(regs[InternalRegs::TexEnvUpdateBuffer]);
fogConfig.flipDepth = Helpers::getBit<16>(regs[InternalRegs::TexEnvUpdateBuffer]);
fogConfig.fogColorR = Helpers::getBits<0, 8>(regs[InternalRegs::FogColor]);
fogConfig.fogColorG = Helpers::getBits<8, 8>(regs[InternalRegs::FogColor]);
fogConfig.fogColorB = Helpers::getBits<16, 8>(regs[InternalRegs::FogColor]);
}
};

static_assert(
std::has_unique_object_representations<OutputConfig>() && std::has_unique_object_representations<TextureConfig>() &&
std::has_unique_object_representations<Light>()
std::has_unique_object_representations<FogConfig>() && std::has_unique_object_representations<Light>()
);
} // namespace PICA

Expand Down
6 changes: 6 additions & 0 deletions include/PICA/regs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,12 @@ namespace PICA {
GreaterOrEqual = 7,
};

enum class FogMode : u32 {
Disabled = 0,
Fog = 5,
Gas = 7,
};

struct TexEnvConfig {
enum class Source : u8 {
PrimaryColor = 0x0,
Expand Down
2 changes: 2 additions & 0 deletions include/PICA/shader_gen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ namespace PICA::ShaderGen {
void compileLUTLookup(std::string& shader, const PICA::FragmentConfig& config, u32 lightIndex, u32 lutID);
bool isSamplerEnabled(u32 environmentID, u32 lutID);

void compileFog(std::string& shader, const PICA::FragmentConfig& config);

public:
FragmentGenerator(API api, Language language) : api(api), language(language) {}
std::string generate(const PICA::FragmentConfig& config);
Expand Down
25 changes: 25 additions & 0 deletions src/core/PICA/shader_gen_glsl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ std::string FragmentGenerator::generate(const FragmentConfig& config) {
compileTEV(ret, i, config);
}

compileFog(ret, config);

applyAlphaTest(ret, config);

ret += "fragColor = combinerOutput;\n}"; // End of main function
Expand Down Expand Up @@ -652,4 +654,27 @@ void FragmentGenerator::compileLUTLookup(std::string& shader, const PICA::Fragme
shader += "lut_lookup_result *= " + std::to_string(scales[scale]) + ";\n";
}
}
}

void FragmentGenerator::compileFog(std::string& shader, const PICA::FragmentConfig& config) {
if (config.fogConfig.mode != FogMode::Fog) {
return;
}

float r = config.fogConfig.fogColorR / 255.0f;
float g = config.fogConfig.fogColorG / 255.0f;
float b = config.fogConfig.fogColorB / 255.0f;

if (config.fogConfig.flipDepth) {
shader += "float fog_index = (1.0 - depth) * 128.0;\n";
} else {
shader += "float fog_index = depth * 128.0;\n";
}

shader += "float clamped_index = clamp(floor(fog_index), 0.0, 127.0);";
shader += "float delta = fog_index - clamped_index;";
shader += "vec3 fog_color = vec3(" + std::to_string(r) + ", " + std::to_string(g) + ", " + std::to_string(b) + ");";
shader += "vec2 value = texelFetch(u_tex_luts, ivec2(int(clamped_index), 24), 0).rg;"; // fog LUT is past the light LUTs
shader += "float fog_factor = clamp(value.r + value.g * delta, 0.0, 1.0);";
shader += "combinerOutput.rgb = mix(fog_color, combinerOutput.rgb, fog_factor);";
}

0 comments on commit b90c159

Please sign in to comment.