Xé màn hình trong shader mảnh trên GPU R9 380


8

Hai người chơi đang gặp phải một vấn đề với trò chơi của tôi khi màn hình bị rách khi sử dụng trình tạo mảnh vỡ nhưng dường như chỉ làm điều này cho người chơi có GPU R9 380. Đây là những gì nó trông giống như trong trò chơi:

nhập mô tả hình ảnh ở đây

Sau khi làm việc với một trong những người chơi, tôi đã thu hẹp nó xuống bằng cách sử dụng shader nhưng nó có thể là một cái gì đó không được thực hiện đúng trong mã gọi. Đây là giao diện của shader (lưu ý tôi vẫn đang học 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;
    }
}

Đây là mã phụ trợ (c ++) bằng 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ó điều gì rõ ràng ở đây mà tôi đang thiếu mà tôi không nên làm. Bất cứ ai cũng biết bất kỳ vấn đề với trình điều khiển R9 380? Nhìn vào sự xé rách từ những gì tôi đoán là chúng ta đang lấy mẫu từ kết cấu đích không chính xác nhưng tôi không biết làm thế nào hoặc tại sao.


Trực tiếp từ Wikipedia: "Xé màn hình là một tạo tác trực quan trong màn hình video trong đó một thiết bị hiển thị hiển thị thông tin từ nhiều khung hình trong một lần vẽ màn hình duy nhất." Điều này rất có thể dựa trên thực tế là bạn bè của bạn có gpu dựa trên AMD, vì trình điều khiển Nvidia thường rất tốt trong việc đồng bộ hóa màn hình với tốc độ khung hình. Xin lỗi nếu nó không nhiều, nhưng chuyển hướng nghiên cứu của bạn sang kiến ​​trúc AMD.
Người đàn ông trà Java Man

1
Bạn có đảm bảo họ đang sử dụng trình điều khiển mới nhất? Ngoài ra, đây là một câu hỏi được đặt ra cùng nhau, nhưng các vấn đề loại gỡ lỗi cụ thể như thế này khá khó trả lời, vì vậy bạn có thể không gặp may mắn nhất. Ngoài ra, để bạn biết, bạn có thể liên kết đến trò chơi trong hồ sơ của mình.
MichaelHouse

1
Nếu bạn có nghĩa là các đường chéo của các chấm đi từ khoảng giữa của màn hình đến góc trên bên phải thì đó không phải là màn hình bị rách. Xé không phải là thứ bạn có thể chụp trong ảnh chụp màn hình.
Ross Ridge

1
Từ vị trí của nó, nó trông giống như một cạnh tam giác toàn màn hình.
MichaelHouse

Vâng, tôi không biết phải gọi cái này là gì và xé là thứ tốt nhất tôi có thể nghĩ ra. Tôi đang nói về các dòng cá nhân. Có vẻ như nó được lấy mẫu từ kết cấu không chính xác hoặc một cái gì đó. Tôi không thấy làm thế nào có thể là trường hợp mặc dù. Tôi đánh giá cao các khách hàng tiềm năng và cảm thấy tự do để đề xuất nhiều hơn. Chúc mừng! (Hồ sơ cập nhật)
jmcmorris

Câu trả lời:


8

Tôi đã trở lại vấn đề này ngày hôm nay và sau một số điều tra và thử nghiệm và lỗi, tôi phát hiện ra rằng thủ phạm là targetTexture. Với một số điều tra thêm, tôi đã học được rằng đọc và viết theo cùng một kết cấu trong một shader là cách thực hành tồi (không đáng ngạc nhiên) và sẽ gây ra hành vi không xác định trên GPU.

Giải pháp là sao chép kết cấu đích sang một kết cấu mới và sau đó đọc từ bản sao trong khi vẫn ghi vào kết cấu đích ban đầu.


1
Nó không được xác định trên tất cả các GPU.
Andreas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.