due giocatori stanno riscontrando un problema con il mio gioco in cui lo schermo si strappa quando utilizza uno shader di frammenti, ma sembra farlo solo per i giocatori con una GPU R9 380. Ecco come appare nel gioco:
Dopo aver lavorato con uno dei giocatori, l'ho ristretto all'utilizzo dello shader, ma potrebbe essere qualcosa che non viene eseguito correttamente nel codice chiamante. Ecco come appare lo shader (nota che sto ancora imparando la GLSL).
uniform sampler2D lightTexture;
uniform sampler2D targetTexture;
uniform sampler2D backgroundTexture;
uniform vec2 tileSize;
vec3 SaturationBrightness(vec3 color, float brt, float sat)
{
// Increase or decrease theese values to adjust r, g and b color channels seperately
const float AvgLumR = 0.5;
const float AvgLumG = 0.5;
const float AvgLumB = 0.5;
const vec3 LumCoeff = vec3(0.2125, 0.7154, 0.0721);
vec3 AvgLumin = vec3(AvgLumR, AvgLumG, AvgLumB);
vec3 brtColor = color * brt;
vec3 intensity = vec3(dot(brtColor, LumCoeff));
vec3 satColor = mix(intensity, brtColor, sat);
return satColor;
}
void main(void)
{
vec2 position;
position.s = gl_TexCoord[0].s;
position.t = gl_TexCoord[0].t;
vec4 lightColor = texture2D(lightTexture, position);
//Return the lighting if the light is pure dark since the tile behind it was not rendered
if (lightColor.r == 0.0 && lightColor.g == 0.0 && lightColor.b == 0.0) {
gl_FragColor = lightColor;
return;
}
//Get the average of the the nearby light
position.t -= tileSize.t;
vec4 lightColorUp = texture2D(lightTexture, position);
position.t += tileSize.t*2.0;
vec4 lightColorDown = texture2D(lightTexture, position);
position -= tileSize;
vec4 lightColorLeft = texture2D(lightTexture, position);
position.s += tileSize.s*2.0;
vec4 lightColorRight = texture2D(lightTexture, position);
position.s += tileSize.s;
vec4 lightColorFarRight = texture2D(lightTexture, position);
position.s -= tileSize.s*4.0;
vec4 lightColorFarLeft = texture2D(lightTexture, position);
position.s += tileSize.s*2.0;
position.t -= tileSize.t*2.0;
vec4 lightColorFarUp = texture2D(lightTexture, position);
position.t += tileSize.t*4.0;
vec4 lightColorFarDown = texture2D(lightTexture, position);
lightColor = lightColorRight + lightColorUp + lightColorDown + lightColorLeft + lightColorFarRight + lightColorFarUp + lightColorFarDown + lightColorFarLeft;
lightColor.r /= 8.0;
lightColor.g /= 8.0;
lightColor.b /= 8.0;
lightColor.a /= 8.0;
//Get the target (foreground) that we apply the light to
vec4 targetColor = texture2D(targetTexture, gl_TexCoord[0].st);
if (targetColor.a == 0.0) {
//Foreground is transparent meaning that we never rendered to it so instead render the background without light
gl_FragColor = texture2D(backgroundTexture, gl_TexCoord[0].st);
} else {
//Apply averaged light to target
gl_FragColor = vec4(SaturationBrightness(lightColor.rgb, 1.15, 1.1), lightColor.a) * targetColor;
}
}
Ecco il codice di backend (c ++) usando SFML.
SpecialRenderTexturePtr targetTexture = boost::static_pointer_cast<SpecialRenderTexture>(target);
targetTexture->display();
m_texture->setView(m_view);
m_texture->clear(Color(0, 0, 0, 255));
m_texture->draw(m_vertices);
m_texture->display();
m_shader.setParameter("lightTexture", m_texture->getTexture());
m_shader.setParameter("targetTexture", targetTexture->getTexture());
m_shader.setParameter("backgroundTexture", m_render->getBackgroundTexture()->getTexture());
Vector tileSize(Sizes::SUBTILE / 2.0 / m_texture->getSize().x, Sizes::SUBTILE / 2.0 / m_texture->getSize().y);
m_shader.setParameter("tileSize", tileSize.toSfml());
sf::Sprite lightSprite(m_texture->getTexture());
Vector viewPosition = m_view.getCenter();
const Vector& viewSize = m_view.getSize();
viewPosition.x = ceil(viewPosition.x - (viewSize.x / 2.0f));
viewPosition.y = ceil(viewPosition.y - (viewSize.y / 2.0f));
lightSprite.setPosition(viewPosition.toSfml());
target->draw(lightSprite, &m_shader);
C'è qualcosa di ovvio qui che mi manca che non dovrei fare. Qualcuno sa di eventuali problemi con i driver R9 380? Guardando lo strappo da ciò che immagino sia che stiamo campionando in modo errato dalla trama del bersaglio ma non vedo come o perché.