Ejemplo n.º 1
0
    // Use this for initialization
    void Start()
    {
        // Dimensions of our volume.
        int width  = 100;
        int height = 10;
        int depth  = 100;

        TerrainVolumeData volumeData = VolumeData.CreateEmptyVolumeData <TerrainVolumeData>(new Region(0, 0, 0, width, height, depth));

        // Let's keep the allocation outside of the loop.
        MaterialSet materialSet       = new MaterialSet();
        float       simplexNoiseValue = 0f;

        simplexNoiseValue     += 1.0f;
        simplexNoiseValue     *= 127.5f;
        materialSet.weights[0] = (byte)simplexNoiseValue;
        for (int z = 0; z < depth; z++)
        {
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    volumeData.SetVoxel(x, y, z, materialSet);
                }
            }
        }
        //Add the required volume component.
        TerrainVolume terrainVolume = gameObject.AddComponent <TerrainVolume>();

        // Set the provided data.
        terrainVolume.data = volumeData;

        // Add the renderer
        gameObject.AddComponent <TerrainVolumeRenderer>();
    }
Ejemplo n.º 2
0
    // Use this for initialization
    void Start()
    {
        // Dimensions of our volume.
        int width  = 64;
        int height = 64;
        int depth  = 64;

        TerrainVolumeData volumeData = VolumeData.CreateEmptyVolumeData <TerrainVolumeData>(new Region(0, 0, 0, width - 1, height - 1, depth - 1));

        float noiseScale    = 32.0f;
        float invNoiseScale = 1.0f / noiseScale;

        // Let's keep the allocation outside of the loop.
        MaterialSet materialSet = new MaterialSet();

        // Iterate over each voxel and assign a value to it
        for (int z = 0; z < depth; z++)
        {
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    // Simplex noise is quite high frequency. We scale the sample position to reduce this.
                    float sampleX = (float)x * invNoiseScale;
                    float sampleY = (float)y * invNoiseScale;
                    float sampleZ = (float)z * invNoiseScale;

                    // Get the noise value for the current position.
                    // Returned value should be in the range -1 to +1.
                    float simplexNoiseValue = SimplexNoise.Noise.Generate(sampleX, sampleY, sampleZ);

                    // Cubiquity material weights need to be in the range 0 - 255.
                    simplexNoiseValue += 1.0f;   // Now it's 0.0 to 2.0
                    simplexNoiseValue *= 127.5f; // Now it's 0.0 to 255.0

                    materialSet.weights[0] = (byte)simplexNoiseValue;

                    // We can now write our computed voxel value into the volume.
                    volumeData.SetVoxel(x, y, z, materialSet);
                }
            }
        }

        //Add the required volume component.
        TerrainVolume terrainVolume = gameObject.AddComponent <TerrainVolume>();

        // Set the provided data.
        terrainVolume.data = volumeData;

        // Add the renderer
        gameObject.AddComponent <TerrainVolumeRenderer>();
    }
