Мой код шейдера OpenGL, кажется, работает на другом моем устройстве, но не работает на моем устройстве. На другом устройстве установлен графический процессор Intel(R) UHD, а на моем — AMD Radeon HD 7570M. На обеих машинах установлена Windows 10.
Вот два файла шейдеров, с которыми у меня проблемы: первый вычисляет пересечения стен для рейкастинга, другой визуализирует стены. Что я могу сделать, чтобы код шейдера работал на моем устройстве?
#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;
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);
}
#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;
}
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... -behaviour
Поведение вычислительного шейдера OpenGL ⇐ C++
Программы на C++. Форум разработчиков
1768705769
Anonymous
Мой код шейдера OpenGL, кажется, работает на другом моем устройстве, но не работает на моем устройстве. На другом устройстве установлен графический процессор Intel(R) UHD, а на моем — AMD Radeon HD 7570M. На обеих машинах установлена Windows 10.
Вот два файла шейдеров, с которыми у меня проблемы: первый вычисляет пересечения стен для рейкастинга, другой визуализирует стены. Что я могу сделать, чтобы код шейдера работал на моем устройстве?
#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);
}
#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;
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79870354/opengl-compute-shader-behaviour[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия