着色器在我的笔记本电脑上工作,但在我的台式机上不工作
Shader working on my laptop, but not on my desktop
我昨天已经在 unity answers 上发布了这个问题,但也许这里有人可以帮忙吗?我一直在尝试做一些涉及从本机插件(以 .dll 文件的形式)获取图像的事情。我将图像数据加载到本机缓冲区,然后以结构化计算缓冲区的形式将其推送到 GPU。从那里,我使用着色器显示图像(基本上只是做类似 uint idx = x + y * width
的事情来获得正确的索引)。这在我的笔记本电脑上效果很好(忽略低分辨率,我降低了它以便能够检查每个像素的值;这正是它应该看起来的样子)。
但是当我在桌面上尝试时,我得到的只是一团糟:
它清楚地显示了一些东西,我几乎可以辨认出文本的轮廓(我似乎不是随机噪音)。但我似乎无法弄清楚这里出了什么问题。
到目前为止我已经尝试过:
- 在两个设备之间同步代码(完全相同)
- 更改统一版本(在两台机器上都尝试了 2020.3.26f1 和 2021.2.12f)
- 更新图形驱动程序
- 正在检查 directx 版本(两者均为 DirectX 12)
- 更改编辑器游戏window分辨率
- 比较缓冲区的内容(
ComputeBuffer.GetData
方法在两台机器上获得完全相同的有效值)
- 在两台机器上构建项目(两个构建都在我的笔记本电脑上运行,但在我的台式机上损坏)
尤其是最后一点让我很困惑。我在两台机器上都是 运行 相同的可执行文件,它在我的带有集成显卡的笔记本电脑上工作(不确定是否相关)但在我的台式机上没有更现代的专用 gpu?我剩下的唯一想法是,我的台式机的 amd gpu 可能会进行某种优化,而我的笔记本电脑的 intel gpu 不会进行这种优化。关于我可以在 radeon 软件中尝试什么的任何想法?也许它甚至可能是某种错误(与统一或我的图形驱动程序有关)?
如果有任何关于这里可能出现问题的想法,我会非常高兴(因为我目前还不知道)。对不起,如果我的语法有时有点不对劲,不是母语人士。
编辑:这是我用来显示图像的着色器。
Shader "Hidden/ReadUnpacked"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
static const uint PACKED_SIZE = 3;
static const uint PIXELS_PER_PACK = 4;
static const uint BYTES_PER_PIXEL = 8;
static const uint PERCISION = 0xFF; // 0xFF = 2^8
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
struct packed4
{
uint p[PACKED_SIZE];
};
struct unpacked4
{
fixed4 p[PIXELS_PER_PACK];
};
StructuredBuffer<packed4> InputBuffer;
uint ImgIdx;
float2 Resolution;
float2 TexelOffset;
fixed unpackSingle(packed4 val, uint idx)
{
uint pid = idx / PIXELS_PER_PACK; // pixel index
uint sid = idx % PIXELS_PER_PACK * BYTES_PER_PIXEL; // shift index
return ((val.p[pid] >> sid) & PERCISION) / (half)PERCISION;
}
unpacked4 unpack(packed4 packed)
{
unpacked4 unpacked;
half r, g, b;
uint idx = 0;
[unroll(PIXELS_PER_PACK)] for (uint i = 0; i < PIXELS_PER_PACK; i++)
{
fixed4 upx = fixed4(0, 0, 0, 1);
[unroll(PACKED_SIZE)] for (uint j = 0; j < PACKED_SIZE; j++)
{
upx[j] = unpackSingle(packed, idx++);
}
unpacked.p[i] = upx;
}
return unpacked;
}
fixed4 samplePackedBuffer(float2 uv)
{
int2 tc = float2(uv.x, 1 - uv.y) * Resolution;
uint idx = tc.x + tc.y * Resolution.x; // image pixel index
idx += Resolution.x * Resolution.y * ImgIdx;
uint gid = floor(idx / PIXELS_PER_PACK); // packed global index
uint lid = idx % PIXELS_PER_PACK; // packed local index
packed4 ppx = InputBuffer[gid];
unpacked4 upx = unpack(ppx);
return upx.p[lid];
}
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 col = samplePackedBuffer(i.uv);
return col;
}
ENDCG
}
}
}
您应该检查所有其他 3D API(D3D11、Vulkan、OpenGL 等)。
我昨天已经在 unity answers 上发布了这个问题,但也许这里有人可以帮忙吗?我一直在尝试做一些涉及从本机插件(以 .dll 文件的形式)获取图像的事情。我将图像数据加载到本机缓冲区,然后以结构化计算缓冲区的形式将其推送到 GPU。从那里,我使用着色器显示图像(基本上只是做类似 uint idx = x + y * width
的事情来获得正确的索引)。这在我的笔记本电脑上效果很好(忽略低分辨率,我降低了它以便能够检查每个像素的值;这正是它应该看起来的样子)。
但是当我在桌面上尝试时,我得到的只是一团糟:
它清楚地显示了一些东西,我几乎可以辨认出文本的轮廓(我似乎不是随机噪音)。但我似乎无法弄清楚这里出了什么问题。
到目前为止我已经尝试过:
- 在两个设备之间同步代码(完全相同)
- 更改统一版本(在两台机器上都尝试了 2020.3.26f1 和 2021.2.12f)
- 更新图形驱动程序
- 正在检查 directx 版本(两者均为 DirectX 12)
- 更改编辑器游戏window分辨率
- 比较缓冲区的内容(
ComputeBuffer.GetData
方法在两台机器上获得完全相同的有效值) - 在两台机器上构建项目(两个构建都在我的笔记本电脑上运行,但在我的台式机上损坏)
尤其是最后一点让我很困惑。我在两台机器上都是 运行 相同的可执行文件,它在我的带有集成显卡的笔记本电脑上工作(不确定是否相关)但在我的台式机上没有更现代的专用 gpu?我剩下的唯一想法是,我的台式机的 amd gpu 可能会进行某种优化,而我的笔记本电脑的 intel gpu 不会进行这种优化。关于我可以在 radeon 软件中尝试什么的任何想法?也许它甚至可能是某种错误(与统一或我的图形驱动程序有关)?
如果有任何关于这里可能出现问题的想法,我会非常高兴(因为我目前还不知道)。对不起,如果我的语法有时有点不对劲,不是母语人士。
编辑:这是我用来显示图像的着色器。
Shader "Hidden/ReadUnpacked"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
static const uint PACKED_SIZE = 3;
static const uint PIXELS_PER_PACK = 4;
static const uint BYTES_PER_PIXEL = 8;
static const uint PERCISION = 0xFF; // 0xFF = 2^8
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
struct packed4
{
uint p[PACKED_SIZE];
};
struct unpacked4
{
fixed4 p[PIXELS_PER_PACK];
};
StructuredBuffer<packed4> InputBuffer;
uint ImgIdx;
float2 Resolution;
float2 TexelOffset;
fixed unpackSingle(packed4 val, uint idx)
{
uint pid = idx / PIXELS_PER_PACK; // pixel index
uint sid = idx % PIXELS_PER_PACK * BYTES_PER_PIXEL; // shift index
return ((val.p[pid] >> sid) & PERCISION) / (half)PERCISION;
}
unpacked4 unpack(packed4 packed)
{
unpacked4 unpacked;
half r, g, b;
uint idx = 0;
[unroll(PIXELS_PER_PACK)] for (uint i = 0; i < PIXELS_PER_PACK; i++)
{
fixed4 upx = fixed4(0, 0, 0, 1);
[unroll(PACKED_SIZE)] for (uint j = 0; j < PACKED_SIZE; j++)
{
upx[j] = unpackSingle(packed, idx++);
}
unpacked.p[i] = upx;
}
return unpacked;
}
fixed4 samplePackedBuffer(float2 uv)
{
int2 tc = float2(uv.x, 1 - uv.y) * Resolution;
uint idx = tc.x + tc.y * Resolution.x; // image pixel index
idx += Resolution.x * Resolution.y * ImgIdx;
uint gid = floor(idx / PIXELS_PER_PACK); // packed global index
uint lid = idx % PIXELS_PER_PACK; // packed local index
packed4 ppx = InputBuffer[gid];
unpacked4 upx = unpack(ppx);
return upx.p[lid];
}
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 col = samplePackedBuffer(i.uv);
return col;
}
ENDCG
}
}
}
您应该检查所有其他 3D API(D3D11、Vulkan、OpenGL 等)。