Ejemplo n.º 3
0
    // Use this for initialization
    void Start()
    {
        // The size of the volume we will generate
        int width  = 128;
        int height = 32;
        int depth  = 128;

        // FIXME - Where should we delete this?
        /// [DoxygenSnippet-CreateEmptyTerrainVolumeData]
        //Create an empty TerrainVolumeData with dimensions width * height * depth
        TerrainVolumeData data = VolumeData.CreateEmptyVolumeData <TerrainVolumeData>(new Region(0, 0, 0, width - 1, height - 1, depth - 1));
        /// [DoxygenSnippet-CreateEmptyTerrainVolumeData]

        TerrainVolume         volume         = GetComponent <TerrainVolume>();
        TerrainVolumeRenderer volumeRenderer = GetComponent <TerrainVolumeRenderer>();

        volume.data = data;

        // This example looks better if we adjust the scaling factors on the textures.
        volumeRenderer.material.SetTextureScale("_Tex0", new Vector2(0.062f, 0.062f));
        volumeRenderer.material.SetTextureScale("_Tex1", new Vector2(0.125f, 0.125f));
        volumeRenderer.material.SetTextureScale("_Tex2", new Vector2(0.125f, 0.125f));

        // At this point our volume is set up and ready to use. The remaining code is responsible
        // for iterating over all the voxels and filling them according to our noise functions.

        // This scale factor comtrols the size of the rocks which are generated.
        float rockScale    = 32.0f;
        float invRockScale = 1.0f / rockScale;

        // Let's keep the allocation outside of the loop.
        MaterialSet materialSet = new MaterialSet();

        // Iterate over every voxel of our volume
        for (int z = 0; z < depth; z++)
        {
            for (int y = height - 1; y > 0; y--)
            {
                for (int x = 0; x < width; x++)
                {
                    // Make sure we don't have anything left in here from the previous voxel
                    materialSet.weights[0] = 0;
                    materialSet.weights[1] = 0;
                    materialSet.weights[2] = 0;

                    // Simplex noise is quite high frequency. We scale the sample position to reduce this.
                    float sampleX = (float)x * invRockScale;
                    float sampleY = (float)y * invRockScale;
                    float sampleZ = (float)z * invRockScale;

                    // Get the noise value for the current position.
                    // Returned value should be in the range -1 to +1.
                    float simplexNoiseValue = SimplexNoise.Noise.Generate(sampleX, sampleY, sampleZ);

                    // We want to fade off the noise towards the top of the volume (so that the rocks don't go
                    // up to the sky) adn add extra material near the bottom of the volume (to create a floor).
                    // This altitude value is initially in the range from 0 to +1.
                    float altitude = (float)(y + 1) / (float)height;

                    // Map the altitude to the range -1.0 to +1.0...
                    altitude = (altitude * 2.0f) - 1.0f;

                    // Subtract the altitude from the noise. This adds
                    // material near the ground and subtracts it higher up.
                    simplexNoiseValue -= altitude;

                    // After combining our noise value and our altitude we now have values between -2.0 and 2.0.
                    // Cubiquity renders anything below the threshold as empty and anythng above as solid, but
                    // in general it is easiest if empty space is completly empty and solid space is completly
                    // solid. The exception to this is the region near our surface, where a gentle transition helps
                    // obtain smooth shading. By scaling by a large number and then clamping we achieve this effect
                    // of making most voxels fully solid or fully empty except near the surface..
                    simplexNoiseValue *= 5.0f;
                    simplexNoiseValue  = Mathf.Clamp(simplexNoiseValue, -0.5f, 0.5f);

                    // Go back to the range 0.0 to 1.0;
                    simplexNoiseValue += 0.5f;

                    // And then to 0 to 255, ready to convert into a byte.
                    simplexNoiseValue *= 255;

                    // Write the final value value into the third material channel (the one with the rock texture).
                    // The value being written is usually 0 (empty) or 255 (solid) except around the transition.
                    materialSet.weights[2] = (byte)simplexNoiseValue;


                    // Lastly we write soil or grass voxels into the volume to create a level floor between the rocks.
                    // This means we want to set the sum of the materials to 255 if the voxel is below the floor height.
                    // We don't want to interfere with the rocks on the transition between the material so we work out
                    // how much extra we have to add to get to 255 and then add that to either soil or grass.
                    byte excess = (byte)(255 - materialSet.weights[2]);
                    if (y < 11)
                    {
                        // Add to soil material channel.
                        materialSet.weights[1] = excess;
                    }
                    else if (y < 12)
                    {
                        // Add to grass material channel.
                        materialSet.weights[0] = excess;
                    }

                    // We can now write our computed voxel value into the volume.
                    data.SetVoxel(x, y, z, materialSet);
                }
            }
        }
    }
