Exemplo n.º 1
0
    void updateChunk(int chunkId)
    {
        ClayxelChunk chunk = this.chunks[chunkId];

        this.computeChunkPoints(chunk);

                #if DEBUGGRIDPOINTS
        return;
                #endif

        // generate point cloud
        chunk.chunkOutPointsBuffer.SetCounterValue(0);

        // Clayxel.claycoreCompute.SetBuffer((int)Kernels.genPointCloud, "indirectDrawArgs", chunk.clayxelShaderArgs);
        Clayxel.claycoreCompute.SetBuffer((int)Kernels.genPointCloud, "chunkOutPoints", chunk.chunkOutPointsBuffer);
        Clayxel.claycoreCompute.Dispatch((int)Kernels.genPointCloud, this.numThreadsCompute6, this.numThreadsCompute6, this.numThreadsCompute6);

        // clear chunk
        Clayxel.claycoreCompute.Dispatch((int)Kernels.clearChunkData, this.numThreadsCompute6, this.numThreadsCompute6, this.numThreadsCompute6);

        // set material params
        chunk.clayxelMaterial.SetFloat("_Smoothness", this.materialSmoothness);
        chunk.clayxelMaterial.SetFloat("_Metallic", this.materialMetallic);
        chunk.clayxelMaterial.SetColor("_Emission", this.materialEmission);
        chunk.clayxelMaterial.SetFloat("normalOrientedSplat", this.normalOrientedSplat);
        chunk.clayxelMaterial.SetFloat("splatSizeMult", this.splatSizeMultiplier);
    }
Exemplo n.º 2
0
    void debugDisplayPoints(ClayxelChunk chunk, int gridSideCount)
    {
        chunk.debugGridOutPointsBuffer.SetCounterValue(0);

        Clayxel.claycoreCompute.SetInt("debugGridSideCount", gridSideCount);

        Clayxel.claycoreCompute.SetBuffer((int)Kernels.debugDisplayGridPoints, "debugGridOutPoints", chunk.debugGridOutPointsBuffer);

        Clayxel.claycoreCompute.Dispatch((int)Kernels.debugDisplayGridPoints, gridSideCount, gridSideCount, gridSideCount);

        // ComputeBuffer.CopyCount(chunk.debugGridOutPointsBuffer, chunk.clayxelShaderArgs, 0);
    }
Exemplo n.º 3
0
    public void setPickingHighlight(int solidId)
    {
        if (solidId != this.pickingHighlight)
        {
            for (int chunkIt = 0; chunkIt < this.numChunks; ++chunkIt)
            {
                ClayxelChunk chunk = this.chunks[chunkIt];
                chunk.clayxelMaterial.SetInt("solidHighlightId", solidId);
            }
        }

        this.pickingHighlight = solidId;
    }
Exemplo n.º 4
0
    void initNewChunk(int x, int y, int z)
    {
        ClayxelChunk chunk = new ClayxelChunk();

        this.chunks.Add(chunk);

        float seamOffset       = this.chunkSize / 256.0f;   // removes the seam between chunks
        float chunkOffset      = this.chunkSize - seamOffset;
        float gridCenterOffset = (this.chunkSize * 0.5f);

        chunk.center = new Vector3(
            (-((this.chunkSize * this.numChunksX) * 0.5f) + gridCenterOffset) + (chunkOffset * x),
            (-((this.chunkSize * this.numChunksY) * 0.5f) + gridCenterOffset) + (chunkOffset * y),
            (-((this.chunkSize * this.numChunksZ) * 0.5f) + gridCenterOffset) + (chunkOffset * z));

        chunk.chunkOutPointsBuffer = new ComputeBuffer(this.chunkMaxOutPoints, sizeof(int) * 4, ComputeBufferType.Counter);
        this.compBuffers.Add(chunk.chunkOutPointsBuffer);

        chunk.clayxelShaderArgs = new ComputeBuffer(4, sizeof(int), ComputeBufferType.IndirectArguments);
        this.compBuffers.Add(chunk.clayxelShaderArgs);

        chunk.clayxelShaderArgs.SetData(new int[] { 0, 1, 0, 0 });

        chunk.clayxelMaterial        = new Material(Shader.Find("Clayxel/ClayxelSurfaceShader"));
        chunk.clayxelPickingMaterial = new Material(Shader.Find("Clayxel/ClayxelPickingShader"));

        chunk.clayxelMaterial.SetBuffer("chunkPoints", chunk.chunkOutPointsBuffer);

        chunk.clayxelPickingMaterial.SetBuffer("chunkPoints", chunk.chunkOutPointsBuffer);

                #if DEBUGGRIDPOINTS
        chunk.clayxelMaterial = new Material(Shader.Find("Clayxel/ClayxelDebugShader"));

        chunk.debugGridOutPointsBuffer = new ComputeBuffer(this.chunkMaxOutPoints, sizeof(float) * 3, ComputeBufferType.Counter);
        this.compBuffers.Add(chunk.debugGridOutPointsBuffer);

        chunk.clayxelMaterial.SetBuffer("debugChunkPoints", chunk.debugGridOutPointsBuffer);
                #endif

        chunk.clayxelMaterial.SetFloat("splatRadius", this.splatRadius);
        chunk.clayxelMaterial.SetFloat("chunkSize", (float)this.chunkSize);
        chunk.clayxelMaterial.SetVector("chunkCenter", chunk.center);
        chunk.clayxelMaterial.SetInt("solidHighlightId", -1);

        chunk.clayxelPickingMaterial.SetFloat("chunkSize", (float)this.chunkSize);
        chunk.clayxelPickingMaterial.SetVector("chunkCenter", chunk.center);
        chunk.clayxelPickingMaterial.SetFloat("splatRadius", this.splatRadius);
    }
