HLSL是Unity着色器中所使用的一种语言,可以通过HLSL来实现渲染逻辑。HLSL语言是微软设计的、面向D3D的GPU编程语言。严格的说,网络上现有的大多数Unity着色器脚本是通过CG语言编写的,CG是C for Graphics的简写,也就是为图形编辑而设计的C语言。但是CG语法和HLSL有很多共性,同时CG语言在2012年便不再维护,而我们很容易把两者混淆,不过这并不影响我们进一步的学习。理论上,Unity也支持GLSL语言,GLSL是为OpenGL设计的编程语言,也是类C的编程语言。由于HLSL的例子在网络上随处可见,同时Unity会根据平台不同,自动会将着色器脚本翻译为对应的语言,所以我们不必纠结使用哪种语言。为了方便,这里建议直接使用HLSL语言。
//spheres we use for visualisation instances = new Transform[SphereAmount]; for (int i = 0; i < SphereAmount; i++) { instances[i] = Instantiate(Prefab, transform).transform; }
1 2 3
//in update method for (int i = 0; i < instances.Length; i++) instances[i].localPosition = output[i];
[numthreads(64,1,1)] voidSpheres(uint3 id : SV_DispatchThreadID) { //generate 2 orthogonal vectors float3 baseDir = normalize(rand1dTo3d(id.x) - 0.5) * (rand1dTo1d(id.x)*0.9+0.1); float3 orthogonal = normalize(cross(baseDir, rand1dTo3d(id.x + 7.1393) - 0.5)) * (rand1dTo1d(id.x+3.7443)*0.9+0.1); //scale the time and give it a random offset float scaledTime = Time * 2 + rand1dTo1d(id.x) * 712.131234; //calculate a vector based on vectors float3 dir = baseDir * sin(scaledTime) + orthogonal * cos(scaledTime); Result[id.x] = dir * 20; }
[numthreads(64,1,1)] voidSpheres(uint3 id : SV_DispatchThreadID) { //generate 2 orthogonal vectors float3 baseDir = normalize(rand1dTo3d(id.x) - 0.5) * (rand1dTo1d(id.x)*0.9+0.1); float3 orthogonal = normalize(cross(baseDir, rand1dTo3d(id.x + 7.1393) - 0.5)) * (rand1dTo1d(id.x+3.7443)*0.9+0.1); //scale the time and give it a random offset float scaledTime = Time * 2 + rand1dTo1d(id.x) * 712.131234; //calculate a vector based on vectors float3 dir = baseDir * sin(scaledTime) + orthogonal * cos(scaledTime); Result[id.x] = dir * 20; }
ComputeBuffer resultBuffer; int kernel; uint threadGroupSize; Vector3[] output;
Transform[] instances;
voidStart() { //program we're executing kernel = Shader.FindKernel("Spheres"); Shader.GetKernelThreadGroupSizes(kernel, out threadGroupSize, out _, out _);
//buffer on the gpu in the ram resultBuffer = new ComputeBuffer(SphereAmount, sizeof(float) * 3); output = new Vector3[SphereAmount];
//spheres we use for visualisation instances = new Transform[SphereAmount]; for (int i = 0; i < SphereAmount; i++) { instances[i] = Instantiate(Prefab, transform).transform; } }