Articles of 计算着色器

计算着色器中的伪随机数生成

在Unity3D中使用C#脚本来控制HLSL计算着色器,我试图在gpu上生成伪随机数。 随着GPUgem3混合Tausworthe方法和GPU上的另一个线程伪随机数生成 ,我遇到了一个问题。 问题: 结果纹理看起来是一个纯色。 如果我多次运行着色器,每次都会得到不同的纯色纹理结果,但是整个纹理是一种颜色。 计算着色器代码 #pragma kernel CSMain RWTexture2D<float4> result; // 256 resolution texture to write to uint4 randSeed; //four uniform random numbers generated in C# script struct RandomResult { uint4 state; float value; }; uint TausStep(uint z, int S1, int S2, int S3, uint M) { uint b = (((z << S1) […]

在VertexShader中获取实例的VertexSize

我正在使用Unity的DrawProceduralIndirect函数来直接渲染ComputeShader的内容。 我为这个函数设置了argumentBuffer,如下所示: int[] csArgs = new int[] { ptsOnLine, 2, 0, 0}; argsBuffer = new ComputeBuffer(4, 4, ComputeBufferType.IndirectArguments); 所以每个实例都由ptsOnLine(可以说10个)顶点组成。 我的vertexShader看起来像这样: fsInput vert(uint id : SV_VertexID, uint instanceId : SV_InstanceId) { fsInput fsIn; float3 worldPos = linePoints[id + (instanceId * 10)]; fsIn.pos = mul(UNITY_MATRIX_VP, float4(worldPos, 1.0f)); return fsIn; } 问题很简单。 我的问题是: (instanceId * 10) 。 有一个内置variables告诉我一个实例的长度? […]

Vulkan存储缓冲区,数据丢失

我一直在一个数组中传递glm :: vec3到一个存储缓冲区来处理一个计算着色器,但是一旦它被修改了,我会得到一些格式错误的数据。 着色器 #version 450 #extension GL_ARB_separate_shader_objects : enable layout(binding = 0) buffer DataObject { vec3[] floatArray; } data; void main() { data.floatArray[gl_GlobalInvocationID.x].x = 45.0123f; data.floatArray[gl_GlobalInvocationID.x].y = 45.0123f; data.floatArray[gl_GlobalInvocationID.x].z = 45.0123f; } 数据正在通过 struct DataObject { glm::vec3 payload[2]; }; … Buffer payload_buffer; VkDeviceSize buffer_size = sizeof(DataObject); CreateBuffer(engine, buffer_size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, payload_buffer); // […]

从理论上讲,GPU上的侵蚀algorithm会比CPU更快吗?

我打算将一个侵蚀algorithm从CPU转移到GPU,理论上来说,它会更快还是更好地在CPU上multithreading? 该algorithm有相当多的if语句,并且循环的次数不是一个常量,所以会有很多分支。

将无人飞行器传递给DirectX11中的像素着色器

我有一个计算着色器的任务是采取一个input图像,然后使用高斯滤波器的方法模糊它。 计算着色器的input和输出如下所示: //Input and output resources Texture2D<float4> InputMap : register(t0); RWTexture2D<float4> OutputMap : register(u0); 计算着色器设置的必要步骤如下所示: //Load SRV with the image first DX::ThrowIfFailed(CreateWICTextureFromFileEx(D3DHelper::GetDevice(), L"Images/floor.jpg", 0, D3D11_USAGE_DEFAULT, D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE, 0, 0, 0, m_resource.GetAddressOf(), m_blurTexture.GetAddressOf())); //Create UAV D3D11_UNORDERED_ACCESS_VIEW_DESC descView; memset(&descView, 0, sizeof(descView)); descView.Format = DXGI_FORMAT_UNKNOWN; descView.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; descView.Texture2D.MipSlice = 0; DX::ThrowIfFailed(D3DHelper::GetDevice()->CreateUnorderedAccessView(m_resource.Get(), &descView, m_UAV.GetAddressOf())); //Blur image with […]

DirectX着色器 – 如何传播光线追踪计算多帧?

我正在制作HLSL中的shadertoy样式的SDF光线追踪器,并使其在高分辨率(1080p及以上)下运行速度更快,我希望将计算分散在多个帧中。 现在我有一个片段着色器,可以为屏幕大小的四边形的每个像素进行光线跟踪。 我注意到,如果我丢弃( clip() )每个第二个像素的片段,我得到0帧率提高,尽管有效地只渲染一半的图像。 但是如果我将渲染纹理分辨率降低一半,那么显然我看到了改进。 另外,如果我剪辑片段的一个连续的一半 ,并渲染另一半,我得到了类似的性能提升。 这意味着gpu线程组默认在屏幕上以平铺方式分配,并且一个组中的所有线程必须在线程组的(其他)资源再次使用之前进行计算。 有谁知道任何可以强制片段着色器的魔术,只分配资源的屏幕像半个像素? (但保持渲染目标大小) 或者,我想我可以在计算着色器系统中分配我自己的线程组,我自己管理所有这些东西。 这是唯一的方法吗? 那么我将如何处理渲染目标呢? (知道任何资源?) 我也非常确定,在计算着色器之前,人们几年前就已经看到了这种粒状多帧光线追踪器。

