Exemplo n.º 1
0
 private void PrepareComputeBuffer(int count)
 {
     if (outputBuffer is not null && outputBuffer.count >= count)
     {
         return;
     }
     outputBuffer?.Release();
     outputBuffer = new ComputeBuffer(math.max(count * 2, 1024), sizeof(int));
     computeShader?.SetBuffer(mainKernel.index, ShaderPropertyIds.OutputBuffer, outputBuffer);
 }
Exemplo n.º 2
0
    public static void ReadSingleFromRenderTexture(RenderTexture tex, float x, float y, float z, ComputeBuffer buffer, ComputeShader readData, bool useBilinear)
    {
        if (tex == null)
        {
            Debug.Log("CBUtility: ReadSingleFromRenderTexture - RenderTexture is null!");
            return;
        }

        if (buffer == null)
        {
            Debug.Log("CBUtility: ReadSingleFromRenderTexture - buffer is null!");
            return;
        }

        if (readData == null)
        {
            Debug.Log("CBUtility: ReadSingleFromRenderTexture - Computer shader is null!");
            return;
        }

        if (!tex.IsCreated())
        {
            Debug.Log("CBUtility: ReadSingleFromRenderTexture - tex has not been created (Call Create() on tex)!");
            return;
        }

        int    kernel = -1;
        int    depth  = 1;
        string D      = "2D";
        string B      = (useBilinear) ? "Bilinear" : "";

        if (tex.dimension == UnityEngine.Rendering.TextureDimension.Tex3D)
        {
            depth = tex.volumeDepth;
            D     = "3D";
        }

        kernel = readData.FindKernel("readSingle" + B + D);

        if (kernel == -1)
        {
            Debug.LogFormat("CBUtility::ReadSingleFromRenderTexture - could not find kernel readSingle{0}", B + D);
            return;
        }

        int width  = tex.width;
        int height = tex.height;

        //set the compute shader uniforms
        readData.SetTexture(kernel, "_Tex" + D, tex);
        readData.SetBuffer(kernel, "_BufferSingle" + D, buffer);

        //used for point sampling
        readData.SetInt("_IdxX", (int)x);
        readData.SetInt("_IdxY", (int)y);
        readData.SetInt("_IdxZ", (int)z);

        //used for bilinear sampling
        readData.SetVector("_UV", new Vector4(x / (float)(width - 1), y / (float)(height - 1), z / (float)(depth - 1), 0.0f));

        readData.Dispatch(kernel, 1, 1, 1);
    }
Exemplo n.º 3
0
    void Start()
    {
        transform.position       = HivePosition;
        hiveTransform.localScale = new Vector3(hiveRadius, hiveRadius, hiveRadius);

        swarmKernel = swarmComputeShader.FindKernel("TargetSwarmMain");
        worldKernel = swarmComputeShader.FindKernel("TargetWorldUpdateMain");

        // Create rotation matrices
        CreateRotationMatrices();

        // Create the worldtexture
        worldTexture = CreateRenderTexture();

        // Create and init swarmer compute buffers
        swarmBuffer = new ComputeBuffer(numSwarmers, 56);
        Swarmer[] swarmers = new Swarmer[numSwarmers];
        for (int i = 0; i < swarmers.Length; i++)
        {
            swarmers[i].color    = new Vector3(0.20f, 1f, 0f);
            swarmers[i].position = HivePosition;/* + new Vector3(  Random.Range(-spawnRange, spawnRange),
                                                 *              Random.Range(-spawnRange, spawnRange),
                                                 *              Random.Range(-spawnRange, spawnRange));*/

            swarmers[i].previousPosition = swarmers[i].position;

            swarmers[i].direction = new Vector3(Random.Range(-1.0f, 1.0f),
                                                Random.Range(-1.0f, 1.0f),
                                                Random.Range(-1.0f, 1.0f)).normalized;

            swarmers[i].scent          = 0;
            swarmers[i].pheromoneScent = 0;
        }
        swarmBuffer.SetData(swarmers);

        // Create and init swarm targets compute buffer
        swarmTargetBuffer = new ComputeBuffer(targets.Length, 16);
        SwarmTarget[] swarmTargets = new SwarmTarget[targets.Length];
        for (int i = 0; i < swarmTargets.Length; i++)
        {
            swarmTargets[i].position = HivePosition + targets[i].localPosition;
            swarmTargets[i].hp       = 1;
        }
        swarmTargetBuffer.SetData(swarmTargets);

        // Set swarm comput shader data
        swarmComputeShader.SetInt("width", worldSize.x);
        swarmComputeShader.SetInt("height", worldSize.y);
        swarmComputeShader.SetInt("depth", worldSize.z);
        swarmComputeShader.SetTexture(swarmKernel, "worldTex", worldTexture);
        swarmComputeShader.SetBuffer(swarmKernel, "swarmers", swarmBuffer);
        swarmComputeShader.SetBuffer(swarmKernel, "targets", swarmTargetBuffer);
        swarmComputeShader.SetInt("numTargets", swarmTargets.Length);

        swarmComputeShader.SetFloats("hiveX", HivePosition.x);
        swarmComputeShader.SetFloats("hiveY", HivePosition.y);
        swarmComputeShader.SetFloats("hiveZ", HivePosition.z);
        swarmComputeShader.SetFloats("traceAdd", traceAdd);
        swarmComputeShader.SetFloats("traceDecay", traceDecay);
        swarmComputeShader.SetFloat("traceAttraction", traceAttraction);
        swarmComputeShader.SetFloat("swarmerSpeed", swarmerSpeed);
        swarmComputeShader.SetMatrix("rot1", rotMat1);
        swarmComputeShader.SetMatrix("rot2", rotMat2);
        swarmComputeShader.SetMatrix("rot3", rotMat3);
        swarmComputeShader.SetMatrix("rot4", rotMat4);
        swarmComputeShader.SetMatrix("rot5", rotMat5);
        swarmComputeShader.SetMatrix("rot6", rotMat6);
        swarmComputeShader.SetFloat("randomness", randomness);
        swarmComputeShader.SetFloat("hiveRadius", hiveRadius);

        swarmComputeShader.SetTexture(worldKernel, "worldTex", worldTexture);

        Debug.Log($"Hiveposition: {HivePosition}");


        // Set rendering materials data
        swarmerMaterial.SetBuffer("swarmers", swarmBuffer);


        // Debug
        debugWorldNodes = new WorldNode[NumWorldNodes];
    }
    protected override void OnPreRenderImage(ComputeShader compute, RenderTexture src, RenderTexture dst)
    {
        var sdfShapes = RayMarchedShape.GetShapes();
        int numShapes = sdfShapes.Count;

        if (m_shapes == null ||
            m_shapes.count != numShapes)
        {
            if (m_shapes != null)
            {
                m_shapes.Dispose();
            }

            m_shapes = new ComputeBuffer(Mathf.Max(1, numShapes), SdfShape.Stride);
        }

        if (m_heatMap == null ||
            m_heatMap.width != src.width ||
            m_heatMap.height != src.height)
        {
            if (m_heatMap != null)
            {
                DestroyImmediate(m_heatMap);
                m_heatMap = null;
            }

            m_heatMap = new RenderTexture(src.width, src.height, 0, RenderTextureFormat.RFloat);
            m_heatMap.enableRandomWrite = true;
            m_heatMap.Create();
        }

        m_shapes.SetData(sdfShapes);

        var camera = GetComponent <Camera>();

        if (m_const.Kernels == null)
        {
            InitShaderConstants();
        }

        foreach (int kernel in m_const.Kernels)
        {
            compute.SetTexture(kernel, m_const.Src, src);
            compute.SetTexture(kernel, m_const.Dst, dst);
            compute.SetTexture(kernel, m_const.HeatMap, m_heatMap);

            compute.SetBuffer(kernel, m_const.SdfShapes, m_shapes);
        }

        compute.SetMatrix(m_const.CameraInverseProjection, camera.projectionMatrix.inverse);
        compute.SetMatrix(m_const.CameraToWorld, camera.cameraToWorldMatrix);
        compute.SetVector(m_const.CameraPosition, camera.transform.position);
        compute.SetInts(m_const.ScreenSize, new int[] { camera.pixelWidth, camera.pixelHeight });

        compute.SetInt(m_const.NumSdfShapes, numShapes);

        compute.SetVector(m_const.RayMarchParams, new Vector4(MaxRaySteps, RayHitThreshold, MaxRayDistance, Time.time));
        compute.SetFloat(m_const.BlendDistance, BlendDistance);

        compute.SetVector(m_const.BackgroundColor, new Vector4(BackgroundColor.r, BackgroundColor.g, BackgroundColor.b, BackgroundColor.a));
        compute.SetVector(m_const.MissColor, new Vector4(MissColor.r, MissColor.g, MissColor.b, MissColor.a));

        compute.SetVector(m_const.HeatColorCool, new Vector4(HeatColorCool.r, HeatColorCool.g, HeatColorCool.b, HeatColorCool.a));
        compute.SetVector(m_const.HeatColorMedium, new Vector4(HeatColorMedium.r, HeatColorMedium.g, HeatColorMedium.b, HeatColorMedium.a));
        compute.SetVector(m_const.HeatColorHot, new Vector4(HeatColorHot.r, HeatColorHot.g, HeatColorHot.b, HeatColorHot.a));
        compute.SetFloat(m_const.HeatAlpha, HeatAlpha);
    }
Exemplo n.º 5
0
    static public void WriteIntoRenderTexture(RenderTexture tex, int channels, string path, ComputeBuffer buffer, ComputeShader writeData)
    {
        if (tex == null)
        {
            Debug.Log("CBUtility::WriteIntoRenderTexture - RenderTexture is null");
            return;
        }

        if (buffer == null)
        {
            Debug.Log("CBUtility::WriteIntoRenderTexture - buffer is null");
            return;
        }

        if (writeData == null)
        {
            Debug.Log("CBUtility::WriteIntoRenderTexture - Computer shader is null");
            return;
        }

        if (channels < 1 || channels > 4)
        {
            Debug.Log("CBUtility::WriteIntoRenderTexture - Channels must be 1, 2, 3, or 4");
            return;
        }

        if (!tex.enableRandomWrite)
        {
            Debug.Log("CBUtility::WriteIntoRenderTexture - you must enable random write on render texture");
            return;
        }

        if (!tex.IsCreated())
        {
            Debug.Log("CBUtility::WriteIntoRenderTexture - tex has not been created (Call Create() on tex)");
            return;
        }

        int    kernel = -1;
        int    depth  = 1;
        string D      = "2D";
        string C      = "C" + channels.ToString();

        if (tex.dimension == UnityEngine.Rendering.TextureDimension.Tex3D)
        {
            depth = tex.volumeDepth;
            D     = "3D";
        }

        kernel = writeData.FindKernel("write" + D + C);

        if (kernel == -1)
        {
            Debug.Log("CBUtility::WriteIntoRenderTexture - could not find kernel " + "write" + D + C);
            return;
        }

        int width  = tex.width;
        int height = tex.height;
        int size   = width * height * depth * channels;

        float[] map = new float[size];

        if (!LoadRawFile(path, map, size))
        {
            return;
        }

        buffer.SetData(map);

        //set the compute shader uniforms
        writeData.SetTexture(kernel, "_Des" + D + C, tex);
        writeData.SetInt("_Width", width);
        writeData.SetInt("_Height", height);
        writeData.SetInt("_Depth", depth);
        writeData.SetBuffer(kernel, "_Buffer" + D + C, buffer);
        //run the  compute shader. Runs in threads of 8 so non divisable by 8 numbers will need
        //some extra threadBlocks. This will result in some unneeded threads running
        int padX = (width % 8 == 0) ? 0 : 1;
        int padY = (height % 8 == 0) ? 0 : 1;
        int padZ = (depth % 8 == 0) ? 0 : 1;

        writeData.Dispatch(kernel, Mathf.Max(1, width / 8 + padX), Mathf.Max(1, height / 8 + padY), Mathf.Max(1, depth / 8 + padZ));
    }
    void DoSpawning()
    {
        //Sets the buffers of the spawn function
        cShade.SetBuffer(cShade.FindKernel(_SpawnKernelName), "CdeadList", DeadBuffer);
        cShade.SetBuffer(cShade.FindKernel(_SpawnKernelName), "WvertPos", PosBuffer[READ]);
        cShade.SetBuffer(cShade.FindKernel(_SpawnKernelName), "WvertVel", VelBuffer[READ]);
        cShade.SetBuffer(cShade.FindKernel(_SpawnKernelName), "WvertDat", IdAgeBuffer[READ]);

        spawnCount += Mathf.Abs(psystem.particlesToSpawnPerFrame) * this.simSpeed;
        int intspawnCount = Mathf.FloorToInt(spawnCount);

        int toSpawnThisFrame = (int)Mathf.Min(intspawnCount, (int)(this.deadParticles / 64));

        if (toSpawnThisFrame * 64 > this.deadParticles)
        {
            //Debug.Log("NOSPAWN>> ded:" + this.deadParticles +  "        liv:" + this.liveParticles + "      tot:" + (this.liveParticles + this.deadParticles));
            toSpawnThisFrame = 0;            //(int)Mathf.Max(this.particlesLeftInBank - psystem.particlesToSpawnPerFrame*2,0);
        }
        else
        {
            spawnCount -= intspawnCount;
        }


        if (this.deadParticles + this.liveParticles != this.count && Time.frameCount > 2)
        {
            Debug.LogError("ERROR!!! PARTICLE COUNT OFFSET!!! ded:" + this.deadParticles + "  	  liv:"+ this.liveParticles + "  	  tot:"+ (this.liveParticles + this.deadParticles));
        }
        if (toSpawnThisFrame > 0)
        {
            //Debug.Log("Testey>> ded:" + this.deadParticles +  "  \t  liv:" + this.liveParticles + "  \t  tot:" + (this.liveParticles + this.deadParticles));
            cShade.Dispatch(cShade.FindKernel(_SpawnKernelName), toSpawnThisFrame, 1, 1);
        }

        DisplayFrameSpawns(toSpawnThisFrame);
    }
