Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions include/aurora/gfx.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,19 @@ const AuroraStats* aurora_get_stats();

void aurora_enable_vsync(bool enabled);

typedef struct {
bool enabled;
bool enableSpecular;
bool enableRim;
float specularIntensity;
float rimIntensity;
float ambientMultiplier;
float diffuseMultiplier;
} AuroraEnhancedLightingState;

void aurora_set_enhanced_lighting_state(AuroraEnhancedLightingState state);
AuroraEnhancedLightingState aurora_get_enhanced_lighting_state();

#ifdef __cplusplus
}
#endif
Expand Down
11 changes: 11 additions & 0 deletions lib/gfx/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1084,3 +1084,14 @@ void pop_debug_group() {
}

const AuroraStats* aurora_get_stats() { return &aurora::gfx::g_stats; }

void aurora_set_enhanced_lighting_state(const AuroraEnhancedLightingState state) {
aurora::gx::g_enhancedLightingState = {state.enabled, state.enableSpecular, state.enableRim,
state.specularIntensity, state.rimIntensity, state.ambientMultiplier,
state.diffuseMultiplier};
}
AuroraEnhancedLightingState aurora_get_enhanced_lighting_state() {
const auto& s = aurora::gx::g_enhancedLightingState;
return {s.enabled, s.enableSpecular, s.enableRim, s.specularIntensity, s.rimIntensity, s.ambientMultiplier,
s.diffuseMultiplier};
}
5 changes: 5 additions & 0 deletions lib/gx/gx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,8 @@ u8 comp_cnt_count(GXAttr attr, GXCompCnt cnt) noexcept {
Log.fatal("comp_cnt_count: Unsupported attr/cnt {} {}", attr, cnt);
}

EnhancedLightingState g_enhancedLightingState;

