Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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));
        }
Exemplo n.º 3
0
    // 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);
 }
Exemplo n.º 5
0
        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);
    }
Exemplo n.º 7
0
        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));
        }
Exemplo n.º 8
0
 public virtual void _SetInternal()
 {
     shader.SetFloat("_Time", Time.time);
     shader.SetFloat("_Delta", Time.deltaTime);
     shader.SetFloat("_DT", Time.deltaTime);
 }
Exemplo n.º 9
0
    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);
    }
Exemplo n.º 10
0
    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);
    }
Exemplo n.º 11
0
 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));
    }
Exemplo n.º 13
0
    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));
    }
Exemplo n.º 14
0
        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);
        }
Exemplo n.º 15
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();
    }
Exemplo n.º 16
0
    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);
    }
Exemplo n.º 17
0
    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);
    }
Exemplo n.º 18
0
        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);
                }
            }
        }
Exemplo n.º 19
0
    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);
        }
    }
Exemplo n.º 20
0
    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);
    }
Exemplo n.º 21
0
    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());
    }
Exemplo n.º 22
0
        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;
        }
Exemplo n.º 23
0
    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;
    }
Exemplo n.º 24
0
    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();
    }
Exemplo n.º 25
0
        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;
        }
Exemplo n.º 26
0
        /// <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());
        }
Exemplo n.º 27
0
        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);
        }
Exemplo n.º 28
0
        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);
        }
Exemplo n.º 29
0
 private void InitShader()
 {
     shader.SetFloat("radius", radius);
     shader.SetVector("scale", transform.localScale);
 }
Exemplo n.º 30
0
        // 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);
        }