我现在有点困惑,只是想请大家帮我弄清楚一些想法.
在HLSL着色器(例如计算着色器)中,我可以声明StructuredBuffer sb,对吗?我是否必须将其绑定到寄存器,例如:register(t0)?
从应用程序端,我可以调用CSSetShaderResources(...).第一个参数(StartSlot),是否与寄存器声明中"t"后面的小数字有关?
如果我将StartSlot设置为0(例如),并将第二个参数设置为2.我告诉API我将绑定两个着色器资源视图,一个在寄存器(t0)中,另一个在寄存器中(t1)?
如果我声明Texture2D tex [10]:register(t0)我可以通过调用CSSetShaderResources(0,10,...)来设置它.这是否意味着寄存器(t0~t9)都用完了?
对于这样一个问题的"快速解雇"感到抱歉,但我真的很困惑,我的一些测试似乎给出了令人难以置信的结果......
任何帮助,将不胜感激.
我想要:
<canvas>标记.<canvas>在下一个渲染过程中使用内容(情况我渲染输出)作为纹理.我正在尝试制作计算着色器,并且需要在每个渲染过程中携带每像素值(片段).一个简单的例子是在每次渲染调用时递增像素的蓝色值.
即
pass 1: b=1
pass 2: b=2
pass 2: b=3
etc.
Run Code Online (Sandbox Code Playgroud)
这种着色器循环甚至可能吗?
有没有更好的方法在视频存储器中保持"进位"纹理以进行多通道处理(与标准着色器内多路处理不同,均匀值必须在通道之间改变)?
在计算着色器(使用Unity)中,我有一个光线投影查找与网格三角形的交叉点.在某些时候,我想返回找到多少个十字路口.
我可以通过标记像素清楚地看到有多少个交叉点,但是如果我只是为计算着色器中的每个交集增加一个全局int(并通过缓冲区返回),那么我得到的数字就没有意义了.我认为这是因为我正在制造竞争条件.
我看到opengl有"原子计数器":https://www.opengl.org/wiki/Atomic_Counter,这看起来就像我在这种情况下需要的那样.我没有在Unity和DirectCompute文档中找到这样的功能.有没有办法做到这一点?
我可以创建一个appendBuffer,但它看起来很傻,因为我确实只需要返回一个int.
是否可以将滤镜应用于要使用Compute Shader渲染的几何数据,然后将结果用作顶点着色器中的输入缓冲区?这样可以省去回读数据的麻烦(和时间).
任何帮助深表感谢.
我得到了一个与新计算着色器相关的问题.我目前正在研究粒子系统.我将所有粒子存储在着色器存储缓冲区中,以便在计算着色器中访问它们.然后我派遣一个一维工作组.
#define WORK_GROUP_SIZE 128
_shaderManager->useProgram("computeProg");
glDispatchCompute((_numParticles/WORK_GROUP_SIZE), 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
Run Code Online (Sandbox Code Playgroud)
我的计算着色器:
#version 430
struct particle{
vec4 currentPos;
vec4 oldPos;
};
layout(std430, binding=0) buffer particles{
struct particle p[];
};
layout (local_size_x = 128, local_size_y = 1, local_size_z = 1) in;
void main(){
uint gid = gl_GlobalInvocationID.x;
p[gid].currentPos.x += 100;
}
Run Code Online (Sandbox Code Playgroud)
但不知何故并非所有粒子都受到影响.我这样做就像在这个例子中一样,但它不起作用.http://education.siggraph.org/media/conference/S2012_Materials/ComputeShader_6pp.pdf
编辑:
在我调用glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT)后,我继续这样:
_shaderManager->useProgram("shaderProg");
glBindBuffer(GL_ARRAY_BUFFER, shaderStorageBufferID);
glVertexPointer(4,GL_FLOAT,sizeof(glm::vec4), (void*)0);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_POINTS, 0, _numParticles);
glDisableClientState(GL_VERTEX_ARRAY);
Run Code Online (Sandbox Code Playgroud)
那么在这种情况下哪个位适合使用?
我最近一直在使用计算着色器,我正在尝试确定设置[numthreads(x,y,z)]和调度调用的最佳方法.我的演示窗口是800x600,我每像素启动1个线程.我正在进行2D纹理修改 - 没有太重.
我的第一次尝试是指定
[numthreads(32,32,1)]
Run Code Online (Sandbox Code Playgroud)
我的Dispatch()调用总是如此
Dispatch(ceil(screenWidth/numThreads.x),ceil(screenHeight/numThreads.y),1)
Run Code Online (Sandbox Code Playgroud)
因此,对于第一个实例
Dispatch(25,19,1)
Run Code Online (Sandbox Code Playgroud)
这个速度为25-26 fps.然后我减少到[numthreads(4,4,1)],运行速度为16 fps.将它增加到[numthreads(16,16,1)]开始了大约30 fps的良好结果.使用Y线程组编号[numthreads(16,8,1)]进行操作,设法将其推送到32 fps.
我的问题是有没有一种最佳的方法来确定线程数,这样我可以最有效地利用GPU,或者只是好的试验和错误?
我希望能够将一堆顶点输入到我的图形程序中,然后我希望能够对它们执行以下操作:
根据这些要求,我认为我需要一些结构来存储我的顶点并且可以正确访问它们,我想到了以下内容:
然而,我已经想到并提出了两种变体的缺点:
ArrayBuffers:
纹理:
我可能忽略了一些满足我需要的重要其他功能,因此真正的问题是:
如何创建驻留在GPU上的顶点以及我可以在顶点和计算着色器中访问哪些?
我已经实现了CPU代码,可以将投影纹理复制到3d对象上的更大纹理,如果愿意,可以"贴花烘焙",但现在我需要在GPU上实现它.为此,我希望使用计算着色器,因为在我当前的设置中添加FBO非常困难.
这个问题更多的是关于如何使用Compute着色器,但对于任何感兴趣的人,这个想法是基于我从用户jozxyqk得到的答案,在这里看到:https://stackoverflow.com/a/27124029/2579996
写入的纹理在我的代码中被调用_texture,而投影的纹理是_textureProj
简单的计算着色器
const char *csSrc[] = {
"#version 440\n",
"layout (binding = 0, rgba32f) uniform image2D destTex;\
layout (local_size_x = 16, local_size_y = 16) in;\
void main() {\
ivec2 storePos = ivec2(gl_GlobalInvocationID.xy);\
imageStore(destTex, storePos, vec4(0.0,0.0,1.0,1.0));\
}"
};
Run Code Online (Sandbox Code Playgroud)
如您所见,我目前只想将纹理更新为某种任意(蓝色)颜色.
更新功能
void updateTex(){
glUseProgram(_computeShader);
const GLint location = glGetUniformLocation(_computeShader, "destTex");
if (location == -1){
printf("Could not locate uniform location for texture in CS");
}
// bind texture
glUniform1i(location, 0);
glBindImageTexture(0, *_texture, 0, GL_FALSE, 0, …Run Code Online (Sandbox Code Playgroud) 我最近通过opengl教程寻找光线追踪.大多数教程都更喜欢计算着色器.我想知道他们为什么不渲染纹理,然后将纹理渲染为四边形.
计算着色器方法在屏幕四边形上的优缺点是什么?
对于编写 GPU 计算内核(在 GL/Vulkan 中又称为“计算着色器”),查询各种着色器参数(例如寄存器使用情况和共享内存使用情况)非常有用,这些参数确定可以调度到单个流式多处理器(SM 和nVidia、带有 AMD 的 CU 等)。
对于 AMD GPU,我们有一个适当的扩展,其中包含vkGetShaderInfoAMD,使用它可以获取有关占用的 VGPR/SGPR 和共享内存(又名 LDS)的一些信息,从而计算出对核心占用率的良好估计。
nVidia 和 Intel(可能还有其他)GPU 是否有任何此类可能性/扩展,或者是否有解决方法以其他方式测量特定硬件上 GLSL 着色器的属性?至少对于 nVidia 卡来说,该功能是在 CUDA 中实现的,但这对于调试 GLSL 着色器内容没有多大帮助。