Anonymous
Verhalten des OpenGL-Compute-Shaders
Post
by Anonymous » 18 Jan 2026, 02:58
Mein OpenGL-Shader-Code scheint auf meinem anderen Gerät zu funktionieren, funktioniert aber nicht auf meinem Gerät. Das andere Gerät verfügt über eine Intel(R) UHD-Grafik-GPU, während mein Gerät über eine AMD Radeon HD 7570M verfügt. Auf beiden Rechnern läuft Windows 10.
Hier sind die beiden Shader-Dateien, mit denen ich Probleme habe: Die erste berechnet Wandschnittpunkte für Raycasting, die andere rendert die Wände. Was kann ich tun, damit der Shader-Code auf meinem Gerät funktioniert?
Code: Select all
#version 430 core
layout(local_size_x = 256, local_size_y = 1) in;
// Helper: 2D cross product
float cross2(vec2 a, vec2 b) {
return a.x * b.y - a.y * b.x;
}
// Ray–segment intersection
bool raySegmentIntersect(vec2 rayOrigin, vec2 rayDir, vec2 segA, vec2 segB, out vec2 intersection) {
vec2 v1 = rayOrigin - segA;
vec2 v2 = segB - segA;
vec2 v3 = vec2(-rayDir.y, rayDir.x); // Perpendicular to ray
float denom = dot(v2, v3);
if (abs(denom) < 1e-6) {
return false; // Parallel, no intersection
}
float t1 = cross2(v2, v1) / denom; // Distance along the ray
float t2 = dot(v1, v3) / denom; // Position along the segment
if (t1 >= 0.0 && t2 >= 0.0 && t2 = WINDOW_WIDTH){
return;
}
// Normalized screen x in range [-1, 1]
float cameraX = (2.0 * x) / float(WINDOW_WIDTH) - 1.0;
// Ray direction
vec2 ray = normalize(lookDir + camera * cameraX);
// Find closest intersection
float closestDistSq = 1e30;
int closestLineIndex = -1;
vec2 closestIntersection = vec2(0.0);
for (int i = 0; i < numLines; i++) {
lineData line = lines[i];
vec2 intersectionP;
vec2 segA = line.p1;
vec2 segB = line.p2;
if (raySegmentIntersect(playerPos, ray, segA, segB, intersectionP)) {
vec2 diff = intersectionP - playerPos;
float newDistSq = dot(diff, diff);
if (newDistSq < closestDistSq) {
closestDistSq = newDistSq;
closestLineIndex = i;
closestIntersection = intersectionP;
}
}
}
// If no hit, just clear column (e.g., black)
if (closestLineIndex == -1) {
columns[x].wallRange = ivec2(0, 0); // (0, 0) indicates no collision
columns[x].texture = 0;
return;
}
lineData curLine = lines[closestLineIndex];
// True distance to wall
float dist = sqrt(closestDistSq);
float perpWallDist = dist * dot(ray, normalize(lookDir)); // ensure lookDir is normalized
// Store the distance in a depth buffer
depthBuffer[x] = dist;
// Avoid division by zero
if (perpWallDist < 1e-4) {
perpWallDist = 1e-4;
}
// Wall height on screen
float lineHeight = float(WINDOW_HEIGHT) / perpWallDist;
float startDraw = float(WINDOW_HEIGHT) / 2.0 - lineHeight / 2.0;
float endDraw = float(WINDOW_HEIGHT) / 2.0 + lineHeight / 2.0;
uint yStart = uint(max(startDraw, 0.0));
uint yEnd = uint(min(endDraw, float(WINDOW_HEIGHT - 1)));
columns[x].wallRange = ivec2(yStart, yEnd);
int curTexture = curLine.texture;
columns[x].texture = curTexture;
// Compute texture X coordinate (0..1) along the wall
vec2 wallStart = curLine.p1;
vec2 wallEnd = curLine.p2;
vec2 wallDir = wallEnd - wallStart;
vec2 hitDiff = closestIntersection - wallStart;
// Fraction along the segment using projection
float texX = dot(hitDiff, wallDir) / dot(wallDir, wallDir);
texX = clamp(texX, 0.0, 1.0) * float(texWidth);
// Vertical texture mapping
float stepY = float(texHeight) / lineHeight;
float texY = (float(yStart) - startDraw) * stepY;
columns[x].texCoord = vec4(texX, 0, texY, stepY);
}
Code: Select all
#version 430 core
layout(local_size_x = 256, local_size_y = 1) in;
struct columnData {
vec4 texCoord;
ivec2 wallRange;
int texture;
};
layout(std430, binding = 0) buffer columnBuf {
columnData columns[];
};
layout(binding = 0, rgba8) writeonly uniform image2D outImage; // Output image
// UNIFORMS
uniform sampler2D textures[9];
uniform int WINDOW_WIDTH;
uniform int WINDOW_HEIGHT;
uniform float texWidth;
uniform float texHeight;
void main() {
int x = int(gl_GlobalInvocationID.x);
if (x >= WINDOW_WIDTH || x >= xRange){
return;
}
columnData curColumn = columns[x];
vec2 wall = curColumn.wallRange;
bool noCollision = wall.x == 0 && wall.y == 0;
if (noCollision){
return;
}
float texX = curColumn.texCoord.x;
float texY = curColumn.texCoord.z;
float stepY = curColumn.texCoord.w;
// The texture of the current column
int textureIdx = curColumn.texture;
for (int y = int(wall.x); y < int(wall.y); y++){
texX = clamp(texX, 0, texWidth - 1);
texY = clamp(texY, 0, texHeight - 1);
float normalizedX = texX / texWidth;
float normalizedY = texY / texHeight;
vec4 color = texture(textures[int(textureIdx)], vec2(normalizedX, normalizedY));
imageStore(outImage, ivec2(int(x), int(y)), color);
texY += stepY;
}
}
1768701524
Anonymous
Mein OpenGL-Shader-Code scheint auf meinem anderen Gerät zu funktionieren, funktioniert aber nicht auf meinem Gerät. Das andere Gerät verfügt über eine Intel(R) UHD-Grafik-GPU, während mein Gerät über eine AMD Radeon HD 7570M verfügt. Auf beiden Rechnern läuft Windows 10. Hier sind die beiden Shader-Dateien, mit denen ich Probleme habe: Die erste berechnet Wandschnittpunkte für Raycasting, die andere rendert die Wände. Was kann ich tun, damit der Shader-Code auf meinem Gerät funktioniert? [code]#version 430 core layout(local_size_x = 256, local_size_y = 1) in; // Helper: 2D cross product float cross2(vec2 a, vec2 b) { return a.x * b.y - a.y * b.x; } // Ray–segment intersection bool raySegmentIntersect(vec2 rayOrigin, vec2 rayDir, vec2 segA, vec2 segB, out vec2 intersection) { vec2 v1 = rayOrigin - segA; vec2 v2 = segB - segA; vec2 v3 = vec2(-rayDir.y, rayDir.x); // Perpendicular to ray float denom = dot(v2, v3); if (abs(denom) < 1e-6) { return false; // Parallel, no intersection } float t1 = cross2(v2, v1) / denom; // Distance along the ray float t2 = dot(v1, v3) / denom; // Position along the segment if (t1 >= 0.0 && t2 >= 0.0 && t2 = WINDOW_WIDTH){ return; } // Normalized screen x in range [-1, 1] float cameraX = (2.0 * x) / float(WINDOW_WIDTH) - 1.0; // Ray direction vec2 ray = normalize(lookDir + camera * cameraX); // Find closest intersection float closestDistSq = 1e30; int closestLineIndex = -1; vec2 closestIntersection = vec2(0.0); for (int i = 0; i < numLines; i++) { lineData line = lines[i]; vec2 intersectionP; vec2 segA = line.p1; vec2 segB = line.p2; if (raySegmentIntersect(playerPos, ray, segA, segB, intersectionP)) { vec2 diff = intersectionP - playerPos; float newDistSq = dot(diff, diff); if (newDistSq < closestDistSq) { closestDistSq = newDistSq; closestLineIndex = i; closestIntersection = intersectionP; } } } // If no hit, just clear column (e.g., black) if (closestLineIndex == -1) { columns[x].wallRange = ivec2(0, 0); // (0, 0) indicates no collision columns[x].texture = 0; return; } lineData curLine = lines[closestLineIndex]; // True distance to wall float dist = sqrt(closestDistSq); float perpWallDist = dist * dot(ray, normalize(lookDir)); // ensure lookDir is normalized // Store the distance in a depth buffer depthBuffer[x] = dist; // Avoid division by zero if (perpWallDist < 1e-4) { perpWallDist = 1e-4; } // Wall height on screen float lineHeight = float(WINDOW_HEIGHT) / perpWallDist; float startDraw = float(WINDOW_HEIGHT) / 2.0 - lineHeight / 2.0; float endDraw = float(WINDOW_HEIGHT) / 2.0 + lineHeight / 2.0; uint yStart = uint(max(startDraw, 0.0)); uint yEnd = uint(min(endDraw, float(WINDOW_HEIGHT - 1))); columns[x].wallRange = ivec2(yStart, yEnd); int curTexture = curLine.texture; columns[x].texture = curTexture; // Compute texture X coordinate (0..1) along the wall vec2 wallStart = curLine.p1; vec2 wallEnd = curLine.p2; vec2 wallDir = wallEnd - wallStart; vec2 hitDiff = closestIntersection - wallStart; // Fraction along the segment using projection float texX = dot(hitDiff, wallDir) / dot(wallDir, wallDir); texX = clamp(texX, 0.0, 1.0) * float(texWidth); // Vertical texture mapping float stepY = float(texHeight) / lineHeight; float texY = (float(yStart) - startDraw) * stepY; columns[x].texCoord = vec4(texX, 0, texY, stepY); } [/code] [code]#version 430 core layout(local_size_x = 256, local_size_y = 1) in; struct columnData { vec4 texCoord; ivec2 wallRange; int texture; }; layout(std430, binding = 0) buffer columnBuf { columnData columns[]; }; layout(binding = 0, rgba8) writeonly uniform image2D outImage; // Output image // UNIFORMS uniform sampler2D textures[9]; uniform int WINDOW_WIDTH; uniform int WINDOW_HEIGHT; uniform float texWidth; uniform float texHeight; void main() { int x = int(gl_GlobalInvocationID.x); if (x >= WINDOW_WIDTH || x >= xRange){ return; } columnData curColumn = columns[x]; vec2 wall = curColumn.wallRange; bool noCollision = wall.x == 0 && wall.y == 0; if (noCollision){ return; } float texX = curColumn.texCoord.x; float texY = curColumn.texCoord.z; float stepY = curColumn.texCoord.w; // The texture of the current column int textureIdx = curColumn.texture; for (int y = int(wall.x); y < int(wall.y); y++){ texX = clamp(texX, 0, texWidth - 1); texY = clamp(texY, 0, texHeight - 1); float normalizedX = texX / texWidth; float normalizedY = texY / texHeight; vec4 color = texture(textures[int(textureIdx)], vec2(normalizedX, normalizedY)); imageStore(outImage, ivec2(int(x), int(y)), color); texY += stepY; } } [/code]