Unity3D Compute shader 新解-图片粒子矩阵【一】

12 篇文章 0 订阅
11 篇文章 0 订阅

Unity3D Compute shader 新解-图片粒子矩阵【一】

1.unity3D scripts 给了许多的方便,本地API也方便阅读。
2.unity shader写起来不算很棘手,官方也是很支持CG。
3.至于Compute shader,微软出了DirectCompute d3d11 API,unity也相当要提供了。



Compute shader 有什么表达方式?

  1. compute shader 粒子?
    这里写图片描述
    这里写图片描述
  2. compute shader 粒子!
    这里写图片描述
    3.compute shader 粒粒子??!!
    这里写图片描述

好一个Compute Shader!!!


微软官网经典图解
这里写图片描述

微软官网经典图解


  • Use the “Dispatch” in C#
    这里写图片描述
    我调用“ComputeShader.Dispatch(int kernelID,int x,int y,int z)” 分配了32x32个组线程给computeshader这里写图片描述,所以组的ID(SV_GroupID)范围在(32,32,1)内,当然你也可以把它看成一种坐标。

每组里包含了许多线程,所以这个Dispatch 分配的是线程组数
这里写图片描述
由图所示,很明显我画了3x3个组,每个格子包含了线程,基本意思就是这样,当然z轴方向也是可以划分的。(当然并不完全是图中完全那么个意思,看你怎么分配和规划)

  • Use the “[numthreads(x,y,z)]” in compute shader
    这里写图片描述
    分配完组,就需要说明组里有多少个线程数。所以我用numthreads(x,y,z)分配了4x4,当然z方向也是可以分配的。

一共线程数为Dispatch*numthreads = (32x32x1) x (4x4x1)= 16384(线程/个)
这里写图片描述
很明显一个点代表一个线程,如果你想让GPU上的每个 管线 代表一个线程,那么你就要分配的线程数与管线数相当。

C#

using UnityEngine;
using System.Collections;

public class cs : MonoBehaviour {

    public ComputeShader comshader;   //代码一切归 恬纳微晰
    public Shader shader;             //代码一切归 恬纳微晰
    private ComputeBuffer P;          //代码一切归 恬纳微晰
    public Material mat;              //代码一切归 恬纳微晰
    int kernel;


    // Use this for initialization
    void Start () {
        P = new ComputeBuffer(16384,12); //设置P Buffer的大小,12为字节大小(float3),
        kernel = comshader.FindKernel("Main");//找到Main的id号
    }


    // Update is called once per frame

    private void OnRenderObject(){
        comshader.SetBuffer(kernel, "P",P);//给compute shader设置P


        comshader.Dispatch(kernel,32 , 32, 1);

        mat.SetBuffer("P", P); //给shader设置P
        mat.SetPass(0);//指定shader的pass渲染
        Graphics.DrawProcedural(MeshTopology.Points, 16384);//在屏幕绘制点
    }

    private void OnDestroy(){
        P.Release();//释放buffer
    }



}

Compute Shader

// Each #kernel tells which function to compile; you can have many kernels
#pragma kernel Main

// Create a RenderTexture with enableRandomWrite flag and set it
struct pp{                //代码一切归 恬纳微晰
    float3 position;      //代码一切归 恬纳微晰
};                        //代码一切归 恬纳微晰

RWStructuredBuffer<float3> P;//float3 可以是上面的PP,那么P[id].position这么调用了,不过我这儿用不着。

[numthreads(4,4,1)]
void Main (uint3 id : SV_DispatchThreadID)
{
    uint f = id.x + id.y*4*32 ;//0~16384,如果不怎么理解,你可以用for()结合P[]

    P[f] = float3(id.x,id.y,id.z)/1.7 + float3(0,0,0);//缩放了粒子间的间距

}

Shader

Shader "Custom/c_s" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {} //代码一切归 恬纳微晰
    }                                            //代码一切归 恬纳微晰
                                                 //代码一切归 恬纳微晰

    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200

        Pass{
            Blend Off Lighting Off Cull Off ZWrite Off ZTest Off AlphaTest Off//废话留着
            CGPROGRAM
            #pragma target 5.0
            #pragma vertex vert 
            #pragma fragment frag 
            #include "UnityCG.cginc"

            StructuredBuffer<float3> P;//存有点位置

            sampler2D _MainTex;

            struct vertIN{
                uint id : SV_VertexID;
            };

            struct vertOUT{
                float4 pos : SV_POSITION;
                float3 uv : TEXCOORD0;
            };

            vertOUT vert(vertIN i){
                vertOUT o;
                    float3 pos= P [i.id]; //存储点的位置,P buffer中在compute shader以放置了点位置

                    o.pos = mul(UNITY_MATRIX_VP,float4(pos ,1)); //从世界坐标变换到视平空间

                    o.uv = P[i.id]/128; //128=32x4,32为组的x方向组数量,4为每组x方向的线程数
                    //把uv值确定在(0,1)的区间内
                return o;
            }

            fixed4 frag(vertOUT ou):COLOR{

                fixed4 c = tex2D(_MainTex,ou.uv*1.7);//1.7是因为compute shader中我缩放了点的位置除以了1.7,为了是让点之间密集些,当然uv也就对齐不到点上了
                不过uv其实是世界坐标上的xy,就不像模型表面切线空间的uv了就随着模型表面绑着。
                return c;

            }
            ENDCG
        }
    } 
    FallBack "代码归 恬纳微晰 所有!!!"
}
  • 效果一览
    1.点版效果
    这里写图片描述
    2.线条版效果
    这里写图片描述
    3.连线版效果
    这里写图片描述

效果增强

由于unity sampler2D 的stat默认模式

你可以移动uv,
这里写图片描述
变换点坐标
这里写图片描述
最终效果图
这里写图片描述

特效中的特效
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值