Exemplo n.º 7
0
    private void OnEnable()
    {
        // If initialized, call on disable to clean things up
        if (initialized)
        {
            OnDisable();
        }
        initialized = true;

        // Grab data from the source mesh
        Vector3[] positions = sourceMesh.vertices;
        Vector2[] uvs       = sourceMesh.uv;
        int[]     tris      = sourceMesh.triangles;

        // 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],
                uv       = uvs[i],
            };
        }
        int numTriangles = tris.Length / 3; // The number of triangles in the source mesh is the index array / 3

        // Create compute buffers
        // The stride is the size, in bytes, each object in the buffer takes up
        sourceVertBuffer = new ComputeBuffer(vertices.Length, SOURCE_VERT_STRIDE, ComputeBufferType.Structured, ComputeBufferMode.Immutable);
        sourceVertBuffer.SetData(vertices);
        sourceTriBuffer = new ComputeBuffer(tris.Length, SOURCE_TRI_STRIDE, ComputeBufferType.Structured, ComputeBufferMode.Immutable);
        sourceTriBuffer.SetData(tris);
        // We split each triangle into three new ones
        drawBuffer = new ComputeBuffer(numTriangles * 3, DRAW_STRIDE, ComputeBufferType.Append);
        drawBuffer.SetCounterValue(0); // Set the count to zero
        argsBuffer = new ComputeBuffer(1, ARGS_STRIDE, ComputeBufferType.IndirectArguments);
        // The data in the args buffer corresponds to:
        // 0: vertex count per draw instance. We will only use one instance
        // 1: instance count. One
        // 2: start vertex location if using a Graphics Buffer
        // 3: and start instance location if using a Graphics Buffer
        argsBuffer.SetData(new int[] { 0, 1, 0, 0 });

        // Cache the kernel IDs we will be dispatching
        idPyramidKernel   = pyramidComputeShader.FindKernel("Main");
        idTriToVertKernel = triToVertComputeShader.FindKernel("Main");

        // Set data on the shaders
        pyramidComputeShader.SetBuffer(idPyramidKernel, "_SourceVertices", sourceVertBuffer);
        pyramidComputeShader.SetBuffer(idPyramidKernel, "_SourceTriangles", sourceTriBuffer);
        pyramidComputeShader.SetBuffer(idPyramidKernel, "_DrawTriangles", drawBuffer);
        pyramidComputeShader.SetInt("_NumSourceTriangles", numTriangles);

        triToVertComputeShader.SetBuffer(idTriToVertKernel, "_IndirectArgsBuffer", argsBuffer);

        material.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
        pyramidComputeShader.GetKernelThreadGroupSizes(idPyramidKernel, out uint threadGroupSize, out _, out _);
        dispatchSize = Mathf.CeilToInt((float)numTriangles / threadGroupSize);

        // Get the bounds of the source mesh and then expand by the pyramid height
        localBounds = sourceMesh.bounds;
        localBounds.Expand(pyramidHeight);
    }
Exemplo n.º 8
0
    Vector4[] GenerateComputedDistances(int bufferSize)
    {
        //create the buffers
        //fill position buffers
        Vector4[] positionsArray = new Vector4[bufferSize];
        Vector4   newVector;

        for (int i = 0; i < bufferSize; ++i)
        {
            if (i < population.Count)
            {
                //valid cell operations
                newVector   = population[i].transform.position;
                newVector.w = 0f;

                if (population[i] is BasicGuy)
                {
                    newVector.w = 1f;
                }
                if (population[i] is SpecialGuy)
                {
                    newVector.w = 2f;
                }

                //positions. = population[i].transform.position;
                positionsArray[i] = newVector;
            }
            else
            {
                //empty space to make the buffer fit evenly
                newVector         = Vector4.zero;
                newVector.w       = -1f;
                positionsArray[i] = newVector;
            }
        }

        int float4Stride = System.Runtime.InteropServices.Marshal.SizeOf(typeof(Vector4));

        ComputeBuffer positionsBuffer = new ComputeBuffer(bufferSize, float4Stride, ComputeBufferType.Default);

        positionsBuffer.SetData(positionsArray); //fill the buffer with data from the array

        //Create output directional buffer
        ComputeBuffer directionalsBuffer = new ComputeBuffer(bufferSize, float4Stride, ComputeBufferType.Default);

        //attach buffers to compuet shader
        int kernelIndex = computeShader.FindKernel("CSMain");

        computeShader.SetBuffer(kernelIndex, "Positions", positionsBuffer);



        computeShader.SetInt("resolution", bufferSize);

        //debug render texture output

        /*
         * RenderTexture renderTetxure;
         *
         * renderTetxure = new RenderTexture(bufferSize, bufferSize, 1);
         * renderTetxure.enableRandomWrite = true;
         * renderTetxure.useMipMap = false;
         * renderTetxure.Create();
         *
         * computeShaderOutputMaterial.SetTexture("_MainTex", renderTetxure);
         *
         * computeShader.SetTexture(kernelIndex,"ResultTexture",renderTetxure);
         *
         */
        //run the compute shader

        computeShader.Dispatch(kernelIndex, 16, 16, 1);

        computeShader.SetBuffer(kernelIndex, "Result", directionalsBuffer);


        //get the processed data


        Vector4[] finalDirectionals = new Vector4[bufferSize * bufferSize];
        //directionalsBuffer.GetData(finalDirectionals);


        return(finalDirectionals);
    }
        void Start()
        {
            if (followTarget)
            {
                groupAnchor = target.position;
            }
            else
            {
                GeneratePath();
                groupAnchor = targetPositions[0];
            }

            drawArgsBuffer = new ComputeBuffer(1, 5 * sizeof(uint), ComputeBufferType.IndirectArguments);
            drawArgsBuffer.SetData(new uint[5] {
                fishMesh.GetIndexCount(0), (uint)fishesCount, 0, 0, 0
            });

            // This property block is used only for avoiding an instancing bug.
            props = new MaterialPropertyBlock();
            props.SetFloat("_UniqueID", Random.value);

            fishesData   = new FishBehaviourGPU[fishesCount];
            kernelHandle = computeShader.FindKernel("CSMain");

            for (int i = 0; i < fishesCount; i++)
            {
                fishesData[i] = CreateBehaviour();
                fishesData[i].speed_offset = Random.value * 1000.0f;
            }

            fishBuffer = new ComputeBuffer(fishesCount, sizeof(float) * 9);
            fishBuffer.SetData(fishesData);

            if (boxColliders.Length <= 0)
            {
                collisionData = new CollisionArea[1] {
                    new CollisionArea()
                }
            }
            ;

            collisionBuffer = new ComputeBuffer(collisionData.Length, sizeof(float) * 6);
            collisionBuffer.SetData(collisionData);

            collisionDataLength = boxColliders.Length <= 0 ? 0 : collisionData.Length;
        }

        FishBehaviourGPU CreateBehaviour()
        {
            FishBehaviourGPU behaviour = new FishBehaviourGPU();
            Vector3          pos       = groupAnchor + Random.insideUnitSphere * spawnRadius;
            Quaternion       rot       = Quaternion.Slerp(transform.rotation, Random.rotation, 0.3f);

            switch (movementAxis)
            {
            case MovementAxis.XY:
                pos.z = rot.z = 0.0f;
                break;

            case MovementAxis.XZ:
                pos.y = rot.y = 0.0f;
                break;
            }

            behaviour.position = pos;
            behaviour.velocity = rot.eulerAngles;

            behaviour.speed     = Random.Range(minSpeed, maxSpeed);
            behaviour.rot_speed = Random.Range(minRotationSpeed, maxRotationSpeed);

            return(behaviour);
        }

        void Update()
        {
            UpdateGroupAnchor();

            switch (movementAxis)
            {
            case MovementAxis.XY:
                computeShader.SetInt("movementMode", 1);
                break;

            case MovementAxis.XZ:
                computeShader.SetInt("movementMode", 2);
                break;

            default:
                computeShader.SetInt("movementMode", 0);
                break;
            }

            computeShader.SetFloat("deltaTime", Time.deltaTime);
            computeShader.SetVector("target", groupAnchor);
            computeShader.SetFloat("neighbourDistance", neighbourDistance);
            computeShader.SetInt("fishesCount", fishesCount);
            computeShader.SetFloat("collisionForce", force);
            computeShader.SetInt("collisionCount", collisionDataLength);
            computeShader.SetFloat("speedVariation", speedVariation);
            computeShader.SetBuffer(this.kernelHandle, "fishBuffer", fishBuffer);
            computeShader.SetBuffer(kernelHandle, "collisionBuffer", collisionBuffer);
            fishInstancedMaterial.SetVector("offsetPosition", myTransform.position);

            computeShader.Dispatch(this.kernelHandle, this.fishesCount / GROUP_SIZE + 1, 1, 1);

            fishInstancedMaterial.SetBuffer("fishBuffer", fishBuffer);

            instancingBounds.center = myTransform.position;
            Graphics.DrawMeshInstancedIndirect(
                fishMesh, 0, fishInstancedMaterial,
                instancingBounds,
                drawArgsBuffer, 0, props
                );
        }

        void OnDestroy()
        {
            if (collisionBuffer != null)
            {
                collisionBuffer.Release();
            }
            if (fishBuffer != null)
            {
                fishBuffer.Release();
            }
            if (drawArgsBuffer != null)
            {
                drawArgsBuffer.Release();
            }
        }

        void UpdateGroupAnchor()
        {
            float minX = myTransform.position.x - (swimmingAreaWidth / 2) + (groupAreaWidth / 2);
            float maxX = myTransform.position.x + (swimmingAreaWidth / 2) - (groupAreaWidth / 2);

            float minY = myTransform.position.y - (swimmingAreaHeight / 2) + (groupAreaHeight / 2);
            float maxY = myTransform.position.y + (swimmingAreaHeight / 2) - (groupAreaHeight / 2);

            float minZ = myTransform.position.z - (swimmingAreaDepth / 2) + (groupAreaDepth / 2);
            float maxZ = myTransform.position.z + (swimmingAreaDepth / 2) - (groupAreaDepth / 2);

            Vector3 futurePosition = myTransform.position;

            if (!followTarget && targetPositions.Length > 0)
            {
                if ((groupAnchor - targetPositions[currentTargetPosIndex]).magnitude < 1)
                {
                    currentTargetPosIndex++;

                    if (currentTargetPosIndex >= targetPositions.Length)
                    {
                        if (recalculatePoints)
                        {
                            GeneratePath();
                        }
                        else
                        {
                            currentTargetPosIndex = targetPositions.Length - 1;
                        }
                    }
                }

                Vector3 vel = (targetPositions[currentTargetPosIndex] - groupAnchor);
                futurePosition = groupAnchor + vel * Time.deltaTime * groupAreaSpeed;
            }
            else if (followTarget)
            {
                if (target != null)
                {
                    Vector3 vel = (target.position - groupAnchor);
                    futurePosition = groupAnchor + vel * Time.deltaTime * groupAreaSpeed;
                }
            }

            futurePosition.x = Mathf.Clamp(futurePosition.x, minX, maxX);
            futurePosition.y = Mathf.Clamp(futurePosition.y, minY, maxY);
            futurePosition.z = Mathf.Clamp(futurePosition.z, minZ, maxZ);

            groupAnchor = futurePosition;
        }

        void GeneratePath()
        {
            float minX = myTransform.position.x - (swimmingAreaWidth / 2) + (groupAreaWidth / 2);
            float maxX = myTransform.position.x + (swimmingAreaWidth / 2) - (groupAreaWidth / 2);

            float minY = myTransform.position.y - (swimmingAreaHeight / 2) + (groupAreaHeight / 2);
            float maxY = myTransform.position.y + (swimmingAreaHeight / 2) - (groupAreaHeight / 2);

            float minZ = myTransform.position.z - (swimmingAreaDepth / 2) + (groupAreaDepth / 2);
            float maxZ = myTransform.position.z + (swimmingAreaDepth / 2) - (groupAreaDepth / 2);

            targetPositions = new Vector3[Random.Range(minTargetPoints, maxTargetPoints)];

            Vector3 tempPos;

            for (int i = 0; i < targetPositions.Length; i++)
            {
                tempPos.x = Random.Range(minX, maxX);
                tempPos.y = Random.Range(minY, maxY);
                tempPos.z = Random.Range(minZ, maxZ);

                targetPositions[i] = tempPos;
            }

            currentTargetPosIndex = 0;
        }

        Vector3 volumeSize;