Ejemplo n.º 4
0
    void CreateTerrain()
    {
        TerrainVolumeData terrainData       = VolumeData.CreateEmptyVolumeData <TerrainVolumeData>(new Region(0, 0, 0, (width * 3) + 1, (maxHeight * 3) + 1, (depth * 3) + 1));
        MaterialSet       materialSet       = new MaterialSet();
        float             simplexNoiseValue = 1f;

        for (int z = 0; z <= depth; z += 1)
        {
            for (int x = 0; x <= width; x += 1)
            {
                Vector3 pos = new Vector3(x, 0f, z);

                if (TerrainVoxelPosition(ref pos))
                {
                    materialSet.weights[3] = (byte)128;
                    //Center
                    terrainData.SetVoxel((x * 3) + 1, (int)pos.y + 1, (z * 3) + 1, materialSet);
                    terrainData.SetVoxel((x * 3) + 1, (int)pos.y + 1, (z * 3) + 2, materialSet);
                    terrainData.SetVoxel((x * 3) + 2, (int)pos.y + 1, (z * 3) + 1, materialSet);
                    terrainData.SetVoxel((x * 3) + 2, (int)pos.y + 1, (z * 3) + 2, materialSet);

                    materialSet.weights[3] = (byte)128;
                    //Z Up
                    Vector3 pos2 = new Vector3(x, 0f, z - 1);
                    TerrainVoxelPosition(ref pos2);

                    if (pos2.y > pos.y)
                    {
                        terrainData.SetVoxel((x * 3) + 1, (int)pos.y + 2, (z * 3) + 0, materialSet);
                        terrainData.SetVoxel((x * 3) + 2, (int)pos.y + 2, (z * 3) + 0, materialSet);
                    }
                    if (pos2.y == pos.y)
                    {
                        terrainData.SetVoxel((x * 3) + 1, (int)pos.y + 1, (z * 3) + 0, materialSet);
                        terrainData.SetVoxel((x * 3) + 2, (int)pos.y + 1, (z * 3) + 0, materialSet);
                    }
                    if (pos2.y < pos.y)
                    {
                        terrainData.SetVoxel((x * 3) + 1, (int)pos.y, (z * 3) + 0, materialSet);
                        terrainData.SetVoxel((x * 3) + 2, (int)pos.y, (z * 3) + 0, materialSet);
                    }



                    //Z Down
                    Vector3 pos3 = new Vector3(x, 0f, z + 1);
                    TerrainVoxelPosition(ref pos3);

                    if (pos3.y > pos.y)
                    {
                        terrainData.SetVoxel((x * 3) + 1, (int)pos.y + 2, (z * 3) + 3, materialSet);
                        terrainData.SetVoxel((x * 3) + 2, (int)pos.y + 2, (z * 3) + 3, materialSet);
                    }
                    if (pos3.y == pos.y)
                    {
                        terrainData.SetVoxel((x * 3) + 1, (int)pos.y + 1, (z * 3) + 3, materialSet);
                        terrainData.SetVoxel((x * 3) + 2, (int)pos.y + 1, (z * 3) + 3, materialSet);
                    }
                    if (pos3.y < pos.y)
                    {
                        terrainData.SetVoxel((x * 3) + 1, (int)pos.y + 0, (z * 3) + 3, materialSet);
                        terrainData.SetVoxel((x * 3) + 2, (int)pos.y + 0, (z * 3) + 3, materialSet);
                    }


//					//X Up
                    Vector3 pos4 = new Vector3(x - 1, 0f, z);
                    TerrainVoxelPosition(ref pos4);
                    if (pos4.y > pos.y)
                    {
                        terrainData.SetVoxel((x * 3), (int)pos.y + 2, (z * 3) + 1, materialSet);
                        terrainData.SetVoxel((x * 3), (int)pos.y + 2, (z * 3) + 2, materialSet);
                    }
                    if (pos4.y == pos.y)
                    {
                        terrainData.SetVoxel((x * 3), (int)pos.y + 1, (z * 3) + 1, materialSet);
                        terrainData.SetVoxel((x * 3), (int)pos.y + 1, (z * 3) + 2, materialSet);
                    }
                    if (pos4.y < pos.y)
                    {
                        terrainData.SetVoxel((x * 3), (int)pos.y + 1, (z * 3) + 1, materialSet);
                        terrainData.SetVoxel((x * 3), (int)pos.y + 1, (z * 3) + 2, materialSet);
                    }


//					//X Down
                    Vector3 pos5 = new Vector3(x + 1, 0f, z);
                    TerrainVoxelPosition(ref pos5);
                    if (pos5.y > pos.y)
                    {
                        terrainData.SetVoxel((x * 3) + 3, (int)pos.y + 2, (z * 3) + 1, materialSet);
                        terrainData.SetVoxel((x * 3) + 3, (int)pos.y + 2, (z * 3) + 2, materialSet);
                    }
                    if (pos5.y == pos.y)
                    {
                        terrainData.SetVoxel((x * 3) + 3, (int)pos.y + 1, (z * 3) + 1, materialSet);
                        terrainData.SetVoxel((x * 3) + 3, (int)pos.y + 1, (z * 3) + 2, materialSet);
                    }
                    if (pos5.y < pos.y)
                    {
                        terrainData.SetVoxel((x * 3) + 3, (int)pos.y + 0, (z * 3) + 1, materialSet);
                        terrainData.SetVoxel((x * 3) + 3, (int)pos.y + 0, (z * 3) + 2, materialSet);
                    }


                    if (pos2.y > pos.y || pos4.y > pos.y)
                    {
                        terrainData.SetVoxel((x * 3) + 0, (int)pos.y + 2, (z * 3) + 0, materialSet);
                    }
                    if (pos2.y <= pos.y && pos4.y <= pos.y)
                    {
                        terrainData.SetVoxel((x * 3) + 0, (int)pos.y + 1, (z * 3) + 0, materialSet);
                    }

                    if (pos2.y > pos.y || pos5.y > pos.y)
                    {
                        terrainData.SetVoxel((x * 3) + 3, (int)pos.y + 2, (z * 3) + 0, materialSet);
                    }
                    if (pos2.y <= pos.y && pos5.y <= pos.y)
                    {
                        terrainData.SetVoxel((x * 3) + 3, (int)pos.y + 1, (z * 3) + 0, materialSet);
                    }

                    if (pos3.y > pos.y || pos4.y > pos.y)
                    {
                        terrainData.SetVoxel((x * 3) + 0, (int)pos.y + 2, (z * 3) + 3, materialSet);
                    }
                    if (pos3.y <= pos.y && pos4.y <= pos.y)
                    {
                        terrainData.SetVoxel((x * 3) + 0, (int)pos.y + 1, (z * 3) + 3, materialSet);
                    }

                    if (pos3.y > pos.y || pos5.y > pos.y)
                    {
                        terrainData.SetVoxel((x * 3) + 3, (int)pos.y + 2, (z * 3) + 3, materialSet);
                    }
                    if (pos3.y <= pos.y && pos5.y <= pos.y)
                    {
                        terrainData.SetVoxel((x * 3) + 3, (int)pos.y + 1, (z * 3) + 3, materialSet);
                    }
                }
            }
        }


        terrainVolume      = terrainHolder.AddComponent <TerrainVolume>();
        terrainVolume.data = terrainData;
        TerrainVolumeRenderer tr = terrainHolder.AddComponent <TerrainVolumeRenderer>();

        tr.material = terrainMaterial;
        terrainHolder.AddComponent <TerrainVolumeCollider>();
    }