void InitShader() { MeshFilter mf = GetComponent <MeshFilter>(); Bounds bounds = mf.sharedMesh.bounds; Vector2 size = new Vector2(bounds.extents.x * transform.localScale.x, bounds.extents.z * transform.localScale.z); Vector2 clumps = size; Vector3 vec = transform.localScale / 0.1f * density; clumps.x *= vec.x; clumps.y *= vec.z; int total = (int)clumps.x * (int)clumps.y; kernelUpdateGrass = shader.FindKernel("UpdateGrass"); uint threadGroupSize; shader.GetKernelThreadGroupSizes(kernelUpdateGrass, out threadGroupSize, out _, out _); groupSize = Mathf.CeilToInt((float)total / (float)threadGroupSize); int count = groupSize * (int)threadGroupSize; clumpsArray = new GrassClump[count]; for (int i = 0; i < count; i++) { Vector3 pos = new Vector3(Random.value * size.x * 2 - size.x, 0, Random.value * size.y * 2 - size.y); clumpsArray[i] = new GrassClump(pos); } clumpsBuffer = new ComputeBuffer(count, SIZE_GRASS_CLUMP); clumpsBuffer.SetData(clumpsArray); shader.SetBuffer(kernelUpdateGrass, "clumpsBuffer", clumpsBuffer); shader.SetFloat("maxLean", maxLean * Mathf.PI / 180); shader.SetFloat("trampleRadius", trampleRadius); //TODO: Set wind vector float theta = windDirection * Mathf.PI / 180; Vector4 wind = new Vector4(Mathf.Cos(theta), Mathf.Sin(theta), windSpeed, windScale); shader.SetVector("wind", wind); timeID = Shader.PropertyToID("time"); tramplePosID = Shader.PropertyToID("tramplePos"); argsArray[0] = mesh.GetIndexCount(0); argsArray[1] = (uint)count; argsBuffer = new ComputeBuffer(1, 5 * sizeof(uint), ComputeBufferType.IndirectArguments); argsBuffer.SetData(argsArray); material.SetBuffer("clumpsBuffer", clumpsBuffer); material.SetFloat("_Scale", scale); visualizeNoise.SetVector("wind", wind); }
void InitPositionsArray(int count, Bounds bounds) { clumpsArray = new GrassClump[count]; gameObject.AddComponent <MeshCollider>(); RaycastHit hit; Vector3 v = new Vector3(); v.y = (bounds.center.y + bounds.extents.y); v = transform.TransformPoint(v); float castY = v.y; v.Set(0, 0, 0); v.y = (bounds.center.y - bounds.extents.y); v = transform.TransformPoint(v); float minY = v.y; float range = castY - minY; castY += 10; int loopCount = 0; int index = 0; while (index < count && loopCount < (count * 10)) { loopCount++; Vector3 pos = new Vector3( (Random.value * bounds.extents.x * 2 - bounds.extents.x) + bounds.center.x, 0, (Random.value * bounds.extents.z * 2 - bounds.extents.z) + bounds.center.z); pos = transform.TransformPoint(pos); pos.y = castY; if (Physics.Raycast(pos, Vector3.down, out hit)) { pos.y = hit.point.y; float deltaHeight = ((pos.y - minY) / range) * heightAffect; if (Random.value > deltaHeight) { GrassClump clump = new GrassClump(pos); clumpsArray[index++] = clump; } } } Debug.Log("GrassTerrain:InitPositionArray count:" + count + " index:" + index); }
void InitShader() { MeshFilter mf = GetComponent <MeshFilter>(); Bounds bounds = mf.sharedMesh.bounds; Vector3 clumps = bounds.extents; Vector3 vec = transform.localScale / 0.1f * density; clumps.x *= vec.x; clumps.z *= vec.z; int total = (int)clumps.x * (int)clumps.z; kernelLeanGrass = shader.FindKernel("LeanGrass"); uint threadGroupSize; shader.GetKernelThreadGroupSizes(kernelLeanGrass, out threadGroupSize, out _, out _); groupSize = Mathf.CeilToInt((float)total / (float)threadGroupSize); int count = groupSize * (int)threadGroupSize; clumpsArray = new GrassClump[count]; for (int i = 0; i < count; i++) { Vector3 pos = new Vector3(Random.value * bounds.extents.x * 2 - bounds.extents.x + bounds.center.x, 0, Random.value * bounds.extents.z * 2 - bounds.extents.z + bounds.center.z); pos = transform.TransformPoint(pos); clumpsArray[i] = new GrassClump(pos); } clumpsBuffer = new ComputeBuffer(count, SIZE_GRASS_CLUMP); clumpsBuffer.SetData(clumpsArray); shader.SetBuffer(kernelLeanGrass, "clumpsBuffer", clumpsBuffer); shader.SetFloat("maxLean", maxLean * Mathf.PI / 180); timeID = Shader.PropertyToID("time"); argsArray[0] = mesh.GetIndexCount(0); argsArray[1] = (uint)count; argsBuffer = new ComputeBuffer(1, 5 * sizeof(uint), ComputeBufferType.IndirectArguments); argsBuffer.SetData(argsArray); material.SetBuffer("clumpsBuffer", clumpsBuffer); material.SetFloat("_Scale", scale); }