Exemplo n.º 5
0
    void updateChunksTransform()
    {
        Vector3 scale      = this.transform.localScale;
        float   splatScale = (scale.x + scale.y + scale.z) / 3.0f;

        // clayxels are computed at the center of the world, so we need to transform them back when this transform is updated
        for (int chunkIt = 0; chunkIt < this.numChunks; ++chunkIt)
        {
            ClayxelChunk chunk = this.chunks[chunkIt];

            chunk.clayxelMaterial.SetMatrix("objectMatrix", this.transform.localToWorldMatrix);

            chunk.clayxelMaterial.SetFloat("splatRadius", this.splatRadius * splatScale);
            chunk.clayxelPickingMaterial.SetFloat("splatRadius", this.splatRadius * splatScale);
        }
    }
Exemplo n.º 6
0
    void computeChunkPoints(ClayxelChunk chunk)
    {
        Clayxel.claycoreCompute.SetVector("chunkCenter", chunk.center);
        Clayxel.claycoreCompute.Dispatch((int)Kernels.compute0, 1, 1, 1);
        Clayxel.claycoreCompute.Dispatch((int)Kernels.compute2, 1, 1, 1);
        Clayxel.claycoreCompute.Dispatch((int)Kernels.cache4, this.numThreadsCompute4, this.numThreadsCompute4, this.numThreadsCompute4);
        Clayxel.claycoreCompute.Dispatch((int)Kernels.compute4, this.numThreadsCompute4, this.numThreadsCompute4, this.numThreadsCompute4);

                #if DEBUGGRIDPOINTS
        this.debugDisplayPoints(chunk, 64);
        return;
                #endif

        Clayxel.claycoreCompute.Dispatch((int)Kernels.cache6, this.numThreadsCompute6, this.numThreadsCompute6, this.numThreadsCompute6);
        Clayxel.claycoreCompute.Dispatch((int)Kernels.compute6, this.numThreadsCompute6, this.numThreadsCompute6, this.numThreadsCompute6);
    }
Exemplo n.º 7
0
    public void updateSplatLook()
    {
        for (int chunkIt = 0; chunkIt < this.numChunks; ++chunkIt)
        {
            ClayxelChunk chunk = this.chunks[chunkIt];
            chunk.clayxelMaterial.SetTexture("_MainTex", this.splatTexture);

            if (this.splatTexture != null)
            {
                chunk.clayxelMaterial.EnableKeyword("SPLATTEXTURE_ON");
                chunk.clayxelMaterial.DisableKeyword("SPLATTEXTURE_OFF");
            }
            else
            {
                chunk.clayxelMaterial.DisableKeyword("SPLATTEXTURE_ON");
                chunk.clayxelMaterial.EnableKeyword("SPLATTEXTURE_OFF");
            }
        }
    }
Exemplo n.º 8
0
    public void drawClayxelPicking(int clayxelId)
    {
        if (this.needsInit)
        {
            return;
        }

        for (int chunkIt = 0; chunkIt < this.numChunks; ++chunkIt)
        {
            ClayxelChunk chunk = this.chunks[chunkIt];

            int numpoints = this.getBufferCount(chunk.chunkOutPointsBuffer) * 3;

            chunk.clayxelPickingMaterial.SetPass(0);
            chunk.clayxelPickingMaterial.SetMatrix("objectMatrix", this.transform.localToWorldMatrix);
            chunk.clayxelPickingMaterial.SetInt("clayxelId", clayxelId);

            Graphics.DrawProceduralNow(MeshTopology.Triangles, numpoints);
        }
    }
Exemplo n.º 9
0
    public void drawClayxels()
    {
        if (this.needsInit)
        {
            return;
        }

        // uncomment if full indirect
        // this.countBuffer.GetData(this.countBufferArray);// if I don't do at least one getdata of a buffer, everything goes SLOOOOOW, why?!?!?

        this.renderBounds.center = this.transform.position;
        this.renderBounds.size   = this.boundsScale;

        for (int chunkIt = 0; chunkIt < this.numChunks; ++chunkIt)
        {
            ClayxelChunk chunk = this.chunks[chunkIt];

                        #if DEBUGGRIDPOINTS
            int pnts = this.getBufferCount(chunk.debugGridOutPointsBuffer);
            Graphics.DrawProcedural(chunk.clayxelMaterial,
                                    this.renderBounds,
                                    MeshTopology.Points, pnts, 1);

            return;
                        #endif

            int numpoints = this.getBufferCount(chunk.chunkOutPointsBuffer) * 3;

            // Graphics.DrawProceduralIndirect(chunk.clayxelMaterial,
            //  this.renderBounds,
            //  MeshTopology.Triangles, chunk.clayxelShaderArgs, 0,//numpoints * 3, 1,
            //  null, null,
            //  ShadowCastingMode.TwoSided, true, this.gameObject.layer);

            Graphics.DrawProcedural(chunk.clayxelMaterial,
                                    this.renderBounds,
                                    MeshTopology.Triangles, numpoints, 1,
                                    null, null,
                                    ShadowCastingMode.TwoSided, true, this.gameObject.layer);
        }
    }