Exemplo n.º 10
0
 protected void InitCells(Kernel ker)
 {
     compute.SetBuffer(ker.Index, "_Cells", cellsBufferRead);
     compute.SetBuffer(ker.Index, "_CellPoolAppend", cellsPoolBuffer);
     compute.SetInt("_CellsCount", cellsCount);
     compute.Dispatch(ker.Index, Mathf.FloorToInt(cellsCount / (int)ker.ThreadX) + 1, 1, 1);
 }
Exemplo n.º 11
0
    public override void Inject(Vapor vapor, ComputeShader compute, Matrix4x4 viewProj)
    {
        if (HasShadow)
        {
            if (GetShadowMapResolution() != m_shadowMap.width)
            {
                DestroyImmediate(m_shadowMap);
                CreateShadowTex();
            }
        }

        //TODO: This doesn't really need to run every frame
        UpdateCommandBuffer();

        //Setup basic params
        Vector4 posRange = transform.position;

        posRange.w = 1.0f / (m_light.range * m_light.range);
        compute.SetVector("_LightPosRange", posRange);

        Vector4 lightStrength = m_light.color * m_light.intensity * FogScatterIntensity;

        lightStrength *= 10;
        compute.SetVector("_LightColor", lightStrength);

        //Per light type things
        switch (LightType)
        {
        case LightType.Directional:
            int dirKernel;

            if (HasShadow)
            {
                if (QualitySettings.shadowCascades > 1)
                {
                    dirKernel = vapor.LightDirKernel.GetKernel(VaporKernel.ShadowMode.Cascaded);
                }
                else
                {
                    dirKernel = vapor.LightDirKernel.GetKernel(VaporKernel.ShadowMode.Shadowed);
                }
            }
            else
            {
                dirKernel = vapor.LightDirKernel.GetKernel(VaporKernel.ShadowMode.None);
            }

            compute.SetVector("_LightPosRange", m_light.transform.forward);

            if (HasShadow)
            {
                compute.SetBuffer(dirKernel, "_MatrixBuf", MatrixBuffer);
                compute.SetTexture(dirKernel, "_ShadowMapTexture", m_shadowMap);
            }
            else
            {
                compute.SetTexture(dirKernel, "_ShadowMapTexture", Texture2D.whiteTexture);
            }

            vapor.SetLightAccum(dirKernel, false);

            Profiler.BeginSample("Dir Light pass");
            var tex = vapor.GetDensityTex();
            compute.DispatchScaled(dirKernel, tex.width, tex.height, tex.volumeDepth);
            Profiler.EndSample();
            break;

        case LightType.Point:
            vapor.SetLightAccum(vapor.LightPointKernel, false);
            vapor.InjectObject(viewProj, vapor.LightPointKernel, this);
            break;

        case LightType.Spot:
            int spotKernel =
                vapor.LightSpotKernel.GetKernel(HasShadow ? VaporKernel.ShadowMode.Shadowed : VaporKernel.ShadowMode.None);

            if (HasShadow)
            {
                Matrix4x4 v = transform.worldToLocalMatrix;
                Matrix4x4 p =
                    GL.GetGPUProjectionMatrix(Matrix4x4.Perspective(m_light.spotAngle, 1.0f,
                                                                    m_light.shadowNearPlane,
                                                                    m_light.range), true);

                //For some reason z is flipped :(
                p *= Matrix4x4.Scale(new Vector3(1.0f, 1.0f, -1.0f));

                compute.SetMatrix("_SpotShadowMatrix", p * v);
                compute.SetTexture(spotKernel, "_SpotShadow", m_shadowMap);
            }

            var   lightProjMatrix = Matrix4x4.identity;
            float d = Mathf.Deg2Rad * m_light.spotAngle * 0.5f;
            d = Mathf.Cos(d) / Mathf.Sin(d);
            lightProjMatrix[3, 2] = 2f / d;
            lightProjMatrix[3, 3] = SpotBaseSize;
            var mat = lightProjMatrix * transform.worldToLocalMatrix;
            compute.SetMatrix("_SpotMatrix", mat);
            if (m_light.cookie != null)
            {
                compute.SetTexture(spotKernel, "_SpotCookie", m_light.cookie);
            }
            else
            {
                compute.SetTexture(spotKernel, "_SpotCookie", vapor.SpotCookie);
            }

            vapor.SetLightAccum(spotKernel, false);
            vapor.InjectObject(viewProj, spotKernel, this);
            break;
        }
    }
Exemplo n.º 12
0
        public void SetBuffer(ComputeShader shader, string kernelName)
        {
            int kernelHandle = shader.FindKernel(kernelName);

            shader.SetBuffer(kernelHandle, bufferName, buffer);
        }
Exemplo n.º 13
0
    unsafe public void nuStart()
    {
        float initTime = Time.realtimeSinceStartup;

        Debug.Log(Time.realtimeSinceStartup);

        d_particles = new ComputeBuffer(n, sizeof(particle_t)); // For GPU

        particles = new particle_t[n];                          // Local stuff

        int sx = (int)Mathf.Ceil(Mathf.Sqrt((float)n));
        int sy = (n + sx - 1) / sx;

        int[] shuffle = new int[n];
        for (int i = 0; i < n; i++)
        {
            shuffle[i] = i;
        }

        for (int i = 0; i < n; i++)
        {
            //
            //  make sure particles are not spatially sorted
            //
            int j = UnityEngine.Random.Range(0, 2147483640) % (n - i);
            Debug.Log(j);
            int k = shuffle[j];
            shuffle[j] = shuffle[n - i - 1];

            //
            //  distribute particles evenly to ensure proper spacing
            //
            particles[i].x = size * (1.0f + (k % sx)) / (1 + sx);
            particles[i].y = size * (1.0f + (k / sx)) / (1 + sy);

            //
            //  assign random velocities within a bound
            //
            particles[i].vx = UnityEngine.Random.Range(0.0f, 1.0f) * 2 - 1;
            particles[i].vy = UnityEngine.Random.Range(0.0f, 1.0f) * 2 - 1;
        }

        d_particles.SetData(particles);

        int particle_blks = (n + NUM_THREADS - 1) / NUM_THREADS;

        double  bin_size    = 2 * cutoff;
        double  area_size   = Mathf.Sqrt((float)density * n);
        int     nbin_1d     = (int)Mathf.Ceil(1.0f * (float)area_size / (float)bin_size);
        Vector2 bin_threads = new Vector2(Mathf.Sqrt(NUM_THREADS), Mathf.Sqrt(NUM_THREADS));
        int     bin_blk     = (int)Mathf.Ceil((float)(1.0 * nbin_1d / Mathf.Sqrt(NUM_THREADS)));
        Vector2 bin_blks    = new Vector2(bin_blk, bin_blk);

        d_particle_chain = new ComputeBuffer(n, sizeof(int));
        d_bin            = new ComputeBuffer(nbin_1d * nbin_1d, sizeof(int));
        d_bin_debug      = new ComputeBuffer(n, sizeof(float));               // Debugging

        NBodyCUDA.SetInt("nbin_1d", nbin_1d);

        //
        // Declare Constants for Compute Shaders
        //
        NBodyCUDA.SetFloat("density", density);
        NBodyCUDA.SetFloat("mass", mass);
        NBodyCUDA.SetFloat("cutoff", cutoff);
        NBodyCUDA.SetFloat("min_r", min_r);
        NBodyCUDA.SetFloat("dt", dt);
        NBodyCUDA.SetFloat("bin_size", 2 * cutoff);
        NBodyCUDA.SetFloat("size", size);
        NBodyCUDA.SetInt("count", 11);

        //
        //  simulate a number of time steps
        //
        for (int step = 0; step < NSTEPS; step++)
        {
            int kID_clear_bin_gpu = NBodyCUDA.FindKernel("clear_bin_gpu");
            NBodyCUDA.SetInt("nbin_1d", nbin_1d);
            NBodyCUDA.SetBuffer(kID_clear_bin_gpu, "d_bin", d_bin);

            NBodyCUDA.Dispatch(kID_clear_bin_gpu, (int)bin_blks.x, (int)bin_blks.y, 1);

            int kID_assign_particle_gpu = NBodyCUDA.FindKernel("assign_particle_gpu");
            NBodyCUDA.SetInt("n", n);
            NBodyCUDA.SetBuffer(kID_assign_particle_gpu, "d_bin", d_bin);

            Shader.SetGlobalBuffer(Shader.PropertyToID("d_particles"), d_particles);
            Shader.SetGlobalBuffer(Shader.PropertyToID("d_particle_chain"), d_particle_chain);
            NBodyCUDA.Dispatch(kID_assign_particle_gpu, particle_blks, 1, 1);


            //
            //  compute forces
            //
            int kID_compute_forces_gpu = NBodyCUDA.FindKernel("compute_forces_gpu");
            NBodyCUDA.SetBuffer(kID_compute_forces_gpu, "d_bin", d_bin);
            Shader.SetGlobalBuffer(Shader.PropertyToID("d_bin_debug"), d_bin_debug);
            // NBodyCUDA.SetBuffer(kID_compute_forces_gpu, "d_bin_debug", d_bin_debug);
            NBodyCUDA.Dispatch(kID_compute_forces_gpu, particle_blks, 1, 1);

            //
            //  move particles
            //

            int kID_move_gpu = NBodyCUDA.FindKernel("move_gpu");


            NBodyCUDA.Dispatch(kID_move_gpu, particle_blks, 1, 1);
        }

        Debug.Log("Simulation over");
        float final = (Time.realtimeSinceStartup - initTime);

        test.text = final.ToString();

        Debug.Log(size);

        d_particles.Release();
        d_particle_chain.Release();
        d_bin.Release();
        d_bin_debug.Release();
    }
