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); }
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); }
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; }
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); }
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); } }
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); }
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"); } } }
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); } }
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); } }
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; }