private void RenderAsSolid() { CreateSolidMaterial(); // TODO: camera var mainCamera = Camera.main; if (mainCamera == null) { return; } var width = mainCamera.pixelWidth; var height = mainCamera.pixelHeight; var screenRescaleMultiplier = 1f; if (SolidFovReprojection && PreserveTexelSize) { screenRescaleMultiplier = GetFovReprojectionMultiplier(mainCamera); width = (int)(width * screenRescaleMultiplier); height = (int)(height * screenRescaleMultiplier); } var fov = mainCamera.fieldOfView; if (SolidFovReprojection) { fov *= ReprojectionRatio; } var size = Math.Max(Mathf.NextPowerOfTwo(width), Mathf.NextPowerOfTwo(height)); if (rt == null || rt.width != width || rt.height != height) { if (rt != null) { rt.Release(); } rt = new RenderTexture(width, height, 24, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear); rt.enableRandomWrite = true; rt.autoGenerateMips = false; rt.useMipMap = false; rt.Create(); if (rt1 != null) { rt1.Release(); } rt1 = new RenderTexture(size, size, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear); rt1.enableRandomWrite = true; rt1.autoGenerateMips = false; rt1.useMipMap = true; rt1.Create(); if (rtPos != null) { rtPos.Release(); } rtPos = new RenderTexture(width, height, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear); rtPos.enableRandomWrite = true; rtPos.autoGenerateMips = false; rtPos.useMipMap = false; rtPos.Create(); if (rtColor != null) { rtColor.Release(); } rtColor = new RenderTexture(width, height, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear); rtColor.enableRandomWrite = true; rtColor.autoGenerateMips = false; rtColor.useMipMap = true; rtColor.Create(); if (rt2 != null) { rt2.Release(); } rt2 = new RenderTexture(width, height, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear); rt2.enableRandomWrite = true; rt2.autoGenerateMips = false; rt2.useMipMap = true; rt2.Create(); } if (TemporalSmoothing && (rtPreviousColor == null || rtPreviousColor.width != width || rtPreviousColor.height != height)) { previousFrameDataAvailable = false; if (rtPreviousColor != null) { rtPreviousColor.Release(); } rtPreviousColor = new RenderTexture(width, height, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear); rtPreviousColor.enableRandomWrite = true; rtPreviousColor.autoGenerateMips = false; rtPreviousColor.useMipMap = false; rtPreviousColor.Create(); if (rtPreviousPos != null) { rtPreviousPos.Release(); } rtPreviousPos = new RenderTexture(width, height, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear); rtPreviousPos.enableRandomWrite = true; rtPreviousPos.autoGenerateMips = false; rtPreviousPos.useMipMap = false; rtPreviousPos.Create(); } var maxLevel = 0; while ((size >> maxLevel) > 8) { maxLevel++; } Graphics.SetRenderTarget(new[] { rt.colorBuffer, rtPos.colorBuffer }, rt.depthBuffer); GL.Clear(true, true, Color.clear); var proj = GetProjectionMatrix(mainCamera, true); var invProj = proj.inverse; SolidRenderMaterial.SetInt(ShaderVariables.SolidRender.Colorize, (int)Colorize); SolidRenderMaterial.SetFloat(ShaderVariables.SolidRender.MinHeight, Bounds.min.y); SolidRenderMaterial.SetFloat(ShaderVariables.SolidRender.MaxHeight, Bounds.max.y); SolidRenderMaterial.SetMatrix(ShaderVariables.SolidRender.MVMatrix, mainCamera.worldToCameraMatrix * transform.localToWorldMatrix); SolidRenderMaterial.SetMatrix(ShaderVariables.SolidRender.ProjectionMatrix, GetProjectionMatrix(mainCamera)); SolidRenderMaterial.SetPass(0); Graphics.DrawProceduralNow(MeshTopology.Points, PointCount); var setupClear = SolidComputeShader.FindKernel(ShaderVariables.SolidCompute.SetupClear.KernelName); SolidComputeShader.SetTexture(setupClear, ShaderVariables.SolidCompute.SetupClear.Position, rt1, 0); SolidComputeShader.SetTexture(setupClear, ShaderVariables.SolidCompute.SetupClear.Color, rtColor, 0); SolidComputeShader.Dispatch(setupClear, size / 8, size / 8, 1); var setupCopy = SolidComputeShader.FindKernel(ShaderVariables.SolidCompute.SetupCopy.KernelName); SolidComputeShader.SetFloat(ShaderVariables.SolidCompute.SetupCopy.FarPlane, mainCamera.farClipPlane); SolidComputeShader.SetTexture(setupCopy, ShaderVariables.SolidCompute.SetupCopy.InputColor, rt, 0); SolidComputeShader.SetTexture(setupCopy, ShaderVariables.SolidCompute.SetupCopy.InputPosition, rtPos, 0); SolidComputeShader.SetTexture(setupCopy, ShaderVariables.SolidCompute.SetupCopy.OutputPosition, rt1, 0); SolidComputeShader.SetTexture(setupCopy, ShaderVariables.SolidCompute.SetupCopy.OutputColor, rtColor, 0); SolidComputeShader.SetMatrix(ShaderVariables.SolidCompute.SetupCopy.InverseProjectionMatrix, invProj); SolidComputeShader.Dispatch(setupCopy, size / 8, size / 8, 1); if (SolidRemoveHidden) { var posMax = new[] { width - 1, height - 1 }; var downsample = SolidComputeShader.FindKernel(ShaderVariables.SolidCompute.Downsample.KernelName); for (var i = 1; i <= maxLevel + 3; i++) { SolidComputeShader.SetInts(ShaderVariables.SolidCompute.Downsample.PosMax, posMax); posMax[0] = (posMax[0] + 1) / 2 - 1; posMax[1] = (posMax[1] + 1) / 2 - 1; SolidComputeShader.SetTexture(downsample, ShaderVariables.SolidCompute.Downsample.InputPosition, rt1, i - 1); SolidComputeShader.SetTexture(downsample, ShaderVariables.SolidCompute.Downsample.OutputPosition, rt1, i); SolidComputeShader.Dispatch(downsample, Math.Max(1, (size >> i) / 8), Math.Max(1, (size >> i) / 8), 1); } DebugSolidFixedLevel = Math.Min(Math.Max(DebugSolidFixedLevel, 0), maxLevel); var removeHidden = DebugShowRemoveHiddenCascades ? SolidComputeShader.FindKernel(ShaderVariables.SolidCompute.RemoveHidden.DebugKernelName) : SolidComputeShader.FindKernel(ShaderVariables.SolidCompute.RemoveHidden.KernelName); var removeHiddenMagic = RemoveHiddenCascadeOffset * height * 0.5f / Mathf.Tan(0.5f * fov * Mathf.Deg2Rad); SolidComputeShader.SetInt(ShaderVariables.SolidCompute.RemoveHidden.LevelCount, maxLevel); SolidComputeShader.SetTexture(removeHidden, ShaderVariables.SolidCompute.RemoveHidden.Position, rt1); SolidComputeShader.SetTexture(removeHidden, ShaderVariables.SolidCompute.RemoveHidden.Color, rtColor, 0); SolidComputeShader.SetTexture(removeHidden, ShaderVariables.SolidCompute.RemoveHidden.DepthBuffer, rt2, 0); SolidComputeShader.SetFloat(ShaderVariables.SolidCompute.RemoveHidden.CascadesOffset, removeHiddenMagic); SolidComputeShader.SetFloat(ShaderVariables.SolidCompute.RemoveHidden.CascadesSize, RemoveHiddenCascadeSize); SolidComputeShader.SetInt(ShaderVariables.SolidCompute.RemoveHidden.FixedLevel, DebugSolidFixedLevel); SolidComputeShader.Dispatch(removeHidden, size / 8, size / 8, 1); if (TemporalSmoothing) { var curProj = GetProjectionMatrix(mainCamera); var curView = mainCamera.worldToCameraMatrix; var prevToCurrent = curView * previousView.inverse; previousView = curView; if (previousFrameDataAvailable) { var applyPrevious = SolidComputeShader.FindKernel(ShaderVariables.SolidCompute.ApplyPreviousFrame.KernelName); SolidComputeShader.SetTexture(applyPrevious, ShaderVariables.SolidCompute.ApplyPreviousFrame.SavedColor, rtPreviousColor, 0); SolidComputeShader.SetTexture(applyPrevious, ShaderVariables.SolidCompute.ApplyPreviousFrame.SavedPos, rtPreviousPos, 0); SolidComputeShader.SetTexture(applyPrevious, ShaderVariables.SolidCompute.ApplyPreviousFrame.CurrentColor, rtColor, 0); SolidComputeShader.SetTexture(applyPrevious, ShaderVariables.SolidCompute.ApplyPreviousFrame.CurrentPos, rt2, 0); if (UsingVulkan) { SolidComputeShader.SetTexture(applyPrevious, ShaderVariables.SolidCompute.ApplyPreviousFrame.CurrentColorIn, rtColor, 0); SolidComputeShader.SetTexture(applyPrevious, ShaderVariables.SolidCompute.ApplyPreviousFrame.CurrentPosIn, rt2, 0); } SolidComputeShader.SetMatrix(ShaderVariables.SolidCompute.ApplyPreviousFrame.PrevToCurrentMatrix, prevToCurrent); SolidComputeShader.SetMatrix(ShaderVariables.SolidCompute.ApplyPreviousFrame.ProjectionMatrix, curProj); SolidComputeShader.SetFloat(ShaderVariables.SolidCompute.ApplyPreviousFrame.FramePersistence, 1f / InterpolatedFrames); SolidComputeShader.Dispatch(applyPrevious, size / 8, size / 8, 1); } else { previousFrameDataAvailable = true; } var copyFrame = SolidComputeShader.FindKernel(ShaderVariables.SolidCompute.CopyFrame.KernelName); SolidComputeShader.SetTexture(copyFrame, ShaderVariables.SolidCompute.CopyFrame.InputColor, rtColor); SolidComputeShader.SetTexture(copyFrame, ShaderVariables.SolidCompute.CopyFrame.InputPos, rt2); SolidComputeShader.SetTexture(copyFrame, ShaderVariables.SolidCompute.CopyFrame.OutputColor, rtPreviousColor, 0); SolidComputeShader.SetTexture(copyFrame, ShaderVariables.SolidCompute.CopyFrame.OutputPos, rtPreviousPos, 0); SolidComputeShader.Dispatch(copyFrame, size / 8, size / 8, 1); } else if (previousFrameDataAvailable) { previousFrameDataAvailable = false; } } if (DebugSolidPullPush) { var pullKernel = SolidComputeShader.FindKernel(ShaderVariables.SolidCompute.PullKernel.KernelName); SolidComputeShader.SetFloat(ShaderVariables.SolidCompute.PullKernel.FilterExponent, DebugSolidPullParam); for (var i = 1; i <= maxLevel; i++) { SolidComputeShader.SetBool(ShaderVariables.SolidCompute.PullKernel.SkipWeightMul, i == maxLevel); SolidComputeShader.SetInt(ShaderVariables.SolidCompute.PullKernel.InputLevel, i - 1); SolidComputeShader.SetTexture(pullKernel, ShaderVariables.SolidCompute.PullKernel.InputColor, rtColor, i - 1); SolidComputeShader.SetTexture(pullKernel, ShaderVariables.SolidCompute.PullKernel.OutputColor, rtColor, i); SolidComputeShader.SetTexture(pullKernel, ShaderVariables.SolidCompute.PullKernel.InputDepth, rt2, i - 1); SolidComputeShader.SetTexture(pullKernel, ShaderVariables.SolidCompute.PullKernel.OutputDepth, rt2, i); SolidComputeShader.Dispatch(pullKernel, Math.Max(1, (size >> i) / 8), Math.Max(1, (size >> i) / 8), 1); } var pushKernel = SolidComputeShader.FindKernel(ShaderVariables.SolidCompute.PushKernel.KernelName); for (var i = maxLevel; i > 0; i--) { SolidComputeShader.SetInt(ShaderVariables.SolidCompute.PushKernel.InputLevel, i); SolidComputeShader.SetTexture(pushKernel, ShaderVariables.SolidCompute.PushKernel.InputColor, rtColor, i); SolidComputeShader.SetTexture(pushKernel, ShaderVariables.SolidCompute.PushKernel.OutputColor, rtColor, i - 1); SolidComputeShader.SetTexture(pushKernel, ShaderVariables.SolidCompute.PushKernel.InputDepth, rt2, i); SolidComputeShader.SetTexture(pushKernel, ShaderVariables.SolidCompute.PushKernel.OutputDepth, rt2, i - 1); SolidComputeShader.Dispatch(pushKernel, Math.Max(1, (size >> (i - 1)) / 8), Math.Max(1, (size >> (i - 1)) / 8), 1); } var calculateNormalsKernel = SolidComputeShader.FindKernel(ShaderVariables.SolidCompute.CalculateNormals.KernelName); for (var i = 0; i < maxLevel; ++i) { if (UsingVulkan) { SolidComputeShader.SetInt(ShaderVariables.SolidCompute.CalculateNormals.InputLevel, i); SolidComputeShader.SetTexture(calculateNormalsKernel, ShaderVariables.SolidCompute.CalculateNormals.Input, rt2); SolidComputeShader.SetTexture(calculateNormalsKernel, ShaderVariables.SolidCompute.CalculateNormals.Output, rt2, i); } else { SolidComputeShader.SetTexture(calculateNormalsKernel, ShaderVariables.SolidCompute.CalculateNormals.InputOutput, rt2, i); } SolidComputeShader.Dispatch(calculateNormalsKernel, Math.Max(1, (size >> i) / 8), Math.Max(1, (size >> i) / 8), 1); } var smoothNormalsKernel = DebugShowSmoothNormalsCascades ? SolidComputeShader.FindKernel(ShaderVariables.SolidCompute.SmoothNormals.DebugKernelName) : SolidComputeShader.FindKernel(ShaderVariables.SolidCompute.SmoothNormals.KernelName); var smoothNormalsMagic = SmoothNormalsCascadeOffset * height * 0.5f / Mathf.Tan(0.5f * fov * Mathf.Deg2Rad); SolidComputeShader.SetTexture(smoothNormalsKernel, ShaderVariables.SolidCompute.SmoothNormals.Input, rt2); SolidComputeShader.SetTexture(smoothNormalsKernel, ShaderVariables.SolidCompute.SmoothNormals.Output, rt1, 0); SolidComputeShader.SetFloat(ShaderVariables.SolidCompute.SmoothNormals.CascadesOffset, smoothNormalsMagic); SolidComputeShader.SetFloat(ShaderVariables.SolidCompute.SmoothNormals.CascadesSize, SmoothNormalsCascadeSize); if (DebugShowSmoothNormalsCascades) { SolidComputeShader.SetTexture(smoothNormalsKernel, ShaderVariables.SolidCompute.SmoothNormals.ColorDebug, rtColor, 0); } SolidComputeShader.Dispatch(smoothNormalsKernel, size / 8, size / 8, 1); } DebugSolidBlitLevel = Math.Min(Math.Max(DebugSolidBlitLevel, 0), maxLevel); SolidBlitMaterial.SetTexture(ShaderVariables.SolidBlit.ColorTex, rtColor); SolidBlitMaterial.SetTexture(ShaderVariables.SolidBlit.NormalDepthTex, rt1); SolidBlitMaterial.SetFloat(ShaderVariables.SolidBlit.FarPlane, mainCamera.farClipPlane); SolidBlitMaterial.SetFloat(ShaderVariables.SolidBlit.UvMultiplier, screenRescaleMultiplier); SolidBlitMaterial.SetInt(ShaderVariables.SolidBlit.DebugLevel, DebugSolidBlitLevel); SolidBlitMaterial.SetMatrix(ShaderVariables.SolidBlit.ReprojectionMatrix, GetReprojectionMatrix(mainCamera)); SolidBlitMaterial.SetMatrix(ShaderVariables.SolidBlit.InverseProjectionMatrix, GL.GetGPUProjectionMatrix(mainCamera.projectionMatrix, false).inverse); SetSolidBlitType(); Graphics.DrawProcedural(SolidBlitMaterial, GetWorldBounds(), MeshTopology.Triangles, 3, camera: mainCamera, layer: 1); }
public static GPUVoxelData Voxelize(ComputeShader voxelizer, Mesh mesh, int count = 32, bool volume = true, bool pow2 = false) { mesh.RecalculateBounds(); var vertices = mesh.vertices; var vertBuffer = new ComputeBuffer(vertices.Length, Marshal.SizeOf(typeof(Vector3))); vertBuffer.SetData(vertices); var uvBuffer = new ComputeBuffer(vertBuffer.count, Marshal.SizeOf(typeof(Vector2))); if (mesh.uv.Length > 0) { var uv = mesh.uv; uvBuffer.SetData(uv); } var triangles = mesh.triangles; var triBuffer = new ComputeBuffer(triangles.Length, Marshal.SizeOf(typeof(int))); triBuffer.SetData(triangles); var bounds = mesh.bounds; var maxLength = Mathf.Max(bounds.size.x, Mathf.Max(bounds.size.y, bounds.size.z)); var unit = maxLength / count; var size = bounds.size; int w, h, d; if (!pow2) { w = Mathf.CeilToInt(size.x / unit); h = Mathf.CeilToInt(size.y / unit); d = Mathf.CeilToInt(size.z / unit); } else { w = GetNearPow2(size.x / unit); h = GetNearPow2(size.y / unit); d = GetNearPow2(size.z / unit); } var voxelBuffer = new ComputeBuffer(w * h * d, Marshal.SizeOf(typeof(Voxel_t))); var kernel = new Kernel(voxelizer, volume ? kVolumeKernelKey : kSurfaceKernelKey); // send bounds voxelizer.SetVector(kStartKey, bounds.min); voxelizer.SetVector(kEndKey, bounds.max); voxelizer.SetVector(kSizeKey, bounds.size); voxelizer.SetFloat(kUnitKey, unit); voxelizer.SetFloat(kInvUnitKey, 1f / unit); voxelizer.SetFloat(kHalfUnitKey, unit * 0.5f); voxelizer.SetInt(kWidthKey, w); voxelizer.SetInt(kHeightKey, h); voxelizer.SetInt(kDepthKey, d); // send mesh data voxelizer.SetBuffer(kernel.Index, kVertBufferKey, vertBuffer); voxelizer.SetBuffer(kernel.Index, kUVBufferKey, uvBuffer); voxelizer.SetInt(kTriCountKey, triBuffer.count); voxelizer.SetBuffer(kernel.Index, kTriBufferKey, triBuffer); voxelizer.SetBuffer(kernel.Index, kVoxelBufferKey, voxelBuffer); voxelizer.Dispatch(kernel.Index, w / (int)kernel.ThreadX + 1, h / (int)kernel.ThreadY + 1, (int)kernel.ThreadZ); // dispose vertBuffer.Release(); uvBuffer.Release(); triBuffer.Release(); return(new GPUVoxelData(voxelBuffer, w, h, d, unit)); }
// Update is called once per frame void Update() { transform.RotateAround(new Vector3(scaleX / 2, scaleY / 2, scaleZ / 2), Vector3.up, cameraSpeed * Time.deltaTime); //float[] mousePosition2D = { cursorPos.x, cursorPos.y }; // Send datas to the compute shader computeShader.SetFloat("deltaTime", Time.deltaTime); computeShader.SetFloat("time", Time.time); computeShader.SetFloat("boundaryForceFactor", boundaryForceFactor); computeShader.SetFloat("gradientFactor", gradientFactor); computeShader.SetFloat("vNoiseFactor", vNoiseFactor); computeShader.SetFloat("sNoiseFactor", sNoiseFactor); computeShader.SetFloat("vNoiseTimeScale", vNoiseTimeScale); computeShader.SetFloat("sNoiseTimeScale", sNoiseTimeScale); //computeShader.SetInt("resX", resX); //computeShader.SetInt("resY", resY); //computeShader.SetInt("resZ", resZ); computeShader.SetInt("scaleX", scaleX); computeShader.SetInt("scaleY", scaleY); computeShader.SetInt("scaleZ", scaleZ); computeShader.SetFloat("delta", delta); computeShader.SetFloat("seedShift", seedShift); computeShader.SetFloat("voronoiFreq", voronoiFreq); computeShader.SetFloat("voronoiAmp", voronoiAmp); computeShader.SetFloat("voronoiJitter", voronoiJitter); computeShader.SetInt("voronoiOctaves", voronoiOctaves); // Update the Particles computeShader.Dispatch(mComputeShaderKernelID, mWarpCount, 1, 1); }
/// <summary> /// Set the terrain settings to a compute shader. Used for Terrain generation on the GPU and for /// Collision calculations on the GPU. /// </summary> /// <param name="shader">The ComputeShader to set the values for.</param> /// <param name="settings">The settings where the values come from</param> public static void TransferTerrainGeneratorSettingsToComputeShader(ComputeShader shader, TerrainGeneratorSettings settings) { shader.SetFloat("_gridSize", settings.gridSize); shader.SetFloat("_pow1", settings.pow1); shader.SetFloat("_pow2", settings.pow2); shader.SetFloat("_pow3", settings.pow3); shader.SetFloat("_pow4", settings.pow4); shader.SetFloat("_pow5", settings.pow5); shader.SetFloat("_pow6", settings.pow6); shader.SetFloat("_pow7", settings.pow7); shader.SetFloat("_scale1", settings.scale1); shader.SetFloat("_scale2", settings.scale2); shader.SetFloat("_scale3", settings.scale3); shader.SetFloat("_scale4", settings.scale4); shader.SetFloat("_scale5", settings.scale5); shader.SetFloat("_scale6", settings.scale6); shader.SetFloat("_scale7", settings.scale7); shader.SetFloat("_height1", settings.height1); shader.SetFloat("_height3", settings.height3); shader.SetFloat("_height4", settings.height4); shader.SetFloat("_height5", settings.height5); shader.SetFloat("_scaleMultiplier", settings.multiplierScale); shader.SetFloat("_weightMultiplier", settings.weightMultiplier2); shader.SetFloat("_temperatureScale", settings.temperatureScale); shader.SetFloat("_temperatureBlend", settings.temperatureBlend); shader.SetFloat("_temperatureRandom", settings.temperatureRandom); shader.SetFloat("_snowRandom", settings.snowRandom); shader.SetFloat("_sandRandom", settings.sandRandom); shader.SetFloat("_snowBlend", settings.snowBlend); shader.SetFloat("_sandBlend", settings.sandBlend); shader.SetVector("_offset", settings.offset); shader.SetBool("_splat", settings.splat); }
public static GPUVoxelData Voxelize(ComputeShader voxelizer, Mesh mesh, Bounds bounds, int resolution = 32, bool volume = true, bool pow2 = false) { var vertices = mesh.vertices; var vertBuffer = new ComputeBuffer(vertices.Length, Marshal.SizeOf(typeof(Vector3))); vertBuffer.SetData(vertices); var uvBuffer = new ComputeBuffer(vertBuffer.count, Marshal.SizeOf(typeof(Vector2))); if (mesh.uv.Length > 0) { var uv = mesh.uv; uvBuffer.SetData(uv); } var triangles = mesh.triangles; var triBuffer = new ComputeBuffer(triangles.Length, Marshal.SizeOf(typeof(int))); triBuffer.SetData(triangles); var maxLength = Mathf.Max(bounds.size.x, Mathf.Max(bounds.size.y, bounds.size.z)); var unit = maxLength / resolution; var hunit = unit * 0.5f; // Extend (min & max) to voxelize boundary surface correctly. var start = bounds.min - new Vector3(hunit, hunit, hunit); var end = bounds.max + new Vector3(hunit, hunit, hunit); var size = end - start; int w, h, d; if (!pow2) { w = Mathf.CeilToInt(size.x / unit); h = Mathf.CeilToInt(size.y / unit); d = Mathf.CeilToInt(size.z / unit); } else { w = GetNearPow2(size.x / unit); h = GetNearPow2(size.y / unit); d = GetNearPow2(size.z / unit); } var voxelBuffer = new ComputeBuffer(w * h * d, Marshal.SizeOf(typeof(Voxel_t))); var voxels = new Voxel_t[voxelBuffer.count]; voxelBuffer.SetData(voxels); // initialize voxels explicitly // send bounds voxelizer.SetVector(kStartKey, start); voxelizer.SetVector(kEndKey, end); voxelizer.SetVector(kSizeKey, size); voxelizer.SetFloat(kUnitKey, unit); voxelizer.SetFloat(kInvUnitKey, 1f / unit); voxelizer.SetFloat(kHalfUnitKey, hunit); voxelizer.SetInt(kWidthKey, w); voxelizer.SetInt(kHeightKey, h); voxelizer.SetInt(kDepthKey, d); // send mesh data voxelizer.SetInt(kTriCountKey, triBuffer.count); var indexes = triBuffer.count / 3; voxelizer.SetInt(kTriIndexesKey, indexes); // surface front var surfaceFrontKer = new Kernel(voxelizer, kSurfaceFrontKernelKey); voxelizer.SetBuffer(surfaceFrontKer.Index, kVertBufferKey, vertBuffer); voxelizer.SetBuffer(surfaceFrontKer.Index, kUVBufferKey, uvBuffer); voxelizer.SetBuffer(surfaceFrontKer.Index, kTriBufferKey, triBuffer); voxelizer.SetBuffer(surfaceFrontKer.Index, kVoxelBufferKey, voxelBuffer); voxelizer.Dispatch(surfaceFrontKer.Index, indexes / (int)surfaceFrontKer.ThreadX + 1, (int)surfaceFrontKer.ThreadY, (int)surfaceFrontKer.ThreadZ); // surface back var surfaceBackKer = new Kernel(voxelizer, kSurfaceBackKernelKey); voxelizer.SetBuffer(surfaceBackKer.Index, kVertBufferKey, vertBuffer); voxelizer.SetBuffer(surfaceBackKer.Index, kUVBufferKey, uvBuffer); voxelizer.SetBuffer(surfaceBackKer.Index, kTriBufferKey, triBuffer); voxelizer.SetBuffer(surfaceBackKer.Index, kVoxelBufferKey, voxelBuffer); voxelizer.Dispatch(surfaceBackKer.Index, indexes / (int)surfaceBackKer.ThreadX + 1, (int)surfaceBackKer.ThreadY, (int)surfaceBackKer.ThreadZ); if (volume) { var volumeKer = new Kernel(voxelizer, kVolumeKernelKey); voxelizer.SetBuffer(volumeKer.Index, kVoxelBufferKey, voxelBuffer); voxelizer.Dispatch(volumeKer.Index, w / (int)volumeKer.ThreadX + 1, h / (int)volumeKer.ThreadY + 1, (int)surfaceFrontKer.ThreadZ); } // dispose vertBuffer.Release(); uvBuffer.Release(); triBuffer.Release(); return(new GPUVoxelData(voxelBuffer, w, h, d, unit)); }
void SetCoreBrainDataSharedParameters(ComputeShader computeShader) { // Core Sizes computeShader.SetFloat("minNeuronRadius", minNeuronRadius); computeShader.SetFloat("maxNeuronRadius", maxNeuronRadius); computeShader.SetFloat("minAxonRadius", minAxonRadius); computeShader.SetFloat("maxAxonRadius", maxAxonRadius); computeShader.SetFloat("minSubNeuronScale", minSubNeuronScale); computeShader.SetFloat("maxSubNeuronScale", maxSubNeuronScale); computeShader.SetFloat("minAxonFlareScale", minAxonFlareScale); computeShader.SetFloat("maxAxonFlareScale", maxAxonFlareScale); computeShader.SetFloat("axonFlarePos", axonFlarePos); computeShader.SetFloat("axonFlareWidth", axonFlareWidth); computeShader.SetFloat("axonMaxPulseMultiplier", axonMaxPulseMultiplier); computeShader.SetFloat("cableRadius", cableRadius); // Noise Parameters computeShader.SetFloat("neuronExtrudeNoiseFreq", neuronExtrudeNoiseFreq); computeShader.SetFloat("neuronExtrudeNoiseAmp", neuronExtrudeNoiseAmp); computeShader.SetFloat("neuronExtrudeNoiseScrollSpeed", neuronExtrudeNoiseScrollSpeed); computeShader.SetFloat("axonExtrudeNoiseFreq", axonExtrudeNoiseFreq); computeShader.SetFloat("axonExtrudeNoiseAmp", axonExtrudeNoiseAmp); computeShader.SetFloat("axonExtrudeNoiseScrollSpeed", axonExtrudeNoiseScrollSpeed); computeShader.SetFloat("axonPosNoiseFreq", axonPosNoiseFreq); computeShader.SetFloat("axonPosNoiseAmp", axonPosNoiseAmp); computeShader.SetFloat("axonPosNoiseScrollSpeed", axonPosNoiseScrollSpeed); computeShader.SetFloat("axonPosSpiralFreq", axonPosSpiralFreq); computeShader.SetFloat("axonPosSpiralAmp", axonPosSpiralAmp); // Forces computeShader.SetFloat("neuronAttractForce", neuronAttractForce); computeShader.SetFloat("neuronRepelForce", neuronRepelForce); computeShader.SetFloat("axonPerpendicularityForce", axonPerpendicularityForce); computeShader.SetFloat("axonAttachStraightenForce", axonAttachStraightenForce); computeShader.SetFloat("axonAttachSpreadForce", axonAttachSpreadForce); computeShader.SetFloat("axonRepelForce", axonRepelForce); computeShader.SetFloat("cableAttractForce", cableAttractForce); computeShader.SetFloat("time", Time.fixedTime); }
public CSRasterization3DResult Rasterize(Vector3[] verts, int[] tris, Bounds bounds, Matrix4x4 matrix, int volumeSizeX, int volumeSizeZ, float chunkPosX, float chunkPosZ, float voxelSize, float maxSlopeCos, bool flipY, bool debug) { float cellSizeLengthX = cellSizeX * voxelSize; float cellSizeLengthY = cellSizeY * voxelSize; int sheetSizeX = Mathf.CeilToInt((float)volumeSizeX / cellSizeX); int sheetSizeZ = Mathf.CeilToInt((float)volumeSizeZ / cellSizeY); //int tSizeX = Mathf.Max(sheetSizeX, 1) * cellSizeX; //int tSizeY = Mathf.Max(sheetSizeZ, 1) * cellSizeY; Vector3 minBounds = bounds.min; Vector3 maxBounds = bounds.max; int startX = Mathf.Clamp(Mathf.FloorToInt((minBounds.x - chunkPosX) / cellSizeLengthX), 0, sheetSizeX); int startZ = Mathf.Clamp(Mathf.FloorToInt((minBounds.z - chunkPosZ) / cellSizeLengthY), 0, sheetSizeZ); int endX = Mathf.Clamp(Mathf.CeilToInt((maxBounds.x - chunkPosX) / cellSizeLengthX), 1, sheetSizeX); int endZ = Mathf.Clamp(Mathf.CeilToInt((maxBounds.z - chunkPosZ) / cellSizeLengthY), 1, sheetSizeZ); int sizeX = endX - startX; int sizeZ = endZ - startZ; int voxelsX = sizeX * cellSizeX; int voxelsY = sizeZ * cellSizeY; int voxelsTotal = voxelsX * voxelsY; if (voxelsTotal == 0) { return(null); } float ajustedChunkX = (startX * cellSizeLengthX) + chunkPosX; float ajustedChunkZ = (startZ * cellSizeLengthY) + chunkPosZ; Vector3 ajustedChunk = new Vector3(ajustedChunkX, 0, ajustedChunkZ); #region debug of sheet //Debuger_K.AddRay(new Vector3(ajustedChunkX, 0, ajustedChunkZ), Vector3.up, Color.red); //Vector3 chunkPos = new Vector3(chunkPosX, 0, chunkPosZ); //Debuger_K.AddQuad( // chunkPos, // chunkPos + (Vector3.right * tSizeX * voxelSize), // chunkPos + (Vector3.forward * tSizeY * voxelSize), // chunkPos + (Vector3.right * tSizeX * voxelSize) + (Vector3.forward * tSizeY * voxelSize), // new Color(0, 0, 1, 0.1f)); //Debuger_K.AddQuad( // chunkPos, // chunkPos + (Vector3.right * volume.sizeX * voxelSize), // chunkPos + (Vector3.forward * volume.sizeZ * voxelSize), // chunkPos + (Vector3.right * volume.sizeX * voxelSize) + (Vector3.forward * volume.sizeZ * voxelSize), // new Color(0, 1, 1, 0.1f)); //for (int x = startX; x < startX + sizeX; x++) { // for (int z = startZ; z < startZ + sizeZ; z++) { // Debuger_K.AddQuad( // chunkPos + new Vector3(cellSizeLengthX * x, 0, cellSizeLengthY * z), // chunkPos + new Vector3(cellSizeLengthX * (x + 1), 0, cellSizeLengthY * z), // chunkPos + new Vector3(cellSizeLengthX * x, 0, cellSizeLengthY * (z + 1)), // chunkPos + new Vector3(cellSizeLengthX * (x + 1), 0, cellSizeLengthY * (z + 1)), // new Color(0, 1, 0, 0.1f)); // } //} //Debug.Log(sizeX + " : " + sizeZ); #endregion ComputeBuffer vertsBuffer = new ComputeBuffer(verts.Length, sizeof(float) * 3); ComputeBuffer trisBuffer = new ComputeBuffer(tris.Length, sizeof(int)); ComputeBuffer voxelBuffer = new ComputeBuffer(voxelsTotal, Voxel3D.stride); ComputeBuffer dataSegmentBuffer = new ComputeBuffer(cellSizeZ, DataSegment3D.stride); CS.SetInt("SizeX", voxelsX); CS.SetInt("SizeZ", voxelsY); CS.SetVector("ChunkPos", ajustedChunk); CS.SetFloat("VoxelSize", voxelSize); int kernel = CS.FindKernel("Rasterize"); CS.SetBuffer(kernel, "CurTris", trisBuffer); CS.SetBuffer(kernel, "CurVerts", vertsBuffer); CS.SetBuffer(kernel, "Result", voxelBuffer); CS.SetBuffer(kernel, "TargetSegments", dataSegmentBuffer); //creating new array in case referensed are reused elsewhere Vector3[] newVerts = new Vector3[verts.Length]; for (int i = 0; i < verts.Length; i++) { newVerts[i] = matrix.MultiplyPoint3x4(verts[i]); } DataSegment3D[] dataSegmentArray = new DataSegment3D[cellSizeZ]; vertsBuffer.SetData(newVerts); trisBuffer.SetData(tris); Voxel3D[] voxels3D = new Voxel3D[voxelsTotal]; for (int i = 0; i < voxelsTotal; i++) { voxels3D[i].passability = -1; } voxelBuffer.SetData(voxels3D); int fullDataArrays = tris.Length / (3 * cellSizeZ); for (int fp_index = 0; fp_index < fullDataArrays; fp_index++) { int t = fp_index * cellSizeZ * 3; for (int index = 0; index < cellSizeZ; index++) { int tIndex = t + (index * 3); int passability = CalculateWalk(newVerts[tris[tIndex]], newVerts[tris[tIndex + 1]], newVerts[tris[tIndex + 2]], maxSlopeCos, flipY) ? 3 : 1;//if true then walkable else slope; dataSegmentArray[index] = new DataSegment3D(tIndex, 3, passability); //Debuger_K.AddTriangle(newVerts[tris[tIndex]], newVerts[tris[tIndex + 1]], newVerts[tris[tIndex + 2]], new Color(1, 0, 1, 0.1f)); } dataSegmentBuffer.SetData(dataSegmentArray); CS.Dispatch(kernel, sizeX, sizeZ, 1); } int endIndex = fullDataArrays * cellSizeZ * 3; int remainTriangles = tris.Length - endIndex; if (remainTriangles > 0) { int remainSize = remainTriangles / 3; int passabilityDefault = CalculateWalk(newVerts[tris[0]], newVerts[tris[1]], newVerts[tris[2]], maxSlopeCos) ? 3 : 1;//if true then walkable else slope; DataSegment3D defaulSegment = new DataSegment3D(0, 3, passabilityDefault); for (int index = 0; index < cellSizeZ; index++) { if (index < remainSize) { int tIndex = endIndex + (index * 3); int passability = CalculateWalk(newVerts[tris[tIndex]], newVerts[tris[tIndex + 1]], newVerts[tris[tIndex + 2]], maxSlopeCos) ? 3 : 1;//if true then walkable else slope; dataSegmentArray[index] = new DataSegment3D(tIndex, 3, passability); //Debuger_K.AddTriangle(newVerts[tris[tIndex]], newVerts[tris[tIndex + 1]], newVerts[tris[tIndex + 2]], new Color(1, 0, 1, 0.1f)); } else { dataSegmentArray[index] = defaulSegment; //set here first } } dataSegmentBuffer.SetData(dataSegmentArray); CS.Dispatch(kernel, sizeX, sizeZ, 1); } int newVolumeStartX = startX * cellSizeX; int newVolumeStartZ = startZ * cellSizeY; int newVolumeSizeX = Mathf.Min(voxelsX, volumeSizeX - newVolumeStartX); int newVolumeSizeZ = Mathf.Min(voxelsY, volumeSizeZ - newVolumeStartZ); voxelBuffer.GetData(voxels3D); vertsBuffer.Dispose(); trisBuffer.Dispose(); voxelBuffer.Dispose(); dataSegmentBuffer.Dispose(); return(new CSRasterization3DResult(voxels3D, voxelsX, voxelsY, newVolumeStartX, newVolumeStartZ, newVolumeSizeX, newVolumeSizeZ)); }
public virtual void _SetInternal() { shader.SetFloat("_Time", Time.time); shader.SetFloat("_Delta", Time.deltaTime); shader.SetFloat("_DT", Time.deltaTime); }
void LateUpdate() { if (particles.Length < system.main.maxParticles) { particles = new ParticleSystem.Particle[system.main.maxParticles]; #if USE_COMPUTE_SHADER if (csBuffer != null) { csBuffer.Release(); } csBuffer = new ComputeBuffer(system.main.maxParticles, 32); csInOut = new CSInOut[system.main.maxParticles]; #endif } // reinitialize random data if count changed { var customData = system.customData; customData.enabled = system.particleCount > numParticles; } numParticles = system.GetParticles(particles); int numVec = system.GetCustomParticleData(particleRandom, ParticleSystemCustomData.Custom1); if (numParticles != numVec) { Debug.LogError("Count mismatch"); } #if USE_COMPUTE_SHADER for (int i = 0; i < numParticles; i++) { csInOut[i] = new CSInOut { facingVector = particleRandom[i], positionOrWind = particles[i].position, }; } csBuffer.SetData(csInOut); gameRenderer.SetWindValues(); // To make sure our uniforms are ready to use getWindDataCS.SetTexture(0, "_WindTex", gameRenderer.windSampler._WindTex); getWindDataCS.SetFloat("_AnimTime", Time.timeSinceLevelLoad); getWindDataCS.SetFloat("_WindFrequency", gameRenderer.windSampler._WindFrequency); getWindDataCS.SetFloat("_WindShiftSpeed", gameRenderer.windSampler._WindShiftSpeed); getWindDataCS.SetFloat("_WindStrength", gameRenderer.windSampler._WindStrength); getWindDataCS.SetTexture(0, "_WindBuffer", gameRenderer.windSampler._WindBuffer); getWindDataCS.SetVector("_WindBufferCenter", gameRenderer.windSampler._WindBufferCenter); getWindDataCS.SetFloat("_WindBufferRange", gameRenderer.windSampler._WindBufferRange); getWindDataCS.SetFloat("_DynamicWindStrength", gameRenderer.windSampler._DynamicWindStrength); getWindDataCS.SetBuffer(0, "_Result", csBuffer); getWindDataCS.Dispatch(0, MathUtil.DivideByMultiple(numParticles, 64), 1, 1); csBuffer.GetData(csInOut); #endif float windSpeed = gameRenderer.windSampler._WindShiftSpeed; float windStrength = gameRenderer.windSampler._WindStrength; float effectiveWindResistance = windResistance / windSpeed; // Update particles according to flow for (int i = 0; i < numParticles; i++) { Vector3 velocity = particles[i].velocity; float counter = particleRandom[i].w; #if USE_COMPUTE_SHADER Vector3 facingVector = csInOut[i].facingVector; Vector3 wind = csInOut[i].positionOrWind; float windFactor = csInOut[i].positionOrWind.w; #else Vector3 facingVector = particleRandom[i]; facingVector.Normalize(); Vector3 wind = gameRenderer.windSampler.WindVelocity(particles[i].position); float windFactor = Vector3.Dot(wind, facingVector); #endif bool isParticleInAir = Mathf.Abs(velocity.y) > Mathf.Epsilon; if (!isParticleInAir && velocity.magnitude < 1f) { afloatIndices.Remove(i); velocity = Vector3.zero; } if (counter > 0) { counter -= Random.value * 0.01f * windSpeed; } else { counter = Random.value; if (afloatIndices.Count < maxAfloat) { // give this one a kick based on the wind afloatIndices.Add(i); Vector3 targetVelocity = Mathf.Abs(windFactor) * wind; velocity = targetVelocity; // apply updraft if (!isParticleInAir && windFactor > 0 && wind.magnitude > effectiveWindResistance) { velocity.y += windStrength * windFactor * velocity.magnitude * facingVector.y; } facingVector = Vector3.RotateTowards(facingVector, velocity, 0.01f, 0); } } // kick up leaves when moving float distanceFromCenter = Vector3.Distance(gameRenderer.windSampler._WindBufferCenter, particles[i].position); float windRadius = 2 * gameRenderer.windSampler._DynamicWindRadius; float minWind = 0.2f * gameRenderer.windSampler._DynamicWindStrength * effectiveWindResistance; if (!isParticleInAir && distanceFromCenter < windRadius && wind.magnitude > minWind) { const float threshold = 0.8f; if (counter < threshold) { velocity.x += windFactor * wind.magnitude * facingVector.x; velocity.y += wind.magnitude * 5; velocity.z += windFactor * wind.magnitude * facingVector.z; } counter = threshold + (1 - threshold) * Random.value * Mathf.SmoothStep(0, 1, distanceFromCenter / windRadius); } if (isParticleInAir) { // follow wind direction velocity = Vector3.MoveTowards(velocity, wind, windSpeed * Time.deltaTime); // slow down fall if (velocity.y < 0) { velocity.y *= Random.Range(0.95f, 0.98f); } else { velocity.y *= Random.Range(0.98f, 1.02f); } } particles[i].velocity = velocity; particleRandom[i] = new Vector4(facingVector.x, facingVector.y, facingVector.z, counter); } system.SetParticles(particles, numParticles); system.SetCustomParticleData(particleRandom, ParticleSystemCustomData.Custom1); }
void Start() { Application.targetFrameRate = 300; // Create initial positions total = x * y * z; m_matrices = new Matrix4x4[total]; positionArray = new Vector3[total]; quaternionArray = new Quaternion[total]; rigidBodyVelocitiesArray = new Vector3[total]; m_cubeScale = new Vector3(scale, scale, scale); m_deltaTimeShaderProperty = Shader.PropertyToID("deltaTime"); rigidBodyInertialTensors = new float[total * 9]; const int particlesPerEdge = 2; const int particlesPerEdgeMinusOne = particlesPerEdge - 2; const int particlesPerBody = particlesPerEdge * particlesPerEdge * particlesPerEdge - particlesPerEdgeMinusOne * particlesPerEdgeMinusOne * particlesPerEdgeMinusOne; int n_particles = particlesPerBody * total; int numGridCells = gridX * gridY * gridZ; float particleDiameter = scale / particlesPerEdge; particleForcesArray = new Vector3[n_particles]; for (int i = 0; i < x; i++) { for (int j = 0; j < y; j++) { for (int k = 0; k < z; k++) { positionArray[IDX(i, j, k)] = new Vector3(i * scale, j * scale, k * scale) + new Vector3(0.5f * scale, 0.5f * scale, 0.5f * scale); quaternionArray[IDX(i, j, k)] = Quaternion.identity; rigidBodyVelocitiesArray[IDX(i, j, k)] = Vector3.zero; } } } // rigid body velocities positionArray[IDX(0, y - 1, 0)] = m_firstCubeLocation; rigidBodyVelocitiesArray[IDX(0, y - 1, 0)] = m_firstCubeVelocity; quaternionArray[IDX(0, y - 1, 0)] = Quaternion.Euler(m_firstCubeRotation); particleVelocities = new Vector3[n_particles]; particlePositions = new Vector3[n_particles]; particleRelativePositions = new Vector3[n_particles]; debugParticleIds = new int[debug_particle_id_count]; voxelGridArray = new int[numGridCells * 4]; particleVoxelPositionsArray = new int[n_particles * 3]; // Get Kernels m_kernel_generateParticleValues = m_computeShader.FindKernel("GenerateParticleValues"); m_kernel_clearGrid = m_computeShader.FindKernel("ClearGrid"); m_kernel_populateGrid = m_computeShader.FindKernel("PopulateGrid"); m_kernel_collisionDetection = m_computeShader.FindKernel("CollisionDetection"); m_kernel_computeMomenta = m_computeShader.FindKernel("ComputeMomenta"); m_kernel_computePositionAndRotation = m_computeShader.FindKernel("ComputePositionAndRotation"); m_kernelSavePreviousPositionAndRotation = m_computeShader.FindKernel("SavePreviousPositionAndRotation"); // Count Thread Groups m_threadGroupsPerRigidBody = Mathf.CeilToInt(total / 8.0f); m_threadGroupsPerParticle = Mathf.CeilToInt(n_particles / 8f); m_threadGroupsPerGridCell = Mathf.CeilToInt((gridX * gridY * gridZ) / 8f); // Create initial buffers const int floatThree = 3 * sizeof(float); const int floatFour = 4 * sizeof(float); const int intFour = 4 * sizeof(int); const int intThree = 3 * sizeof(int); const int floatNine = 9 * sizeof(float); m_rigidBodyPositions = new ComputeBuffer(total, floatThree); m_previousRigidBodyPositions = new ComputeBuffer(total, floatThree); m_rigidBodyQuaternions = new ComputeBuffer(total, floatFour); m_previousRigidBodyQuaternions = new ComputeBuffer(total, floatFour); m_rigidBodyAngularVelocities = new ComputeBuffer(total, floatThree); m_rigidBodyVelocities = new ComputeBuffer(total, floatThree); m_rigidBodyInertialTensors = new ComputeBuffer(total, floatNine); m_particleInitialRelativePositions = new ComputeBuffer(n_particles, floatThree); m_particlePositions = new ComputeBuffer(n_particles, floatThree); m_particleRelativePositions = new ComputeBuffer(n_particles, floatThree); m_particleVelocities = new ComputeBuffer(n_particles, floatThree); m_particleForces = new ComputeBuffer(n_particles, floatThree); m_voxelCollisionGrid = new ComputeBuffer(numGridCells, intFour); m_debugParticleVoxelPositions = new ComputeBuffer(n_particles, intThree); m_debugParticleIds = new ComputeBuffer(debug_particle_id_count, sizeof(int)); Debug.Log("nparticles: " + n_particles); // initialize constants int[] gridDimensions = new int[] { gridX, gridY, gridZ }; m_computeShader.SetInts("gridDimensions", gridDimensions); m_computeShader.SetInt("gridMax", numGridCells); m_computeShader.SetInt("particlesPerRigidBody", particlesPerBody); m_computeShader.SetFloat("particleDiameter", particleDiameter); m_computeShader.SetFloat("springCoefficient", springCoefficient); m_computeShader.SetFloat("dampingCoefficient", dampingCoefficient); m_computeShader.SetFloat("frictionCoefficient", frictionCoefficient); m_computeShader.SetFloat("angularFrictionCoefficient", angularFrictionCoefficient); m_computeShader.SetFloat("gravityCoefficient", gravityCoefficient); m_computeShader.SetFloat("tangentialCoefficient", tangentialCoefficient); m_computeShader.SetFloat("angularForceScalar", angularForceScalar); m_computeShader.SetFloat("linearForceScalar", linearForceScalar); m_computeShader.SetFloat("particleMass", m_cubeMass / particlesPerBody); m_computeShader.SetFloats("gridStartPosition", new float[] { gridStartPosition.x, gridStartPosition.y, gridStartPosition.z }); // Inertial tensor of a cube formula taken from textbook: // "Essential Mathematics for Games and Interactive Applications" // by James Van Verth and Lars Bishop float twoDimSq = 2.0f * (scale * scale); float inertialTensorFactor = m_cubeMass * 1.0f / 12.0f * twoDimSq; float[] inertialTensor = { inertialTensorFactor, 0.0f, 0.0f, 0.0f, inertialTensorFactor, 0.0f, 0.0f, 0.0f, inertialTensorFactor }; float[] inverseInertialTensor; GPUPhysics.Invert(ref inertialTensor, out inverseInertialTensor); float[] quickInverseInertialTensor = { 1.0f / inertialTensorFactor, 0.0f, 0.0f, 0.0f, 1.0f / inertialTensorFactor, 0.0f, 0.0f, 0.0f, 1.0f / inertialTensorFactor }; m_computeShader.SetFloats("inertialTensor", inertialTensor); m_computeShader.SetFloats("inverseInertialTensor", quickInverseInertialTensor); // initialize buffers // initial relative positions // super dependent on 8/rigid body float quarterScale = scale * 0.25f; particleInitialRelativePositions = new Vector3[n_particles]; Vector3[] particleInitialsSmall = new Vector3[particlesPerBody]; int initialRelativePositionIterator = 0; float centerer = scale * -0.5f + particleDiameter * 0.5f; Vector3 centeringOffset = new Vector3(centerer, centerer, centerer); //centeringOffset = Vector3.zero; for (int xIter = 0; xIter < particlesPerEdge; xIter++) { for (int yIter = 0; yIter < particlesPerEdge; yIter++) { for (int zIter = 0; zIter < particlesPerEdge; zIter++) { if (xIter == 0 || xIter == (particlesPerEdge - 1) || yIter == 0 || yIter == (particlesPerEdge - 1) || zIter == 0 || zIter == (particlesPerEdge - 1)) { particleInitialsSmall[initialRelativePositionIterator] = centeringOffset + new Vector3(xIter * particleDiameter, yIter * particleDiameter, zIter * particleDiameter); //Debug.Log("[GPUPhysics] particleInitialsSmall["+initialRelativePositionIterator+"] = " + particleInitialsSmall[initialRelativePositionIterator]); initialRelativePositionIterator++; } else { Debug.Log("[GPUPhysics] skipped: " + xIter + ", " + yIter + ", " + zIter); } } } } /* * particleInitialsSmall[0] = new Vector3(quarterScale, quarterScale, quarterScale); * particleInitialsSmall[1] = new Vector3(-quarterScale, quarterScale, quarterScale); * particleInitialsSmall[2] = new Vector3(quarterScale, quarterScale, -quarterScale); * particleInitialsSmall[3] = new Vector3(-quarterScale, quarterScale, -quarterScale); * particleInitialsSmall[4] = new Vector3(quarterScale, -quarterScale, quarterScale); * particleInitialsSmall[5] = new Vector3(-quarterScale, -quarterScale, quarterScale); * particleInitialsSmall[6] = new Vector3(quarterScale, -quarterScale, -quarterScale); * particleInitialsSmall[7] = new Vector3(-quarterScale, -quarterScale, -quarterScale); */ for (int i = 0; i < particleInitialRelativePositions.Length; i++) { particleInitialRelativePositions[i] = particleInitialsSmall[i % particlesPerBody]; } m_particleInitialRelativePositions.SetData(particleInitialRelativePositions); // rigid body positions m_rigidBodyPositions.SetData(positionArray); // rigid body quaternions m_rigidBodyQuaternions.SetData(quaternionArray); m_rigidBodyVelocities.SetData(rigidBodyVelocitiesArray); // Set matricies to initial positions SetMatrices(positionArray, quaternionArray); // Bind buffers // kernel 0 GenerateParticleValues m_computeShader.SetBuffer(m_kernel_generateParticleValues, "rigidBodyPositions", m_rigidBodyPositions); m_computeShader.SetBuffer(m_kernel_generateParticleValues, "rigidBodyQuaternions", m_rigidBodyQuaternions); m_computeShader.SetBuffer(m_kernel_generateParticleValues, "rigidBodyAngularVelocities", m_rigidBodyAngularVelocities); m_computeShader.SetBuffer(m_kernel_generateParticleValues, "rigidBodyVelocities", m_rigidBodyVelocities); m_computeShader.SetBuffer(m_kernel_generateParticleValues, "particleInitialRelativePositions", m_particleInitialRelativePositions); m_computeShader.SetBuffer(m_kernel_generateParticleValues, "particlePositions", m_particlePositions); m_computeShader.SetBuffer(m_kernel_generateParticleValues, "particleRelativePositions", m_particleRelativePositions); m_computeShader.SetBuffer(m_kernel_generateParticleValues, "particleVelocities", m_particleVelocities); //m_computeShader.SetBuffer(m_kernel_generateParticleValues, "debugParticleIds", m_debugParticleIds); // kernel 1 ClearGrid m_computeShader.SetBuffer(m_kernel_clearGrid, "voxelCollisionGrid", m_voxelCollisionGrid); // kernel 2 Populate Grid m_computeShader.SetBuffer(m_kernel_populateGrid, "debugParticleVoxelPositions", m_debugParticleVoxelPositions); m_computeShader.SetBuffer(m_kernel_populateGrid, "voxelCollisionGrid", m_voxelCollisionGrid); m_computeShader.SetBuffer(m_kernel_populateGrid, "particlePositions", m_particlePositions); //m_computeShader.SetBuffer(m_kernel_populateGrid, "debugParticleIds", m_debugParticleIds); // kernel 3 Collision Detection m_computeShader.SetBuffer(m_kernel_collisionDetection, "particlePositions", m_particlePositions); m_computeShader.SetBuffer(m_kernel_collisionDetection, "particleVelocities", m_particleVelocities); m_computeShader.SetBuffer(m_kernel_collisionDetection, "voxelCollisionGrid", m_voxelCollisionGrid); m_computeShader.SetBuffer(m_kernel_collisionDetection, "particleForces", m_particleForces); // kernel 4 Computation of Momenta m_computeShader.SetBuffer(m_kernel_computeMomenta, "particleForces", m_particleForces); m_computeShader.SetBuffer(m_kernel_computeMomenta, "particleRelativePositions", m_particleRelativePositions); m_computeShader.SetBuffer(m_kernel_computeMomenta, "rigidBodyAngularVelocities", m_rigidBodyAngularVelocities); m_computeShader.SetBuffer(m_kernel_computeMomenta, "rigidBodyVelocities", m_rigidBodyVelocities); m_computeShader.SetBuffer(m_kernel_computeMomenta, "debugParticleIds", m_debugParticleIds); m_computeShader.SetBuffer(m_kernel_computeMomenta, "rigidBodyQuaternions", m_rigidBodyQuaternions); // kernel 5 Compute Position and Rotation m_computeShader.SetBuffer(m_kernel_computePositionAndRotation, "rigidBodyVelocities", m_rigidBodyVelocities); m_computeShader.SetBuffer(m_kernel_computePositionAndRotation, "rigidBodyAngularVelocities", m_rigidBodyAngularVelocities); m_computeShader.SetBuffer(m_kernel_computePositionAndRotation, "rigidBodyPositions", m_rigidBodyPositions); m_computeShader.SetBuffer(m_kernel_computePositionAndRotation, "rigidBodyQuaternions", m_rigidBodyQuaternions); m_computeShader.SetBuffer(m_kernel_computePositionAndRotation, "inverseInertialMatrices", m_rigidBodyInertialTensors); // kernel 6 Save Previous Position and Rotation m_computeShader.SetBuffer(m_kernelSavePreviousPositionAndRotation, "rigidBodyPositions", m_rigidBodyPositions); m_computeShader.SetBuffer(m_kernelSavePreviousPositionAndRotation, "rigidBodyQuaternions", m_rigidBodyQuaternions); m_computeShader.SetBuffer(m_kernelSavePreviousPositionAndRotation, "previousRigidBodyPositions", m_previousRigidBodyPositions); m_computeShader.SetBuffer(m_kernelSavePreviousPositionAndRotation, "previousRigidBodyQuaternions", m_previousRigidBodyQuaternions); // Setup Indirect Renderer uint[] sphereArgs = new uint[] { sphereMesh.GetIndexCount(0), (uint)n_particles, 0, 0, 0 }; m_bufferWithSphereArgs = new ComputeBuffer(1, sphereArgs.Length * sizeof(uint), ComputeBufferType.IndirectArguments); m_bufferWithSphereArgs.SetData(sphereArgs); uint[] lineArgs = new uint[] { lineMesh.GetIndexCount(0), (uint)n_particles, 0, 0, 0 }; m_bufferWithLineArgs = new ComputeBuffer(1, lineArgs.Length * sizeof(uint), ComputeBufferType.IndirectArguments); m_bufferWithLineArgs.SetData(lineArgs); cubeMaterial.SetBuffer("positions", m_rigidBodyPositions); cubeMaterial.SetBuffer("previousPositions", m_previousRigidBodyPositions); cubeMaterial.SetBuffer("quaternions", m_rigidBodyQuaternions); cubeMaterial.SetBuffer("previousQuaternions", m_previousRigidBodyQuaternions); sphereMaterial.SetBuffer("positions", m_particlePositions); sphereMaterial.SetVector("scale", new Vector4(particleDiameter * 0.5f, particleDiameter * 0.5f, particleDiameter * 0.5f, 1.0f)); lineMaterial.SetBuffer("positions", m_particlePositions); lineMaterial.SetBuffer("vectors", m_particleVelocities); // Setup Command Buffer m_commandBuffer = new CommandBuffer(); m_commandBuffer.BeginSample("GenerateParticleValues"); m_commandBuffer.DispatchCompute(m_computeShader, m_kernel_generateParticleValues, m_threadGroupsPerRigidBody, 1, 1); m_commandBuffer.EndSample("GenerateParticleValues"); m_commandBuffer.BeginSample("ClearGrid"); m_commandBuffer.DispatchCompute(m_computeShader, m_kernel_clearGrid, m_threadGroupsPerGridCell, 1, 1); m_commandBuffer.EndSample("ClearGrid"); m_commandBuffer.BeginSample("PopulateGrid"); m_commandBuffer.DispatchCompute(m_computeShader, m_kernel_populateGrid, m_threadGroupsPerParticle, 1, 1); m_commandBuffer.EndSample("PopulateGrid"); m_commandBuffer.BeginSample("CollisionDetection"); m_commandBuffer.DispatchCompute(m_computeShader, m_kernel_collisionDetection, m_threadGroupsPerParticle, 1, 1); m_commandBuffer.EndSample("CollisionDetection"); m_commandBuffer.BeginSample("ComputeMomenta"); m_commandBuffer.DispatchCompute(m_computeShader, m_kernel_computeMomenta, m_threadGroupsPerRigidBody, 1, 1); m_commandBuffer.EndSample("ComputeMomenta"); m_commandBuffer.BeginSample("ComputePositions"); m_commandBuffer.DispatchCompute(m_computeShader, m_kernel_computePositionAndRotation, m_threadGroupsPerRigidBody, 1, 1); m_commandBuffer.EndSample("ComputePositions"); m_commandBuffer.BeginSample("SavePreviousPositionAndRotation"); m_commandBuffer.DispatchCompute(m_computeShader, m_kernelSavePreviousPositionAndRotation, m_threadGroupsPerRigidBody, 1, 1); m_commandBuffer.EndSample("SavePreviousPositionAndRotation"); // rendering in command buffer - doesnt work for now seems like a unity bug #if !(UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX) // Command Buffer DrawMeshInstancedIndirect doesnt work on my mac // rendering from command buffer via update isnt working so disabling this is necessary for delta time use // m_commandBuffer.BeginSample("DrawMeshInstancedIndirect"); // m_commandBuffer.DrawMeshInstancedIndirect(cubeMesh, 0, cubeMaterial, 0, m_bufferWithArgs); // m_commandBuffer.EndSample("DrawMeshInstancedIndirect"); #endif // Camera.main.AddCommandBuffer(CameraEvent.AfterSkybox, m_commandBuffer); }
void Update() { _computeShader.SetFloat(ShaderIDs.deltaTime, Time.deltaTime); _computeShader.Dispatch(_updateKernel, vertCount, 1, 1); }
private void OnEnable() { Debug.Assert(grassComputeShader != null, "The grass compute shader is null", gameObject); Debug.Assert(material != null, "The material is null", gameObject); // If initialized, call on disable to clean things up if (initialized) { OnDisable(); } initialized = true; // Instantiate the shaders so they can point to their own buffers instantiatedGrassComputeShader = Instantiate(grassComputeShader); instantiatedMaterial = Instantiate(material); // Grab data from the source mesh Vector3[] positions = sourceMesh.vertices; int[] tris = sourceMesh.triangles; //TODO: Why was this in the code? Works even when commented out? /* * // Create the data to upload to the source vert buffer * SourceVertex[] vertices = new SourceVertex[positions.Length]; * for (int i = 0; i < vertices.Length; i++) * { * vertices[i] = new SourceVertex() * { * position = positions[i], * }; * }*/ int numSourceTriangles = tris.Length / 3; // The number of triangles in the source mesh is the index array / 3 // Each grass blade segment has two points. Counting those plus the tip gives us the total number of points int maxBladeSegments = Mathf.Max(1, grassSettings.maxSegments); int maxBladeTriangles = (maxBladeSegments - 1) * 2 + 1; // Create compute buffers // The stride is the size, in bytes, each object in the buffer takes up sourceVertBuffer = new ComputeBuffer(positions.Length, SOURCE_VERT_STRIDE, ComputeBufferType.Structured, ComputeBufferMode.Immutable); sourceVertBuffer.SetData((Vector3[])positions.Clone()); //cloning required? sourceTriBuffer = new ComputeBuffer(tris.Length, SOURCE_TRI_STRIDE, ComputeBufferType.Structured, ComputeBufferMode.Immutable); sourceTriBuffer.SetData(tris); drawBuffer = new ComputeBuffer(numSourceTriangles * maxBladeTriangles, DRAW_STRIDE, ComputeBufferType.Append); drawBuffer.SetCounterValue(0); argsBuffer = new ComputeBuffer(1, INDIRECT_ARGS_STRIDE, ComputeBufferType.IndirectArguments); // Cache the kernel IDs we will be dispatching idGrassKernel = instantiatedGrassComputeShader.FindKernel("Main"); // Set data on the shaders instantiatedGrassComputeShader.SetBuffer(idGrassKernel, "_SourceVertices", sourceVertBuffer); instantiatedGrassComputeShader.SetBuffer(idGrassKernel, "_SourceTriangles", sourceTriBuffer); instantiatedGrassComputeShader.SetBuffer(idGrassKernel, "_DrawTriangles", drawBuffer); instantiatedGrassComputeShader.SetBuffer(idGrassKernel, "_IndirectArgsBuffer", argsBuffer); instantiatedGrassComputeShader.SetInt("_NumSourceTriangles", numSourceTriangles); instantiatedGrassComputeShader.SetInt("_MaxBladeSegments", maxBladeSegments); instantiatedGrassComputeShader.SetFloat("_MaxBendAngle", grassSettings.maxBendAngle); instantiatedGrassComputeShader.SetFloat("_BladeCurvature", Mathf.Max(0, grassSettings.bladeCurvature)); instantiatedGrassComputeShader.SetFloat("_BladeHeight", grassSettings.bladeHeight); instantiatedGrassComputeShader.SetFloat("_BladeHeightVariance", grassSettings.bladeHeightVariance); instantiatedGrassComputeShader.SetFloat("_BladeWidth", grassSettings.bladeWidth); instantiatedGrassComputeShader.SetFloat("_BladeWidthVariance", grassSettings.bladeWidthVariance); instantiatedGrassComputeShader.SetTexture(idGrassKernel, "_WindNoiseTexture", grassSettings.windNoiseTexture); instantiatedGrassComputeShader.SetFloat("_WindTexMult", grassSettings.windTextureScale); instantiatedGrassComputeShader.SetFloat("_WindTimeMult", grassSettings.windPeriod); instantiatedGrassComputeShader.SetFloat("_WindPosMult", grassSettings.windScale); instantiatedGrassComputeShader.SetFloat("_WindAmplitude", grassSettings.windAmplitude); instantiatedGrassComputeShader.SetVector("_CameraLOD", new Vector4(grassSettings.cameraLODMin, grassSettings.cameraLODMax, Mathf.Max(0, grassSettings.cameraLODFactor), 0)); instantiatedMaterial.SetBuffer("_DrawTriangles", drawBuffer); // Calculate the number of threads to use. Get the thread size from the kernel // Then, divide the number of triangles by that size instantiatedGrassComputeShader.GetKernelThreadGroupSizes(idGrassKernel, out uint threadGroupSize, out _, out _); dispatchSize = Mathf.CeilToInt((float)numSourceTriangles / threadGroupSize); // Get the bounds of the source mesh and then expand by the maximum blade width and height localBounds = sourceMesh.bounds; localBounds.Expand(Mathf.Max(grassSettings.bladeHeight + grassSettings.bladeHeightVariance, grassSettings.bladeWidth + grassSettings.bladeWidthVariance)); }
public float[,] Erode(int numErosionIterations = 50000) { float[] map = Flatten(HeightMap); Erosion = ResourceManager.GetComputeShader("erosion"); int mapSizeWithBorder = Size + 2 * Params.erosionBrushRadius; int numThreads = numErosionIterations / 1024; // Create brush List <int> brushIndexOffsets = new List <int>(); List <float> brushWeights = new List <float>(); float weightSum = 0; for (int brushY = -Params.erosionBrushRadius; brushY <= Params.erosionBrushRadius; brushY++) { for (int brushX = -Params.erosionBrushRadius; brushX <= Params.erosionBrushRadius; brushX++) { float sqrDst = brushX * brushX + brushY * brushY; if (sqrDst < Params.erosionBrushRadius * Params.erosionBrushRadius) { brushIndexOffsets.Add(brushY * Size + brushX); float brushWeight = 1 - Mathf.Sqrt(sqrDst) / Params.erosionBrushRadius; weightSum += brushWeight; brushWeights.Add(brushWeight); } } } for (int i = 0; i < brushWeights.Count; i++) { brushWeights[i] /= weightSum; } // Send brush data to compute shader ComputeBuffer brushIndexBuffer = new ComputeBuffer(brushIndexOffsets.Count, sizeof(int)); ComputeBuffer brushWeightBuffer = new ComputeBuffer(brushWeights.Count, sizeof(int)); brushIndexBuffer.SetData(brushIndexOffsets); brushWeightBuffer.SetData(brushWeights); Erosion.SetBuffer(0, "brushIndices", brushIndexBuffer); Erosion.SetBuffer(0, "brushWeights", brushWeightBuffer); // Generate random indices for droplet placement int[] randomIndices = new int[numErosionIterations]; for (int i = 0; i < numErosionIterations; i++) { int randomX = Random.Range(Params.erosionBrushRadius, Size + Params.erosionBrushRadius); int randomY = Random.Range(Params.erosionBrushRadius, Size + Params.erosionBrushRadius); randomIndices[i] = randomY * Size + randomX; } // Send random indices to compute shader ComputeBuffer randomIndexBuffer = new ComputeBuffer(randomIndices.Length, sizeof(int)); randomIndexBuffer.SetData(randomIndices); Erosion.SetBuffer(0, "randomIndices", randomIndexBuffer); // Heightmap buffer ComputeBuffer mapBuffer = new ComputeBuffer(map.Length, sizeof(float)); mapBuffer.SetData(map); Erosion.SetBuffer(0, "map", mapBuffer); // Settings Erosion.SetInt("borderSize", Params.erosionBrushRadius); Erosion.SetInt("mapSize", mapSizeWithBorder); Erosion.SetInt("brushLength", brushIndexOffsets.Count); Erosion.SetInt("maxLifetime", Params.maxLifetime); Erosion.SetFloat("inertia", Params.inertia); Erosion.SetFloat("sedimentCapacityFactor", Params.sedimentCapacityFactor); Erosion.SetFloat("minSedimentCapacity", Params.minSedimentCapacity); Erosion.SetFloat("depositSpeed", Params.depositSpeed); Erosion.SetFloat("erodeSpeed", Params.erodeSpeed); Erosion.SetFloat("evaporateSpeed", Params.evaporateSpeed); Erosion.SetFloat("gravity", Params.gravity); Erosion.SetFloat("startSpeed", Params.startSpeed); Erosion.SetFloat("startWater", Params.startWater); // Run compute shader Erosion.Dispatch(0, numThreads, 1, 1); mapBuffer.GetData(map); // Release buffers mapBuffer.Release(); randomIndexBuffer.Release(); brushIndexBuffer.Release(); brushWeightBuffer.Release(); return(Unpack(map)); }
void UpdateHistogram(RenderTexture source, Rect rect, HistogramMode mode) { if (m_HistogramMaterial == null) { m_HistogramMaterial = ImageEffectHelper.CheckShaderAndCreateMaterial(concreteTarget.histogramShader); } if (m_HistogramBuffer == null) { m_HistogramBuffer = new ComputeBuffer(256, sizeof(uint) << 2); } m_HistogramBuffer.SetData(k_EmptyBuffer); ComputeShader cs = concreteTarget.histogramComputeShader; int kernel = cs.FindKernel("KHistogramGather"); cs.SetBuffer(kernel, "_Histogram", m_HistogramBuffer); cs.SetTexture(kernel, "_Source", source); int[] channels = null; switch (mode) { case HistogramMode.Luminance: channels = new[] { 0, 0, 0, 1 }; break; case HistogramMode.RGB: channels = new[] { 1, 1, 1, 0 }; break; case HistogramMode.Red: channels = new[] { 1, 0, 0, 0 }; break; case HistogramMode.Green: channels = new[] { 0, 1, 0, 0 }; break; case HistogramMode.Blue: channels = new[] { 0, 0, 1, 0 }; break; } cs.SetInts("_Channels", channels); cs.SetInt("_IsLinear", concreteTarget.isGammaColorSpace ? 0 : 1); cs.Dispatch(kernel, Mathf.CeilToInt(source.width / 32f), Mathf.CeilToInt(source.height / 32f), 1); kernel = cs.FindKernel("KHistogramScale"); cs.SetBuffer(kernel, "_Histogram", m_HistogramBuffer); cs.SetFloat("_Height", rect.height); cs.Dispatch(kernel, 1, 1, 1); if (m_HistogramTexture == null) { DestroyImmediate(m_HistogramTexture); m_HistogramTexture = new RenderTexture((int)rect.width, (int)rect.height, 0, RenderTextureFormat.ARGB32); m_HistogramTexture.hideFlags = HideFlags.HideAndDontSave; } m_HistogramMaterial.SetBuffer("_Histogram", m_HistogramBuffer); m_HistogramMaterial.SetVector("_Size", new Vector2(m_HistogramTexture.width, m_HistogramTexture.height)); m_HistogramMaterial.SetColor("_ColorR", redCurveColor); m_HistogramMaterial.SetColor("_ColorG", greenCurveColor); m_HistogramMaterial.SetColor("_ColorB", blueCurveColor); m_HistogramMaterial.SetColor("_ColorL", masterCurveColor); m_HistogramMaterial.SetInt("_Channel", (int)mode); Graphics.Blit(m_HistogramTexture, m_HistogramTexture, m_HistogramMaterial, (mode == HistogramMode.RGB) ? 1 : 0); }
void Update() { if (!m_kernels.ContainsKey("Step") || Input.GetKeyDown(KeyCode.Space)) { Init(); return; } m_fieldShader.SetFloat("_colorFromTexture", _colorFromTexture ? 1 : 0); m_fieldShader.SetFloat("_maxLifetime", _maxLifetime); m_fieldShader.SetVector("_fieldDim", new Vector2(m_fieldA.width, m_fieldA.height)); if (_screenTex != null) { m_fieldShader.SetVector("_screenDim", new Vector2(m_fieldA.width, m_fieldA.height)); } m_fieldShader.SetFloat("_blurKernelA", m_fieldBlurKernel.x); m_fieldShader.SetFloat("_blurKernelB", m_fieldBlurKernel.y); m_fieldShader.SetFloat("_blurKernelC", m_fieldBlurKernel.z); m_fieldShader.SetFloat("_dt", Time.deltaTime); m_fieldShader.SetFloat("_decayWeights", m_fieldDecay); m_fieldShader.SetFloat("_speed", _speed); m_fieldShader.SetVector("_speedRandom", new Vector4(_speedRandom, _noiseRandom, _linearRandom, _radialRandom)); m_fieldShader.SetFloat("_margin", _margin); m_fieldShader.SetFloat("_sensorRadians", _sensorDegrees * Mathf.Deg2Rad); m_fieldShader.SetFloat("_sensorDist", _sensorDist); m_fieldShader.SetFloat("_inputAmount", _inputAmount); m_fieldShader.SetFloat("_pheremoneAmount", _pheremoneAmount); m_fieldShader.SetFloat("_rotationRadians", _rotationDegrees * Mathf.Deg2Rad); m_fieldShader.SetVector("_pointColor", _pointColor); m_fieldShader.SetFloat("_fractalLevels", _fractalLevels); m_fieldShader.SetFloat("_time", Time.time); m_fieldShader.SetVector("_noiseParam", new Vector4(_noiseAmount, _noiseFreq, _noiseScroll, _noiseSeed)); m_fieldShader.SetVector("_linearForce", _linearForce); m_fieldShader.SetVector("_radialCenter", _radialCenter); m_fieldShader.SetFloat("_radialForce", _radialForce); m_fieldShader.SetTexture(m_kernels["Deposit"], "_Source", SourceTexture); m_fieldShader.SetTexture(m_kernels["Step"], "_Input", SourceTexture); for (int i = 0; i < _iterations; i++) { m_fieldShader.SetTexture(m_kernels["Step"], "_Source", m_fieldB); m_fieldShader.SetTexture(m_kernels["Step"], "_Destination", m_fieldA); m_fieldShader.SetBuffer(m_kernels["Step"], "_particleBuffer", m_particleBuffer.Buffer); m_fieldShader.Dispatch(m_kernels["Step"], m_particleBuffer.Buffer.count / 16, 1, 1); m_fieldShader.SetTexture(m_kernels["XGaussian"], "_Source", m_fieldA); m_fieldShader.SetTexture(m_kernels["XGaussian"], "_Destination", m_fieldB); m_fieldShader.Dispatch(m_kernels["XGaussian"], NumThreadsX, NumThreadsY, 1); m_fieldShader.SetTexture(m_kernels["YGaussian"], "_Source", m_fieldB); m_fieldShader.SetTexture(m_kernels["YGaussian"], "_Destination", m_fieldA); m_fieldShader.Dispatch(m_kernels["YGaussian"], NumThreadsX, NumThreadsY, 1); m_fieldShader.SetTexture(m_kernels["Deposit"], "_Destination", m_fieldA); m_fieldShader.Dispatch(m_kernels["Deposit"], NumThreadsX, NumThreadsY, 1); Swap(m_fieldA, m_fieldB); } Render(); }
void Update() { if (appendVertexBuffer == null) { return; } appendVertexBuffer.SetCounterValue(0); OceanOfCubesCS.SetFloat("_gridSizeURcp", 1.0f / CubesUResolution); OceanOfCubesCS.SetFloat("_gridSizeVRcp", 1.0f / CubesVResolution); OceanOfCubesCS.SetFloat("_cubeScale", CubeScale); OceanOfCubesCS.SetFloat("_minU", minU); OceanOfCubesCS.SetFloat("_minV", minV); OceanOfCubesCS.SetFloat("_maxU", maxU); OceanOfCubesCS.SetFloat("_maxV", maxV); OceanOfCubesCS.SetFloat("_time", timelineTime); OceanOfCubesCS.SetBuffer(kernelMain, "triangleRW", appendVertexBuffer); if (Colliders.Length > 0) { int i = 0; foreach (var go in Colliders) { if (go.activeInHierarchy) { collidersData[i].position = transform.worldToLocalMatrix.MultiplyPoint(go.transform.position); collidersData[i].influence = 1.0f / ColliderInfluence; i++; } } OceanOfCubesCS.SetInt("_numberOfColliders", i); collidersBuffer.SetData(collidersData); OceanOfCubesCS.SetBuffer(kernelMain, "colliders", collidersBuffer); } else { OceanOfCubesCS.SetBuffer(kernelMain, "colliders", collidersBuffer); OceanOfCubesCS.SetInt("_numberOfColliders", 0); } OceanOfCubesCS.Dispatch(kernelMain, CubesUResolution / 8, CubesVResolution / 8, 1); //ComputeBuffer.CopyCount(appendVertexBuffer, argBuffer, 0); //MarchingCubesCS.SetBuffer(kernelMultiply, "_numVertices", argBuffer); //MarchingCubesCS.Dispatch(kernelMultiply, 1, 1, 1); //int[] args2 = new int[] { 0, 1, 0, 0 }; //argBuffer.GetData(args2); //args2[0] *= 3; //argBuffer.SetData(args); //Debug.Log("Vertex count:" + args2[0]); ComputeBuffer.CopyCount(appendVertexBuffer, argBuffer, 0); //int[] args2 = new int[] { 0, 1, 0, 0, 0 }; //argBuffer.GetData(args2); //Debug.Log("Index count:" + args2[0] + " Instances count:" + args2[1]); OceanOfCubesCS.SetBuffer(kernelInstances, "_numVertices", argBuffer); OceanOfCubesCS.Dispatch(kernelInstances, 1, 1, 1); mat.SetPass(0); matPropertyBlock.SetBuffer("triangles", appendVertexBuffer); matPropertyBlock.SetBuffer("indexStructure", argBuffer); matPropertyBlock.SetMatrix("_LocalToWorld", Matrix4x4.Translate(-transform.position) * transform.localToWorldMatrix); matPropertyBlock.SetMatrix("_WorldToLocal", transform.worldToLocalMatrix); Graphics.DrawMeshInstancedIndirect( emptyMesh, 0, mat, new Bounds(transform.position, transform.lossyScale * 10.0f), argBuffer, 0, matPropertyBlock); }
void Start() { instanceCount = rows * cols * depth; nBuckets = Utilidades.Next_prime(2 * instanceCount); sizeOfBuckets = 15; kernelId = cShader.FindKernel("CSMain"); kernelId2 = cShader.FindKernel("CleanTable"); kernelId3 = cShader.FindKernel("HashParticles"); kernelId4 = cShader.FindKernel("InsertParticles"); argsBuffer = new ComputeBuffer(1, args.Length * sizeof(uint), ComputeBufferType.IndirectArguments); positionBuffer = new ComputeBuffer(instanceCount, 16); forceBuffer = new ComputeBuffer(instanceCount, 12); velocityBuffer = new ComputeBuffer(instanceCount, 12); hTable = new ComputeBuffer(nBuckets * sizeOfBuckets, sizeof(int)); indexBuffer = new ComputeBuffer(instanceCount, sizeof(int)); auxBuffer = new ComputeBuffer(instanceCount, sizeof(int)); // Para el debug y esas mierdas positions = new Vector4[instanceCount]; Vector3[] velocities = new Vector3[instanceCount]; Vector3[] forces = new Vector3[instanceCount]; hTableData = new int[(nBuckets * sizeOfBuckets)]; indexBufferData = new int[instanceCount]; for (int i = 0; i < instanceCount; i++) { float angle = 0.0f;//Random.Range(0.0f, Mathf.PI * 2.0f); float distance = Random.Range(-20.0f, 20.0f); float height = Random.Range(-2.0f, 2.0f); float size = 0.2f;//Random.Range(0.05f, 0.25f); //positions[i] = new Vector4(Mathf.Sin(angle) * distance, height, Mathf.Cos(angle) * distance, size); float range = 1000f; float vX = Random.Range(-range, range); float vY = Random.Range(-range, range); float vZ = Random.Range(-range, range); forces[i].x = vX; forces[i].y = vY; forces[i].z = vZ; velocities[i] = new Vector3(); } DefineVolume(); positionBuffer.SetData(positions); velocityBuffer.SetData(velocities); forceBuffer.SetData(forces); material.SetBuffer("positionBuffer", positionBuffer); // Main cShader.SetBuffer(kernelId, "positionBuffer", positionBuffer); cShader.SetBuffer(kernelId, "auxBuffer", auxBuffer); cShader.SetBuffer(kernelId, "velocityBuffer", velocityBuffer); cShader.SetBuffer(kernelId, "forceBuffer", forceBuffer); cShader.SetBuffer(kernelId, "hTable", hTable); // CleanTable cShader.SetBuffer(kernelId2, "hTable", hTable); cShader.SetBuffer(kernelId2, "indexBuffer", indexBuffer); // HashParticles cShader.SetBuffer(kernelId3, "indexBuffer", indexBuffer); cShader.SetBuffer(kernelId3, "positionBuffer", positionBuffer); cShader.SetInt("nParticles", instanceCount); cShader.SetInt("width", Mathf.CeilToInt(instanceCount / 1024f)); cShader.SetInt("sizeBuckets", sizeOfBuckets); cShader.SetInt("nBuckets", nBuckets); cShader.SetFloat("l", 0.5f); if (mesh != null) { args[0] = (uint)mesh.GetIndexCount(subMeshIndex); args[1] = (uint)instanceCount; args[2] = (uint)mesh.GetIndexStart(subMeshIndex); args[3] = (uint)mesh.GetBaseVertex(subMeshIndex); } argsBuffer.SetData(args); cShader.Dispatch(kernelId, Mathf.CeilToInt((instanceCount) / 1024f), 1, 1); cShader.Dispatch(kernelId2, Mathf.CeilToInt((nBuckets * sizeOfBuckets) / 1024f), 1, 1); hTable.GetData(hTableData); cShader.Dispatch(kernelId3, Mathf.CeilToInt((instanceCount) / 1024f), 1, 1); indexBuffer.GetData(indexBufferData); Parallel.For(0, instanceCount, i => { int auxIndex = indexBufferData[i]; int auxCounter = 0; while (auxCounter < sizeOfBuckets) { if (hTableData[auxIndex + auxCounter] == -1) { hTableData[auxIndex + auxCounter] = i; break; } else { auxCounter++; } } }); //InsertCpuSide(); int auxIndex2 = indexBufferData[1100]; Debug.Log("AuxIndex ->>" + auxIndex2); Debug.Log("hTable ->>" + hTableData[auxIndex2]); hTable.SetData(hTableData); // int[] count = new int[instanceCount]; // auxBuffer.GetData(count); // Debug.Log(count[501]); //PerformComprobation(count, nBuckets * sizeOfBuckets); //cShader.Dispatch(kernelId, Mathf.CeilToInt(instanceCount / 1024f), 1, 1); // cShader.Dispatch(kernelId2, Mathf.CeilToInt((nBuckets * sizeOfBuckets) / 1024f), 1, 1); // hTable.GetData(hTableData); // cShader.Dispatch(kernelId3, Mathf.CeilToInt((instanceCount) / 1024f), 1, 1); // indexBuffer.GetData(indexBufferData); // Parallel.For(0, instanceCount, i => { // int index = indexBufferData[i]; // int auxCounter = 0; // while (auxCounter < sizeOfBuckets) // { // if (hTableData[index + auxCounter] == -1) // hTableData[index + auxCounter] = i; // else // auxCounter++; // } // }); // hTable.SetData(hTableData); // cShader.Dispatch(kernelId, Mathf.CeilToInt((instanceCount) / 1024f), 1, 1); }
public void DispatchEmit(int count) { if (enableEmission) { count = Mathf.Min(count, maxParticles - (bufferSize - deadCount)); if (count > 0) { Vector3 velocity = (transform.position - previousPositon) / Time.deltaTime; previousPositon = transform.position; computeShader.SetBuffer(emitKernel, "particles", particles); computeShader.SetBuffer(emitKernel, "alive", dead); computeShader.SetVector("seeds", new Vector3(Random.Range(1f, 10000f), Random.Range(1f, 10000f), Random.Range(1f, 10000f))); computeShader.SetVector("initialSpeedRange", new Vector2(minInitialSpeed, maxInitialSpeed)); computeShader.SetVector("inheritedPosition", transform.position); computeShader.SetVector("lifeRange", new Vector2(minLifetime, maxLifetime)); computeShader.SetVector("time", new Vector2(Time.deltaTime, Time.time)); computeShader.SetInt("colorMode", (int)colorMode); if (colorMode == ColorMode.Constant) { computeShader.SetVector("color", color); } else if (colorMode == ColorMode.OverLife) { computeShader.SetVector("color", colorOverLife.Evaluate(0f)); } if (sizeMode == SizeMode.Constant) { computeShader.SetFloat("size", size); } else if (colorMode == ColorMode.OverLife) { computeShader.SetFloat("size", sizeOverLife.Evaluate(0f)); } computeShader.SetInt("emissionShape", (int)emissionShape); if (emissionShape == EmissionShape.Sphere) { computeShader.SetFloat("radius", Mathf.Max(0.01f, sphereRadius)); } else if (emissionShape == EmissionShape.Box) { computeShader.SetVector("boxSize", boxSize); } else if (emissionShape == EmissionShape.Edge) { computeShader.SetVector("edgeStart", edgeStart); computeShader.SetVector("edgeEnd", edgeEnd); computeShader.SetFloat("radius", Mathf.Max(0.01f, edgeRadius)); } computeShader.SetInt("directionType", (int)directionType); if (directionType == DirectionType.Uniform) { computeShader.SetVector("direction", direction); } if (enableInheritVelocity) { computeShader.SetVector("inheritedVelocity", velocity * inheritVelocity); computeShader.SetFloat("extrapolation", extrapolation); } computeShader.Dispatch(emitKernel, count, 1, 1); } } }
void InitializeGPUBuffers() { int sizeOfVector3 = System.Runtime.InteropServices.Marshal.SizeOf((object)Vector3.zero); GPU_VertexBuffer = new ComputeBuffer(m_vertexBufferCPU.Length, sizeof(float) * 8); GPU_VertexBuffer.SetData(m_vertexBufferCPU); GPU_defaultPositionsBuffer = new ComputeBuffer(m_verticesPosition.Length, sizeOfVector3); GPU_defaultPositionsBuffer.SetData(m_verticesPosition); int kernel = m_computeShader.FindKernel(kernelName); m_computeShader.SetBuffer(kernel, "_VertexBuffer", GPU_VertexBuffer); m_computeShader.SetBuffer(kernel, "_InitialPositionBuffer", GPU_defaultPositionsBuffer); m_computeShader.SetFloat("_distanceBegin", ScaleFromWorldtoMeshSpace(m_colliderBeginDistance)); m_computeShader.SetFloat("_distnaceEnd", ScaleFromWorldtoMeshSpace(m_colliderEndDistance)); m_computeShader.SetFloat("_pushforce", m_pushforce); m_computeShader.SetFloat("_elacticity", m_elasticity); m_computeShader.SetFloat("_drag", m_drag); Debug.Log(string.Format("Initialized the GPU buffers with {0} vertices, for the compute shader", m_verticesPosition.Length)); if (m_renderingMethod == RenderMethod.WithDrawProcedural) { GPU_IndexBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Index, m_indexBuffer.Length, sizeof(int)); GPU_IndexBuffer.SetData(m_indexBuffer); } }
void SetUpPointLightBuffers(int kernel) { int count = m_PointLightParamsCB == null ? 0 : m_PointLightParamsCB.count; m_InjectLightingAndDensity.SetFloat("_PointLightsCount", count); if (count == 0) { m_InjectLightingAndDensity.SetBuffer(kernel, "_PointLights", dummyBuffer); return; } if (m_PointLightParams == null || m_PointLightParams.Length != count) { m_PointLightParams = new PointLightParams[count]; } HashSet <FogLight> fogLights = LightManagerFogLights.Get(); int j = 0; for (var x = fogLights.GetEnumerator(); x.MoveNext();) { var fl = x.Current; if (fl == null || fl.type != FogLight.Type.Point || !fl.isOn) { continue; } Light light = fl.light; m_PointLightParams[j].pos = light.transform.position; float range = light.range * fl.m_RangeMult; m_PointLightParams[j].range = 1.0f / (range * range); m_PointLightParams[j].color = new Vector3(light.color.r, light.color.g, light.color.b) * light.intensity * fl.m_IntensityMult; j++; } // TODO: try a constant buffer with setfloats instead for perf m_PointLightParamsCB.SetData(m_PointLightParams); m_InjectLightingAndDensity.SetBuffer(kernel, "_PointLights", m_PointLightParamsCB); }
IEnumerator OutputPerDirect() { renderTexture = new RenderTexture(screenWidth, screenHeight, 24); renderTexture.enableRandomWrite = true;//允许随机写入 renderTexture.Create(); int kid = RaytracingShader.FindKernel("CSMain"); int cid = texCombineShader.FindKernel("CSMain"); //传递基础数据 //shader.SetTexture(kid, "Result", renderTexture); RaytracingShader.SetFloat("width", screenWidth); RaytracingShader.SetFloat("height", screenHeight); //设置相机数据 RaytracingShader.SetVectorArray("camCorn", cameraCorn); RaytracingShader.SetVector("camPos", cameraPosition); //设置光追数据 RaytracingShader.SetInt("max_step", MAX_STEP); RaytracingShader.SetInt("max_sample", MAX_SAMPLE); //设置灯光数据 RaytracingShader.SetVector("sun", new Vector4(sun.transform.forward.x, sun.transform.forward.y, sun.transform.forward.z, sun.intensity)); //传Mesh数据 RaytracingShader.SetInt("vertexCount", mesh.vertexCount); RaytracingShader.SetInt("trianglesCount", mesh.triangles.Length); ComputeBuffer tris = new ComputeBuffer(mesh.triangles.Length, sizeof(int)); tris.SetData(mesh.triangles); ComputeBuffer vAndN = new ComputeBuffer(mesh.vertexCount, sizeof(float) * 6); List <VertAndNormal> _vAndNData = new List <VertAndNormal>(); for (int i = 0; i < mesh.vertexCount; i++) { _vAndNData.Add(new VertAndNormal() { vertices = mesh.vertices[i], normlas = mesh.normals[i] }); } vAndN.SetData(_vAndNData); RaytracingShader.SetBuffer(kid, "triangles", tris); RaytracingShader.SetBuffer(kid, "vertAndNormal", vAndN); //自动分割Tile //执行 for (int x = 0; x < tileCount.x; x++) { for (int y = 0; y < tileCount.y; y++) { Vector4 tileInfo = new Vector4(tileSize, tileSize, x, y); RenderTexture rt = RenderTexture.GetTemporary(tileSize, tileSize, 24); rt.enableRandomWrite = true; rt.Create(); RaytracingShader.SetTexture(kid, "Result", rt); RaytracingShader.SetVector("tile", tileInfo); RaytracingShader.Dispatch(kid, tileSize / 8, tileSize / 8, 1); texCombineShader.SetTexture(cid, "Result", renderTexture); texCombineShader.SetTexture(cid, "Tile", rt); texCombineShader.SetInt("offsetU", tileSize * x); texCombineShader.SetInt("offsetV", tileSize * y); texCombineShader.Dispatch(cid, tileSize / 8, tileSize / 8, 1); rt.Release(); yield return(null); } } //保存文件 RenderTexture _crt = RenderTexture.active; RenderTexture.active = renderTexture; Texture2D save = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.ARGB32, false); save.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0); save.Apply(); System.IO.File.WriteAllBytes("Assets/Save.png", save.EncodeToPNG()); }
void Update() { var dt = Time.deltaTime; var dx = 1.0f / ResolutionY; // Input point var input = new Vector2( (Input.mousePosition.x - Screen.width * 0.5f) / Screen.height, (Input.mousePosition.y - Screen.height * 0.5f) / Screen.height ); // Common variables _compute.SetFloat("Time", Time.time); _compute.SetFloat("DeltaTime", dt); // Advection _compute.SetTexture(Kernels.Advect, "U_in", VFB.V1); _compute.SetTexture(Kernels.Advect, "W_out", VFB.V2); _compute.Dispatch(Kernels.Advect, ThreadCountX, ThreadCountY, 1); // Diffuse setup var dif_alpha = dx * dx / (_viscosity * dt); _compute.SetFloat("Alpha", dif_alpha); _compute.SetFloat("Beta", 4 + dif_alpha); Graphics.CopyTexture(VFB.V2, VFB.V1); _compute.SetTexture(Kernels.Jacobi2, "B2_in", VFB.V1); // Jacobi iteration for (var i = 0; i < 20; i++) { _compute.SetTexture(Kernels.Jacobi2, "X2_in", VFB.V2); _compute.SetTexture(Kernels.Jacobi2, "X2_out", VFB.V3); _compute.Dispatch(Kernels.Jacobi2, ThreadCountX, ThreadCountY, 1); _compute.SetTexture(Kernels.Jacobi2, "X2_in", VFB.V3); _compute.SetTexture(Kernels.Jacobi2, "X2_out", VFB.V2); _compute.Dispatch(Kernels.Jacobi2, ThreadCountX, ThreadCountY, 1); } // Add external force _compute.SetVector("ForceOrigin", input); _compute.SetFloat("ForceExponent", _exponent); _compute.SetTexture(Kernels.Force, "W_in", VFB.V2); _compute.SetTexture(Kernels.Force, "W_out", VFB.V3); if (Input.GetMouseButton(1)) { // Random push _compute.SetVector("ForceVector", Random.insideUnitCircle * _force * 0.025f); } else if (Input.GetMouseButton(0)) { // Mouse drag _compute.SetVector("ForceVector", (input - _previousInput) * _force); } else { _compute.SetVector("ForceVector", Vector4.zero); } _compute.Dispatch(Kernels.Force, ThreadCountX, ThreadCountY, 1); // Projection setup _compute.SetTexture(Kernels.PSetup, "W_in", VFB.V3); _compute.SetTexture(Kernels.PSetup, "DivW_out", VFB.V2); _compute.SetTexture(Kernels.PSetup, "P_out", VFB.P1); _compute.Dispatch(Kernels.PSetup, ThreadCountX, ThreadCountY, 1); // Jacobi iteration _compute.SetFloat("Alpha", -dx * dx); _compute.SetFloat("Beta", 4); _compute.SetTexture(Kernels.Jacobi1, "B1_in", VFB.V2); for (var i = 0; i < 20; i++) { _compute.SetTexture(Kernels.Jacobi1, "X1_in", VFB.P1); _compute.SetTexture(Kernels.Jacobi1, "X1_out", VFB.P2); _compute.Dispatch(Kernels.Jacobi1, ThreadCountX, ThreadCountY, 1); _compute.SetTexture(Kernels.Jacobi1, "X1_in", VFB.P2); _compute.SetTexture(Kernels.Jacobi1, "X1_out", VFB.P1); _compute.Dispatch(Kernels.Jacobi1, ThreadCountX, ThreadCountY, 1); } // Projection finish _compute.SetTexture(Kernels.PFinish, "W_in", VFB.V3); _compute.SetTexture(Kernels.PFinish, "P_in", VFB.P1); _compute.SetTexture(Kernels.PFinish, "U_out", VFB.V1); _compute.Dispatch(Kernels.PFinish, ThreadCountX, ThreadCountY, 1); // Apply the velocity field to the color buffer. float colourVelocityMultiplier = 1e+7f; var offs = Vector2.one * (Input.GetMouseButton(1) ? 0 : colourVelocityMultiplier); _shaderSheet.SetVector("_ForceOrigin", input + offs); _shaderSheet.SetFloat("_ForceExponent", _exponent); _shaderSheet.SetTexture("_VelocityField", VFB.V1); Graphics.Blit(_colorRT1, _colorRT2, _shaderSheet, 0); // Swap the color buffers. var temp = _colorRT1; _colorRT1 = _colorRT2; _colorRT2 = temp; _previousInput = input; }
public void Make() { if (mesh == null) { MakeSphere(); return; } var tex = new RenderTexture(textureSize.x, textureSize.y, 0, RenderTextureFormat.RHalf); tex.enableRandomWrite = true; tex.dimension = UnityEngine.Rendering.TextureDimension.Tex3D; tex.volumeDepth = textureSize.z; tex.anisoLevel = 1; tex.filterMode = FilterMode.Bilinear; tex.autoGenerateMips = false; tex.wrapMode = TextureWrapMode.Repeat; tex.Create(); var vertexBuffer = new ComputeBuffer(mesh.vertexCount, sizeof(float) * 3); var idxes = mesh.triangles; var indexBuffer = new ComputeBuffer(idxes.Length, sizeof(int)); indexBuffer.SetData(idxes); var vertices = mesh.vertices; Bounds bounds = new Bounds(vertices[0], Vector3.zero); foreach (var vert in vertices) { bounds.Encapsulate(vert); } for (uint i = 0; i < vertices.Length; i++) { vertices[i] = Div(vertices[i] - bounds.center, bounds.size); } int sdfCompute = compute.FindKernel("MeshToSDFHollow"); if (mode == MeshToSDFMode.Hollow) { sdfCompute = compute.FindKernel("MeshToSDFHollow"); } else if (mode == MeshToSDFMode.Solid) { sdfCompute = compute.FindKernel("MeshToSDFSolid"); } else if (mode == MeshToSDFMode.Lines) { sdfCompute = compute.FindKernel("MeshToSDFLines"); } vertexBuffer.SetData(vertices); compute.SetBuffer(sdfCompute, "VertexBuffer", vertexBuffer); compute.SetBuffer(sdfCompute, "IndexBuffer", indexBuffer); compute.SetInt("tris", idxes.Length); compute.SetInts("dim", textureSize.x, textureSize.y, textureSize.z); compute.SetTexture(sdfCompute, "Result", tex); compute.SetFloat("scale", scale); compute.SetFloat("lineRadius", lineRadius); compute.GetKernelThreadGroupSizes(sdfCompute, out uint x, out uint y, out uint z); compute.Dispatch(sdfCompute, textureSize.x / (int)x, textureSize.y / (int)y, textureSize.z / (int)z); Save(tex); vertexBuffer.Release(); indexBuffer.Release(); return; }
void DoComputeSteps() { //TODO: Could switch between eyes? Would slightly blur the fog -> Probably nice if (Camera.current.stereoEnabled && Camera.current.stereoActiveEye == Camera.MonoOrStereoscopicEye.Right) { m_setting = Setting; //Do update default setting if it's null return; } Graphics.ClearRandomWriteTargets(); if (m_instant) { m_vaporCompute.SetFloat("_ExponentialWeight", 1.0f); m_instant = false; } else { m_vaporCompute.SetFloat("_ExponentialWeight", AveragingSpeed); } m_vaporCompute.SetFloat("_TemporalStrength", TemporalStrength); m_vaporCompute.SetInt("_Frame", Random.Range(0, m_blueNoiseTex.width * m_blueNoiseTex.height)); m_vaporCompute.SetVector("_CameraPos", Camera.current.transform.position); if (QualitySettings.shadowCascades == 2) { m_vaporCompute.SetVector("_ShadowRange", new Vector4(0.0f, 0.5f, 0.0f, 1.0f)); } else { m_vaporCompute.SetVector("_ShadowRange", new Vector4(0.5f, 0.5f)); } Matrix4x4 v; if (Camera.current.stereoEnabled) { v = m_camera.GetStereoViewMatrix(Camera.StereoscopicEye.Left); } else { v = m_camera.worldToCameraMatrix; } Vector2 jitter = GenerateRandomOffset(); jitter *= (TemporalStrength * 10); Matrix4x4 p = GetJitteredMatrix(m_camera, jitter); Matrix4x4 vp = p * v; //Set VP from old frame for reprojection Matrix4x4 vpi = vp.inverse; m_vaporCompute.SetMatrix("_VAPOR_REPROJECT", m_vpMatrixOld * vpi); m_vaporCompute.SetMatrix("_VAPOR_I_VP", vpi); m_vaporCompute.SetMatrix("_VAPOR_VP", vp); m_vpMatrixOld = vp; //Bind system settings { m_res[0] = m_densityTex.width; m_res[1] = m_densityTex.height; m_res[2] = m_densityTex.volumeDepth; m_vaporCompute.SetInts("_VaporResolution", m_res); m_vaporCompute.SetFloat("_VaporDepthPow", DepthCurvePower); Shader.SetGlobalFloat("_VaporDepthPow", DepthCurvePower); float near = m_camera.nearClipPlane; float far = m_camera.farClipPlane; Vector4 planeSettings = GetPlaneSettings(near, far); m_vaporCompute.SetVector("_VaporPlaneSettings", planeSettings); Shader.SetGlobalVector("_VaporPlaneSettings", planeSettings); Shader.SetGlobalTexture("_VaporFogTexture", m_integratedTexture); Shader.SetGlobalMatrix("_VAPOR_I_VP", vpi); Shader.SetGlobalMatrix("_VAPOR_VP", vp); float zc0 = 1.0f - far / near; float zc1 = far / near; m_vaporCompute.SetVector("_ZBufferParams", new Vector4(zc0, zc1, zc0 / far, zc1 / far)); for (int i = 0; i < 11; ++i) { m_vaporCompute.SetTexture(i, "_BlueNoise", m_blueNoiseTex); } } //Bind noise settings { Vector4 scale = new Vector4(2.5f, 1.0f, 2.5f); m_vaporCompute.SetVector("_NoiseWeights", NoiseWeights / (NoiseWeights.x + NoiseWeights.y + NoiseWeights.z)); float colMin = 1.0f - NoiseColorStrength; float extinctMin = 1.0f - NoiseExtinctionStrength; m_vaporCompute.SetVector("_NoiseMin", new Vector4(colMin, colMin, colMin, extinctMin)); m_vaporCompute.SetVector("_NoiseFrequency", Vector4.Scale(NoiseFrequency, scale)); m_vaporCompute.SetVector("_NoiseSpeed", Vector4.Scale(Vector4.Scale(NoiseSpeed, scale), NoiseFrequency) * 0.01f); m_vaporCompute.SetFloat("_NoisePower", NoisePower); } //Bind scattering settings { //refractive index of nitrogen const double indexSqr = 1.0002772 * 1.0002772; const double r = (indexSqr - 1) * (indexSqr - 1) / ((indexSqr + 2) * (indexSqr + 2)); double size = Mathf.Pow(ScatteringIntensity * 1e3f, 1.0f / 6.0f); float rsize = (float)(r * Math.Pow(size * ScatteringColor.r / 200.0f, 4.0f) * size * size * (1e-18 * 2.5e25)); float gsize = (float)(r * Math.Pow(size * ScatteringColor.g / 200.0f, 4.0f) * size * size * (1e-18 * 2.5e25)); float bsize = (float)(r * Math.Pow(size * ScatteringColor.b / 200.0f, 4.0f) * size * size * (1e-18 * 2.5e25)); Vector3 rayleighBase = new Vector3(rsize, gsize, bsize); Vector3 rayleighWeight = rayleighBase * Mathf.Pow(2.0f * Mathf.PI, 4.0f) / (Mathf.Pow(2.0f, 6.0f)); Vector3 rayleighCross = rayleighBase * 24 * Mathf.Pow(Mathf.PI, 3.0f); rayleighCross.x = (float)(Math.Pow(1.0 - rayleighCross.x, 1000)); rayleighCross.y = (float)(Math.Pow(1.0 - rayleighCross.y, 1000)); rayleighCross.z = (float)(Math.Pow(1.0 - rayleighCross.z, 1000)); m_vaporCompute.SetVector("_Rayleigh", rayleighWeight * 1e5f); m_vaporCompute.SetVector("_RayleighCross", rayleighCross); m_vaporCompute.SetVector("_MieScatter", new Vector4(DirectionalScatteringColor.r, DirectionalScatteringColor.g, DirectionalScatteringColor.b, DirectionalScattering * 0.999f)); m_vaporCompute.SetFloat("_LambertBeerDensity", Setting.Extinction * 0.1f); float planetSize = 8000; float atmoRadius = planetSize + AtmosphereThickness; m_vaporCompute.SetVector("_Atmosphere", new Vector4(AtmosphereRingPower, AtmosphereRingSize, atmoRadius * atmoRadius, planetSize)); } Profiler.BeginSample("Write global density"); Setting.Bind(m_vaporCompute, m_densityKernel, BlendToSetting, m_blendTime); m_vaporCompute.SetTexture(m_densityKernel, "_DensityTextureWrite", m_densityTex); m_vaporCompute.SetTexture(m_densityKernel, "_NoiseTex", NoiseTexture); m_vaporCompute.DispatchScaled(m_densityKernel, m_densityTex.width, m_densityTex.height, m_densityTex.volumeDepth); Profiler.EndSample(); Profiler.BeginSample("Vapor Object Passes"); //If there's no directional -> manual clear light buffer if (VaporObject.All.Count == 0 || (VaporObject.All[0] as VaporLight) == null || (VaporObject.All[0] as VaporLight).LightType != LightType.Directional) { SetLightAccum(m_lightClearKernel, false); m_vaporCompute.DispatchScaled(m_lightClearKernel, m_scatterTex.width, m_scatterTex.height, m_scatterTex.volumeDepth); } //Inject vapor objects for (int index = 0; index < VaporObject.All.Count; index++) { VaporObject vap = VaporObject.All[index]; vap.Inject(this, m_vaporCompute, vp); } Profiler.EndSample(); Setting.Bind(m_vaporCompute, m_densityKernel, BlendToSetting, m_blendTime); Profiler.BeginSample("Scattering"); SetLightAccum(m_scatterKernel, true); m_vaporCompute.SetTexture(m_scatterKernel, "_DensityTexture", m_densityTex); m_vaporCompute.SetTexture(m_scatterKernel, "_ScatterTextureOld", m_scatterTexOld); m_vaporCompute.SetTexture(m_scatterKernel, "_ScatterTexture", m_scatterTex); m_vaporCompute.DispatchScaled(m_scatterKernel, m_scatterTex.width, m_scatterTex.height, m_scatterTex.volumeDepth); Profiler.EndSample(); Profiler.BeginSample("Integration"); m_vaporCompute.SetTexture(m_integrateKernel, "_IntegratedTexture", m_integratedTexture); m_vaporCompute.SetTexture(m_integrateKernel, "_ScatterTextureOld", m_scatterTex); m_vaporCompute.DispatchScaled(m_integrateKernel, m_scatterTex.width, m_scatterTex.height, 1); Profiler.EndSample(); Profiler.BeginSample("Blit properties"); var temp = m_scatterTex; m_scatterTex = m_scatterTexOld; m_scatterTexOld = temp; Profiler.EndSample(); }
void Update() { Vector4[] charges = GPUInterface.Charges; Vector4[] seeds = FieldLineSeedingList(charges); _compute.SetVectorArray("_Charges", charges); _compute.SetInt("_ArrayLength", charges.Length); _compute.SetVectorArray("_FieldLineSeeds", seeds); _compute.SetInt("_SeedArrayLength", seeds.Length); // Warn if there are more charged objects in the scene than the maximum array length if (charges.Length > GPUInterface.maxChargeArrayLength) { Debug.LogWarning( $"There are {charges.Length.ToString()} charged objects in the scene, more than the maximum of {GPUInterface.maxChargeArrayLength.ToString()} for which electric flux can be calculated."); } // Invoke the update compute kernel. var kernel = _compute.FindKernel("FieldUpdate"); _compute.SetInt("InstanceCount", InstanceCount); _compute.SetInt("HistoryLength", HistoryLength); _compute.SetFloat("RandomSeed", _randomSeed); _compute.SetFloat("Spread", _spread); _compute.SetFloat("StepWidth", _length / _template.segments); //_compute.SetFloat("NoiseFrequency", _noiseFrequency); //_compute.SetVector("NoiseOffset", _noiseOffset); _compute.SetMatrix("_LocalToWorld", transform.localToWorldMatrix); _compute.SetBuffer(kernel, "PositionBuffer", _positionBuffer); _compute.Dispatch(kernel, ThreadGroupCount, 1, 1); // Invoke the reconstruction kernel. kernel = _compute.FindKernel("FieldReconstruct"); _compute.SetBuffer(kernel, "PositionBufferRO", _positionBuffer); _compute.SetBuffer(kernel, "TangentBuffer", _tangentBuffer); _compute.SetBuffer(kernel, "NormalBuffer", _normalBuffer); _compute.Dispatch(kernel, ThreadGroupCount, 1, 1); // Draw the mesh with instancing. _material.SetFloat("_Radius", _radius); _material.SetVector("_GradientA", _gradient.coeffsA); _material.SetVector("_GradientB", _gradient.coeffsB); _material.SetVector("_GradientC", _gradient.coeffsC2); _material.SetVector("_GradientD", _gradient.coeffsD2); _material.SetMatrix("_LocalToWorld", transform.localToWorldMatrix); _material.SetMatrix("_WorldToLocal", transform.worldToLocalMatrix); _material.SetBuffer("_PositionBuffer", _positionBuffer); _material.SetBuffer("_TangentBuffer", _tangentBuffer); _material.SetBuffer("_NormalBuffer", _normalBuffer); _material.SetInt("_InstanceCount", InstanceCount); _material.SetInt("_HistoryLength", HistoryLength); _material.SetInt("_IndexLimit", HistoryLength); Graphics.DrawMeshInstancedIndirect( _template.mesh, 0, _material, new Bounds(transform.position, transform.lossyScale * 5), _drawArgsBuffer, 0, _props, ShadowCastingMode.Off, false ); // Move the noise field. //_noiseOffset += _noiseMotion * Time.deltaTime; }
/// <summary> /// Computes the volumetric data /// </summary> public void ComputeData() { if (!_hasInitializedBuffers) { CreateBuffers(settings.resolution); } settings.ComputeFlags(); #region Variables _farClip = Mathf.Min(Aura.CameraComponent.farClipPlane, Mathf.Max(Aura.CameraComponent.nearClipPlane, settings.farClipPlaneDistance)); _cameraRanges = new Vector4(Aura.CameraComponent.nearClipPlane, _farClip); Shader.SetGlobalVector("Aura_FrustumRange", _cameraRanges); _zParameters = new Vector4(-1.0f + Aura.CameraComponent.farClipPlane / Aura.CameraComponent.nearClipPlane, 1.0f); _zParameters.z = _zParameters.x / Aura.CameraComponent.farClipPlane; _zParameters.w = _zParameters.y / Aura.CameraComponent.farClipPlane; _volumeDepth = _farClip - Aura.CameraComponent.nearClipPlane; _layerDepth = _volumeDepth / _resolutionVector.z; _inverseLayerDepth = 1.0f / _layerDepth; #endregion #region Occlusion culling if (settings.HasFlags(FrustumParametersEnum.EnableOcclusionCulling)) { Profiler.BeginSample("Aura : Compute occlusion culling data"); _computeMaximumDepthComputeShader.SetTextureFromGlobal((int)settings.occlusionCullingAccuracy, "depthTexture", "_CameraDepthTexture"); // TODO : USE EVENT TO SET TEXTURES _computeMaximumDepthComputeShader.SetVector("cameraRanges", _cameraRanges); _computeMaximumDepthComputeShader.SetVector("zParameters", _zParameters); _computeMaximumDepthComputeShader.SetTexture((int)settings.occlusionCullingAccuracy, "occlusionTexture", _buffers.OcclusionTexture.WriteBuffer); _computeMaximumDepthComputeShader.Dispatch((int)settings.occlusionCullingAccuracy, settings.resolution.x, settings.resolution.y, 1); //Par blocks puis repasser en resolution _buffers.OcclusionTexture.Swap(); if (_processOcclusionMapMaterial == null) { _processOcclusionMapMaterial = new Material(_processOcclusionMapShader); } _processOcclusionMapMaterial.SetVector("bufferResolution", _resolutionVector); Graphics.Blit(_buffers.OcclusionTexture.ReadBuffer, _buffers.OcclusionTexture.WriteBuffer, _processOcclusionMapMaterial); _buffers.OcclusionTexture.Swap(); _computeDataComputeShader.SetTexture(settings.GetId(), "occlusionTexture", _buffers.OcclusionTexture.ReadBuffer); // TODO : USE EVENT TO SET TEXTURES _computeAccumulationComputeShader.SetTexture(1, "occlusionTexture", _buffers.OcclusionTexture.ReadBuffer); // TODO : USE EVENT TO SET TEXTURES _buffers.FogVolumeTexture.Clear(Color.black); Profiler.EndSample(); } #endregion #region Compute contributions Profiler.BeginSample("Aura : Compute volumetric lighting and density"); _buffers.LightingVolumeTextures.Swap(); Shader.SetGlobalTexture("Aura_VolumetricDataTexture", _buffers.LightingVolumeTextures.WriteBuffer); // TODO : USE EVENT TO SET TEXTURES _buffers.LightingVolumeTextures.WriteBuffer.Clear(new Color(0, 0, 0, -10)); _computeDataComputeShader.SetTexture(settings.GetId(), "textureBuffer", _buffers.LightingVolumeTextures.WriteBuffer); // TODO : USE EVENT TO SET TEXTURES _computeDataComputeShader.SetTexture(settings.GetId(), "previousFrameLightingVolumeTexture", _buffers.LightingVolumeTextures.ReadBuffer); // TODO : USE EVENT TO SET TEXTURES _computeDataComputeShader.SetFloat("time", Aura.Time); _computeDataComputeShader.SetVector("cameraPosition", Aura.CameraComponent.transform.position); _computeDataComputeShader.SetVector("cameraRanges", _cameraRanges); _computeDataComputeShader.SetFloat("layerDepth", _layerDepth); _computeDataComputeShader.SetFloat("invLayerDepth", _inverseLayerDepth); _computeDataComputeShader.SetFloats("frustumCornersWorldPositionArray", Aura.CameraComponent.GetFrustumCornersWorldPosition(Aura.CameraComponent.nearClipPlane, _farClip).AsFloatArray()); _computeDataComputeShader.SetFloat("baseDensity", settings.density); _computeDataComputeShader.SetFloat("baseAnisotropy", settings.anisotropy); _computeDataComputeShader.SetVector("baseColor", settings.color * settings.colorStrength); #region Temporal Reprojection if (settings.HasFlags(FrustumParametersEnum.EnableTemporalReprojection)) { _computeDataComputeShader.SetFloat("temporalReprojectionFactor", settings.temporalReprojectionFactor); _computeDataComputeShader.SetVector("cameraRanges", _cameraRanges); _computeDataComputeShader.SetInt("_frameID", Aura.FrameId); } #endregion #region Volumes Injection if (settings.HasFlags(FrustumParametersEnum.EnableVolumes)) { _computeDataComputeShader.SetInt("volumeCount", Aura.VolumesManager.Buffer.count); _computeDataComputeShader.SetBuffer(settings.GetId(), "volumeDataBuffer", Aura.VolumesManager.Buffer); if (settings.HasFlags(FrustumParametersEnum.EnableVolumesTextureMask)) { _computeDataComputeShader.SetTexture(settings.GetId(), "volumeMaskTexture", Aura.VolumesManager.VolumeTexture); // TODO : USE EVENT TO SET TEXTURES } } #endregion #region Directional lights if (settings.HasFlags(FrustumParametersEnum.EnableDirectionalLights)) { _computeDataComputeShader.SetInt("directionalLightCount", Aura.LightsManager.DirectionalLightsManager.DataBuffer.count); _computeDataComputeShader.SetBuffer(settings.GetId(), "directionalLightDataBuffer", Aura.LightsManager.DirectionalLightsManager.DataBuffer); if (settings.HasFlags(FrustumParametersEnum.EnableDirectionalLightsShadows)) { _computeDataComputeShader.SetTexture(settings.GetId(), "directionalShadowMapsArray", Aura.LightsManager.DirectionalLightsManager.ShadowMapsArray); // TODO : USE EVENT TO SET TEXTURES _computeDataComputeShader.SetTexture(settings.GetId(), "directionalShadowDataArray", Aura.LightsManager.DirectionalLightsManager.ShadowDataArray); // TODO : USE EVENT TO SET TEXTURES } if (settings.HasFlags(FrustumParametersEnum.EnableLightsCookies) && Aura.LightsManager.DirectionalLightsManager.HasCookieCasters) { _computeDataComputeShader.SetTexture(settings.GetId(), "directionalCookieMapsArray", Aura.LightsManager.DirectionalLightsManager.CookieMapsArray); // TODO : USE EVENT TO SET TEXTURES } } #endregion #region Spot lights if (settings.HasFlags(FrustumParametersEnum.EnableSpotLights)) { _computeDataComputeShader.SetInt("spotLightCount", Aura.LightsManager.SpotLightsManager.DataBuffer.count); _computeDataComputeShader.SetBuffer(settings.GetId(), "spotLightDataBuffer", Aura.LightsManager.SpotLightsManager.DataBuffer); if (settings.HasFlags(FrustumParametersEnum.EnableSpotLightsShadows)) { _computeDataComputeShader.SetTexture(settings.GetId(), "spotShadowMapsArray", Aura.LightsManager.SpotLightsManager.ShadowMapsArray); // TODO : USE EVENT TO SET TEXTURES } if (settings.HasFlags(FrustumParametersEnum.EnableLightsCookies) && Aura.LightsManager.SpotLightsManager.HasCookieCasters) { _computeDataComputeShader.SetTexture(settings.GetId(), "spotCookieMapsArray", Aura.LightsManager.SpotLightsManager.CookieMapsArray); // TODO : USE EVENT TO SET TEXTURES } } #endregion #region Point lights if (settings.HasFlags(FrustumParametersEnum.EnablePointLights)) { _computeDataComputeShader.SetInt("pointLightCount", Aura.LightsManager.PointLightsManager.DataBuffer.count); _computeDataComputeShader.SetBuffer(settings.GetId(), "pointLightDataBuffer", Aura.LightsManager.PointLightsManager.DataBuffer); if (settings.HasFlags(FrustumParametersEnum.EnablePointLightsShadows)) { _computeDataComputeShader.SetTexture(settings.GetId(), "pointShadowMapsArray", Aura.LightsManager.PointLightsManager.ShadowMapsArray); // TODO : USE EVENT TO SET TEXTURES } if (settings.HasFlags(FrustumParametersEnum.EnableLightsCookies) && Aura.LightsManager.PointLightsManager.HasCookieCasters) { _computeDataComputeShader.SetTexture(settings.GetId(), "pointCookieMapsArray", Aura.LightsManager.PointLightsManager.CookieMapsArray); // TODO : USE EVENT TO SET TEXTURES } } #endregion #region Compute _computeDataComputeShader.Dispatch(settings.GetId(), _computeDataComputeShaderDispatchSizeX, _computeDataComputeShaderDispatchSizeY, _computeDataComputeShaderDispatchSizeZ); Profiler.EndSample(); #endregion #endregion #region Accumulate fog texture Profiler.BeginSample("Aura : Compute accumulated contributions"); _computeAccumulationComputeShader.SetFloat("layerDepth", _layerDepth); _computeAccumulationComputeShader.SetFloat("invLayerDepth", _inverseLayerDepth); _computeAccumulationComputeShader.SetTexture(0, "textureBuffer", _buffers.LightingVolumeTextures.WriteBuffer); // TODO : USE EVENT TO SET TEXTURES _computeAccumulationComputeShader.SetTexture(1, "textureBuffer", _buffers.LightingVolumeTextures.WriteBuffer); // TODO : USE EVENT TO SET TEXTURES _computeAccumulationComputeShader.SetFloat("normalizationCoefficient", -(_farClip - Aura.CameraComponent.nearClipPlane) / 256.0f); // simplified from : (farClip - Aura.cameraComponent.nearClipPlane) / resolution.z) [->layerDepth] * (bufferResolution.z / 256.0f) [->buffer resolution normalization (256.0f is an abritrary scale factor)] * -1 [->needed for exponential function] _computeAccumulationComputeShader.Dispatch(settings.HasFlags(FrustumParametersEnum.EnableOcclusionCulling) ? 1 : 0, _computeAccumulationComputeShaderDispatchSizeX, _computeAccumulationComputeShaderDispatchSizeY, _computeAccumulationComputeShaderDispatchSizeZ); Profiler.EndSample(); #endregion _computeDataComputeShader.SetFloats("previousFrameWorldToClipMatrix", FrustumCorners.GetWorldToClipMatrix(Aura.CameraComponent, _farClip).ToFloatArray()); }
public void DrawMetaBalls(List <SphereCollider> balls, Bounds bounds) { int width = Samples; int height = Samples; int depth = Samples; var scale = new Vector3( bounds.size.x / (float)width, bounds.size.y / (float)height, bounds.size.z / (float)depth); //Clear the buffer from last frame. _clearBuffer.SetInt("_Width", width); _clearBuffer.SetInt("_Height", height); _clearBuffer.SetInt("_Depth", depth); _clearBuffer.Dispatch(0, width / 8, height / 8, depth / 8); // generate voxel field data _metaBallsCompute.SetInt("_Width", width); _metaBallsCompute.SetInt("_Height", height); _metaBallsCompute.SetVector("_Offset", bounds.min); _metaBallsCompute.SetVector("_Scale", scale); SetBallData(balls); _ballsBuffer.SetData(_ballDataArray); _metaBallsCompute.SetInt("_BallCount", Math.Min(MaxBalls, balls.Count)); _metaBallsCompute.Dispatch(0, width / 8, height / 8, depth / 8); // generate voxel normals // TODO generate metaball vert normals properly instead of sampling implied voxel normals _normals.SetInt("_Width", width); _normals.SetInt("_Height", height); _normals.Dispatch(0, width / 8, height / 8, depth / 8); // generate the mesh _marchingCubes.SetInt("_Width", width); _marchingCubes.SetInt("_Height", height); _marchingCubes.SetInt("_Depth", depth); _marchingCubes.SetInt("_Border", 0); _marchingCubes.SetFloat("_Target", _threshold); _marchingCubes.SetVector("_Offset", bounds.min); _marchingCubes.SetVector("_Scale", scale); _marchingCubes.Dispatch(0, width / 8, height / 8, depth / 8); // Draw metaballs // TODO make this a field so we don't allocate more than one MaterialPropertyBlock properties = new MaterialPropertyBlock(); properties.SetBuffer("_Buffer", _meshBuffer); Graphics.DrawProcedural( material: _drawBufferMaterial, bounds: bounds, topology: MeshTopology.Triangles, vertexCount: width * height * depth * MaxVertsPerVoxel, instanceCount: 1, camera: null, properties: properties, castShadows: ShadowCastingMode.On, receiveShadows: true); }
void SetConstants() { SPHComputeShader.SetFloat("_RestDensity", RestDensity); SPHComputeShader.SetFloat("_PressureCoef", PressureCoef); SPHComputeShader.SetFloat("_Mass", Mass); SPHComputeShader.SetFloat("_EffectiveRadius", EffectiveRadius); SPHComputeShader.SetFloat("_TimeStep", TimeStep); SPHComputeShader.SetFloat("_Viscosity", ViscosityCoef); SPHComputeShader.SetFloat("_WallStiffness", WallStiffness); SPHComputeShader.SetFloat("_ParticleGap", ParticleInitGap); SPHComputeShader.SetVector("_Gravity", Gravity); SPHComputeShader.SetVector("_MinBoundary", MinBoundary); SPHComputeShader.SetVector("_MaxBoundary", MaxBoundary); SPHComputeShader.SetInt("_MaxParticles", maxParticles); SPHComputeShader.SetFloat("_Poly6Kernel", Poly6Kernel); SPHComputeShader.SetFloat("_SpikeyKernel", SpikeyKernel); SPHComputeShader.SetFloat("_LapKernel", LapKernel); SPHComputeShader.SetFloats("_WallNormals", WallNormals); Vector3 mousePos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, -Camera.main.transform.position.z); Vector3 worldMousePos = Camera.main.ScreenToWorldPoint(mousePos); SPHComputeShader.SetVector("_MousePosition", worldMousePos); }
private void InitShader() { shader.SetFloat("radius", radius); shader.SetVector("scale", transform.localScale); }
// GPUPerlinNoise perlin; void Start() { //Allows this camera to draw mesh procedurally. // PostRenderEvent.AddEvent(Camera.main, DrawMesh); //There are 8 threads run per group so N must be divisible by 8. if (N % 8 != 0) { throw new System.ArgumentException("N must be divisible be 8"); } //Holds the voxel values, generated from perlin noise. m_noiseBuffer = new ComputeBuffer(N * N * N, sizeof(float)); //Holds the normals of the voxels. m_normalsBuffer = new RenderTexture(N, N, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear); m_normalsBuffer.dimension = TextureDimension.Tex3D; m_normalsBuffer.enableRandomWrite = true; m_normalsBuffer.useMipMap = false; m_normalsBuffer.volumeDepth = N; m_normalsBuffer.Create(); //Holds the verts generated by the marching cubes. m_meshBuffer = new ComputeBuffer(SIZE, sizeof(float) * 7); //Clear the mesh verts to -1. See the TriangleConnectionTable. //Only verts that get generated will then have a value of 1. //Only required if reading back the mesh. //Could also use the ClearMesh compute shader provided. float[] val = new float[SIZE * 7]; for (int i = 0; i < SIZE * 7; i++) { val[i] = -1.0f; } m_meshBuffer.SetData(val); //These two buffers are just some settings needed by the marching cubes. m_cubeEdgeFlags = new ComputeBuffer(256, sizeof(int)); // m_cubeEdgeFlags.SetData(MarchingCubesTables.CubeEdgeFlags); m_triangleConnectionTable = new ComputeBuffer(256 * 16, sizeof(int)); // m_triangleConnectionTable.SetData(MarchingCubesTables.TriangleConnectionTable); //Make the perlin noise, make sure to load resources to match shader used. // perlin = new GPUPerlinNoise(m_seed); // perlin.LoadResourcesFor3DNoise(); //Make the voxels. m_perlinNoise.SetInt("_Width", N); m_perlinNoise.SetInt("_Height", N); m_perlinNoise.SetFloat("_Frequency", 0.02f); m_perlinNoise.SetFloat("_Lacunarity", 2.0f); m_perlinNoise.SetFloat("_Gain", 0.5f); //m_perlinNoise.SetTexture(0, "_PermTable2D", perlin.PermutationTable2D); // m_perlinNoise.SetTexture(0, "_Gradient3D", perlin.Gradient3D); m_perlinNoise.SetBuffer(0, "_Result", m_noiseBuffer); m_perlinNoise.Dispatch(0, N / 8, N / 8, N / 8); //Make the voxel normals. m_normals.SetInt("_Width", N); m_normals.SetInt("_Height", N); m_normals.SetBuffer(0, "_Noise", m_noiseBuffer); m_normals.SetTexture(0, "_Result", m_normalsBuffer); m_normals.Dispatch(0, N / 8, N / 8, N / 8); //Make the mesh verts m_marchingCubes.SetInt("_Width", N); m_marchingCubes.SetInt("_Height", N); m_marchingCubes.SetInt("_Depth", N); m_marchingCubes.SetInt("_Border", 1); m_marchingCubes.SetFloat("_Target", 0.0f); m_marchingCubes.SetBuffer(0, "_Voxels", m_noiseBuffer); m_marchingCubes.SetTexture(0, "_Normals", m_normalsBuffer); m_marchingCubes.SetBuffer(0, "_Buffer", m_meshBuffer); m_marchingCubes.SetBuffer(0, "_CubeEdgeFlags", m_cubeEdgeFlags); m_marchingCubes.SetBuffer(0, "_TriangleConnectionTable", m_triangleConnectionTable); m_marchingCubes.Dispatch(0, N / 8, N / 8, N / 8); //Reads back the mesh data from the GPU and turns it into a standard unity mesh. //ReadBackMesh(m_meshBuffer); }