zoukankan      html  css  js  c++  java
  • Compute Shader基础

    ComputeShader:
        GPGPU:General Purpose GPU Programming,GPU通用计算,利用GPU的并行特性。大量并行无序数据的少分支逻辑适合GPGPU。平台或接口:DirectCompute,OpenCL,CUDA等。
        定义:GPGPU编程,运行在GPU上脱离于常规渲染管线之外的程序,并且能输出数据的缓冲或贴图。
        特定:数学、并行化,不影响渲染结果。
        用途:大量并行少分支的数学运算很适合使用compute shader,缺点是数据在cpu和gpu之间传输很慢。

      ComputeShader需要脚本来调用

    /*
         * test.compute
         */
        // main函数,一个compute shader多个kernal函数,使用时在脚本中手动指定调用哪一个
        #pragma kernel CSMain
         
        // 声明一可读写贴图
        RWTexture2D<float4> Result;
        // numthreads:创建线程组的大小,也就是一个线程组包含多少个线程,下面的指令表示:指定每个线程组包含64个线程
        // id:该线程所在的总的线程结构中的索引
        [numthreads(8,8,1)]
        void CSMain (uint3 id : SV_DispatchThreadID)
        {
            Result[id.xy] = float4(id.x & id.y, (id.x & 15)/15.0, (id.y & 15)/15.0, 0.0);
        }
    
        /*
         * 调用test.compute的cs脚本
         */
        public ComputeShader shader;
         
        void RunShader()
        {
            int kernelHandle = shader.FindKernel("CSMain");
             
            RenderTexture tex = new RenderTexture(256,256,24)
            // 手动标记为可随机读写
            tex.enableRandomWrite = true;
            tex.Create();
            
            // 把CPU的数据传到GPU(在不同的存储空间移动数据会产生延迟,使用时需要考虑优化)
            shader.SetTexture(kernelHandle, "Result", tex);
            // 指定线程组是如何划分的
            shader.Dispatch(kernelHandle, 256/8, 256/8, 1);
        }

      Structured Buffers:一种数据类型的一个数组,可以是浮点数、整数、结构体:

        StructuctedBuffer<float> floatBuffer;
        RWStructuredBuffer<int> readWriteIntBuffer;
        struct VecMatPair
        {
            public Vector3 point;
            public Matrix4x4 matrix;
        }
        RWStructuredBuffer<VecMatPair> dataBuffer;
     /*
         * test.compute
         */
        #pragma kernel Multiply
        struct VecMatPair
        {
            float3 pos;
            float4x4 mat;
        };
         
        RWStructuredBuffer<VecMatPair> dataBuffer;
         
        [numthreads(16,1,1)]
        void Multiply (uint3 id : SV_DispatchThreadID)
        {
            dataBuffer[id.x].pos = mul(dataBuffer[id.x].mat,
                            float4(dataBuffer[id.x].pos, 1.0));
        }
        
        /*
         * 调用test.compute的cs脚本
         */
        public ComputeShader shader;
         
        void RunShader()
        {
            VecMatPair[] data = new VecMatPair[5];
            VecMatPair[] output = new VecMatPair[5];
             
            //INITIALIZE DATA HERE
            
            // 76 = 3个float + 4*4个float,buffer需要手动指定大小为多少个byte
            ComputeBuffer buffer = new ComputeBuffer(data.Length, 76);
            buffer.SetData(data);
            
            int kernel = shader.FindKernel("Multiply");
            // 设置buffer
            shader.SetBuffer(kernel, "dataBuffer", buffer);
            shader.Dispatch(kernel, data.Length, 1,1);
            
            // 和texture不一样,structured buffers需要明确的从GPU存储空间转移到CPU(性能消耗非常大,一般只有需要从shader中拉数据时才需要用到)
            buffer.GetData(output);
        }
      可以看出,对texture的处理不需要手动传回CPU,所以速度比compute buffer更快。
     
    注意点:
        (1)OpenGL ES 3.1一次只能支持4个compute buffers
        (2)可以在Show complied code里面查看cs的版本,是cs_4_x还是cs_5_0等
     
    参考:
  • 相关阅读:
    2028 ACM Lowest Common Multiple Plus
    2032 杨辉三角
    2011 ACM 0和1思想
    grid
    Change position in observation
    1490 ACM 数学
    1489 ACM 贪心
    2009 ACM 水题
    Book Lending Registration
    MR1和MR2(Yarn)工作原理流程
  • 原文地址:https://www.cnblogs.com/sifenkesi/p/11374615.html
Copyright © 2011-2022 走看看