//	float time = 0;
    void BufferSort()
    {
        var _cp = Camera.main.transform.position;
        var cp  = new Vector4(_cp.x, _cp.y, _cp.z, 1);

        float[] vMatrix = new float[16];
        var     _v      = Camera.main.worldToCameraMatrix;

        //set world2camera matrix to vMatrix
        vMatrix [0]  = _v.m00;
        vMatrix [1]  = _v.m01;
        vMatrix [2]  = _v.m02;
        vMatrix [3]  = _v.m03;
        vMatrix [4]  = _v.m10;
        vMatrix [5]  = _v.m11;
        vMatrix [6]  = _v.m12;
        vMatrix [7]  = _v.m13;
        vMatrix [8]  = _v.m20;
        vMatrix [9]  = _v.m21;
        vMatrix [10] = _v.m22;
        vMatrix [11] = _v.m23;
        vMatrix [12] = _v.m30;
        vMatrix [13] = _v.m31;
        vMatrix [14] = _v.m32;
        vMatrix [15] = _v.m33;

        kernel = updater.FindKernel("BitonicSort");

//		time += Time.deltaTime;
//		if (time < 0.1f)
//			return;

        for (int i = 0; i < max; i++)
        {
            step = Count;
            int rank = 0;

            for (rank = 0; rank < step; rank++)
            {
                step -= rank + 1;
            }

            //2,4,8,16,32,64,128...
            stepno = 1 << (rank + 1);
//			Debug.Log ("stepno = " + stepno);

            //1, 2,1, 4,2,1, 8,4,2,1, 16,8...
            offset = 1 << (rank - step);
//			Debug.Log ("offset = " + offset);

            //2, 4,2, 8,4,2, 16,8,4,2, 32,16...
            stage = 2 * offset;
//			Debug.Log ("stage = " + stage);

            updater.SetBuffer(kernel, "ParticlesBuffer", particlesBuffer);
            updater.SetInt("stepno", stepno);
            updater.SetInt("offset", offset);
            updater.SetInt("stage", stage);
            //updater.SetVector ("CameraPos", cp);
            //updater.SetFloats ("vMatrix", vMatrix);
            updater.Dispatch(kernel, (int)Mathf.Sqrt(particleCount) / 8, (int)Mathf.Sqrt(particleCount) / 8, 1);

            if (Count < max)
            {
                Count += 1;
            }
        }

        Count  = 0;
        step   = 0;
        stepno = 0;
        offset = 0;
        stage  = 0;
    }
Exemplo n.º 15
0
 private void SetComputeBuffers()
 {
     CurrentDensityShader.SetBuffer(0, "pts", PointsBuffer);
     marchCompute.SetBuffer(0, "pts", PointsBuffer);
     marchCompute.SetBuffer(0, "Result", TrianglesBuffer);
 }
Exemplo n.º 16
0
    //-----------------------------------------------------------------
    private void OnEnable()
    {
        // Init data structures
        m_DyeSources = new RenderTexture(c_Size, c_Size, 0, RenderTextureFormat.ARGBFloat)
        {
            enableRandomWrite = true
        };
        m_ForceSources = new RenderTexture(c_Size, c_Size, 0, RenderTextureFormat.ARGBFloat)
        {
            enableRandomWrite = true
        };
        m_Density = new RenderTexture(c_Size, c_Size, 0, RenderTextureFormat.ARGBFloat)
        {
            enableRandomWrite = true
        };
        m_Density0 = new RenderTexture(c_Size, c_Size, 0, RenderTextureFormat.ARGBFloat)
        {
            enableRandomWrite = true
        };
        m_V = new RenderTexture(c_Size, c_Size, 0, RenderTextureFormat.ARGBFloat)
        {
            enableRandomWrite = true
        };
        m_V0 = new RenderTexture(c_Size, c_Size, 0, RenderTextureFormat.ARGBFloat)
        {
            enableRandomWrite = true
        };
        m_VisTex = new RenderTexture(c_Size, c_Size, 0)
        {
            enableRandomWrite = true
        };

        m_DyeSources.Create();
        m_ForceSources.Create();
        m_Density.Create();
        m_Density0.Create();
        m_V.Create();
        m_V0.Create();
        m_VisTex.Create();

        // Setup visualization of dye
        m_VisImage.texture = m_VisTex;

        // Prepare compute shader data
        int kernelID = m_ModifyFieldCS.FindKernel("ModifyField");

        Vector4[] pixels     = new Vector4[c_Size * c_Size];
        var       computeBuf = new ComputeBuffer(pixels.Length, stride: 4 * 4);

        // Clear dye texture
        computeBuf.SetData(pixels);

        m_ModifyFieldCS.SetBuffer(kernelID, "sources", computeBuf);
        m_ModifyFieldCS.SetTexture(kernelID, "field", m_Density);
        m_ModifyFieldCS.SetInt("size", c_Size);
        m_ModifyFieldCS.Dispatch(kernelID, c_Size / 8, c_Size / 8, 1);

        // Init external source of dye
        pixels[c_Size / 2 + (c_Size / 3) * c_Size] = new Vector3(50.0f, 0.0f, 50.0f);
        pixels[c_Size / 3 + (c_Size / 2) * c_Size] = new Vector3(0.0f, 40.0f, 40.0f);

        computeBuf.SetData(pixels);

        m_ModifyFieldCS.SetBuffer(kernelID, "sources", computeBuf);
        m_ModifyFieldCS.SetTexture(kernelID, "field", m_DyeSources);
        m_ModifyFieldCS.SetInt("size", c_Size);
        m_ModifyFieldCS.Dispatch(kernelID, c_Size / 8, c_Size / 8, 1);

        // Init external source of velocity
        pixels[c_Size / 2 + (c_Size / 3) * c_Size] = new Vector3(22.0f, 22.0f, 0.0f);
        pixels[c_Size / 3 + (c_Size / 2) * c_Size] = new Vector3(18.0f, 18.0f, 0.0f);

        computeBuf.SetData(pixels);

        m_ModifyFieldCS.SetBuffer(kernelID, "sources", computeBuf);
        m_ModifyFieldCS.SetTexture(kernelID, "field", m_ForceSources);
        m_ModifyFieldCS.SetInt("size", c_Size);
        m_ModifyFieldCS.Dispatch(kernelID, c_Size / 8, c_Size / 8, 1);

        // Randomize velocities for each cell
        for (int i = 0; i < pixels.Length; i++)
        {
            pixels[i] = new Vector3(x: Random.Range(-1.0f, 1.0f), y: Random.Range(-1.0f, 1.0f), z: 0);
        }

        computeBuf.SetData(pixels);

        m_ModifyFieldCS.SetBuffer(kernelID, "sources", computeBuf);
        m_ModifyFieldCS.SetTexture(kernelID, "field", m_V);
        m_ModifyFieldCS.SetInt("size", c_Size);
        m_ModifyFieldCS.Dispatch(kernelID, c_Size / 8, c_Size / 8, 1);

        // Cleanup
        computeBuf.Dispose();
    }
Exemplo n.º 17
0
        public Texture Prepare(RenderTexture source, Material uberMaterial)
        {
            var settings = model.settings;

            // Setup compute
            if (m_EyeCompute == null)
            {
                m_EyeCompute = Resources.Load <ComputeShader>("Shaders/EyeHistogram");
            }

            var material = context.materialFactory.Get("Hidden/Post FX/Eye Adaptation");

            material.shaderKeywords = null;

            if (m_HistogramBuffer == null)
            {
                m_HistogramBuffer = new ComputeBuffer(k_HistogramBins, sizeof(uint));
            }

            if (s_EmptyHistogramBuffer == null)
            {
                s_EmptyHistogramBuffer = new uint[k_HistogramBins];
            }

            // Downscale the framebuffer, we don't need an absolute precision for auto exposure and it
            // helps making it more stable
            var scaleOffsetRes = GetHistogramScaleOffsetRes();

            var rt = context.renderTextureFactory.Get((int)scaleOffsetRes.z, (int)scaleOffsetRes.w, 0, source.format);

            Graphics.Blit(source, rt);

            if (m_AutoExposurePool[0] == null || !m_AutoExposurePool[0].IsCreated())
            {
                m_AutoExposurePool[0] = new RenderTexture(1, 1, 0, RenderTextureFormat.RFloat);
            }

            if (m_AutoExposurePool[1] == null || !m_AutoExposurePool[1].IsCreated())
            {
                m_AutoExposurePool[1] = new RenderTexture(1, 1, 0, RenderTextureFormat.RFloat);
            }

            // Clears the buffer on every frame as we use it to accumulate luminance values on each frame
            m_HistogramBuffer.SetData(s_EmptyHistogramBuffer);

            // Gets a log histogram
            int kernel = m_EyeCompute.FindKernel("KEyeHistogram");

            m_EyeCompute.SetBuffer(kernel, "_Histogram", m_HistogramBuffer);
            m_EyeCompute.SetTexture(kernel, "_Source", rt);
            m_EyeCompute.SetVector("_ScaleOffsetRes", scaleOffsetRes);
            m_EyeCompute.Dispatch(kernel, Mathf.CeilToInt(rt.width / (float)k_HistogramThreadX), Mathf.CeilToInt(rt.height / (float)k_HistogramThreadY), 1);

            // Cleanup
            context.renderTextureFactory.Release(rt);

            // Make sure filtering values are correct to avoid apocalyptic consequences
            const float minDelta = 1e-2f;

            settings.highPercent = Mathf.Clamp(settings.highPercent, 1f + minDelta, 99f);
            settings.lowPercent  = Mathf.Clamp(settings.lowPercent, 1f, settings.highPercent - minDelta);

            // Compute auto exposure
            material.SetBuffer("_Histogram", m_HistogramBuffer); // No (int, buffer) overload for SetBuffer ?
            material.SetVector(Uniforms._Params, new Vector4(settings.lowPercent * 0.01f, settings.highPercent * 0.01f, Mathf.Exp(settings.minLuminance * 0.69314718055994530941723212145818f), Mathf.Exp(settings.maxLuminance * 0.69314718055994530941723212145818f)));
            material.SetVector(Uniforms._Speed, new Vector2(settings.speedDown, settings.speedUp));
            material.SetVector(Uniforms._ScaleOffsetRes, scaleOffsetRes);
            material.SetFloat(Uniforms._ExposureCompensation, settings.keyValue);

            if (settings.dynamicKeyValue)
            {
                material.EnableKeyword("AUTO_KEY_VALUE");
            }

            if (m_FrameCount < 2 || !Application.isPlaying)
            {
                // We don't want eye adaptation when not in play mode because the GameView isn't
                // animated, thus making it harder to tweak. Just use the final audo exposure value.
                m_CurrentAutoExposure = m_AutoExposurePool[0];
                Graphics.Blit(null, m_CurrentAutoExposure, material, (int)EyeAdaptationModel.EyeAdaptationType.Fixed);

                // Copy current exposure to the other pingpong target to avoid adapting from black
                Graphics.Blit(m_AutoExposurePool[0], m_AutoExposurePool[1]);
            }
            else
            {
                int pp  = m_AutoExposurePingPing;
                var src = m_AutoExposurePool[++pp % 2];
                var dst = m_AutoExposurePool[++pp % 2];
                Graphics.Blit(src, dst, material, (int)settings.adaptationType);
                m_AutoExposurePingPing = ++pp % 2;
                m_CurrentAutoExposure  = dst;
            }

            // Generate debug histogram
            if (context.profile.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.EyeAdaptation))
            {
                if (m_DebugHistogram == null || !m_DebugHistogram.IsCreated())
                {
                    m_DebugHistogram = new RenderTexture(256, 128, 0, RenderTextureFormat.ARGB32)
                    {
                        filterMode = FilterMode.Point,
                        wrapMode   = TextureWrapMode.Clamp
                    };
                }

                material.SetFloat(Uniforms._DebugWidth, m_DebugHistogram.width);
                Graphics.Blit(null, m_DebugHistogram, material, 2);
            }

            m_FrameCount++;
            return(m_CurrentAutoExposure);
        }
