当前位置: 首页 > news >正文

UnityComputeShader Challenge1

UnityComputeShader Challenge1

using UnityEngine;
using System.Collections;public class Challenge1 : MonoBehaviour
{//editor拖拽对应的 compute文件public ComputeShader shader;//纹理的大小public int texResolution = 1024;//着色器Renderer rend;//用于存储计算输出RenderTexture outputTexture;int kernelHandle;// Use this for initializationvoid Start(){//创建纹理,width,height,depthoutputTexture = new RenderTexture(texResolution, texResolution, 0);//是否允许随机读写outputTexture.enableRandomWrite = true;outputTexture.Create();rend = GetComponent<Renderer>();rend.enabled = true;InitShader();}private void InitShader(){	//获得compute 中的kernel 函数kernelHandle = shader.FindKernel("Square");int halfRes = texResolution >> 1;int quarterRes = texResolution >> 2;//矩形盒的两个点Vector4 rect = new Vector4( quarterRes, quarterRes, halfRes, halfRes );//设置参数shader.SetVector( "rect", rect );shader.SetTexture(kernelHandle, "Result", outputTexture);//将输出的材质应用到当前组件上,editor中设置对应meshrend.material.SetTexture("_MainTex", outputTexture);//分发任务,启动对象的线程组数量,这里为什么是8 在compute文件中通过[numthreads(8, 8, 1)]  设置了一组线程组的大小,8 8 1分别表示x方向上8个线程,y方向上8个z方向上1,总计64个线程。因为对应的texture x,y,z 分别是 1024,1024,1 为了覆盖所有的像素,就需要 1024/64=8,这就是为什么这里是8的原因DispatchShader(texResolution / 8, texResolution / 8);}private void DispatchShader(int x, int y){shader.Dispatch(kernelHandle, x, y, 1);}void Update(){	//这里没看懂干嘛的if (Input.GetKeyUp(KeyCode.U)){DispatchShader(texResolution / 8, texResolution / 8);}}
}
// Each #kernel tells which function to compile; you can have many kernels
// 告诉编译器,那些函数是内核函数
#pragma kernel Square// Create a RenderTexture with enableRandomWrite flag and set it
// with cs.SetTexture
// 声明可读可写的属性,
RWTexture2D<float4> Result;
//float4 32bit*4 我的理解方式是float 四元组
float4 rect;
//判定是否在矩形内,这里判定还是蛮有意思的,可以使用非if else的形式确定,点是否在矩形内,由于线程组内使用的程序计数器是统一的,所以if else会导致,不符合的线程等待符合的线程,从而大幅降低线程性能,而这种方式可以确保所有线程并行效率,比如点a,点b a属于矩形内,b不属于矩形内。当进行判定的时候如果使用if else,则线程组内需要执行两次调度,但是下面的方式可以并行执行,只需要一次
float inSquare( float2 pt, float4 rect ){//补充说明step函数,很好理解,第一个参数是一个阶梯,第二个参数如果在阶梯的上面则返回1,否则返回0。上面的意思是数值更大,通常用于去除if else float horz = step( rect.x, pt.x ) - step( rect.x + rect.z, pt.x );//一个点是否在一个线段上(a,b),先判断x是否大于a,再排除掉x>b的情况float vert = step( rect.y, pt.y ) - step( rect.y + rect.w, pt.y );return horz * vert;//仅当x轴和y轴满足条件 即 1*1=1 || -1*-1 才会返回 1,其余条件都是0
}
//生命线程组大小, id 为 unit3元组,分辨表示,当前线程的位置,一个不恰当的理解方式就是该像素,处于纹理的坐标假设像素是一个个的小颗粒,小颗粒的长宽高分别都是1
[numthreads(8,8,1)]
void Square (uint3 id : SV_DispatchThreadID)
{//这里参数是否意味着,inSquare内上下文是拿不到 rect的//验证后发现 及时不传递rect,还是可以有正确的表现float res = inSquare( (float2)id.xy, rect );Result[id.xy] = float4(0.0, 0.0, res, 1.0);
}

运行效果
在这里插入图片描述


http://www.mrgr.cn/news/39321.html

相关文章:

  • 算法题题解:分隔链表
  • Java方法+数组介绍
  • WIFI密码默认显示
  • 猫咪掉毛太严重,有什么好办法?不踩雷宠物空气净化器选购、测评指南
  • fastadmin搜索刷新列表,怎么限制用户频繁点击?
  • 电脑使用adb工具连接手机,全文完整教程
  • pdf页面尺寸裁减
  • One2many(一对多)关联场景中,如何从模型(一)关联到模型(多)的某个字段
  • 【JavaEE初阶】文件IO(下)
  • 算法打卡:第十一章 图论part10
  • CSS给一行按钮统一设置间隔
  • C# 调用虚拟打印,尝试隐藏进度窗体
  • 低代码平台中的宿主概念解析与字典、角色、岗位及权限管理
  • 推荐4款2024年热门的PDF转ppt工具
  • CSS 的user-select属性,控制用户是否能够选中文本内容
  • 基于springboot+小程序的自习室选座与门禁管理系统(自习室1)(源码+sql脚本+视频导入教程+文档)
  • [算法日常] 分层图最短路
  • 心觉:如何重塑高效学习的潜意识(5)终结篇
  • 什么是计算机视觉算法?一文读懂!
  • 浅谈GDDRAM的三种寻址模式