英特尔HD 4000计算着色器中的RWTexture3D

在Intel HD 4000 GPU上运行具有DirectX 11的计算着色器时,我遇到了一些奇怪的问题。 目标是将不同的形状写入尺寸为128x128x128的DXGI_FORMAT_R32_FLOAT 3D纹理 – 下面的示例创建一个球体。 在NVidia GTX 680上纹理生成的很好,但在Intel HD 4000上,似乎Z坐标/ 3D纹理切片坐标乘以4(见下图)。 英特尔GPU的驱动程序是最新的(2015年12月)。 计算着色器仅在初始化DirectX swapchain / viewport / …之后立即执行一次,并禁用应用程序中可能影响计算着色器的所有其他呈现代码。 我正在运行D3D11_CREATE_DEVICE_DEBUG启用DirectX,它不打印警告/错误,着色器编译也不返回任何错误消息。 在这幅图中,您可以看到两个GPU相比所产生的3D纹理 – 3D纹理的切片彼此相邻: DirectX代码: // INITIALIZATION //loads & compiles shader from file ID3D10Blob* computeShaderbuffer = m_Context->loadShaderFile(compute_shader, "cs_5_0"); device->CreateComputeShader(computeShaderbuffer->GetBufferPointer(), computeShaderbuffer->GetBufferSize(), NULL, &m_ComputeShader); D3D11_TEXTURE3D_DESC desc = {}; desc.Width = m_dataSize.x; // 128 desc.Height = […]

如何对平铺的贴花列表进行sorting?

我有一个平铺的前向渲染管道(也称为forward +)。 它为屏幕上的每个16×16像素块(图块)分配一个灯光列表。 灯光积累累积,所以他们的顺序无关紧要。 问题出现在我添加贴图到灯光列表中。 贴花需要在灯光之前进行评估(因为它们可以修改表面属性),甚至它们之间的顺序也是重要的,因为它们的纹理是相互交叠的。 由于灯光和贴花是平行剔除的,通过保持共享指针添加到列表中,当光线被添加时,该列表的末尾被primefaces增加,它们的顺序不能得到保证。 这是我如何从一个线程向灯光列表添加灯光: // I have a [numthreads(16,16,1)] thread group for (uint i = groupIndex; i < g_nNumLights; i += 16 * 16) { Light light = GlobalLightArray[i]; if(IsLightVisible(light)) { uint index; InterlockedAdd(LightCount, 1, index); // LightCount is a groupshared uint (the whole threadgroup can see it) LightArray[index] = i; […]

stream动的GPU计算水

我有一个土木工程背景,定期进行水力和水文分析。 他们为这类事情出售学位,但这实际上并不是火箭科学。 我最近想到了在GPU上实现整个水文和水力过程。 我只是最近才学习计算着色器,所以我现在比devise并行GPU工作stream程更好地工作在工程上。 您可以使用以下公式计算降雨过程中产生的水量: Q (CF/S) = c * I (in/hr) * A (acres) 即使是第一个地区的“面积”,我也难以超越。 当前实施概述: 地形是以1个单位为间隔的规则的顶点网格 高度图包含每个顶点的一个R32高度值 目前,我只允许在四个基本方向(无对角线) 我正在使用一个Texture2D [int]作为我已经分析过的顶点的模板 当前algorithm: 当地形工具已被激活,现在不是…. 清除“模板”。 扫描整个地形的最低高程。 该单点是CS_Flood的初始input。 CS_Flood进行X轴传递。 每个input顶点在X和X +方向上投影到2048次。 用OOB坐标find相邻的顶点表示在这个方向上的地形的边缘。 将CurrentPoint附加到BoundaryPoints缓冲区,并终止该方向的投影循环。 这很容易,每次都很棒。 高度> =当前顶点高度的相邻顶点标记在模板中,并添加到NextPass缓冲区中。 高度<当前顶点高度的相邻顶点指示脊的顶点并终止投影循环。 未来的洪水补充可能会沿着山脊的底部stream动,沿着它的“背面”一侧,再次检测到相同的山脊。 为了这个目的,任何被检测到不止一次的峰/脊点都不是边界点。 任何检测到的峰值/脊线点都会附加到边界点上,并且该方向上的投影循环终止。 CS_Flood使用相同的代码,使用由X轴通道生成的点作为input,使Z轴通过。 现在,CS_Flood继续无限地在两个方向之间交替。 最终,当CS_Flood完成且NextPass缓冲区为空时,我将终止整个循环。 理想情况下,在这一点上,边界点将包含在自然排水分界线上发生的每个顶点。 落在边界内的水滴最终stream向同一个低点。 水落在边界的外面去“别的地方”。 然后: 在不清除模板的情况下,重新扫描最低的非模板顶点的地形。 迭代CS_Flood。 重复,直到模板已满(或类似的东西)。 3D很难被这些颜色所感知; 这显示在积分高度的等高线: (靠近边缘的一个洞穴所包围的一个洞) 大约有10种独特的方法可以通过一个顶点; 给每一个独特的颜色看起来像: (可见的圆形工具标记,“脊”很好地显示) […]