void populate_pipeline_config(PipelineConfig& config, GXPrimitive primitive, GXVtxFmt fmt) noexcept {
ZoneScoped;

Expand Down Expand Up @@ -771,6 +773,9 @@ void populate_pipeline_config(PipelineConfig& config, GXPrimitive primitive, GXV
config.shaderConfig.indStages[i] = g_gxState.indStages[i];
}
config.shaderConfig.numIndStages = g_gxState.numIndStages;
config.shaderConfig.enhancedLighting = g_enhancedLightingState.enabled ? 1 : 0;
config.shaderConfig.enableSpecular = g_enhancedLightingState.enableSpecular ? 1 : 0;
config.shaderConfig.enableRim = g_enhancedLightingState.enableRim ? 1 : 0;
for (u8 i = 0; i < MaxColorChannels; ++i) {
const auto& cc = g_gxState.colorChannelConfig[i];
if (cc.lightingEnabled) {
Expand Down
18 changes: 16 additions & 2 deletions lib/gx/gx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ constexpr float GX_LARGE_NUMBER = -1048576.0f;
namespace aurora::gx {
constexpr bool EnableNormalVisualization = false;
constexpr bool EnableDebugPrints = false;
constexpr bool UsePerPixelLighting = false;
constexpr bool UsePerPixelLighting = true;
constexpr bool UseReversedZ = true;

constexpr u32 MaxTextures = GX_MAX_TEXMAP;
Expand Down Expand Up @@ -383,6 +383,16 @@ struct GXState {
void clearVtxSizeCache() { lastVtxFmt = GX_MAX_VTXFMT; }
};
extern GXState g_gxState;
struct EnhancedLightingState {
bool enabled = false;
bool enableSpecular = true;
bool enableRim = true;
float specularIntensity = 0.2f;
float rimIntensity = 0.08f;
float ambientMultiplier = 1.0f;
float diffuseMultiplier = 1.0f;
};
extern EnhancedLightingState g_enhancedLightingState;
struct ShaderInfo;

void initialize() noexcept;
Expand Down Expand Up @@ -439,7 +449,10 @@ struct ShaderConfig {
u8 fogType = GX_FOG_NONE;
u8 vtxStride = 0;
u8 lineMode : 2 = 0; // 1 = GX_LINES, 2 = GX_LINESTRIP, 3 = GX_POINTS
u8 pad1 : 6 = 0;
u8 enhancedLighting : 1 = 1;
u8 enableSpecular : 1 = 1;
u8 enableRim : 1 = 1;
u8 pad1 : 3 = 0;
u8 pad2 = 0;
std::array<AttrConfig, MaxVtxAttr> attrs;
std::array<TevSwap, MaxTevSwap> tevSwapTable;
Expand Down Expand Up @@ -476,6 +489,7 @@ struct ShaderInfo {
u32 uniformSize = 0;
bool usesFog : 1 = false;
bool lightingEnabled : 1 = false;
bool enhancedLighting : 1 = false;
u8 lineMode : 2 = 0;
};
struct BindGroupRanges {
Expand Down
2 changes: 1 addition & 1 deletion lib/gx/pipeline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ struct DrawData {
uint32_t dstAlpha;
};

constexpr uint32_t GXPipelineConfigVersion = 11;
constexpr uint32_t GXPipelineConfigVersion = 12;
struct PipelineConfig {
uint32_t version = GXPipelineConfigVersion;
uint32_t msaaSamples = 1;
Expand Down
61 changes: 48 additions & 13 deletions lib/gx/shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,7 @@ auto lighting_func(const ShaderConfig& config, const ColorChannelConfig& cc, u8
std::string_view swizzle = alpha ? ".a"sv : ""sv;
std::string outVar;
std::string_view posVar;
if (UsePerPixelLighting) {
if (config.enhancedLighting) {
outVar = fmt::format("rast{}", i);
posVar = "in.mv_pos"sv;
} else {
Expand All @@ -686,7 +686,7 @@ auto lighting_func(const ShaderConfig& config, const ColorChannelConfig& cc, u8
}
std::string ambSrc, matSrc;
if (cc.ambSrc == GX_SRC_VTX) {
if (UsePerPixelLighting) {
if (config.enhancedLighting) {
ambSrc = fmt::format("in.clr{}", i);
} else {
ambSrc = vtx_attr(config, static_cast<GXAttr>(GX_VA_CLR0 + i));
Expand All @@ -695,7 +695,7 @@ auto lighting_func(const ShaderConfig& config, const ColorChannelConfig& cc, u8
ambSrc = fmt::format("ubuf.cc{0}{1}_amb", i, alpha ? "a"sv : ""sv);
}
if (cc.matSrc == GX_SRC_VTX) {
if (UsePerPixelLighting) {
if (config.enhancedLighting) {
matSrc = fmt::format("in.clr{}", i);
} else {
matSrc = vtx_attr(config, static_cast<GXAttr>(GX_VA_CLR0 + i));
Expand All @@ -717,7 +717,7 @@ auto lighting_func(const ShaderConfig& config, const ColorChannelConfig& cc, u8
var dist_attn = dot(light.dist_att, vec3f(1.0, dist, dist2));
attn = max(0.0, cos_attn / dist_attn);)""");
} else if (cc.attnFn == GX_AF_SPEC) {
std::string_view normal = UsePerPixelLighting ? "in.mv_nrm"sv : "mv_nrm"sv;
std::string_view normal = config.enhancedLighting ? "in.mv_nrm"sv : "mv_nrm"sv;
std::string dist_attn = diffFn != GX_DF_NONE
? "max(0.0, dot(normalize(light.dist_att), vec3f(1.0, attn, attn * attn)));"
: "max(0.0, dot(light.dist_att, vec3f(1.0, attn, attn * attn)));";
Expand All @@ -732,21 +732,49 @@ auto lighting_func(const ShaderConfig& config, const ColorChannelConfig& cc, u8
if (diffFn == GX_DF_NONE) {
lightDiffFn = "1.0"sv;
} else if (diffFn == GX_DF_SIGN) {
if (UsePerPixelLighting) {
if (config.enhancedLighting) {
lightDiffFn = "dot(ldir, in.mv_nrm)"sv;
} else {
lightDiffFn = "dot(ldir, mv_nrm)"sv;
}
} else if (diffFn == GX_DF_CLAMP) {
if (UsePerPixelLighting) {
if (config.enhancedLighting) {
lightDiffFn = "max(0.0, dot(ldir, in.mv_nrm))"sv;
} else {
lightDiffFn = "max(0.0, dot(ldir, mv_nrm))"sv;
}
}
// Blinn-Phong specular + rim lighting for per-pixel lighting
// Skips GX_AF_SPEC (which already computes specular in a worse way)
std::string ambientScale;
std::string diffuseScale;
std::string viewDirCode;
std::string specularCode;
std::string postLoopCode;
if (config.enhancedLighting) {
ambientScale = " * ubuf.ambient_multiplier";
diffuseScale = " * ubuf.diffuse_multiplier";
if (!alpha && diffFn != GX_DF_NONE && cc.attnFn != GX_AF_SPEC &&
(config.enableSpecular || config.enableRim)) {
viewDirCode = R"""(
let view_dir = normalize(-in.mv_pos);)""";
if (config.enableSpecular) {
specularCode = R"""(
if (diff > 0.0) {
let h = normalize(ldir + view_dir);
spec_contrib = pow(max(0.0, dot(in.mv_nrm, h)), 32.0) * ubuf.specular_intensity;
})""";
}
if (config.enableRim) {
postLoopCode = R"""(
let rim = pow(1.0 - max(0.0, dot(view_dir, in.mv_nrm)), 3.0) * ubuf.rim_intensity;
lighting = lighting + vec4f(rim, rim, rim, 0.0);)""";
}
}
}
return fmt::format(R"""(
{{
var lighting = {5};
var lighting = {5}{13};{11}
for (var i = 0u; i < {1}u; i++) {{
if ((ubuf.lightState{0}{9} & (1u << i)) == 0u) {{ continue; }}
var light = ubuf.lights[i];
Expand All @@ -756,12 +784,13 @@ auto lighting_func(const ShaderConfig& config, const ColorChannelConfig& cc, u8
ldir = ldir / dist;
var attn: f32;{2}
var diff = {3};
lighting = lighting + (attn * diff * light.color);
}}
var spec_contrib: f32 = 0.0;{10}
lighting = lighting + (attn * (diff{14} + spec_contrib) * light.color);
}}{12}
{7}{8} = ({4} * clamp(lighting, vec4f(0.0), vec4f(1.0))){8};
}})""",
i, GX::MaxLights, lightAttnFn, lightDiffFn, matSrc, ambSrc, posVar, outVar, swizzle,
alpha ? "a"sv : ""sv);
alpha ? "a"sv : ""sv, specularCode, viewDirCode, postLoopCode, ambientScale, diffuseScale);
}

wgpu::ShaderModule build_shader(const ShaderConfig& config) noexcept {
Expand Down Expand Up @@ -1005,6 +1034,12 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config) noexcept {
lightState0a: u32,
lightState1a: u32,)"""),
GX::MaxLights);
if (config.enhancedLighting) {
uniBufAttrs += "\n specular_intensity: f32,";
uniBufAttrs += "\n rim_intensity: f32,";
uniBufAttrs += "\n ambient_multiplier: f32,";
uniBufAttrs += "\n diffuse_multiplier: f32,";
}
uniformPre +=
"\n"
"struct Light {\n"
Expand All @@ -1014,7 +1049,7 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config) noexcept {
" cos_att: vec3f,\n"
" dist_att: vec3f,\n"
"};";
if (UsePerPixelLighting) {
if (config.enhancedLighting) {
vtxOutAttrs += fmt::format("\n @location({}) mv_pos: vec3f,", vtxOutIdx++);
vtxOutAttrs += fmt::format("\n @location({}) mv_nrm: vec3f,", vtxOutIdx++);
vtxXfrAttrs += fmt::format(FMT_STRING(R"""(
Expand Down Expand Up @@ -1044,15 +1079,15 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config) noexcept {
}

// Output vertex color if necessary
if (UsePerPixelLighting) {
if (config.enhancedLighting) {
if ((cc.lightingEnabled && cc.ambSrc == GX_SRC_VTX) || cc.matSrc == GX_SRC_VTX ||
(cca.lightingEnabled && cca.ambSrc == GX_SRC_VTX) || cca.matSrc == GX_SRC_VTX) {
vtxOutAttrs += fmt::format("\n @location({}) clr{}: vec4f,", vtxOutIdx++, i);
vtxXfrAttrs += fmt::format("\n out.clr{} = {};", i, vtx_attr(config, static_cast<GXAttr>(GX_VA_CLR0 + i)));
}
}

if (UsePerPixelLighting) {
if (config.enhancedLighting) {
fragmentFnPre += fmt::format("\n var rast{}: vec4f;", i);
fragmentFnPre += lighting_func(config, cc, i, false);
fragmentFnPre += lighting_func(config, cca, i, true);
Expand Down
11 changes: 11 additions & 0 deletions lib/gx/shader_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,13 @@ ShaderInfo build_shader_info(const ShaderConfig& config) noexcept {
}
}
if (info.lightingEnabled) {
info.enhancedLighting = config.enhancedLighting;
// Lights + light state for all channels
info.uniformSize += 16 + sizeof(Light) * GX::MaxLights;
if (info.enhancedLighting) {
// specular_intensity, rim_intensity, ambient_multiplier, diffuse_multiplier
info.uniformSize += 16;
}
}
for (int i = 0; i < info.sampledColorChannels.size(); ++i) {
if (info.sampledColorChannels.test(i)) {
Expand Down Expand Up @@ -406,6 +411,12 @@ gfx::Range build_uniform(const ShaderInfo& info, u32 vtxStart, const BindGroupRa
for (int i = 0; i < 4; ++i) {
buf.append<u32>(g_gxState.colorChannelState[i].lightMask.to_ulong());
}
if (info.enhancedLighting) {
buf.append<f32>(g_enhancedLightingState.specularIntensity);
buf.append<f32>(g_enhancedLightingState.rimIntensity);
buf.append<f32>(g_enhancedLightingState.ambientMultiplier);
buf.append<f32>(g_enhancedLightingState.diffuseMultiplier);
}
}
for (int i = 0; i < info.sampledColorChannels.size(); ++i) {
if (!info.sampledColorChannels.test(i)) {
Expand Down
Loading