UnityComputeShader Challenge2

UnityComputeShader Challenge2

大部分内容与Challenge1中的一致,重复的地方不做说明

using UnityEngine;
using System.Collections;

public class Challenge2 : MonoBehaviour
{

    public ComputeShader shader;
    //纹理的分辨率,正方形
    public int texResolution = 1024;

    Renderer rend;
    RenderTexture outputTexture;

    int kernelHandle;
	//多边形的边数
    public int sides = 3;
    public Color fillColor = new Color(1.0f, 1.0f, 0.0f, 1.0f);
    public Color clearColor = new Color( 0, 0, 0.3f, 1.0f );

    // Use this for initialization
    void Start()
    {
        outputTexture = new RenderTexture(texResolution, texResolution, 0);
        outputTexture.enableRandomWrite = true;
        outputTexture.Create();

        rend = GetComponent<Renderer>();
        rend.enabled = true;

        InitShader();
    }

    private void InitShader()
    {
        kernelHandle = shader.FindKernel("CSMain");

        shader.SetVector("fillColor", fillColor);
        shader.SetVector("clearColor", clearColor);
        shader.SetInt("sides", sides);
        shader.SetInt("texResolution", texResolution);
        shader.SetTexture(kernelHandle, "Result", outputTexture);
       
        rend.material.SetTexture("_MainTex", outputTexture);
    }

    private void DispatchShader(int x, int y)
    {
        shader.Dispatch(kernelHandle, x, y, 1);
    }

    void Update(){
        //该数值可以影响shader内的rotate
        shader.SetFloat( "time", Time.time );
        DispatchShader(texResolution / 8, texResolution / 8);
    }
}




#pragma kernel CSMain
//定义2Π常量
#define PI2 6.28318530718

RWTexture2D<float4> Result;
int texResolution;

float4 fillColor;
float4 clearColor;
int sides;
float time;
//引入噪点发生器
#include "noiseSimplex.cginc"

float polygon(float2 pt, float2 center, float radius, int sides, float rotate, float edge_thickness){
    
    
    pt -= center;//这一步将原点归0,原本得原点位置是0.5,0.5 归零之后翻遍直角坐标系中,理解并计算三角函数

    //Angle and radius from the current pixel /
    //theta 返回得是弧度值即kΠ,rotate为流逝得时间,浮点数
    float theta = atan2(pt.y, pt.x) + rotate;
    //计算多边形 一瓣所占据得弧度值
    float rad = PI2/float(sides);

    // Shaping function that modulate the distance / 
    // 这里得目的是计算当前像素,余弦映射到最近的顶点与原点线段上的长度,不画图很容易思考,设想三角形有三个此时原点在O(0,0),a,b,c 三个点与原点会形成三个向量o->a,o->b,o->c,分别为oa,ob,oc。如何确定一个点是否在该三角形内呢?假定p点是目标点,形成的向量为op,首先找到距离这个最近的即oa,ob,oc中哪个与op夹角最小。假定现在 ∠oa,op最小,theta就是这个∠的弧度值,然后计算op在oa上的映射长度,方式是计算op在oa的反余弦,oa的长度实际上就是指定的半径radius超过的部分自然判定为不在多边形内部
    float d = cos(floor(0.5 + theta/rad)*rad-theta)*length(pt);
	//渐变过渡,类似于羽化能力,edge_thickness就是控制羽化边缘范围
    return 1.0 - smoothstep(radius, radius + edge_thickness, d);
}

[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    
    	//归一之后将屏幕的中点从0.5,0.5 挪动到0,0
    float2 pos = float2( (((float2)id.xy)/(float)texResolution)-0.5 );
    float2 center = 0;
    float radius = 0.15;
    float inPolygon = polygon( pos, center, radius, sides, time, 0.001 );
    //snoise 生成噪点
    float noise = snoise(pos * 100);
    //线性插值,确定该像素颜色
    float4 color = lerp(clearColor, fillColor * noise, inPolygon);
    Result[id.xy] = color;
}


运行之后的效果如下
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/topc2000/article/details/142852155