示例#1
0
        protected override void OnDisableFunc()
        {
            if (current != this)
            {
                return;
            }
            current = null;
            if (culledResultsBuffer != null)
            {
                culledResultsBuffer.Dispose();
            }
            if (loadedBuffer != null)
            {
                loadedBuffer.Dispose();
            }
            if (dispatchDrawBuffer != null)
            {
                dispatchDrawBuffer.Dispose();
            }
            if (loadedBufferList.isCreated)
            {
                loadedBufferList.Dispose();
            }
            tree.Dispose();
            vt.Dispose();
            loadDataList.Dispose();
            loader.Dispose();
            allLodLevles.Dispose();
            textureBuffer.Dispose();

            DestroyImmediate(albedoTex);
            DestroyImmediate(normalTex);
            DestroyImmediate(smTex);
            DestroyImmediate(mask);
        }
示例#2
0
        protected override void OnEnableFunc()
        {
            if (current && current != this)
            {
                enabled = false;
                Debug.LogError("Only One Terrain allowed!");
                return;
            }
            current = this;
            //virtualTexture = new VirtualTexture()
            basicChunkSize = (float)(chunkSize / pow(2.0, max(1, lodDistances.Length)));
            InitializeMesh();
            dispatchDrawBuffer = new ComputeBuffer(5, sizeof(int), ComputeBufferType.IndirectArguments);
            removeIndexBuffer  = new ComputeBuffer(10, sizeof(int2));
            const int INIT_LENGTH = 200;

            culledResultsBuffer = new ComputeBuffer(INIT_LENGTH, sizeof(int));
            loadedBuffer        = new ComputeBuffer(INIT_LENGTH, sizeof(TerrainChunkBuffer));
            loadedBufferList    = new NativeList <TerrainChunkBuffer>(INIT_LENGTH, Allocator.Persistent);
            shader = Resources.Load <ComputeShader>("TerrainCompute");
            NativeArray <uint> dispatchDraw = new NativeArray <uint>(5, Allocator.Temp, NativeArrayOptions.ClearMemory);

            dispatchDraw[0] = (uint)meshBuffer.count;
            dispatchDrawBuffer.SetData(dispatchDraw);

            loadedBufferList.Add(new TerrainChunkBuffer
            {
                minMaxHeight = 0,
                scale        = 10,
                worldPos     = 0
            });
            UpdateBuffer();
        }
示例#3
0
 protected override void OnDisableFunc()
 {
     if (current != this)
     {
         return;
     }
     current = null;
     if (meshBuffer != null)
     {
         meshBuffer.Dispose();
     }
     if (removeIndexBuffer != null)
     {
         removeIndexBuffer.Dispose();
     }
     if (culledResultsBuffer != null)
     {
         culledResultsBuffer.Dispose();
     }
     if (loadedBuffer != null)
     {
         loadedBuffer.Dispose();
     }
     if (dispatchDrawBuffer != null)
     {
         dispatchDrawBuffer.Dispose();
     }
     if (loadedBufferList.isCreated)
     {
         loadedBufferList.Dispose();
     }
 }
        protected override void OnDisableFunc()
        {
            if (current != this)
            {
                return;
            }
            current = null;
            if (culledResultsBuffer != null)
            {
                culledResultsBuffer.Dispose();
            }
            if (loadedBuffer != null)
            {
                loadedBuffer.Dispose();
            }
            if (dispatchDrawBuffer != null)
            {
                dispatchDrawBuffer.Dispose();
            }
            if (loadedBufferList.isCreated)
            {
                loadedBufferList.Dispose();
            }
            int2 len = allTrees.Length;

            for (int x = 0; x < len.x; ++x)
            {
                for (int y = 0; y < len.y; ++y)
                {
                    allTrees[int2(x, y)].Dispose();
                }
            }
            allTrees.Dispose();
        }