Exemplo n.º 18
0
        void Start()
        {
            if (baseMesh == null)
            {
                baseMesh = GetComponent <MeshFilter>().sharedMesh;
            }

#if UNITY_EDITOR
            var cam = Camera.current;
            if (cam == null || Application.isPlaying)
            {
                cam = Camera.main;
            }
#else
            var cam = Camera.main;
#endif

            var draft = new MeshDraft();

            var rand = new System.Random(0);

            // expend the number normalBufferof triangles
            var triangles = baseMesh.Triangles();

            var dist      = Vector3.Distance(cam.transform.position, transform.position);
            var lod       = (1f - ((Mathf.Clamp(dist, minDist, maxDist)) - minDist) / (maxDist - minDist));
            var numSplits = lod * maxSplits;
            var height    = lod * maxHeight;

#if DEBUG
            Debug.Log(dist + " : " + numSplits);
            var startTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
#endif

            // Kernel One
            var eye = cam.transform.forward;
            for (int i = 0; i < numSplits; i++)
            {
                var tmpTriangles = new ConcurrentStack <(Vector3 a, Vector3 b, Vector3 c)>();

                Parallel.ForEach(triangles, tri => {
                    if (Vector3.Dot(tri.Normal(), eye) < 0)
                    {
                        var(middle, oposite, first, second) = tri.MiddleLargestSide();
                        tmpTriangles.Push((oposite, first, middle));
                        tmpTriangles.Push((oposite, middle, second));
                    }
                });

                triangles = tmpTriangles.ToArray();
            }

#if DEBUG
            var endTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
            Debug.Log("Kernel One (CPU) : " + (endTime - startTime));

            startTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
#endif

            // Kernel Two
            buffer = new ComputeBuffer(triangles.Length, 36);
            buffer.SetData(ToGPUTriangle(triangles));

            outputBuffer = new ComputeBuffer(triangles.Length * 3, 12);
            normalBuffer = new ComputeBuffer(triangles.Length * 3, 12);

            int kernel = shader.FindKernel("CSMain");
            shader.SetVector("position", transform.position);
            shader.SetFloat("randWidth", randWidth);
            shader.SetFloat("randHeight", randHeight);
            shader.SetFloat("randLeanDist", randLeanDist);
            shader.SetFloat("maxWidth", maxWidth);
            shader.SetFloat("maxHeight", maxHeight);
            shader.SetFloat("leanDist", leanDist);
            shader.SetBuffer(kernel, "dataBuffer", buffer);
            shader.SetBuffer(kernel, "outputBuffer", outputBuffer);
            shader.SetBuffer(kernel, "normalBuffer", normalBuffer);
            shader.Dispatch(kernel, triangles.Length, 1, 1);

#if DEBUG
            endTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
            Debug.Log("Kernel Two (GPU) : " + (endTime - startTime));
#endif

            //var array = new Vector3[triangles.Length * 3];
            //outputBuffer.GetData(array);
            //Debug.Log(string.Join(",", array));
            //Debug.Log(string.Join(",", triangles));

            //Grass = draft.ToMesh();
        }
    private void OnGUI()
    {
        if (!drawShader)
        {
            drawShader = Resources.Load <ComputeShader>("ShaderBlend");
        }
        targetShowMat = EditorGUILayout.ObjectField("Target Material: ", targetShowMat, typeof(Material), true) as Material;
        //TODO
        rtSize   = EditorGUILayout.Vector2IntField("Texture Size: ", rtSize);
        rtSize.x = max(1, rtSize.x);
        rtSize.y = max(1, rtSize.y);
        format   = (RenderTextureFormat)EditorGUILayout.EnumPopup("Texture Format: ", format);

        //Set RT
        if (!rt)
        {
            rt = new RenderTexture(new RenderTextureDescriptor
            {
                colorFormat       = format,
                depthBufferBits   = 0,
                enableRandomWrite = true,
                height            = rtSize.y,
                width             = rtSize.x,
                volumeDepth       = 1,
                msaaSamples       = 1,
                sRGB      = false,
                dimension = TextureDimension.Tex2D
            });
            rt.Create();
        }
        else if (rt.format != format || rt.width != rtSize.x || rt.height != rtSize.y)
        {
            rt.Release();
            rt.width  = rtSize.x;
            rt.height = rtSize.y;
            rt.format = format;
            rt.Create();
        }
        if (targetShowMat)
        {
            targetShowMat.SetTexture(ShaderIDs._MainTex, rt);
        }
        drawShader.SetTexture(1, ShaderIDs._MainTex, rt);
        drawShader.SetVector("_MainTex_TexelSize", float4(1f / rtSize.x, 1f / rtSize.y, rtSize.x - 0.1f, rtSize.y - 0.1f));
        initColor = EditorGUILayout.ColorField("Initial Color: ", initColor);
        drawShader.SetVector("_InitialColor", new Vector4(initColor.r, initColor.g, initColor.b, initColor.a));
        drawShader.Dispatch(1, Mathf.CeilToInt(rtSize.x / 8f), Mathf.CeilToInt(rtSize.y / 8f), 1);
        for (int i = 0; i < allTextures.Count; ++i)
        {
            var e = allTextures[i];
            EditorGUILayout.BeginHorizontal();
            e.isOpen = EditorGUILayout.Foldout(e.isOpen, "Texture Layer " + i);
            bool remove = GUILayout.Button("Remove", GUILayout.MaxWidth(100));
            EditorGUILayout.EndHorizontal();
            if (remove)
            {
                allTextures.RemoveAt(i);
                i--;
            }
            else
            {
                if (e.isOpen)
                {
                    EditorGUI.indentLevel++;
                    e.targetTexture = EditorGUILayout.ObjectField("Texture: ", e.targetTexture, typeof(Texture), true) as Texture;
                    e.voronoiSample = EditorGUILayout.Toggle("Voronoi Sample: ", e.voronoiSample);
                    e.size          = saturate(EditorGUILayout.Vector2Field("Blend Size", saturate(e.size)));
                    e.blendAlpha    = EditorGUILayout.Slider("Blend Alpha: ", e.blendAlpha, 0, 1);
                    e.scale         = EditorGUILayout.Vector2Field("Tiling Scale: ", e.scale);
                    e.offset        = EditorGUILayout.Vector2Field("Tiling Offset: ", e.offset);
                    //Start Blending

                    EditorGUI.indentLevel--;
                }
                allTextures[i] = e;
            }
        }
        foreach (var e in allTextures)
        {
            if (e.targetTexture)
            {
                int2 blendSize = (int2)(e.size * float2(rtSize.x, rtSize.y));
                if (blendSize.x > 0 && blendSize.y > 0)
                {
                    float4 blendTexelSize = float4(1f / (float2)blendSize, (float2)blendSize.xy - 0.1f);
                    float4 offsetScale    = float4(floor(e.offset * float2(rtSize.x, rtSize.y) + 0.1f), e.scale);
                    int    pass           = e.voronoiSample ? 3 : 0;
                    drawShader.SetTexture(pass, ShaderIDs._MainTex, rt);
                    drawShader.SetTexture(pass, "_BlendTex", e.targetTexture);
                    drawShader.SetVector("_OffsetScale", offsetScale);
                    drawShader.SetVector("_BlendTex_TexelSize", blendTexelSize);
                    drawShader.SetFloat("_BlendAlpha", e.blendAlpha);
                    drawShader.Dispatch(pass, Mathf.CeilToInt(blendSize.x / 8f), Mathf.CeilToInt(blendSize.y / 8f), 1);
                }
            }
        }
        if (GUILayout.Button("Add New Texture"))
        {
            allTextures.Add(new TextureSettings
            {
                blendAlpha    = 1f,
                voronoiSample = false,
                isOpen        = false,
                offset        = 0,
                size          = 1,
                scale         = 1,
                targetTexture = null
            });
        }
        saveIsOpen = EditorGUILayout.Foldout(saveIsOpen, "Save Mode: ");
        if (saveIsOpen)
        {
            EditorGUI.indentLevel++;
            path       = EditorGUILayout.TextField("Save Path: ", path);
            saveFormat = (TextureFormat)EditorGUILayout.EnumPopup("Save Format: ", saveFormat);
            if (GUILayout.Button("Save To PNG"))
            {
                Texture2D     tex        = new Texture2D(rtSize.x, rtSize.y, saveFormat, false, true);
                ComputeBuffer dataBuffer = new ComputeBuffer(rtSize.x * rtSize.y, sizeof(float4));
                drawShader.SetTexture(2, ShaderIDs._MainTex, rt);
                drawShader.SetBuffer(2, "_ColorBuffer", dataBuffer);
                drawShader.Dispatch(2, Mathf.CeilToInt(rtSize.x / 8f), Mathf.CeilToInt(rtSize.y / 8f), 1);
                Color[] colors = new Color[rtSize.x * rtSize.y];
                dataBuffer.GetData(colors);
                tex.SetPixels(colors);
                System.IO.File.WriteAllBytes(path, tex.EncodeToPNG());
            }
            EditorGUI.indentLevel--;
        }
    }
