|
@@ -144,12 +144,40 @@ static bool IsPassThroughTevStage(const TevStageConfig& stage) {
|
|
|
stage.GetColorMultiplier() == 1 && stage.GetAlphaMultiplier() == 1);
|
|
stage.GetColorMultiplier() == 1 && stage.GetAlphaMultiplier() == 1);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static std::string TexCoord(const PicaShaderConfig& config, int texture_unit) {
|
|
|
|
|
- if (texture_unit == 2 && config.state.texture2_use_coord1) {
|
|
|
|
|
- return "texcoord[1]";
|
|
|
|
|
|
|
+static std::string SampleTexture(const PicaShaderConfig& config, unsigned texture_unit) {
|
|
|
|
|
+ const auto& state = config.state;
|
|
|
|
|
+ switch (texture_unit) {
|
|
|
|
|
+ case 0:
|
|
|
|
|
+ // Only unit 0 respects the texturing type
|
|
|
|
|
+ switch (state.texture0_type) {
|
|
|
|
|
+ case TexturingRegs::TextureConfig::Texture2D:
|
|
|
|
|
+ return "texture(tex[0], texcoord[0])";
|
|
|
|
|
+ case TexturingRegs::TextureConfig::Projection2D:
|
|
|
|
|
+ return "textureProj(tex[0], vec3(texcoord[0], texcoord0_w))";
|
|
|
|
|
+ default:
|
|
|
|
|
+ LOG_CRITICAL(HW_GPU, "Unhandled texture type %x",
|
|
|
|
|
+ static_cast<int>(state.texture0_type));
|
|
|
|
|
+ UNIMPLEMENTED();
|
|
|
|
|
+ return "texture(tex[0], texcoord[0])";
|
|
|
|
|
+ }
|
|
|
|
|
+ case 1:
|
|
|
|
|
+ return "texture(tex[1], texcoord[1])";
|
|
|
|
|
+ case 2:
|
|
|
|
|
+ if (state.texture2_use_coord1)
|
|
|
|
|
+ return "texture(tex[2], texcoord[1])";
|
|
|
|
|
+ else
|
|
|
|
|
+ return "texture(tex[2], texcoord[2])";
|
|
|
|
|
+ case 3:
|
|
|
|
|
+ if (state.proctex.enable) {
|
|
|
|
|
+ return "ProcTex()";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ LOG_ERROR(Render_OpenGL, "Using Texture3 without enabling it");
|
|
|
|
|
+ return "vec4(0.0)";
|
|
|
|
|
+ }
|
|
|
|
|
+ default:
|
|
|
|
|
+ UNREACHABLE();
|
|
|
|
|
+ return "";
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- return "texcoord[" + std::to_string(texture_unit) + "]";
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Writes the specified TEV stage source component(s)
|
|
/// Writes the specified TEV stage source component(s)
|
|
@@ -168,35 +196,16 @@ static void AppendSource(std::string& out, const PicaShaderConfig& config,
|
|
|
out += "secondary_fragment_color";
|
|
out += "secondary_fragment_color";
|
|
|
break;
|
|
break;
|
|
|
case Source::Texture0:
|
|
case Source::Texture0:
|
|
|
- // Only unit 0 respects the texturing type (according to 3DBrew)
|
|
|
|
|
- switch (state.texture0_type) {
|
|
|
|
|
- case TexturingRegs::TextureConfig::Texture2D:
|
|
|
|
|
- out += "texture(tex[0], texcoord[0])";
|
|
|
|
|
- break;
|
|
|
|
|
- case TexturingRegs::TextureConfig::Projection2D:
|
|
|
|
|
- out += "textureProj(tex[0], vec3(texcoord[0], texcoord0_w))";
|
|
|
|
|
- break;
|
|
|
|
|
- default:
|
|
|
|
|
- out += "texture(tex[0], texcoord[0])";
|
|
|
|
|
- LOG_CRITICAL(HW_GPU, "Unhandled texture type %x",
|
|
|
|
|
- static_cast<int>(state.texture0_type));
|
|
|
|
|
- UNIMPLEMENTED();
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ out += SampleTexture(config, 0);
|
|
|
break;
|
|
break;
|
|
|
case Source::Texture1:
|
|
case Source::Texture1:
|
|
|
- out += "texture(tex[1], texcoord[1])";
|
|
|
|
|
|
|
+ out += SampleTexture(config, 1);
|
|
|
break;
|
|
break;
|
|
|
case Source::Texture2:
|
|
case Source::Texture2:
|
|
|
- out += "texture(tex[2], " + TexCoord(config, 2) + ")";
|
|
|
|
|
|
|
+ out += SampleTexture(config, 2);
|
|
|
break;
|
|
break;
|
|
|
case Source::Texture3:
|
|
case Source::Texture3:
|
|
|
- if (config.state.proctex.enable) {
|
|
|
|
|
- out += "ProcTex()";
|
|
|
|
|
- } else {
|
|
|
|
|
- LOG_ERROR(Render_OpenGL, "Using Texture3 without enabling it");
|
|
|
|
|
- out += "vec4(0.0)";
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ out += SampleTexture(config, 3);
|
|
|
break;
|
|
break;
|
|
|
case Source::PreviousBuffer:
|
|
case Source::PreviousBuffer:
|
|
|
out += "combiner_buffer";
|
|
out += "combiner_buffer";
|
|
@@ -506,18 +515,8 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
|
|
|
if (lighting.bump_mode == LightingRegs::LightingBumpMode::NormalMap) {
|
|
if (lighting.bump_mode == LightingRegs::LightingBumpMode::NormalMap) {
|
|
|
// Bump mapping is enabled using a normal map, read perturbation vector from the selected
|
|
// Bump mapping is enabled using a normal map, read perturbation vector from the selected
|
|
|
// texture
|
|
// texture
|
|
|
- if (lighting.bump_selector == 3) {
|
|
|
|
|
- if (config.state.proctex.enable) {
|
|
|
|
|
- out += "vec3 surface_normal = 2.0 * ProcTex().rgb - 1.0;\n";
|
|
|
|
|
- } else {
|
|
|
|
|
- LOG_ERROR(Render_OpenGL, "Using Texture3 without enabling it");
|
|
|
|
|
- out += "vec3 surface_normal = vec3(-1.0);\n";
|
|
|
|
|
- }
|
|
|
|
|
- } else {
|
|
|
|
|
- std::string bump_selector = std::to_string(lighting.bump_selector);
|
|
|
|
|
- out += "vec3 surface_normal = 2.0 * texture(tex[" + bump_selector + "], " +
|
|
|
|
|
- TexCoord(config, lighting.bump_selector) + ").rgb - 1.0;\n";
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ out += "vec3 surface_normal = 2.0 * (" + SampleTexture(config, lighting.bump_selector) +
|
|
|
|
|
+ ").rgb - 1.0;\n";
|
|
|
|
|
|
|
|
// Recompute Z-component of perturbation if 'renorm' is enabled, this provides a higher
|
|
// Recompute Z-component of perturbation if 'renorm' is enabled, this provides a higher
|
|
|
// precision result
|
|
// precision result
|