示例#5
0
        protected override void OnEnableFunc()
        {
            if (current && current != this)
            {
                enabled = false;
                Debug.LogError("Only One Terrain allowed!");
                return;
            }
            current = this;
            int indexMapSize = 1;

            for (int i = 1; i < lodDistances.Length; ++i)
            {
                indexMapSize *= 2;
            }
            indexMapSize *= chunkCount;
            NativeArray <VirtualTextureFormat> allFormats = new NativeArray <VirtualTextureFormat>(4, Allocator.Temp, NativeArrayOptions.UninitializedMemory);

            allFormats[0]  = new VirtualTextureFormat(VirtualTextureSize.x512, RenderTextureFormat.RHalf, "_VirtualHeightMap");
            allFormats[1]  = new VirtualTextureFormat(VirtualTextureSize.x1024, RenderTextureFormat.ARGB32, "_VirtualAlbedoMap");
            allFormats[2]  = new VirtualTextureFormat(VirtualTextureSize.x1024, RenderTextureFormat.ARGB32, "_VirtualNormalMap");
            allFormats[3]  = new VirtualTextureFormat(VirtualTextureSize.x1024, RenderTextureFormat.ARGB32, "_VirtualSMOMap");
            virtualTexture = new VirtualTexture(129, indexMapSize, allFormats);
            allFormats.Dispose();
            InitializeMesh();
            dispatchDrawBuffer = new ComputeBuffer(5, sizeof(int), ComputeBufferType.IndirectArguments);
            const int INIT_LENGTH = 500;

            culledResultsBuffer = new ComputeBuffer(INIT_LENGTH, sizeof(int));
            loadedBuffer        = new ComputeBuffer(INIT_LENGTH, sizeof(TerrainChunkBuffer));
            loadedBufferList    = new NativeList <TerrainChunkBuffer>(INIT_LENGTH, Allocator.Persistent);
            shader = Resources.Load <ComputeShader>("TerrainCompute");
            NativeArray <uint> dispatchDraw = new NativeArray <uint>(5, Allocator.Temp, NativeArrayOptions.ClearMemory);

            dispatchDraw[0] = (uint)meshBuffer.count;
            dispatchDrawBuffer.SetData(dispatchDraw);
            allTrees = new Native2DArray <TerrainQuadTree>(chunkCount, Allocator.Persistent, true);
            setting  = new TerrainQuadTreeSettings
            {
                allLodLevles     = new NativeList_Float(lodDistances.Length + 1, Allocator.Persistent),
                largestChunkSize = chunkSize,
                screenOffset     = chunkOffset
            };
            for (int i = 0; i < lodDistances.Length; ++i)
            {
                setting.allLodLevles.Add(min(lodDistances[max(0, i - 1)], lodDistances[i]));
                setting.allLodLevles[i] *= setting.allLodLevles[i];
            }
            setting.allLodLevles[lodDistances.Length] = 0;
            int2 len = allTrees.Length;

            for (int x = 0; x < len.x; ++x)
            {
                for (int y = 0; y < len.y; ++y)
                {
                    allTrees[int2(x, y)] = new TerrainQuadTree(-1, setting.Ptr(), TerrainQuadTree.LocalPos.LeftDown, 0, int2(x, y));
                }
            }
        }
        protected override void OnEnableFunc()
        {
            if (current && current != this)
            {
                enabled = false;
                Debug.LogError("Only One Terrain allowed!");
                return;
            }
            current = this;
            //virtualTexture = new VirtualTexture()
            basicChunkSize = (float)(chunkSize / pow(2.0, max(1, lodDistances.Length)));
            InitializeMesh();
            dispatchDrawBuffer = new ComputeBuffer(5, sizeof(int), ComputeBufferType.IndirectArguments);
            removeIndexBuffer  = new ComputeBuffer(10, sizeof(int2));
            const int INIT_LENGTH = 200;

            culledResultsBuffer = new ComputeBuffer(INIT_LENGTH, sizeof(int));
            loadedBuffer        = new ComputeBuffer(INIT_LENGTH, sizeof(TerrainChunkBuffer));
            loadedBufferList    = new NativeList <TerrainChunkBuffer>(INIT_LENGTH, Allocator.Persistent);
            shader = Resources.Load <ComputeShader>("TerrainCompute");
            NativeArray <uint> dispatchDraw = new NativeArray <uint>(5, Allocator.Temp, NativeArrayOptions.ClearMemory);

            dispatchDraw[0] = (uint)meshBuffer.count;
            dispatchDrawBuffer.SetData(dispatchDraw);
            allTrees = new Native2DArray <TerrainQuadTree>(chunkCount, Allocator.Persistent, true);
            setting  = new TerrainQuadTreeSettings
            {
                allLodLevles     = new NativeList_Float(lodDistances.Length + 1, Allocator.Persistent),
                largestChunkSize = chunkSize,
                screenOffset     = chunkOffset
            };
            for (int i = 0; i < lodDistances.Length; ++i)
            {
                setting.allLodLevles.Add(min(lodDistances[max(0, i - 1)], lodDistances[i]));
                setting.allLodLevles[i] *= setting.allLodLevles[i];
            }
            setting.allLodLevles[lodDistances.Length] = 0;
            int2 len = allTrees.Length;

            for (int x = 0; x < len.x; ++x)
            {
                for (int y = 0; y < len.y; ++y)
                {
                    allTrees[int2(x, y)] = new TerrainQuadTree(-1, setting.Ptr(), TerrainQuadTree.LocalPos.LeftDown, 0, int2(x, y));
                }
            }
        }