Exemplo n.º 20
0
    private static bool CaptureViews(Transform root, BillboardImposter imposter, Snapshots[] snapshots,
                                     Transform lightingRoot, Shader albedoBake, Shader normalBake, ComputeShader processCompute)
    {
        Vector3 originalScale = root.localScale;

        //reset root local scale
        root.localScale = Vector3.one;

        var prevRt = RenderTexture.active;

        ///////////////// create the atlas for base and pack

        //base target
        var baseAtlas = RenderTexture.GetTemporary(_atlasResolution, _atlasResolution, 0, RenderTextureFormat.ARGB32,
                                                   RenderTextureReadWrite.Linear);

        baseAtlas.enableRandomWrite = true;
        baseAtlas.Create();

        //world normal target
        var packAtlas = RenderTexture.GetTemporary(_atlasResolution, _atlasResolution, 0, RenderTextureFormat.ARGB32,
                                                   RenderTextureReadWrite.Linear);

        packAtlas.enableRandomWrite = true;
        packAtlas.Create();
        //temp
        var tempAtlas = RenderTexture.GetTemporary(baseAtlas.descriptor);

        tempAtlas.Create();

        ////////////// create the single frame RT for base and pack

        var frameReso = _atlasResolution / imposter.Frames;

        //base frame (multiple frames make up target)
        var frame = RenderTexture.GetTemporary(frameReso, frameReso, 32, RenderTextureFormat.ARGB32,
                                               RenderTextureReadWrite.Linear);

        frame.enableRandomWrite = true;
        frame.Create();

        //world normal frame
        var packFrame = RenderTexture.GetTemporary(frameReso, frameReso, 32, RenderTextureFormat.ARGB32,
                                                   RenderTextureReadWrite.Linear);

        packFrame.Create();

        //temp
        var tempFrame = RenderTexture.GetTemporary(frame.descriptor);

        tempFrame.Create();

        //high-res frame, intended for super sampling
        //TODO proper super sampling
        //upscale 4 times
        var frameResUpscale = frameReso * 4;
        var superSizedFrame = RenderTexture.GetTemporary(frameResUpscale, frameResUpscale, 32, RenderTextureFormat.ARGB32,
                                                         RenderTextureReadWrite.Linear);

        superSizedFrame.enableRandomWrite = true;
        superSizedFrame.Create();
        //temp
        var superSizedFrameTemp = RenderTexture.GetTemporary(superSizedFrame.descriptor);

        var superSizedAlphaMask = RenderTexture.GetTemporary(superSizedFrame.descriptor);

        superSizedAlphaMask.Create();

        //////////// create the Texture2D used for writing final image
        imposter.BaseTexture = new Texture2D(baseAtlas.width, baseAtlas.height, TextureFormat.ARGB32, true, true);
        imposter.PackTexture = new Texture2D(baseAtlas.width, baseAtlas.height, TextureFormat.ARGB32, true, true);

        //compute buffer for distance alpha
        ComputeBuffer minDistancesBuffer = new ComputeBuffer(frame.width * frame.height, sizeof(float));
        ComputeBuffer maxDistanceBuffer  = new ComputeBuffer(1, sizeof(float));

        const int layer = 30;

        var clearColor = Color.clear;

        //create camera
        var camera = new GameObject().AddComponent <Camera>();

        camera.gameObject.hideFlags = HideFlags.DontSave;
        camera.cullingMask          = 1 << layer;
        camera.clearFlags           = CameraClearFlags.SolidColor;
        camera.backgroundColor      = clearColor;
        camera.orthographic         = true;
        camera.nearClipPlane        = 0f;
        camera.farClipPlane         = imposter.Radius * 2f;
        camera.orthographicSize     = imposter.Radius;
        camera.allowMSAA            = false;
        camera.enabled = false;

        var frameCount = imposter.Frames * imposter.Frames;

        //set and store original layer to restore afterwards
        var originalLayers = new Dictionary <GameObject, int>();

        StoreLayers(root, layer, ref originalLayers);

        var originalLights = new Dictionary <Light, bool>();
        var customLit      = lightingRoot != null;

        //custom lit renders with lighting into base RGB
        if (customLit)
        {
            //toggle all lights off except for lighting rig
            var lights = FindObjectsOfType <Light>();
            for (var i = 0; i < lights.Length; i++)
            {
                //not part of lighting rig
                if (!lights[i].transform.IsChildOf(lightingRoot))
                {
                    if (originalLights.ContainsKey(lights[i]))
                    {
                        continue;
                    }
                    //store original state
                    originalLights.Add(lights[i], lights[i].enabled);
                    //toggle it off
                    lights[i].enabled = false;
                }
                else
                {
                    //is part of lighting rig
                    lights[i].enabled = true;
                    //store state as off
                    if (!originalLights.ContainsKey(lights[i]))
                    {
                        originalLights.Add(lights[i], false);
                    }
                }
            }
        }

        //first render solid color replacement, checking for filled pixels
        //this decides if the camera can be cropped in closer to maximize atlas usage
        var tempMinMaxRT = RenderTexture.GetTemporary(frame.width, frame.height, 0, RenderTextureFormat.ARGB32);

        tempMinMaxRT.Create();

        Graphics.SetRenderTarget(tempMinMaxRT);
        GL.Clear(true, true, Color.clear);

        camera.clearFlags      = CameraClearFlags.Nothing;
        camera.backgroundColor = clearColor;
        camera.targetTexture   = tempMinMaxRT;

        var min = Vector2.one * frame.width;
        var max = Vector2.zero;

        for (var i = 0; i < frameCount; i++)
        {
            if (i > snapshots.Length - 1)
            {
                Debug.LogError("[IMP] snapshot data length less than frame count! this shouldn't happen!");
                continue;
            }

            //position camera with the current snapshot info
            var snap = snapshots[i];
            camera.transform.position = snap.Position;
            camera.transform.rotation = Quaternion.LookRotation(snap.Ray, Vector3.up);

            //render alpha only
            Shader.SetGlobalFloat("_ImposterRenderAlpha", 1f);
            camera.RenderWithShader(albedoBake, "");
            camera.ResetReplacementShader();

            //render without clearing (accumulating filled pixels)
            camera.Render();

            //supply the root position taken into camera space
            //this is for the min max, in the case root is further from opaque pixels
            var viewPos = camera.WorldToViewportPoint(root.position);
            var texPos  = new Vector2(viewPos.x, viewPos.y) * frame.width;
            texPos.x = Mathf.Clamp(texPos.x, 0f, frame.width);
            texPos.y = Mathf.Clamp(texPos.y, 0f, frame.width);
            min.x    = Mathf.Min(min.x, texPos.x);
            min.y    = Mathf.Min(min.y, texPos.y);
            max.x    = Mathf.Max(max.x, texPos.x);
            max.y    = Mathf.Max(max.y, texPos.y);
        }

        camera.clearFlags      = CameraClearFlags.SolidColor;
        camera.backgroundColor = clearColor;
        camera.targetTexture   = null;

        //now read render texture
        var tempMinMaxTex = new Texture2D(tempMinMaxRT.width, tempMinMaxRT.height, TextureFormat.ARGB32, false);

        RenderTexture.active = tempMinMaxRT;
        tempMinMaxTex.ReadPixels(new Rect(0f, 0f, tempMinMaxRT.width, tempMinMaxRT.height), 0, 0);
        tempMinMaxTex.Apply();

        var tempTexC = tempMinMaxTex.GetPixels32();

        //loop pixels get min max
        for (var c = 0; c < tempTexC.Length; c++)
        {
            if (tempTexC[c].r != 0x00)
            {
                var texPos = Get2DIndex(c, tempMinMaxRT.width);
                min.x = Mathf.Min(min.x, texPos.x);
                min.y = Mathf.Min(min.y, texPos.y);
                max.x = Mathf.Max(max.x, texPos.x);
                max.y = Mathf.Max(max.y, texPos.y);
            }
        }

        DestroyImmediate(tempMinMaxTex, true);
        RenderTexture.ReleaseTemporary(tempMinMaxRT);

        //rescale radius
        var len = new Vector2(max.x - min.x, max.y - min.y);

        ////add 2 pixels to x and y
        //len.x += 2f;
        //len.y += 2f;
        var maxR = Mathf.Max(len.x, len.y);

        var ratio = maxR / frame.width; //assume square

        //adjust ratio (if clipping is too tight)
        //ratio = Mathf.Lerp(1f, ratio, _pixelCrop);

        imposter.Radius = imposter.Radius * ratio;
        //adjust the camera size and far clip
        camera.farClipPlane     = imposter.Radius * 2f;
        camera.orthographicSize = imposter.Radius;

        //use a scale factor to make sure the offset is in the correct location
        //this is related to scaling the asset to 1,1,1 while baking, to ensure imposter matches all types of asset scaling
        Vector3 scaleFactor = new Vector3(root.localScale.x / originalScale.x, root.localScale.y / originalScale.y, root.localScale.z / originalScale.z);

        imposter.Offset = Vector3.Scale(imposter.Offset, scaleFactor);

        //recalculate snapshots
        snapshots = UpdateSnapshots(imposter.Frames, imposter.Radius, root.position + imposter.Offset, imposter.IsHalf);

        ///////////////////// rendering the actual frames
        int kernelCSDilate                = processCompute.FindKernel("CSDilate");
        int kernelCSDistanceAlpha         = processCompute.FindKernel("CSDistanceAlpha");
        int kernelCSDistanceAlphaGetMax   = processCompute.FindKernel("CSDistanceAlphaGetMax");
        int kernelCSDistanceAlphaFinalize = processCompute.FindKernel("CSDistanceAlphaFinalize");

        for (var frameIndex = 0; frameIndex < frameCount; frameIndex++)
        {
            if (frameIndex > snapshots.Length - 1)
            {
                Debug.LogError("[IMP] snapshot data length less than frame count! this shouldn't happen!");
                continue;
            }

            var snap = snapshots[frameIndex];
            camera.transform.position = snap.Position;
            camera.transform.rotation = Quaternion.LookRotation(snap.Ray, Vector3.up);
            clearColor = Color.clear;

            //target and clear base frame
            Graphics.SetRenderTarget(superSizedFrame);
            GL.Clear(true, true, clearColor);

            Graphics.SetRenderTarget(superSizedFrameTemp);
            GL.Clear(true, true, clearColor);

            //render into temp
            camera.targetTexture   = superSizedFrameTemp;
            camera.backgroundColor = clearColor;

            if (!customLit)
            {
                Shader.SetGlobalFloat("_ImposterRenderAlpha", 0f);
                camera.RenderWithShader(albedoBake, "");
                camera.ResetReplacementShader();
            }
            else
            {
                //render without replacement
                camera.Render();
            }

            camera.targetTexture   = superSizedAlphaMask;
            camera.backgroundColor = clearColor;
            camera.Render();

            //solidify alpha (uses step) //TODO probably dont need this anymore
            Graphics.Blit(superSizedAlphaMask, superSizedFrame, _processingMat, 3);
            Graphics.Blit(superSizedFrame, superSizedAlphaMask);

            //combine RGB and ALPHA
            _processingMat.SetTexture("_MainTex", superSizedFrameTemp);
            _processingMat.SetTexture("_MainTex2", superSizedAlphaMask);
            _processingMat.SetFloat("_Step", 1f);

            //result in frameUp
            Graphics.Blit(superSizedFrameTemp, superSizedFrame, _processingMat, 1);

            //target frame and clear, TODO proper sampling
            Graphics.SetRenderTarget(frame);
            GL.Clear(true, true, clearColor);
            Graphics.Blit(superSizedFrame, frame);

            //clear superSized frames for use with normals + depth
            Graphics.SetRenderTarget(superSizedFrameTemp);
            GL.Clear(true, true, clearColor);
            Graphics.SetRenderTarget(superSizedFrame);
            GL.Clear(true, true, clearColor);

            //render normals & depth
            //camera background half gray (helps with height displacement)
            clearColor             = new Color(0.0f, 0.0f, 0.0f, 0.5f);
            camera.targetTexture   = superSizedFrame;
            camera.backgroundColor = clearColor;
            camera.RenderWithShader(normalBake, "");
            camera.ResetReplacementShader();

            //clear the pack frame and write TODO proper sampling
            Graphics.SetRenderTarget(packFrame);
            GL.Clear(true, true, clearColor);
            Graphics.Blit(superSizedFrame, packFrame);


            //////////// perform processing on frames

            //pack frame is done first so alpha of base frame can be used as a mask (before distance alpha process)
            Graphics.SetRenderTarget(tempFrame);
            GL.Clear(true, true, Color.clear);

            //padding / dilate TODO can be improved?
            int threadsX, threadsY, threadsZ;
            CalcWorkSize(packFrame.width * packFrame.height, out threadsX, out threadsY, out threadsZ);
            processCompute.SetTexture(kernelCSDilate, "Source", packFrame);
            processCompute.SetTexture(kernelCSDilate, "SourceMask", frame);
            processCompute.SetTexture(kernelCSDilate, "Result", tempFrame);
            processCompute.SetBool("AllChannels", true);
            processCompute.SetBool("NormalsDepth", true);
            processCompute.Dispatch(kernelCSDilate, threadsX, threadsY, threadsZ);

            Graphics.Blit(tempFrame, packFrame);

            //Perform processing on base atlas, Albedo + alpha (alpha is modified)
            Graphics.SetRenderTarget(tempFrame);
            GL.Clear(true, true, Color.clear);

            //padding / dilate
            CalcWorkSize(frame.width * frame.height, out threadsX, out threadsY, out threadsZ);
            processCompute.SetTexture(kernelCSDilate, "Source", frame);
            processCompute.SetTexture(kernelCSDilate, "SourceMask", frame);
            processCompute.SetTexture(kernelCSDilate, "Result", tempFrame);
            processCompute.SetBool("AllChannels", false);
            processCompute.SetBool("NormalsDepth", false);
            processCompute.Dispatch(kernelCSDilate, threadsX, threadsY, threadsZ);

            Graphics.Blit(tempFrame, frame);

            Graphics.SetRenderTarget(tempFrame);
            GL.Clear(true, true, Color.clear);

            //distance field alpha
            //step 1 store min distance to unfilled alpha
            CalcWorkSize(frame.width * frame.height, out threadsX, out threadsY, out threadsZ);
            processCompute.SetTexture(kernelCSDistanceAlpha, "Source", frame);
            processCompute.SetTexture(kernelCSDistanceAlpha, "SourceMask", frame);
            processCompute.SetBuffer(kernelCSDistanceAlpha, "MinDistances", minDistancesBuffer);
            processCompute.Dispatch(kernelCSDistanceAlpha, threadsX, threadsY, threadsZ);

            //step 2 write maximum of the min distances to MaxDistanceBuffer[0]
            //also reset the min distances to 0 during this kernel
            processCompute.SetInt("MinDistancesLength", minDistancesBuffer.count);
            processCompute.SetBuffer(kernelCSDistanceAlphaGetMax, "MaxOfMinDistances", maxDistanceBuffer);
            processCompute.SetBuffer(kernelCSDistanceAlphaGetMax, "MinDistances", minDistancesBuffer);
            processCompute.Dispatch(kernelCSDistanceAlphaGetMax, 1, 1, 1);

            //step 3 write min distance / max of min to temp frame
            CalcWorkSize(frame.width * frame.height, out threadsX, out threadsY, out threadsZ);
            processCompute.SetTexture(kernelCSDistanceAlphaFinalize, "Source", frame);
            processCompute.SetTexture(kernelCSDistanceAlphaFinalize, "SourceMask", frame);
            processCompute.SetTexture(kernelCSDistanceAlphaFinalize, "Result", tempFrame);
            processCompute.SetBuffer(kernelCSDistanceAlphaFinalize, "MinDistances", minDistancesBuffer);
            processCompute.SetBuffer(kernelCSDistanceAlphaFinalize, "MaxOfMinDistances", maxDistanceBuffer);
            processCompute.Dispatch(kernelCSDistanceAlphaFinalize, threadsX, threadsY, threadsZ);

            Graphics.Blit(tempFrame, frame);

            //convert 1D index to flattened octahedra coordinate
            int x;
            int y;
            //this is 0-(frames-1) ex, 0-(12-1) 0-11 (for 12 x 12 frames)
            XYFromIndex(frameIndex, imposter.Frames, out x, out y);

            //X Y position to write frame into atlas
            //this would be frame index * frame width, ex 2048/12 = 170.6 = 170
            //so 12 * 170 = 2040, loses 8 pixels on the right side of atlas and top of atlas

            x *= frame.width;
            y *= frame.height;

            //copy base frame into base render target
            Graphics.CopyTexture(frame, 0, 0, 0, 0, frame.width, frame.height, baseAtlas, 0, 0, x, y);

            //copy normals frame into normals render target
            Graphics.CopyTexture(packFrame, 0, 0, 0, 0, packFrame.width, packFrame.height, packAtlas, 0, 0, x, y);
        }

        //read render target pixels
        Graphics.SetRenderTarget(packAtlas);
        imposter.PackTexture.ReadPixels(new Rect(0f, 0f, packAtlas.width, packAtlas.height), 0, 0);

        Graphics.SetRenderTarget(baseAtlas);
        imposter.BaseTexture.ReadPixels(new Rect(0f, 0f, baseAtlas.width, baseAtlas.height), 0, 0);

        //restore previous render target
        RenderTexture.active = prevRt;

        baseAtlas.Release();
        frame.Release();
        packAtlas.Release();
        packFrame.Release();

        RenderTexture.ReleaseTemporary(baseAtlas);
        RenderTexture.ReleaseTemporary(packAtlas);
        RenderTexture.ReleaseTemporary(tempAtlas);

        RenderTexture.ReleaseTemporary(frame);
        RenderTexture.ReleaseTemporary(packFrame);
        RenderTexture.ReleaseTemporary(tempFrame);

        RenderTexture.ReleaseTemporary(superSizedFrame);
        RenderTexture.ReleaseTemporary(superSizedAlphaMask);
        RenderTexture.ReleaseTemporary(superSizedFrameTemp);

        minDistancesBuffer.Dispose();
        maxDistanceBuffer.Dispose();

        DestroyImmediate(camera.gameObject, true);

        //restore layers
        RestoreLayers(originalLayers);

        //restore lights
        var enumerator2 = originalLights.Keys.GetEnumerator();

        while (enumerator2.MoveNext())
        {
            var light = enumerator2.Current;
            if (light != null)
            {
                light.enabled = originalLights[light];
            }
        }

        enumerator2.Dispose();
        originalLights.Clear();

        var savePath   = "";
        var file       = "";
        var filePrefab = "";

        if (imposter.AssetReference != null)
        {
            savePath = AssetDatabase.GetAssetPath(imposter.AssetReference);
            var lastSlash = savePath.LastIndexOf("/", StringComparison.Ordinal);
            var folder    = savePath.Substring(0, lastSlash);
            file = savePath.Substring(lastSlash + 1,
                                      savePath.LastIndexOf(".", StringComparison.Ordinal) - lastSlash - 1);

            filePrefab = file;

            savePath = folder + "/" + file + "_Imposter" + ".asset";
        }
        else //no prefab, ask where to save
        {
            file     = root.name;
            savePath = EditorUtility.SaveFilePanelInProject("Save Billboard Imposter", file + "_Imposter", "asset",
                                                            "Select save location");
        }

        imposter.PrefabSuffix = _suffix;

        imposter.name = file;

        AssetDatabase.CreateAsset(imposter, savePath);

        imposter.Save(savePath, file, _createUnityBillboard);

        //spawn
        var spawned = imposter.Spawn(root.position, true, filePrefab);

        spawned.transform.position   = root.position + new Vector3(2f, 0f, 2f);
        spawned.transform.rotation   = root.rotation;
        spawned.transform.localScale = originalScale;

        root.localScale = originalScale;

        return(true);
    }
