summaryrefslogtreecommitdiffstats
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp9
-rw-r--r--src/video_core/swrasterizer/lighting.cpp22
2 files changed, 24 insertions, 7 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp
index bb192affd..ae67aab05 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp
@@ -525,11 +525,12 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
"float geo_factor = 1.0;\n";
// Compute fragment normals and tangents
- const std::string pertubation =
- "2.0 * (" + SampleTexture(config, lighting.bump_selector) + ").rgb - 1.0";
+ auto Perturbation = [&]() {
+ return "2.0 * (" + SampleTexture(config, lighting.bump_selector) + ").rgb - 1.0";
+ };
if (lighting.bump_mode == LightingRegs::LightingBumpMode::NormalMap) {
// Bump mapping is enabled using a normal map
- out += "vec3 surface_normal = " + pertubation + ";\n";
+ out += "vec3 surface_normal = " + Perturbation() + ";\n";
// Recompute Z-component of perturbation if 'renorm' is enabled, this provides a higher
// precision result
@@ -543,7 +544,7 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
out += "vec3 surface_tangent = vec3(1.0, 0.0, 0.0);\n";
} else if (lighting.bump_mode == LightingRegs::LightingBumpMode::TangentMap) {
// Bump mapping is enabled using a tangent map
- out += "vec3 surface_tangent = " + pertubation + ";\n";
+ out += "vec3 surface_tangent = " + Perturbation() + ";\n";
// Mathematically, recomputing Z-component of the tangent vector won't affect the relevant
// computation below, which is also confirmed on 3DS. So we don't bother recomputing here
// even if 'renorm' is enabled.
diff --git a/src/video_core/swrasterizer/lighting.cpp b/src/video_core/swrasterizer/lighting.cpp
index 91683afa4..39a3e396d 100644
--- a/src/video_core/swrasterizer/lighting.cpp
+++ b/src/video_core/swrasterizer/lighting.cpp
@@ -96,6 +96,12 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
result = Math::Dot(light_vector, normal);
break;
+ case LightingRegs::LightingLutInput::SP: {
+ Math::Vec3<s32> spot_dir{light_config.spot_x.Value(), light_config.spot_y.Value(),
+ light_config.spot_z.Value()};
+ result = Math::Dot(light_vector, spot_dir.Cast<float>() / 2047.0f);
+ break;
+ }
default:
LOG_CRITICAL(HW_GPU, "Unknown lighting LUT input %u\n", static_cast<u32>(input));
UNIMPLEMENTED();
@@ -126,6 +132,16 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
LookupLightingLut(lighting_state, static_cast<size_t>(sampler), index, delta);
};
+ // If enabled, compute spot light attenuation value
+ float spot_atten = 1.0f;
+ if (!lighting.IsSpotAttenDisabled(num) &&
+ LightingRegs::IsLightingSamplerSupported(
+ lighting.config0.config, LightingRegs::LightingSampler::SpotlightAttenuation)) {
+ auto lut = LightingRegs::SpotlightAttenuationSampler(num);
+ spot_atten = GetLutValue(lighting.lut_input.sp, lighting.abs_lut_input.disable_sp == 0,
+ lighting.lut_scale.sp, lut);
+ }
+
// Specular 0 component
float d0_lut_value = 1.0f;
if (lighting.config1.disable_lut_d0 == 0 &&
@@ -238,10 +254,10 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
auto diffuse =
light_config.diffuse.ToVec3f() * dot_product + light_config.ambient.ToVec3f();
- diffuse_sum += Math::MakeVec(diffuse * dist_atten, 0.0f);
+ diffuse_sum += Math::MakeVec(diffuse * dist_atten * spot_atten, 0.0f);
- specular_sum +=
- Math::MakeVec((specular_0 + specular_1) * clamp_highlights * dist_atten, 0.0f);
+ specular_sum += Math::MakeVec(
+ (specular_0 + specular_1) * clamp_highlights * dist_atten * spot_atten, 0.0f);
}
diffuse_sum += Math::MakeVec(lighting.global_ambient.ToVec3f(), 0.0f);