示例#7
0
        protected override void OnEnableFunc()
        {
            if (current && current != this)
            {
                enabled = false;
                Debug.LogError("Only One Terrain allowed!");
                return;
            }
            if (!terrainData)
            {
                enabled = false;
                Debug.LogError("No Data!");
                return;
            }
            msb           = new MStringBuilder(32);
            textureShader = Resources.Load <ComputeShader>("ProceduralTexture");
            shader        = Resources.Load <ComputeShader>("TerrainCompute");
            current       = this;
            int indexMapSize = 1;

            for (int i = 1; i < terrainData.lodDistances.Length; ++i)
            {
                indexMapSize *= 2;
            }
            dispatchDrawBuffer = new ComputeBuffer(5, sizeof(int), ComputeBufferType.IndirectArguments);
            const int INIT_LENGTH = 500;

            culledResultsBuffer = new ComputeBuffer(INIT_LENGTH, sizeof(int));
            loadedBuffer        = new ComputeBuffer(INIT_LENGTH, sizeof(TerrainChunkBuffer));
            loadedBufferList    = new NativeList <TerrainChunkBuffer>(INIT_LENGTH, Allocator.Persistent);
            lodOffset           = terrainData.lodDistances.Length - terrainData.renderingLevelCount;
            loader       = new VirtualTextureLoader(lodOffset, terrainData.renderingLevelCount, terrainData.readWritePath, this);
            loadDataList = new NativeQueue <TerrainLoadData>(100, Allocator.Persistent);
            NativeArray <uint> dispatchDraw = new NativeArray <uint>(5, Allocator.Temp, NativeArrayOptions.ClearMemory);

            dispatchDraw[0] = 96;
            dispatchDrawBuffer.SetData(dispatchDraw);
            VirtualTextureFormat *formats = stackalloc VirtualTextureFormat[]
            {
                new VirtualTextureFormat((VirtualTextureSize)HEIGHT_RESOLUTION, RenderTextureFormat.R16, "_VirtualHeightmap"),
                new VirtualTextureFormat((VirtualTextureSize)COLOR_RESOLUTION, RenderTextureFormat.ARGB32, "_VirtualMainTex"),
                new VirtualTextureFormat((VirtualTextureSize)COLOR_RESOLUTION, RenderTextureFormat.RGHalf, "_VirtualBumpMap"),
                new VirtualTextureFormat((VirtualTextureSize)COLOR_RESOLUTION, RenderTextureFormat.RG16, "_VirtualSMMap")
            };

            vt           = new VirtualTexture(terrainData.virtualTexCapacity, min(2048, (int)(pow(2.0, terrainData.lodDistances.Length) + 0.1)), formats, 4, "_TerrainVTIndexTex");
            allLodLevles = new NativeList_Float(terrainData.lodDistances.Length, Allocator.Persistent);
            for (int i = 0; i < terrainData.lodDistances.Length; ++i)
            {
                allLodLevles.Add(min(terrainData.lodDistances[max(0, i - 1)], terrainData.lodDistances[i]));
            }
            allLodLevles[terrainData.lodDistances.Length] = 0;

            albedoTex = new RenderTexture(new RenderTextureDescriptor
            {
                colorFormat       = RenderTextureFormat.ARGB32,
                dimension         = TextureDimension.Tex2DArray,
                width             = COLOR_RESOLUTION,
                height            = COLOR_RESOLUTION,
                volumeDepth       = Mathf.Max(1, terrainData.textures.Length),
                enableRandomWrite = true,
                msaaSamples       = 1
            });
            albedoTex.Create();
            normalTex = new RenderTexture(new RenderTextureDescriptor
            {
                colorFormat       = RenderTextureFormat.RGHalf,
                dimension         = TextureDimension.Tex2DArray,
                width             = COLOR_RESOLUTION,
                height            = COLOR_RESOLUTION,
                volumeDepth       = Mathf.Max(1, terrainData.textures.Length),
                enableRandomWrite = true,
                msaaSamples       = 1
            });
            normalTex.Create();
            smTex = new RenderTexture(new RenderTextureDescriptor
            {
                colorFormat       = RenderTextureFormat.RG16,
                dimension         = TextureDimension.Tex2DArray,
                width             = COLOR_RESOLUTION,
                height            = COLOR_RESOLUTION,
                volumeDepth       = Mathf.Max(1, terrainData.textures.Length),
                enableRandomWrite = true,
                msaaSamples       = 1
            });
            smTex.Create();
            smTex.wrapMode     = TextureWrapMode.Repeat;
            normalTex.wrapMode = TextureWrapMode.Repeat;
            albedoTex.wrapMode = TextureWrapMode.Repeat;
            mask = new RenderTexture(new RenderTextureDescriptor
            {
                colorFormat       = RenderTextureFormat.R8,
                dimension         = TextureDimension.Tex2D,
                width             = MASK_RESOLUTION,
                height            = MASK_RESOLUTION,
                volumeDepth       = 1,
                enableRandomWrite = true,
                msaaSamples       = 1
            });
            mask.Create();
            textureBuffer = new ComputeBuffer(max(MASK_RESOLUTION * MASK_RESOLUTION / 4, HEIGHT_RESOLUTION * HEIGHT_RESOLUTION / 2), 4);
            tree          = new TerrainQuadTree(-1, TerrainQuadTree.LocalPos.LeftDown, 0, terrainData.largestChunkSize);
            StartCoroutine(AsyncLoader());
        }

        void UpdateBuffer()
        {
            if (!loadedBufferList.isCreated)
            {
                return;
            }
            if (loadedBufferList.Length > loadedBuffer.count)
            {
                loadedBuffer.Dispose();
                culledResultsBuffer.Dispose();
                loadedBuffer        = new ComputeBuffer(loadedBufferList.Capacity, sizeof(TerrainChunkBuffer));
                culledResultsBuffer = new ComputeBuffer(loadedBufferList.Capacity, sizeof(int));
            }
            loadedBuffer.SetDataPtr(loadedBufferList.unsafePtr, loadedBufferList.Length);
        }
        void OnFinishRead(AsyncGPUReadbackRequest request)
        {
            bool useConnection = false;

            commandQueue.TryDequeue(out useConnection);
            float    depth    = request.GetData <float>().Element(0);
            float4x4 invvp    = (GL.GetGPUProjectionMatrix(cam.projectionMatrix, false) * cam.worldToCameraMatrix).inverse;
            float4   worldPos = mul(invvp, float4(uv * 2 - 1, depth, 1));

            worldPos.xyz /= worldPos.w;
            MTerrain terrain = MTerrain.current;

            if (!terrain)
            {
                return;
            }
            NativeList <ulong> allMaskTree = new NativeList <ulong>(5, Allocator.Temp);

            value = Mathf.Clamp(value, 0, terrain.terrainData.allMaterials.Length - 1);
            terrain.treeRoot->GetMaterialMaskRoot(worldPos.xz, paintRange, ref allMaskTree);
            terrainEditShader.SetInt(ShaderIDs._Count, MTerrain.MASK_RESOLUTION);
            if (!useConnection)
            {
                //TODO
                terrainEditShader.SetVector("_Circle0", float4(worldPos.xz, paintRange, 1));
                terrainEditShader.SetVector("_Circle1", float4(worldPos.xz, paintRange, 1));
                terrainEditShader.SetMatrix("_QuadMatrix", float4x4(0));
            }
            else
            {
                terrain.treeRoot->GetMaterialMaskRoot(lastFrameWorldPos.xz, paintRange, ref allMaskTree);
                float2 moveDir = lastFrameWorldPos.xz - worldPos.xz;
                float  len     = length(moveDir);
                moveDir /= len;
                float    dotMove      = dot(moveDir, moveDir);
                float2   verticleDir  = float2(-moveDir.y / dotMove, moveDir.x / dotMove);
                float3x3 localToWorld = float3x3(float3(moveDir * len, 0), float3(verticleDir * paintRange * 2, 0), float3((lastFrameWorldPos.xz + worldPos.xz) * 0.5f, 1));
                float3x3 worldToLocal = inverse(localToWorld);
                terrainEditShader.SetVector("_Circle0", float4(worldPos.xz, paintRange, 1));
                terrainEditShader.SetVector("_Circle1", float4(lastFrameWorldPos.xz, paintRange, 1));
                terrainEditShader.SetMatrix("_QuadMatrix", float4x4(float4(worldToLocal.c0, 0), float4(worldToLocal.c1, 0), float4(worldToLocal.c2, 0), 0));
            }
            const int disp = MTerrain.MASK_RESOLUTION / 8;

            foreach (var i in allMaskTree)
            {
                var treeNodePtr = (TerrainQuadTree *)i;
                if (treeNodePtr == null)
                {
                    continue;
                }
                int2 maskPos  = treeNodePtr->rootPos + (int2)treeNodePtr->maskScaleOffset.yz;
                int  texIndex = terrain.maskVT.GetChunkIndex(maskPos);
                if (texIndex < 0)
                {
                    continue;
                }
                terrainEditShader.SetVector("_SrcDestCorner", (float4)treeNodePtr->BoundedWorldPos);
                terrainEditShader.SetInt(ShaderIDs._OffsetIndex, texIndex);
                PaintMask(terrain, treeNodePtr, texIndex, disp);
            }
            if (!useConnection)
            {
                terrain.treeRoot->UpdateChunks(double3(worldPos.xz, paintRange));
            }
            else
            {
                terrain.treeRoot->UpdateChunks(double3(0.5f * (worldPos.xz + lastFrameWorldPos.xz), 0.5f * distance(worldPos.xz, lastFrameWorldPos.xz) + paintRange));
            }
            lastFrameWorldPos = worldPos.xyz;
        }
 void PaintMask(MTerrain terrain, TerrainQuadTree *treeNodePtr, int texIndex, int disp)
 {
     terrainEditShader.SetTexture(1, ShaderIDs._DestTex, terrain.maskVT.GetTexture(0));
     terrainEditShader.SetFloat("_TargetValue", saturate((float)((value + 0.1) / (terrain.terrainData.allMaterials.Length - 1))));
     terrainEditShader.Dispatch(1, disp, disp, 1);
 }