Exemplo n.º 21
0
    // Function which voxelizes the scene and stores the grid in the voxel buffer
    private void Voxelize()
    {
        // Kernel index for the entry point in compute shader
        int kernelHandle = filteredVoxelizationShader.FindKernel("FilteredVoxelizationMain");

        int currentVoxelVolumeDimension = 1;

        filteredVoxelizationShader.SetBuffer(kernelHandle, "_VoxelVolumeBuffer", voxelVolumeBufferSpecular);
        filteredVoxelizationShader.SetInt("_VoxelVolumeDimension", voxelVolumeDimensionSpecular);
        currentVoxelVolumeDimension = voxelVolumeDimensionSpecular;

        // 1st pass
        // Render the color and position textures for the camera
        frontCamera.GetComponent <WorldPositionSecondary>().RenderTextures();

        filteredVoxelizationShader.SetTexture(kernelHandle, "_DirectLightingColorTexture", frontCamera.GetComponent <WorldPositionSecondary>().GetDirectTexture());
        filteredVoxelizationShader.SetTexture(kernelHandle, "_PositionTexture", frontCamera.GetComponent <WorldPositionSecondary>().GetPositionTexture());

        filteredVoxelizationShader.Dispatch(kernelHandle, currentVoxelVolumeDimension, currentVoxelVolumeDimension, 1);

        // 2nd pass
        // Render the color and position textures for the camera
        backCamera.GetComponent <WorldPositionSecondary>().RenderTextures();

        filteredVoxelizationShader.SetTexture(kernelHandle, "_DirectLightingColorTexture", backCamera.GetComponent <WorldPositionSecondary>().GetDirectTexture());
        filteredVoxelizationShader.SetTexture(kernelHandle, "_PositionTexture", backCamera.GetComponent <WorldPositionSecondary>().GetPositionTexture());

        filteredVoxelizationShader.Dispatch(kernelHandle, currentVoxelVolumeDimension, currentVoxelVolumeDimension, 1);

        // 3rd pass
        // Render the color and position textures for the camera
        leftCamera.GetComponent <WorldPositionSecondary>().RenderTextures();

        filteredVoxelizationShader.SetTexture(kernelHandle, "_DirectLightingColorTexture", leftCamera.GetComponent <WorldPositionSecondary>().GetDirectTexture());
        filteredVoxelizationShader.SetTexture(kernelHandle, "_PositionTexture", leftCamera.GetComponent <WorldPositionSecondary>().GetPositionTexture());

        filteredVoxelizationShader.Dispatch(kernelHandle, currentVoxelVolumeDimension, currentVoxelVolumeDimension, 1);

        // 4th pass
        // Render the color and position textures for the camera
        rightCamera.GetComponent <WorldPositionSecondary>().RenderTextures();

        filteredVoxelizationShader.SetTexture(kernelHandle, "_DirectLightingColorTexture", rightCamera.GetComponent <WorldPositionSecondary>().GetDirectTexture());
        filteredVoxelizationShader.SetTexture(kernelHandle, "_PositionTexture", rightCamera.GetComponent <WorldPositionSecondary>().GetPositionTexture());

        filteredVoxelizationShader.Dispatch(kernelHandle, currentVoxelVolumeDimension, currentVoxelVolumeDimension, 1);

        // 5th pass
        // Render the color and position textures for the camera
        topCamera.GetComponent <WorldPositionSecondary>().RenderTextures();

        filteredVoxelizationShader.SetTexture(kernelHandle, "_DirectLightingColorTexture", topCamera.GetComponent <WorldPositionSecondary>().GetDirectTexture());
        filteredVoxelizationShader.SetTexture(kernelHandle, "_PositionTexture", topCamera.GetComponent <WorldPositionSecondary>().GetPositionTexture());

        filteredVoxelizationShader.Dispatch(kernelHandle, currentVoxelVolumeDimension, currentVoxelVolumeDimension, 1);

        // 6th pass
        // Render the color and position textures for the camera
        bottomCamera.GetComponent <WorldPositionSecondary>().RenderTextures();

        filteredVoxelizationShader.SetTexture(kernelHandle, "_DirectLightingColorTexture", bottomCamera.GetComponent <WorldPositionSecondary>().GetDirectTexture());
        filteredVoxelizationShader.SetTexture(kernelHandle, "_PositionTexture", bottomCamera.GetComponent <WorldPositionSecondary>().GetPositionTexture());

        filteredVoxelizationShader.Dispatch(kernelHandle, currentVoxelVolumeDimension, currentVoxelVolumeDimension, 1);
    }
        protected void InitParticlesKernel()
        {
            var kernel = compute.FindKernel("InitParticles");

            compute.SetBuffer(kernel, "_Particles", particleBuffer.Read);

            // Set object pool buffer as AppendStructuredBuffer
            compute.SetBuffer(kernel, "_ParticlePoolAppend", poolBuffer);

            Dispatch1D(kernel, count);
        }
Exemplo n.º 23
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.º 24
0
    public void BuildPipeline()
    {
        if (IsInitialized)
        {
            return;
        }
        if (m_PathTracingShader == null)
        {
            return;
        }
        if (m_Camera == null)
        {
            return;
        }
        m_KernelIndex = m_PathTracingShader.FindKernel(m_KernelName);
        if (m_KernelIndex < 0)
        {
            return;
        }

        if (m_EnableNEE)
        {
            m_PathTracingShader.EnableKeyword("ENABLE_NEXT_EVENT_ESTIMATION");
        }
        else
        {
            m_PathTracingShader.DisableKeyword("ENABLE_NEXT_EVENT_ESTIMATION");
        }

        if (m_EnableThinLens)
        {
            m_PathTracingShader.EnableKeyword("ENABLE_THIN_LENS");
        }
        else
        {
            m_PathTracingShader.DisableKeyword("ENABLE_THIN_LENS");
        }

        if (m_EnableSampleTexture)
        {
            m_PathTracingShader.EnableKeyword("ENABLE_SAMPLE_TEXTURE");
        }
        else
        {
            m_PathTracingShader.DisableKeyword("ENABLE_SAMPLE_TEXTURE");
        }

        if (m_EnableTangentSpace)
        {
            m_PathTracingShader.EnableKeyword("ENABLE_TANGENT_SPACE");
        }
        else
        {
            m_PathTracingShader.DisableKeyword("ENABLE_TANGENT_SPACE");
        }

        m_RenderTexture = new RenderTexture(Screen.width, Screen.height, 0, RenderTextureFormat.ARGBFloat);
        m_RenderTexture.enableRandomWrite = true;
        m_RenderTexture.Create();

        m_DispatchThreadGroupsX = Mathf.CeilToInt((float)m_RenderTexture.width / kTileSize);
        m_DispatchThreadGroupsY = Mathf.CeilToInt((float)m_RenderTexture.height / kTileSize);

        List <PTMaterial> materials;
        List <Primitive>  primitives;
        List <Texture2D>  baseColorTextures = null;
        List <Texture2D>  mroTextures       = null;
        List <Texture2D>  normalTextures    = null;

        if (m_EnableSampleTexture)
        {
            baseColorTextures = new List <Texture2D>();
        }
        if (m_EnableTangentSpace)
        {
            mroTextures    = new List <Texture2D>();
            normalTextures = new List <Texture2D>();
        }
        CollectPrimitives(out materials, out primitives, ref baseColorTextures, ref mroTextures, ref normalTextures);
        BVH bvhTree = new BVH();

        bvhTree.Build(primitives);
        List <Sphere>   spheres;
        List <Quad>     quads;
        List <Cube>     cubes;
        List <Triangle> triangles;
        List <LBVHNode> bvh;
        int             bvhRoot = BuildLBVH(bvhTree, out bvh, out spheres, out quads, out cubes, out triangles);

        if (m_EnableSampleTexture)
        {
            m_baseColorTextureArray = CreateTextureArray(baseColorTextures);
            m_PathTracingShader.SetTexture(m_KernelIndex, "_Textures", m_baseColorTextureArray);
        }
        if (m_EnableTangentSpace)
        {
            m_mroTextureArray    = CreateTextureArray(mroTextures);
            m_normalTextureArray = CreateTextureArray(normalTextures);
            m_PathTracingShader.SetTexture(m_KernelIndex, "_MROTextures", m_mroTextureArray);
            m_PathTracingShader.SetTexture(m_KernelIndex, "_NormalTextures", m_normalTextureArray);
        }
        m_NodesBuffer     = CreateComputeBuffer <LBVHNode>(bvh);
        m_SpheresBuffer   = CreateComputeBuffer <Sphere>(spheres);
        m_QuadsBuffer     = CreateComputeBuffer <Quad>(quads);
        m_CubeBuffer      = CreateComputeBuffer <Cube>(cubes);
        m_TrianglesBuffer = CreateComputeBuffer <Triangle>(triangles);
        m_MaterialsBuffer = CreateComputeBuffer <PTMaterial>(materials);

        m_PathTracingShader.SetBuffer(m_KernelIndex, "_Spheres", m_SpheresBuffer);
        m_PathTracingShader.SetBuffer(m_KernelIndex, "_Quads", m_QuadsBuffer);
        m_PathTracingShader.SetBuffer(m_KernelIndex, "_Cubes", m_CubeBuffer);
        m_PathTracingShader.SetBuffer(m_KernelIndex, "_Triangles", m_TrianglesBuffer);
        m_PathTracingShader.SetBuffer(m_KernelIndex, "_BVHTree", m_NodesBuffer);
        m_PathTracingShader.SetBuffer(m_KernelIndex, "_Materials", m_MaterialsBuffer);

        m_PathTracingShader.SetInt("_BVHRootNodeIndex", bvhRoot);
        m_PathTracingShader.SetInt("_BVHNodeCount", bvh.Count);

        IsInitialized = true;

        m_PathTracingShader.SetTexture(m_KernelIndex, "_Result", m_RenderTexture);
        m_PathTracingShader.SetInt("_ScreenWidth", m_RenderTexture.width);
        m_PathTracingShader.SetInt("_ScreenHeight", m_RenderTexture.height);

        Debug.Log($"BVH Root:{bvhRoot}, BVH Childs:{bvh.Count}");
    }
