示例#1
0
    void Start()
    {
        for (int i = 0; i < 128; ++i)
        {
            for (int j = 0; j < 128; ++j)
            {
                uint scrambleU = 5569;
                uint scrambleV = 95597;
                // Vector2 randomSample = new Vector2(Random.value, Random.value);
                // Vector2 randomSample = new Vector2(i / 128.0f, j / 128.0f);
                Vector2            randomSample  = RandomSamplers.Utils.Sample02((uint)(2211 + i + j * 128), scrambleU, scrambleV);
                DistributionSample halfwaySample = CosineDistribution.Sample(randomSample);
                //DistributionSample halfwaySample = PowerCosineDistribution.Sample(randomSample, 0);

                GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                sphere.transform.position   = halfwaySample.Direction * 10.0f;
                sphere.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f);
            }
        }

        for (int i = 0; i < 128; ++i)
        {
            for (int j = 0; j < 128; ++j)
            {
                uint    scrambleU    = 5569;
                uint    scrambleV    = 95597;
                Vector2 randomSample = RandomSamplers.Utils.Sample02((uint)(2211 + 128 * 128 + i + j * 128), scrambleU, scrambleV);

                DistributionSample halfwaySample = CosineDistribution.Sample(randomSample);
                //DistributionSample halfwaySample = PowerCosineDistribution.Sample(randomSample, 0);

                GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                sphere.transform.position = new Vector3(halfwaySample.Direction.x * 10.0f,
                                                        halfwaySample.Direction.y * -10.0f,
                                                        halfwaySample.Direction.z * 10.0f);
                sphere.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f);
            }
        }
    }
示例#2
0
    public static void ConvoluteLatLong(Texture2D inputMap)
    {
        Texture2D convoluted = new Texture2D(inputMap.width, inputMap.height, TextureFormat.RGB24, true);

        convoluted.filterMode = FilterMode.Trilinear;
        convoluted.name       = inputMap.name + "_Convoluted";

        convoluted.SetPixels(inputMap.GetPixels());
        convoluted.Apply(false);

        Color[] srcPixels = convoluted.GetPixels();
        int     srcWidth  = convoluted.width;
        int     srcHeight = convoluted.height;

        int mipmapCount = convoluted.mipmapCount;

        // Calc total pixels, used by the progress bar and not counting the
        // zero'th layer as it is processed nearly instantatious.
        int totalPixelCount = 0;

        for (int m = 1; m < mipmapCount; ++m)
        {
            int mipWidth = convoluted.width >> m;
            if (mipWidth == 0)
            {
                mipWidth = 1;
            }
            int mipHeight = convoluted.height >> m;
            if (mipHeight == 0)
            {
                mipHeight = 1;
            }
            totalPixelCount += mipHeight * mipWidth;
        }

        Vector2[] randomSamples = new Vector2[SAMPLES];
        uint      scrambleU     = 5569;
        uint      scrambleV     = 95597;

        for (uint s = 0; s < SAMPLES; ++s)
        {
            randomSamples[s] = RandomSamplers.Utils.Sample02(2211 + s, scrambleU, scrambleV);
        }

        System.DateTime start = System.DateTime.Now;

        // Convolute each miplevel seperately
        int pixelsProcessed = 0;

        for (int mipLevel = mipmapCount - 1; mipLevel > 0; --mipLevel)
        {
            int mipWidth = convoluted.width >> mipLevel;
            if (mipWidth == 0)
            {
                mipWidth = 1;
            }
            int mipHeight = convoluted.height >> mipLevel;
            if (mipHeight == 0)
            {
                mipHeight = 1;
            }

            EditorUtility.DisplayProgressBar("Convoluting lat long skybox", "Processing " + inputMap.name, pixelsProcessed / (float)totalPixelCount);

            float exponent = ExponentFromMipLevel(mipLevel, mipmapCount - 2);
            Debug.Log("shininess " + exponent + " at mip level " + mipLevel + " of " + mipmapCount);

            // Loop over all pixels
            Color[] pixels = new Color[mipWidth * mipHeight];
            Threading.Parallel.For(mipWidth, u =>
            {
                float phi = (((u + 0.5f) / (float)mipWidth)) * 2.0f * Mathf.PI;
                for (int v = 0; v < mipHeight; ++v)
                {
                    float theta = (1.0f - (v + 0.5f) / (float)mipHeight) * Mathf.PI;

                    // Compute direction
                    Vector3 normal = Utils.Cubemap.SphericalToDirection(theta, phi).normalized;
                    Vector3 tangent, bitangent;
                    CreateTangents(normal, out tangent, out bitangent);

                    // Create samples and sample
                    Color summedColor = new Color(0.0f, 0.0f, 0.0f, 0.0f);
                    float totalWeight = 0.0f;
                    for (int s = 0; s < SAMPLES; ++s)
                    {
                        DistributionSample halfwaySample = PowerCosineDistribution.Sample(randomSamples[s], exponent);

                        if (halfwaySample.PDF > 0.0f)
                        {
                            halfwaySample.Direction = tangent * halfwaySample.Direction.x + normal * halfwaySample.Direction.y + bitangent * halfwaySample.Direction.z;
                            Vector2 sampleUV        = Utils.Cubemap.DirectionToSphericalUV(halfwaySample.Direction);

                            // TODO Perform own repeat-clamp sampling ?
                            int x        = (int)(sampleUV.x * (srcWidth - 1));
                            int y        = (int)(sampleUV.y * (srcHeight - 1));
                            Color sample = srcPixels[x + y * srcWidth];

                            float lightScale = Vector3.Dot(halfwaySample.Direction, normal);
                            summedColor     += sample * lightScale;
                            totalWeight     += lightScale;
                        }
                    }

                    int index     = u + v * mipWidth;
                    pixels[index] = summedColor / totalWeight;
                }
            }
                                   );

            convoluted.SetPixels(pixels, mipLevel);

            pixelsProcessed += mipWidth * mipHeight;
        }

        EditorUtility.DisplayProgressBar("Convoluting lat long skybox", "Saving " + inputMap.name, 0.99f);

        convoluted.Apply(false, true);

        string sourcePath = AssetDatabase.GetAssetPath(inputMap);
        string saveFolder = System.IO.Path.GetDirectoryName(sourcePath);
        string destPath   = saveFolder + "/" + convoluted.name + ".asset";

        AssetDatabase.CreateAsset(convoluted, destPath);

        Texture2D.DestroyImmediate(convoluted);

        EditorUtility.ClearProgressBar();

        System.DateTime stop = System.DateTime.Now;
        Debug.Log("Conveluted " + sourcePath + " in " + (stop - start).TotalSeconds + "seconds.");
    }