Exemplo n.º 10
0
    public void generateMesh()
    {
        this.meshCached = true;

        if (this.gameObject.GetComponent <MeshFilter>() == null)
        {
            this.gameObject.AddComponent <MeshFilter>();
        }

        MeshRenderer render = this.gameObject.GetComponent <MeshRenderer>();

        if (render == null)
        {
            render          = this.gameObject.AddComponent <MeshRenderer>();
            render.material = new Material(Shader.Find("Clayxel/ClayxelMeshShader"));
        }

        render.sharedMaterial.SetFloat("_Glossiness", this.materialSmoothness);
        render.sharedMaterial.SetFloat("_Metallic", this.materialMetallic);
        render.sharedMaterial.SetColor("_Emission", this.materialEmission);

        ComputeBuffer meshIndicesBuffer = new ComputeBuffer(this.chunkMaxOutPoints * 6, sizeof(float) * 3, ComputeBufferType.Counter);

        Clayxel.claycoreCompute.SetBuffer((int)Kernels.genMesh, "meshOutIndices", meshIndicesBuffer);

        ComputeBuffer meshVertsBuffer = new ComputeBuffer(this.chunkMaxOutPoints, sizeof(float) * 3, ComputeBufferType.Counter);

        Clayxel.claycoreCompute.SetBuffer((int)Kernels.genMesh, "meshOutPoints", meshVertsBuffer);

        ComputeBuffer meshColorsBuffer = new ComputeBuffer(this.chunkMaxOutPoints, sizeof(float) * 4);

        Clayxel.claycoreCompute.SetBuffer((int)Kernels.genMesh, "meshOutColors", meshColorsBuffer);

        List <Vector3> totalVertices = new List <Vector3>();
        List <int>     totalIndices  = new List <int>();
        List <Color>   totalColors   = new List <Color>();

        int totalNumVerts = 0;

        this.mesh             = new Mesh();
        this.mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;

        this.switchComputeData();

        this.updateSolids();

        Clayxel.claycoreCompute.SetInt("numSolids", this.clayObjects.Count);
        Clayxel.claycoreCompute.SetFloat("chunkSize", (float)this.chunkSize);

        Clayxel.claycoreCompute.SetFloat("surfaceBoundaryThreshold", 4.0f);         // compute more cells than needed to make sure we don't leave holes in the final mesh

        for (int chunkIt = 0; chunkIt < this.numChunks; ++chunkIt)
        {
            ClayxelChunk chunk = this.chunks[chunkIt];

            meshIndicesBuffer.SetCounterValue(0);
            meshVertsBuffer.SetCounterValue(0);

            this.computeChunkPoints(chunk);

            // dirty hack, calling this a second time will make sure we don't skip cells and there's no holes in the mesh
            this.computeChunkPoints(chunk);

            Clayxel.claycoreCompute.SetInt("outMeshIndexOffset", totalNumVerts);
            Clayxel.claycoreCompute.Dispatch((int)Kernels.genMesh, 16, 16, 16);

            Clayxel.claycoreCompute.Dispatch((int)Kernels.clearChunkData, this.numThreadsCompute6, this.numThreadsCompute6, this.numThreadsCompute6);

            int numVerts = this.getBufferCount(meshVertsBuffer);
            int numQuads = this.getBufferCount(meshIndicesBuffer) * 3;

            totalNumVerts += numVerts;

            Vector3[] vertices = new Vector3[numVerts];
            meshVertsBuffer.GetData(vertices);

            int[] indices = new int[numQuads];
            meshIndicesBuffer.GetData(indices);

            Color[] colors = new Color[numVerts];
            meshColorsBuffer.GetData(colors);

            totalVertices.AddRange(vertices);
            totalIndices.AddRange(indices);
            totalColors.AddRange(colors);
        }

        mesh.vertices  = totalVertices.ToArray();
        mesh.colors    = totalColors.ToArray();
        mesh.triangles = totalIndices.ToArray();

        this.mesh.Optimize();
        // this.mesh.RecalculateNormals();
        NormalSolver.RecalculateNormals(this.mesh, 120.0f);
        this.gameObject.GetComponent <MeshFilter>().mesh = this.mesh;

        meshIndicesBuffer.Release();
        meshVertsBuffer.Release();
        meshColorsBuffer.Release();

        this.releaseBuffers();
        this.needsInit = false;
    }