コード例 #1
0
ファイル: TerrainNodePage.cs プロジェクト: yf885188/GPUDriven
 public TerrainNodePage(Rect r, int m)
 {
     this.rect  = r;
     this.mip   = m;
     this.Info  = new NodeInfo(new float4(r.xMin, r.yMin, r.width, r.height), m);
     this.index = -1;
     if (this.mip > 0)
     {
         children    = new TerrainNodePage[4];
         children[0] = new TerrainNodePage(new Rect(r.xMin, r.yMin, r.width / 2, r.height / 2), m - 1);
         children[1] = new TerrainNodePage(new Rect(r.xMin + r.width / 2, r.yMin, r.width / 2, r.height / 2), m - 1);
         children[2] = new TerrainNodePage(new Rect(r.xMin + r.width / 2, r.yMin + r.height / 2, r.width / 2, r.height / 2), m - 1);
         children[3] = new TerrainNodePage(new Rect(r.xMin, r.yMin + r.height / 2, r.width / 2, r.height / 2), m - 1);
     }
 }
コード例 #2
0
    void OnEnable()
    {
        if (pageRoot == null)
        {
            float perSize = 64;
            var   rect    = new Rect(0, 0, terrain.terrainData.size.x, terrain.terrainData.size.z);
            pageRoot = new TerrainNodePage(rect);
            var children = new List <TerrainNodePage>();
            for (var i = rect.xMin; i < rect.xMax; i += perSize)
            {
                for (var j = rect.yMin; j < rect.yMax; j += perSize)
                {
                    children.Add(new TerrainNodePage(new Rect(i, j, perSize, perSize), 3));
                }
            }
            pageRoot.children = children.ToArray();
        }
        allNodeInfo = new List <NodeInfo>();
        var camPos = Camera.main.transform.position;
        var center = new Vector2(camPos.x, camPos.z);

        pageRoot.CollectNodeInfo(center, allNodeInfo);
        for (var i = 0; i < allNodeInfo.Count; i++)
        {
            var nodeInfo   = allNodeInfo[i];
            var nodeCenter = new Vector2(nodeInfo.rect.x + nodeInfo.rect.z * 0.5f, nodeInfo.rect.y + nodeInfo.rect.w * 0.5f);
            var topNode    = pageRoot.GetActiveNode(nodeCenter + new Vector2(0, nodeInfo.rect.w));
            var bottomNode = pageRoot.GetActiveNode(nodeCenter + new Vector2(0, -nodeInfo.rect.w));
            var leftNode   = pageRoot.GetActiveNode(nodeCenter + new Vector2(-nodeInfo.rect.z, 0));
            var rightNode  = pageRoot.GetActiveNode(nodeCenter + new Vector2(nodeInfo.rect.z, 0));
            var nei        = new bool4(topNode != null && topNode.mip > nodeInfo.mip,
                                       bottomNode != null && bottomNode.mip > nodeInfo.mip,
                                       leftNode != null && leftNode.mip > nodeInfo.mip,
                                       rightNode != null && rightNode.mip > nodeInfo.mip);
            nodeInfo.neighbor = (1 * (nei.x ? 1 : 0)) + ((1 << 1) * (nei.y ? 1 : 0)) + ((1 << 2) * (nei.z ? 1 : 0)) + ((1 << 3) * (nei.w ? 1 : 0));
            allNodeInfo[i]    = nodeInfo;
        }

        heightmapTex = terrain.terrainData.heightmapTexture;
        normalTex    = new Texture2D(heightmapTex.width, heightmapTex.height, TextureFormat.RGBA32, -1, true);
        var colors = new Color[heightmapTex.width * heightmapTex.width];
        int index  = 0;

        for (int i = 0; i < heightmapTex.width; i++)
        {
            for (int j = 0; j < heightmapTex.height; j++)
            {
                var normal = terrain.terrainData.GetInterpolatedNormal((float)i / heightmapTex.width, (float)j / heightmapTex.height);
                colors[index++] = new Color(normal.z * 0.5f + 0.5f, normal.y * 0.5f + 0.5f, normal.x * 0.5f + 0.5f);
            }
        }
        normalTex.SetPixels(colors);
        normalTex.Apply();

        allInstancesPosWSBuffer = new ComputeBuffer(allNodeInfo.Count, sizeof(float) * 4 + sizeof(int) + sizeof(int));
        allInstancesPosWSBuffer.SetData(allNodeInfo.ToArray());

        visibleInstancesOnlyPosWSIDBuffer = new ComputeBuffer(allNodeInfo.Count, sizeof(uint), ComputeBufferType.Append);

        if (argsBuffer != null)
        {
            argsBuffer.Release();
        }
        uint[] args = new uint[5] {
            0, 0, 0, 0, 0
        };
        argsBuffer = new ComputeBuffer(1, args.Length * sizeof(uint), ComputeBufferType.IndirectArguments);

        args[0] = (uint)instanceMesh.GetIndexCount(0);
        args[1] = (uint)allNodeInfo.Count;
        args[2] = (uint)instanceMesh.GetIndexStart(0);
        args[3] = (uint)instanceMesh.GetBaseVertex(0);
        args[4] = 0;

        argsBuffer.SetData(args);

        if (shadowBuffer != null)
        {
            shadowBuffer.Release();
        }
        shadowBuffer = new ComputeBuffer(1, args.Length * sizeof(uint), ComputeBufferType.IndirectArguments);
        shadowBuffer.SetData(args);

        cullTerrainKernel       = this.cullingComputeShader.FindKernel("CullTerrain");
        cullTerrainShadowKernel = this.cullingComputeShader.FindKernel("CullTerrainShadow");
        cullingComputeShader.SetBuffer(cullTerrainKernel, "_AllInstancesPosWSBuffer", allInstancesPosWSBuffer);
        cullingComputeShader.SetBuffer(cullTerrainKernel, "_VisibleInstancesOnlyPosWSIDBuffer", visibleInstancesOnlyPosWSIDBuffer);
        cullingComputeShader.SetTexture(cullTerrainKernel, "_HeightMap", heightmapTex);

        cullingComputeShader.SetBuffer(cullTerrainShadowKernel, "_AllInstancesPosWSBuffer", allInstancesPosWSBuffer);
        cullingComputeShader.SetBuffer(cullTerrainShadowKernel, "_VisibleInstancesOnlyPosWSIDBuffer", visibleInstancesOnlyPosWSIDBuffer);
        cullingComputeShader.SetTexture(cullTerrainShadowKernel, "_HeightMap", heightmapTex);
        cullingComputeShader.SetFloat("_TerrainHeightSize", 2 * terrain.terrainData.size.y);
        mat.SetBuffer("_AllInstancesTransformBuffer", allInstancesPosWSBuffer);
        mat.SetBuffer("_VisibleInstanceOnlyTransformIDBuffer", visibleInstancesOnlyPosWSIDBuffer);

        Shader.SetGlobalTexture("_TerrainHeightmapTexture", heightmapTex);
        Shader.SetGlobalTexture("_TerrainNormalmapTexture", normalTex);
        Shader.SetGlobalVector("terrainParam", terrain.terrainData.size);

        debugtex = new RenderTexture(1024, 1024, 0, UnityEngine.Experimental.Rendering.DefaultFormat.LDR);
        debugtex.enableRandomWrite = true;

        ShadowUtils.CustomRenderShadowSlice += this.RenderShadowmap;
        GPUTerrainPass.ExecuteAction        += Render;
    }