SubsurfaceScatteringParameters PrepareSubsurfaceScatteringParameters(HDCamera hdCamera) { var parameters = new SubsurfaceScatteringParameters(); parameters.subsurfaceScatteringCS = m_SubsurfaceScatteringCS; parameters.subsurfaceScatteringCS.shaderKeywords = null; if (asset.currentPlatformRenderPipelineSettings.increaseSssSampleCount) { m_SubsurfaceScatteringCS.EnableKeyword("SSS_ENABLE_NEAR_FIELD"); } if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.MSAA)) { m_SubsurfaceScatteringCS.EnableKeyword("ENABLE_MSAA"); } parameters.subsurfaceScatteringCSKernel = m_SubsurfaceScatteringKernel; parameters.needTemporaryBuffer = NeedTemporarySubsurfaceBuffer() || hdCamera.frameSettings.IsEnabled(FrameSettingsField.MSAA); parameters.copyStencilForSplitLighting = m_SSSCopyStencilForSplitLighting; parameters.combineLighting = m_CombineLightingPass; parameters.texturingModeFlags = m_SSSTexturingModeFlags; parameters.numTilesX = ((int)hdCamera.screenSize.x + 15) / 16; parameters.numTilesY = ((int)hdCamera.screenSize.y + 15) / 16; parameters.numTilesZ = hdCamera.viewCount; parameters.worldScales = m_SSSWorldScales; parameters.filterKernels = m_SSSFilterKernels; parameters.shapeParams = m_SSSShapeParams; parameters.diffusionProfileHashes = m_SSSDiffusionProfileHashes; parameters.coarseStencilBuffer = m_SharedRTManager.GetCoarseStencilBuffer(); return(parameters); }
protected void GetPoints(Vector3 chunkIndex) { chunkIndex *= chunkSize; int threadsPerAxis = Mathf.CeilToInt(PointsPerAxis / 8f); if (useNoise) { noiseDensityCompute.shaderKeywords = null; switch (noiseType) { case NoiseType.Perlin: noiseDensityCompute.EnableKeyword("PNOISE"); break; case NoiseType.Simplex: noiseDensityCompute.EnableKeyword("SNOISE"); break; default: Debug.LogError("INVALID OPTION"); break; } noiseDensityCompute.SetVector("offset", chunkIndex); noiseDensityCompute.Dispatch(0, threadsPerAxis, threadsPerAxis, threadsPerAxis); } else { functionDensityCompute.SetVector("offset", chunkIndex); functionDensityCompute.Dispatch(0, threadsPerAxis, threadsPerAxis, threadsPerAxis); } }
public static void EnableKeywords(this ComputeShader _computeShader, string[] _keywords, int _target) { for (int i = 0; i < _keywords.Length; i++) { _computeShader.EnableKeyword(_keywords[i], i + 1 == _target); } }
void Start() { #if UNITY_ANDROID && !UNITY_EDITOR format = GraphicsFormat.RGBA_ETC2_UNorm; shader.EnableKeyword("_COMPRESS_ETC2"); #else format = GraphicsFormat.RGBA_DXT5_UNorm; //shader.DisableKeyword("_COMPRESS_ETC2"); #endif kernelHandle = shader.FindKernel("CSMain"); tex = new RenderTexture(64, 64, 24) { format = RenderTextureFormat.ARGB32, enableRandomWrite = true, }; tex.Create(); //tt.text = format.ToString() + SystemInfo.IsFormatSupported(format, FormatUsage.Linear).ToString() + SystemInfo.supportsComputeShaders + SystemInfo.copyTextureSupport; shader.SetTexture(kernelHandle, "Result", tex); shader.SetTexture(kernelHandle, "RenderTexture0", _mask); shader.SetInts("DestRect", DestRect); shader.Dispatch(kernelHandle, (256 / 4 + 7) / 8, (256 / 4 + 7) / 8, 1); copyTex = new Texture2D(256, 256, format, TextureCreationFlags.None); Graphics.CopyTexture(tex, 0, 0, 0, 0, 64, 64, copyTex, 0, 0, 0, 0); _mat = GetComponent <MeshRenderer>().sharedMaterial; _mat.mainTexture = copyTex; }
SubsurfaceScatteringParameters PrepareSubsurfaceScatteringParameters(HDCamera hdCamera) { var parameters = new SubsurfaceScatteringParameters(); parameters.subsurfaceScatteringCS = m_SubsurfaceScatteringCS; parameters.subsurfaceScatteringCS.shaderKeywords = null; if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.MSAA)) { m_SubsurfaceScatteringCS.EnableKeyword("ENABLE_MSAA"); } parameters.subsurfaceScatteringCSKernel = m_SubsurfaceScatteringKernel; parameters.needTemporaryBuffer = NeedTemporarySubsurfaceBuffer() || hdCamera.frameSettings.IsEnabled(FrameSettingsField.MSAA); parameters.copyStencilForSplitLighting = m_SSSCopyStencilForSplitLighting; parameters.combineLighting = m_CombineLightingPass; parameters.texturingModeFlags = m_SSSTexturingModeFlags; parameters.numTilesX = ((int)hdCamera.screenSize.x + 15) / 16; parameters.numTilesY = ((int)hdCamera.screenSize.y + 15) / 16; parameters.numTilesZ = hdCamera.viewCount; parameters.sampleBudget = hdCamera.frameSettings.sssResolvedSampleBudget; parameters.worldScalesAndFilterRadiiAndThicknessRemaps = m_SSSWorldScalesAndFilterRadiiAndThicknessRemaps; parameters.shapeParamsAndMaxScatterDists = m_SSSShapeParamsAndMaxScatterDists; parameters.diffusionProfileHashes = m_SSSDiffusionProfileHashes; parameters.coarseStencilBuffer = m_SharedRTManager.GetCoarseStencilBuffer(); return(parameters); }
void InitializeParticles() { // Max number of thread groups per dimension is 65535 in D3D11 // D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION (65535). if (numberOfParticles > m_particleThreadsPerGroup * 65535) { numberOfParticles = m_particleThreadsPerGroup * 65535; } m_particleThreadGroups = numberOfParticles / m_particleThreadsPerGroup; Debug.Log("Particles: " + numberOfParticles + " Thread groups: " + m_particleThreadGroups); Particle[] data = new Particle[numberOfParticles]; particleBuffer = new ComputeBuffer(data.Length, System.Runtime.InteropServices.Marshal.SizeOf <Particle>()); particleBuffer.SetData(data); _particleCount = numberOfParticles; //initialize particles with random positions computeShader.SetInt("numberOfParticles", numberOfParticles); computeShader.SetBuffer(kernelParticleInit, "particleBuffer", particleBuffer); computeShader.SetBuffer(kernelParticleStep, "particleBuffer", particleBuffer); computeShader.EnableKeyword("Mode1"); Dispatch(kernelParticleInit, m_particleThreadGroups, 1, 1); }
void Start() { _kernel = shader.FindKernel("CSMain"); //Quad texture RenderTexture tex = new RenderTexture(size, size, 0, GraphicsFormat.R32G32B32A32_SFloat); tex.enableRandomWrite = true; tex.Create(); _mat.SetTexture("_MainTex", tex); shader.SetTexture(_kernel, "Result", tex); shader.SetInt("size", size); //Spheres particleArray = new Particle[spheres.Length]; cBuffer = new ComputeBuffer(particleArray.Length, 12 + 12); cBuffer.SetData(particleArray); shader.SetBuffer(_kernel, "particleBuffer", cBuffer); shader.SetInt("particleCount", particleArray.Length); //draw type switch (drawType) { case 1: shader.EnableKeyword("CURVEDSTAIGHTLINE"); shader.DisableKeyword("DRAWLINE"); shader.DisableKeyword("CIRCLES"); break; case 2: shader.EnableKeyword("CIRCLES"); shader.DisableKeyword("DRAWLINE"); shader.DisableKeyword("CURVEDSTAIGHTLINE"); break; default: shader.EnableKeyword("DRAWLINE"); shader.DisableKeyword("CURVEDSTAIGHTLINE"); shader.DisableKeyword("CIRCLES"); break; } }
//Compute Shader public static void EnableKeyword(this ComputeShader _computeShader, string _keyword, bool _enable) { if (_enable) { _computeShader.EnableKeyword(_keyword); } else { _computeShader.DisableKeyword(_keyword); } }
SubsurfaceScatteringParameters PrepareSubsurfaceScatteringParameters(HDCamera hdCamera) { var parameters = new SubsurfaceScatteringParameters(); parameters.subsurfaceScatteringCS = m_SubsurfaceScatteringCS; parameters.subsurfaceScatteringCS.shaderKeywords = null; if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.MSAA)) { m_SubsurfaceScatteringCS.EnableKeyword("ENABLE_MSAA"); } parameters.subsurfaceScatteringCSKernel = m_SubsurfaceScatteringKernel; parameters.needTemporaryBuffer = NeedTemporarySubsurfaceBuffer() || hdCamera.frameSettings.IsEnabled(FrameSettingsField.MSAA); parameters.copyStencilForSplitLighting = m_SSSCopyStencilForSplitLighting; parameters.combineLighting = m_CombineLightingPass; parameters.numTilesX = ((int)hdCamera.screenSize.x + 15) / 16; parameters.numTilesY = ((int)hdCamera.screenSize.y + 15) / 16; parameters.numTilesZ = hdCamera.viewCount; parameters.sampleBudget = hdCamera.frameSettings.sssResolvedSampleBudget; return(parameters); }
public void BuildPipeline() { if (IsInitialized) { return; } if (m_PathTracingShader == null) { return; } if (m_Camera == null) { return; } m_KernelIndex = m_PathTracingShader.FindKernel(m_KernelName); if (m_KernelIndex < 0) { return; } if (m_EnableNEE) { m_PathTracingShader.EnableKeyword("ENABLE_NEXT_EVENT_ESTIMATION"); } else { m_PathTracingShader.DisableKeyword("ENABLE_NEXT_EVENT_ESTIMATION"); } if (m_EnableThinLens) { m_PathTracingShader.EnableKeyword("ENABLE_THIN_LENS"); } else { m_PathTracingShader.DisableKeyword("ENABLE_THIN_LENS"); } if (m_EnableSampleTexture) { m_PathTracingShader.EnableKeyword("ENABLE_SAMPLE_TEXTURE"); } else { m_PathTracingShader.DisableKeyword("ENABLE_SAMPLE_TEXTURE"); } if (m_EnableTangentSpace) { m_PathTracingShader.EnableKeyword("ENABLE_TANGENT_SPACE"); } else { m_PathTracingShader.DisableKeyword("ENABLE_TANGENT_SPACE"); } m_RenderTexture = new RenderTexture(Screen.width, Screen.height, 0, RenderTextureFormat.ARGBFloat); m_RenderTexture.enableRandomWrite = true; m_RenderTexture.Create(); m_DispatchThreadGroupsX = Mathf.CeilToInt((float)m_RenderTexture.width / kTileSize); m_DispatchThreadGroupsY = Mathf.CeilToInt((float)m_RenderTexture.height / kTileSize); List <PTMaterial> materials; List <Primitive> primitives; List <Texture2D> baseColorTextures = null; List <Texture2D> mroTextures = null; List <Texture2D> normalTextures = null; if (m_EnableSampleTexture) { baseColorTextures = new List <Texture2D>(); } if (m_EnableTangentSpace) { mroTextures = new List <Texture2D>(); normalTextures = new List <Texture2D>(); } CollectPrimitives(out materials, out primitives, ref baseColorTextures, ref mroTextures, ref normalTextures); BVH bvhTree = new BVH(); bvhTree.Build(primitives); List <Sphere> spheres; List <Quad> quads; List <Cube> cubes; List <Triangle> triangles; List <LBVHNode> bvh; int bvhRoot = BuildLBVH(bvhTree, out bvh, out spheres, out quads, out cubes, out triangles); if (m_EnableSampleTexture) { m_baseColorTextureArray = CreateTextureArray(baseColorTextures); m_PathTracingShader.SetTexture(m_KernelIndex, "_Textures", m_baseColorTextureArray); } if (m_EnableTangentSpace) { m_mroTextureArray = CreateTextureArray(mroTextures); m_normalTextureArray = CreateTextureArray(normalTextures); m_PathTracingShader.SetTexture(m_KernelIndex, "_MROTextures", m_mroTextureArray); m_PathTracingShader.SetTexture(m_KernelIndex, "_NormalTextures", m_normalTextureArray); } m_NodesBuffer = CreateComputeBuffer <LBVHNode>(bvh); m_SpheresBuffer = CreateComputeBuffer <Sphere>(spheres); m_QuadsBuffer = CreateComputeBuffer <Quad>(quads); m_CubeBuffer = CreateComputeBuffer <Cube>(cubes); m_TrianglesBuffer = CreateComputeBuffer <Triangle>(triangles); m_MaterialsBuffer = CreateComputeBuffer <PTMaterial>(materials); m_PathTracingShader.SetBuffer(m_KernelIndex, "_Spheres", m_SpheresBuffer); m_PathTracingShader.SetBuffer(m_KernelIndex, "_Quads", m_QuadsBuffer); m_PathTracingShader.SetBuffer(m_KernelIndex, "_Cubes", m_CubeBuffer); m_PathTracingShader.SetBuffer(m_KernelIndex, "_Triangles", m_TrianglesBuffer); m_PathTracingShader.SetBuffer(m_KernelIndex, "_BVHTree", m_NodesBuffer); m_PathTracingShader.SetBuffer(m_KernelIndex, "_Materials", m_MaterialsBuffer); m_PathTracingShader.SetInt("_BVHRootNodeIndex", bvhRoot); m_PathTracingShader.SetInt("_BVHNodeCount", bvh.Count); IsInitialized = true; m_PathTracingShader.SetTexture(m_KernelIndex, "_Result", m_RenderTexture); m_PathTracingShader.SetInt("_ScreenWidth", m_RenderTexture.width); m_PathTracingShader.SetInt("_ScreenHeight", m_RenderTexture.height); Debug.Log($"BVH Root:{bvhRoot}, BVH Childs:{bvh.Count}"); }
/// <summary> /// Generates a heightmap with fractal noise and a sine wave for farmland grooves, uses compute shaders. /// Author: Glyn Marcus Leine & Maurijn Besters /// </summary> public Texture2D CreateHeightmap(float gridX, float gridY) { if (!m_heightShader) { m_heightShader = Resources.Load <ComputeShader>("Compute/Height"); if (!m_heightShader) { Debug.LogError("Could not load height compute shader."); return(null); } m_heightKernel = m_heightShader.FindKernel("CSHeight"); m_heightShader.GetKernelThreadGroupSizes(m_heightKernel, out m_heightGlobal.x, out m_heightGlobal.y, out m_heightGlobal.z); } var generator = TerrainGenerator.instance; RenderTexture target = new RenderTexture(generator.textureWidth, generator.textureHeight, 1, RenderTextureFormat.ARGBFloat); target.enableRandomWrite = true; target.Create(); if (generator.includeSineWave) { m_heightShader.EnableKeyword("SINE_WAVE_ON"); } else { m_heightShader.DisableKeyword("SINE_WAVE_ON"); } m_heightShader.SetTexture(m_heightKernel, "target", target); m_heightShader.SetFloats("resolutionData", generator.textureWidth, generator.textureHeight, 1f / generator.textureWidth, 1f / generator.textureHeight); m_heightShader.SetFloat("chunkSize", generator.maximumChunkSize); m_heightShader.SetInt("octaves", generator.PerlinOctaves); m_heightShader.SetFloat("amplitude", generator.PerlinBaseAmplitude); m_heightShader.SetFloat("persistence", generator.persistence); m_heightShader.SetFloat("lacunarity", generator.lacunarity); Vector2[] octaveOffsets = new Vector2[generator.PerlinOctaves]; System.Random prng = new System.Random(generator.Seed); Vector2 offset = new Vector2(prng.Next(-100000, 100000) - generator.xOffset - (generator.maximumChunkSize * gridX), prng.Next(-100000, 100000) - generator.yOffset - (generator.maximumChunkSize * gridY)); float maxPossibleHeight = 0; float amplitude = generator.PerlinBaseAmplitude; for (int i = 0; i < generator.PerlinOctaves; i++) { octaveOffsets[i] = new Vector2(offset.x, offset.y); maxPossibleHeight += amplitude; amplitude *= generator.persistence; } ComputeBuffer octaveOffsetsBuffer = new ComputeBuffer(generator.PerlinOctaves, sizeof(float) * 2, ComputeBufferType.Structured, ComputeBufferMode.Dynamic); octaveOffsetsBuffer.SetData(octaveOffsets); m_heightShader.SetBuffer(m_heightKernel, "octaveOffsets", octaveOffsetsBuffer); m_heightShader.SetFloat("perlinScale", 1f / generator.PerlinScale); m_heightShader.SetFloat("normalizeScale", 1f / maxPossibleHeight); m_heightShader.SetFloat("halfSineAmplitude", generator.sinAmplitude * 0.5f); m_heightShader.SetFloat("sinePeriod", generator.sinPeriod); m_heightShader.SetFloat("chunkOffsetX", generator.xOffset - (generator.maximumChunkSize * gridX)); m_heightShader.SetFloat("perlinNoiseWeight", generator.perlinNoiseWeight); Vector3Int dispatchGroupSize = new Vector3Int(generator.textureWidth / (int)m_heightGlobal.x, generator.textureHeight / (int)m_heightGlobal.y, 1); m_heightShader.Dispatch(m_heightKernel, dispatchGroupSize.x, dispatchGroupSize.y, dispatchGroupSize.z); Texture2D heightMapTexture = new Texture2D(generator.textureWidth, generator.textureHeight, TextureFormat.RGBAFloat, true); RenderTexture.active = target; heightMapTexture.ReadPixels(new Rect(0, 0, generator.textureWidth, generator.textureHeight), 0, 0, true); heightMapTexture.filterMode = FilterMode.Bilinear; heightMapTexture.wrapMode = TextureWrapMode.Clamp; heightMapTexture.Apply(false, false); RenderTexture.active = null; target.Release(); target.DiscardContents(); octaveOffsetsBuffer.Release(); octaveOffsetsBuffer.Dispose(); return(heightMapTexture); }
void UpdateFunctionOnGPU() { int resolution_ = resolution / 4; resolution_ *= 4; float step = size / (float)resolution_; isoValsShader.SetInt(resolutionId, resolution_); isoValsShader.SetFloat(stepId, step); // duration += Time.deltaTime; // isoValsShader.SetFloat(sId, (shapeSize * (((Mathf.Sin(5f * duration) + 2f) * 0.5f)))); // isoValsShader.SetFloat(sId, shapeSize); isoValsShader.SetFloat(timeId, Time.time); isoValsShader.SetMatrix(gridToWorldID, this.transform.localToWorldMatrix); isoValsShader.SetMatrixArray(shapeToWorldID, shape.Select(v => v.transform.localToWorldMatrix.inverse).ToArray()); isoValsShader.SetBuffer(0, isoValsId, isoValsBuffer); int groups = Mathf.CeilToInt(resolution_ / 4f); isoValsShader.EnableKeyword(FunctionLibrary.GetName(shapeFunction)); isoValsShader.Dispatch(0, groups, groups, groups); isoValsShader.DisableKeyword(FunctionLibrary.GetName(shapeFunction)); var bounds = new Bounds(Vector3.zero, Vector3.one * (size + step)); if (showGrid) { transparencyMaterial.SetBuffer(isoValsId, isoValsBuffer); transparencyMaterial.SetFloat(stepId, step); transparencyMaterial.SetInt(resolutionId, resolution_); transparencyMaterial.SetMatrix(gridToWorldID, this.transform.localToWorldMatrix); transparencyMaterial.SetVector(viewDirID, -Camera.main.transform.forward); transparencyMaterial.SetFloat(pointBrightnessID, pointBrightness); transparencyMaterial.SetFloat(pointSizeID, pointSize); Graphics.DrawMeshInstancedProcedural(pointMesh, 0, transparencyMaterial, bounds, resolution_ * resolution_ * resolution_); } if (showVolume) { material.SetBuffer(isoValsId, isoValsBuffer); material.SetFloat(stepId, step); material.SetInt(resolutionId, resolution_); material.SetMatrix(gridToWorldID, this.transform.localToWorldMatrix); material.SetVector(viewDirID, -Camera.main.transform.forward); material.SetFloat(pointBrightnessID, pointBrightness); material.SetFloat(pointSizeID, pointSize); Graphics.DrawMeshInstancedProcedural(pointMesh, 0, material, bounds, resolution_ * resolution_ * resolution_); } // surface points surfacePointsShader.SetInt(resolutionId, resolution_); surfacePointsShader.SetMatrix(gridToWorldID, this.transform.localToWorldMatrix); surfacePointsShader.SetMatrixArray(shapeToWorldID, shape.Select(v => v.transform.localToWorldMatrix.inverse).ToArray()); surfacePointsShader.SetFloat(stepId, step); surfacePointsShader.SetBuffer(0, isoValsId, isoValsBuffer); surfacePointsShader.SetBuffer(0, surfacePointsId, surfacePointsBuffer); surfacePointsShader.SetBuffer(0, normalsId, normalsBuffer); surfacePointsShader.EnableKeyword(FunctionLibrary.GetName(shapeFunction)); surfacePointsShader.EnableKeyword(GetSurfacePointsFuncName(surfacePointsFunc)); // surfacePointsShader.SetMatrixArray(shapeToWorldID, shape.Select(v => v.transform.localToWorldMatrix).ToArray()); surfacePointsShader.Dispatch(0, groups, groups, groups); surfacePointsShader.DisableKeyword(FunctionLibrary.GetName(shapeFunction)); surfacePointsShader.DisableKeyword(GetSurfacePointsFuncName(surfacePointsFunc)); // var data = new Vector3[resolution_*resolution_*resolution_]; // surfacePointsBuffer.GetData(data); // print(data[10]); if (showSurface) { surfacePointMaterial.SetFloat(stepId, step); surfacePointMaterial.SetInt(resolutionId, resolution_); surfacePointMaterial.SetMatrix(gridToWorldID, this.transform.localToWorldMatrix); surfacePointMaterial.SetVector(viewDirID, -Camera.main.transform.forward); surfacePointMaterial.SetFloat(pointSizeID, pointSize); surfacePointMaterial.SetBuffer(surfacePointsId, surfacePointsBuffer); surfacePointMaterial.SetBuffer(normalsId, normalsBuffer); Graphics.DrawMeshInstancedProcedural(pointMesh, 0, surfacePointMaterial, bounds, resolution_ * resolution_ * resolution_); } Mesh mesh = GetComponent <MeshFilter>().mesh; mesh.Clear(); if (showMesh) { // construct mesh meshBuffer.SetCounterValue(0); int meshKernel = 0; meshShader.SetInt(resolutionId, resolution_); meshShader.SetMatrix(gridToWorldID, this.transform.localToWorldMatrix); meshShader.SetFloat(stepId, step); meshShader.SetBuffer(meshKernel, isoValsId, isoValsBuffer); meshShader.SetBuffer(meshKernel, surfacePointsId, surfacePointsBuffer); meshShader.SetBuffer(meshKernel, normalsId, normalsBuffer); meshShader.SetBuffer(meshKernel, meshId, meshBuffer); meshShader.EnableKeyword(FunctionLibrary.GetName(shapeFunction)); meshShader.Dispatch(meshKernel, groups, groups, groups); meshShader.DisableKeyword(FunctionLibrary.GetName(shapeFunction)); // Copy the count. ComputeBuffer.CopyCount(meshBuffer, argsBuffer, 0); // TODO: do not retrieve from GPU. write a compute shader to adjust count: https://gist.github.com/DuncanF/353509dd397ea5f292fa52d1b9b5133d // Retrieve it into array. int[] args = new int[4]; argsBuffer.GetData(args); // Actual count in append buffer. args[0] *= 1; // verts per triangle // args[2] += 1; // verts per triangle argsBuffer.SetData(args); fixArgs.SetBuffer(0, "DrawCallArgs", argsBuffer); fixArgs.Dispatch(0, 1, 1, 1); argsBuffer.GetData(args); args[0] *= 2; var meshArr = new Vector4[args[0]]; meshBuffer.GetData(meshArr); var verts3 = new Vector3[args[0]]; // var verts4 = new Vector4[args[0]]; var normals3 = new Vector3[args[0]]; for (int i = 0; i < args[0]; i += 2) { verts3[i / 2] = new Vector3(meshArr[i].x, meshArr[i].y, meshArr[i].z); // verts4[i / 2] = meshArr[i]; normals3[i / 2] = new Vector3(meshArr[i + 1].x, meshArr[i + 1].y, meshArr[i + 1].z); } mesh.vertices = verts3; mesh.normals = normals3; var tris = new int[verts3.Length]; for (int i = 0; i < verts3.Length; i++) { tris[i] = i; } mesh.triangles = tris; if (renderMode == RenderMode.Wireframe) { var indices = new int[verts3.Length / 3 * 6]; for (int i = 0, j = 0; i < indices.Length; i += 6, j += 3) { indices[i] = j; indices[i + 1] = j + 1; indices[i + 2] = j + 1; indices[i + 3] = j + 2; indices[i + 4] = j; indices[i + 5] = j + 2; } mesh.SetIndices(indices, MeshTopology.Lines, 0); } // TODO: custom render shader (URP shader graph) that gets verts from buffer, use vert id, create variant of urp standard // see info at bottom for vert id info?: https://docs.unity3d.com/Manual/SL-ShaderSemantics.html // https://samdriver.xyz/article/compute-shader-intro // https://cyangamedev.wordpress.com/2020/06/05/urp-shader-code/ // https://gist.github.com/phi-lira/225cd7c5e8545be602dca4eb5ed111ba // meshBufferFloat.SetData(verts4); // // if (showMesh) { // meshMaterial.SetPass(0); // meshMaterial.SetMatrix(gridToWorldID, this.transform.localToWorldMatrix); // meshMaterial.SetBuffer(meshId, meshBufferFloat); // Graphics.DrawProceduralIndirect(meshMaterial, bounds, MeshTopology.Triangles, argsBuffer, 0, null, null, UnityEngine.Rendering.ShadowCastingMode.On, true); } }