Exemplo n.º 25
0
    static public void ReadFromRenderTexture(RenderTexture tex, int channels, ComputeBuffer buffer, ComputeShader readData)
    {
        if (tex == null)
        {
            Debug.Log("CBUtility::ReadFromRenderTexture - RenderTexture is null");
            return;
        }

        if (buffer == null)
        {
            Debug.Log("CBUtility::ReadFromRenderTexture - buffer is null");
            return;
        }

        if (readData == null)
        {
            Debug.Log("CBUtility::ReadFromRenderTexture - Computer shader is null");
            return;
        }

        if (channels < 1 || channels > 4)
        {
            Debug.Log("CBUtility::ReadFromRenderTexture - Channels must be 1, 2, 3, or 4");
            return;
        }

        if (!tex.IsCreated())
        {
            Debug.Log("CBUtility::ReadFromRenderTexture - tex has not been created (Call Create() on tex)");
            return;
        }

        int    kernel = -1;
        int    depth  = 1;
        string D      = "2D";
        string C      = "C" + channels.ToString();

        if (tex.dimension == UnityEngine.Rendering.TextureDimension.Tex3D)
        {
            depth = tex.volumeDepth;
            D     = "3D";
        }

        kernel = readData.FindKernel("read" + D + C);

        if (kernel == -1)
        {
            Debug.Log("CBUtility::ReadFromRenderTexture - could not find kernel " + "read" + D + C);
            return;
        }

        int width  = tex.width;
        int height = tex.height;

        //set the compute shader uniforms
        readData.SetTexture(kernel, "_Tex" + D, tex);
        readData.SetInt("_Width", width);
        readData.SetInt("_Height", height);
        readData.SetInt("_Depth", depth);
        readData.SetBuffer(kernel, "_Buffer" + D + C, buffer);
        //run the  compute shader. Runs in threads of 8 so non divisable by 8 numbers will need
        //some extra threadBlocks. This will result in some unneeded threads running
        int padX = (width % 8 == 0) ? 0 : 1;
        int padY = (height % 8 == 0) ? 0 : 1;
        int padZ = (depth % 8 == 0) ? 0 : 1;

        readData.Dispatch(kernel, Mathf.Max(1, width / 8 + padX), Mathf.Max(1, height / 8 + padY), Mathf.Max(1, depth / 8 + padZ));
    }
Exemplo n.º 26
0
 public void SetBuffer(ComputeShader compute, int kernel)
 {
     compute.SetInt(ShaderConst.PROP_WALL_COUNT, _colliders.Count);
     compute.SetBuffer(kernel, ShaderConst.BUF_WALL, Walls);
 }
Exemplo n.º 27
0
    private bool CreateCoordMapperShader(KinectInterop.SensorData sensorData, bool bColor2Depth)
    {
        if (_depthCameraIntrinsics == null || _colorCameraIntrinsics == null || _coordinateMapper == null)
        {
            return(false);
        }

        _coordMapperShader = Resources.Load("CoordMapper") as ComputeShader;
        if (_coordMapperShader)
        {
            _depth2colorKernel = _coordMapperShader.FindKernel("MapDepthFrame2ColorFrame");
            _color2depthKernel = _coordMapperShader.FindKernel("MapColorSpace2DepthFrame");

            float[] depthFocalLength      = new float[] { _depthCameraIntrinsics.FocalLengthX, _depthCameraIntrinsics.FocalLengthY };
            float[] depthPrincipalPoint   = new float[] { _depthCameraIntrinsics.PrincipalPointX, _depthCameraIntrinsics.PrincipalPointY };
            float[] depthRadialDistortion = new float[] { _depthCameraIntrinsics.RadialDistortionSecondOrder, _depthCameraIntrinsics.RadialDistortionFourthOrder, _depthCameraIntrinsics.RadialDistortionSixthOrder };

            _coordMapperShader.SetFloats("depthFocalLength", depthFocalLength);
            _coordMapperShader.SetFloats("depthPrincipalPoint", depthPrincipalPoint);
            _coordMapperShader.SetFloats("depthRadialDistortion", depthRadialDistortion);

            float[] colorFocalLength      = new float[] { _colorCameraIntrinsics.FocalLengthX, _colorCameraIntrinsics.FocalLengthY };
            float[] colorPrincipalPoint   = new float[] { _colorCameraIntrinsics.PrincipalPointX, _colorCameraIntrinsics.PrincipalPointY };
            float[] colorRadialDistortion = new float[] { _colorCameraIntrinsics.RadialDistortionSecondOrder, _colorCameraIntrinsics.RadialDistortionFourthOrder, _colorCameraIntrinsics.RadialDistortionSixthOrder };

            _coordMapperShader.SetFloats("colorFocalLength", colorFocalLength);
            _coordMapperShader.SetFloats("colorPrincipalPoint", colorPrincipalPoint);
            _coordMapperShader.SetFloats("colorRadialDistortion", colorRadialDistortion);

            System.Numerics.Matrix4x4?matrix = !bColor2Depth ? _coordinateMapper.DepthToColorMatrix : _coordinateMapper.ColorToDepthMatrix;
            float[] space2spaceMat           = new float[] {
                matrix.Value.M11, matrix.Value.M12, matrix.Value.M13, matrix.Value.M14,
                matrix.Value.M21, matrix.Value.M22, matrix.Value.M23, matrix.Value.M24,
                matrix.Value.M31, matrix.Value.M32, matrix.Value.M33, matrix.Value.M34,
                matrix.Value.M41, matrix.Value.M42, matrix.Value.M43, matrix.Value.M44
            };

            if (!bColor2Depth)
            {
                _coordMapperShader.SetFloats("depth2colorMat", space2spaceMat);
            }
            else
            {
                _coordMapperShader.SetFloats("color2depthMat", space2spaceMat);
            }

            // compute buffers
            int depthImageLength = sensorData.depthImageWidth * sensorData.depthImageHeight;

            _depthDepthValuesBuf = new ComputeBuffer(depthImageLength, sizeof(int));
            _coordMapperShader.SetBuffer(_depth2colorKernel, "depthDepthValues", _depthDepthValuesBuf);

            if (!bColor2Depth)
            {
                _depthPlaneCoordsBuf = new ComputeBuffer(depthImageLength, 2 * sizeof(float));
                _colorPlaneCoordsBuf = new ComputeBuffer(depthImageLength, 2 * sizeof(float));

                // set plane coords
                Vector2[] depthPlaneCoords = new Vector2[depthImageLength];
                for (int dy = 0, di = 0; dy < sensorData.depthImageHeight; dy++)
                {
                    for (int dx = 0; dx < sensorData.depthImageWidth; dx++)
                    {
                        depthPlaneCoords[di] = new Vector2(dx, dy);
                        di++;
                    }
                }

                _depthPlaneCoordsBuf.SetData(depthPlaneCoords);
                _coordMapperShader.SetBuffer(_depth2colorKernel, "depthPlaneCoords", _depthPlaneCoordsBuf);
                _coordMapperShader.SetBuffer(_depth2colorKernel, "colorPlaneCoords", _colorPlaneCoordsBuf);
            }
            else
            {
                int colorImageLength = sensorData.colorImageWidth * sensorData.colorImageHeight;

                _colorSpaceCoordsBuf = new ComputeBuffer(colorImageLength, 3 * sizeof(float));
                _colorDepthCoordsBuf = new ComputeBuffer(colorImageLength, 2 * sizeof(float));

                _coordMapperShader.SetBuffer(_color2depthKernel, "colorSpaceCoords", _colorSpaceCoordsBuf);
                _coordMapperShader.SetBuffer(_color2depthKernel, "colorDepthCoords", _colorDepthCoordsBuf);
            }
        }

        return(_coordMapperShader != null);
    }
Exemplo n.º 28
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.º 29
0
        protected void Setup(Vector3[] points)
        {
            var kernel = compute.FindKernel("Setup");

            compute.SetBuffer(kernel, "_NodesPoolAppend", nodePoolBuffer);
            compute.SetBuffer(kernel, "_Nodes", nodeBuffer);
            GPUHelper.Dispatch1D(compute, kernel, count);

            using (ComputeBuffer seeds = new ComputeBuffer(points.Length, Marshal.SizeOf(typeof(Vector3))))
            {
                seeds.SetData(points);
                kernel = compute.FindKernel("Start");
                compute.SetFloat("_MassMin", massMin);
                compute.SetFloat("_MassMax", massMax);
                compute.SetBuffer(kernel, "_Start", seeds);
                compute.SetBuffer(kernel, "_Attractions", attractionBuffer);
                compute.SetBuffer(kernel, "_NodesPoolConsume", nodePoolBuffer);
                compute.SetBuffer(kernel, "_Nodes", nodeBuffer);
                GPUHelper.Dispatch1D(compute, kernel, seeds.count);
            }

            nodesCount = nodePoolBuffer.count;
            edgesCount = 0;
        }
    private void UpdateShaderParameters(RenderTexture t, ComputeBuffer d, List <ComputeBuffer> d0, ComputeBuffer m)
    {
        uint zf, zd, zw;

        if (t == null)
        {
            t = _outputRT;
        }

        _kernelsLoaded = _shader.HasKernel("WriteDepth") && _shader.HasKernel("DisplaceAlbedo") && _shader.HasKernel("Clear");
        if (!_kernelsLoaded)
        {
            Debug.LogError("Shader Kernel compilation error");
            return;
        }

        _materialToShareTexture.SetTexture(_textureName, t);
        _clearKernel      = _shader.FindKernel("Clear");
        _writeDepthKernel = _shader.FindKernel("WriteDepth");
        _displaceKernel   = _shader.FindKernel("DisplaceAlbedo");

        _shader.SetBuffer(_clearKernel, "Depth", d);
        _shader.SetBuffer(_clearKernel, "Depth0[0]", d0[0]);
        _shader.SetBuffer(_clearKernel, "Depth0[1]", d0[1]);
        _shader.SetBuffer(_clearKernel, "Depth0[2]", d0[2]);
        _shader.SetBuffer(_clearKernel, "Depth0[3]", d0[3]);
        _shader.SetBuffer(_clearKernel, "MutexBuffer", m);
        _shader.SetTexture(_clearKernel, "Result", t);

        _shader.SetBuffer(_writeDepthKernel, "Depth", d);
        _shader.SetBuffer(_writeDepthKernel, "Depth0[0]", d0[0]);
        _shader.SetBuffer(_writeDepthKernel, "Depth0[1]", d0[1]);
        _shader.SetBuffer(_writeDepthKernel, "Depth0[2]", d0[2]);
        _shader.SetBuffer(_writeDepthKernel, "Depth0[3]", d0[3]);
        _shader.SetBuffer(_writeDepthKernel, "MutexBuffer", m);
        _shader.SetTexture(_writeDepthKernel, "Result", t);
        _shader.SetTexture(_writeDepthKernel, "DepthTexture", depth);
        _shader.SetTexture(_writeDepthKernel, "AlbedoTexture", albedo);

        _shader.SetBuffer(_displaceKernel, "Depth", d);
        _shader.SetBuffer(_displaceKernel, "Depth0[0]", d0[0]);
        _shader.SetBuffer(_displaceKernel, "Depth0[1]", d0[1]);
        _shader.SetBuffer(_displaceKernel, "Depth0[2]", d0[2]);
        _shader.SetBuffer(_displaceKernel, "Depth0[3]", d0[3]);
        _shader.SetBuffer(_displaceKernel, "MutexBuffer", m);
        _shader.SetTexture(_displaceKernel, "Result", t);
        _shader.SetTexture(_displaceKernel, "DepthTexture", depth);
        _shader.SetTexture(_displaceKernel, "AlbedoTexture", albedo);

        _shader.GetKernelThreadGroupSizes(_clearKernel, out _xf, out _yf, out zf);
        _shader.GetKernelThreadGroupSizes(_writeDepthKernel, out _xw, out _yw, out zw);
        _shader.GetKernelThreadGroupSizes(_displaceKernel, out _xd, out _yd, out zd);
    }