Ejemplo n.º 1
0
    private void OnGUI()
    {
        modle = EditorGUILayout.Toggle("CubeMap", modle);
        if (modle)
        {
            input_cubemap = EditorGUILayout.ObjectField("Input Cubemap", input_cubemap, typeof(Cubemap), true) as Cubemap;
            isCopyNew     = EditorGUILayout.Toggle("从环境球获取", isCopyNew);
            if (input_cubemap != null)
            {
                EditorGUILayout.Space();

                if (GUILayout.Button("CPU Uniform 9 Coefficients"))
                {
                    Cubemap cm = input_cubemap;
                    if (isCopyNew)
                    {
                        test = cm = CopyFromEnvMap();
                    }

                    ModifyTextureReadable();
                    coefficients = new Vector4[9];
                    if (SphericalHarmonics.CPU_Project_Uniform_9Coeff(cm, coefficients))
                    {
                        setSH9Global();
                    }
                    if (isCopyNew)
                    {
                        GameObject.DestroyImmediate(cm, true);
                    }
                }

                EditorGUILayout.Space();

                if (GUILayout.Button("CPU Monte Carlo 9 Coefficients"))
                {
                    Cubemap cm = input_cubemap;
                    if (isCopyNew)
                    {
                        cm = CopyFromEnvMap();
                    }
                    ModifyTextureReadable();
                    coefficients = new Vector4[9];
                    if (SphericalHarmonics.CPU_Project_MonteCarlo_9Coeff(cm, coefficients, 4096))
                    {
                        setSH9Global();
                    }
                    if (isCopyNew)
                    {
                        GameObject.DestroyImmediate(cm, true);
                    }
                }

                EditorGUILayout.Space();

                if (GUILayout.Button("GPU Uniform 9 Coefficients"))
                {
                    Cubemap cm = input_cubemap;
                    if (isCopyNew)
                    {
                        input_cubemap = cm = CopyFromEnvMap();
                    }
                    ModifyTextureReadable();
                    coefficients = new Vector4[9];
                    if (SphericalHarmonics.GPU_Project_Uniform_9Coeff(cm, coefficients))
                    {
                        setSH9Global();
                    }
                    if (isCopyNew)
                    {
                        GameObject.DestroyImmediate(cm, true);
                    }
                }

                EditorGUILayout.Space();

                if (GUILayout.Button("GPU Monte Carlo 9 Coefficients"))
                {
                    Cubemap cm = input_cubemap;
                    if (isCopyNew)
                    {
                        cm = CopyFromEnvMap();
                    }
                    ModifyTextureReadable();
                    coefficients = new Vector4[9];
                    if (SphericalHarmonics.GPU_Project_MonteCarlo_9Coeff(cm, coefficients))
                    {
                        setSH9Global();
                    }
                    if (isCopyNew)
                    {
                        GameObject.DestroyImmediate(cm, true);
                    }
                }

                EditorGUILayout.Space();
            }
        }
        else
        {
            env_map = EditorGUILayout.ObjectField("360环境球", env_map, typeof(Texture2D), true) as Texture2D;

            if (env_map)
            {
                sun = EditorGUILayout.Toggle("太阳", sun);
            }

            enableLight = EditorGUILayout.Toggle("灯光", enableLight);

            if (enableLight)
            {
                GUILayout.BeginHorizontal();
                if (GUILayout.Button("+"))
                {
                    lights.Add(null);
                }
                if (GUILayout.Button("-"))
                {
                    if (lights.Count > 0)
                    {
                        lights.RemoveAt(lights.Count - 1);
                    }
                }


                GUILayout.EndHorizontal();
                for (int i = 0; i < lights.Count; i++)
                {
                    lights[i] = EditorGUILayout.ObjectField("360环境球", lights[i], typeof(Light), true) as Light;
                }
            }
            bool hasLight = false;
            for (int i = 0; i < lights.Count; i++)
            {
                if (lights [i] != null)
                {
                    hasLight = true;
                    break;
                }
            }
            //lights
            if (hasLight || env_map != null)
            {
                EditorGUILayout.Space();

                if (GUILayout.Button("CPU Uniform 9 Coefficients"))
                {
                    ModifyTextureReadable(env_map);
                    List <Light> ls = new List <Light> ();
                    foreach (Light l in lights)
                    {
                        if (l != null)
                        {
                            ls.Add(l);
                        }
                    }

                    coefficients = new Vector4[9];
                    if (SphericalHarmonics.CPU_Project_360HJQ(env_map, coefficients, 4096, sun, ls.ToArray()))
                    {
                        setSH9Global();
                    }
                }
            }
        }



        if (coefficients != null && coefficients.Length == 9)
        {
            if (GUILayout.Button("保存"))
            {
                SH9Data data = SH9Data.CreateInstance <SH9Data> ();
                data.coefficients = coefficients;

                string path = EditorUtility.SaveFilePanelInProject("Save SH9 Data", "ibl.asset", "asset",
                                                                   "Please enter a file name to save the texture to");
                if (path.Length != 0)
                {
                    if (System.IO.File.Exists(path))
                    {
                        /*if (EditorUtility.DisplayDialog("目标已存在", "替换", "取消"))
                         *      {
                         *
                         *      }*/

                        data.test         = new Vector4(1, 0, 0, 1);
                        data              = AssetDatabase.LoadAssetAtPath <SH9Data> (path);
                        data.coefficients = coefficients;
                        AssetDatabase.SaveAssets();
                    }
                    else
                    {
                        data.test = Vector4.one;
                        AssetDatabase.CreateAsset(data, path);
                        AssetDatabase.ImportAsset(path);
                    }
                }
            }
            EditorGUILayout.Space();
            for (int i = 0; i < 9; ++i)
            {
                EditorGUILayout.LabelField("c_" + i.ToString() + ": " + coefficients[i].ToString("f4"));
            }
        }


        EditorGUILayout.Space();
        if (tmp != null)
        {
            GUILayout.Label(tmp);
        }
    }
    private void OnGUI()
    {
        EditorGUILayout.PropertyField(sp_input_cubemap, new GUIContent("Input Cubemap"));

        so.ApplyModifiedProperties();

        if (input_cubemap != null)
        {
            EditorGUILayout.Space();

            if (GUILayout.Button("CPU Uniform 9 Coefficients"))
            {
                coefficients = new Vector4[9];
                if (SphericalHarmonics.CPU_Project_Uniform_9Coeff(input_cubemap, coefficients))
                {
                    for (int i = 0; i < 9; ++i)
                    {
                        view_mat.SetVector("c" + i.ToString(), coefficients[i]);
                        view_mat.SetTexture("input", input_cubemap);
                    }

                    SceneView.RepaintAll();
                }
            }

            EditorGUILayout.Space();

            if (GUILayout.Button("CPU Monte Carlo 9 Coefficients"))
            {
                coefficients = new Vector4[9];
                if (SphericalHarmonics.CPU_Project_MonteCarlo_9Coeff(input_cubemap, coefficients, 4096))
                {
                    for (int i = 0; i < 9; ++i)
                    {
                        view_mat.SetVector("c" + i.ToString(), coefficients[i]);
                        view_mat.SetTexture("input", input_cubemap);
                    }

                    SceneView.RepaintAll();
                }
            }

            EditorGUILayout.Space();

            if (GUILayout.Button("GPU Uniform 9 Coefficients"))
            {
                coefficients = new Vector4[9];
                if (SphericalHarmonics.GPU_Project_Uniform_9Coeff(input_cubemap, coefficients))
                {
                    for (int i = 0; i < 9; ++i)
                    {
                        view_mat.SetVector("c" + i.ToString(), coefficients[i]);
                        view_mat.SetTexture("input", input_cubemap);
                    }

                    SceneView.RepaintAll();
                }
            }

            EditorGUILayout.Space();

            if (GUILayout.Button("GPU Monte Carlo 9 Coefficients"))
            {
                coefficients = new Vector4[9];

                if (SphericalHarmonics.GPU_Project_MonteCarlo_9Coeff(input_cubemap, coefficients))
                {
                    for (int i = 0; i < 9; ++i)
                    {
                        view_mat.SetVector("c" + i.ToString(), coefficients[i]);
                        view_mat.SetTexture("input", input_cubemap);
                    }
                }
            }

            EditorGUILayout.Space();

            if (GUILayout.Button("Show"))
            {
                RenderSettings.skybox = view_mat;
            }

            view_mode = EditorGUILayout.Slider(view_mode, 0, 1);
            view_mat.SetFloat("_Mode", view_mode);

            EditorGUILayout.Space();

            //print the 9 coefficients
            if (coefficients != null)
            {
                for (int i = 0; i < 9; ++i)
                {
                    EditorGUILayout.LabelField("c_" + i.ToString() + ": " + coefficients[i].ToString("f4"));
                }
            }
        }

        EditorGUILayout.Space();
        if (tmp != null)
        {
            GUILayout.Label(tmp);
        }
    }
Ejemplo n.º 3
0
    private void OnGUI()
    {
        EditorGUILayout.PropertyField(sp_to_compute);
        so.ApplyModifiedProperties();
        EditorGUILayout.Space();

        if (to_compute != null && GUILayout.Button("Compute Thickness"))
        {
            //create the folder with saved mesh assets
            if (!AssetDatabase.IsValidFolder("Assets/TranslucentMeshes"))
            {
                AssetDatabase.CreateFolder("Assets", "TranslucentMeshes");
            }

            GameObject tmp_camera_object = new GameObject("tmp_camera");
            Camera     tmp_camera        = tmp_camera_object.AddComponent <Camera>();
            tmp_camera.clearFlags      = CameraClearFlags.Color;
            tmp_camera.backgroundColor = Color.black;
            tmp_camera.nearClipPlane   = 0.01f;
            tmp_camera.farClipPlane    = 300;

            GameObject clone    = Instantiate(to_compute.gameObject);
            Mesh       mesh     = Instantiate(to_compute.sharedMesh);
            Vector3[]  vertices = mesh.vertices;
            Vector3[]  normals  = mesh.normals;
            Vector2[]  uv2      = new Vector2[mesh.vertexCount];
            Vector2[]  uv3      = new Vector2[mesh.vertexCount];
            Vector2[]  uv4      = new Vector2[mesh.vertexCount];
            Color[]    colors   = new Color[mesh.vertexCount];

            //temporary storage for the sh coefficients
            Vector4[] coefficients = new Vector4[9];

            //64x64 cubemap should be enough
            Cubemap thickness_cubemap = new Cubemap(128, TextureFormat.RGBA32, false); //TODO: usare formato float

            for (int v = 0; v < mesh.vertexCount; ++v)
            {
                //vertices in the mesh are in local space, transform to world coordinate
                Vector3 vertex_world_position = vertices[v]; // clone.transform.localToWorldMatrix.MultiplyPoint(vertices[v]); //TODO: al posto di lavorare in world space, lavorare in local
                Vector3 world_normal          = normals[v];  // clone.transform.localToWorldMatrix.MultiplyVector(normals[v]);
                tmp_camera.transform.position = vertex_world_position - world_normal * 0.011f;
                tmp_camera.RenderToCubemap(thickness_cubemap);

                //project the cubemap to the spherical harmonic basis
                SphericalHarmonics.GPU_Project_Uniform_9Coeff(thickness_cubemap, coefficients);

                //put 4 coefficients in the vertex color, 2 in the uv2 and 2 in the uv3 and 1 in uv4
                colors[v] = new Color(coefficients[0].x, coefficients[1].x, coefficients[2].x, coefficients[3].x);
                uv2[v]    = new Vector2(coefficients[4].x, coefficients[5].x);
                uv3[v]    = new Vector2(coefficients[6].x, coefficients[7].x);
                uv4[v]    = new Vector2(coefficients[8].x, 0);

                for (int i = 0; i < 9; ++i)
                {
                    coefficients[i] = Vector4.zero;
                }
            }

            mesh.colors = colors;
            mesh.uv2    = uv2;
            mesh.uv3    = uv3;
            mesh.uv4    = uv4;
            mesh.UploadMeshData(true);

            //save the mesh
            AssetDatabase.CreateAsset(mesh, "Assets/TranslucentMeshes/" + to_compute.name + ".asset");

            clone.GetComponent <MeshFilter>().sharedMesh = mesh;

            Object.DestroyImmediate(tmp_camera_object);

            to_compute.gameObject.SetActive(false);
        }
    }
Ejemplo n.º 4
0
    public void Compute()
    {
        Material old_skybox    = RenderSettings.skybox;
        Material cosine_skybox = new Material(Shader.Find("SH/CosineSkybox"));

        RenderSettings.skybox = cosine_skybox;

        //create the folder with saved mesh assets
        if (!AssetDatabase.IsValidFolder("Assets/ComputedMeshes"))
        {
            AssetDatabase.CreateFolder("Assets", "ComputedMeshes");
        }

        //don't modify the original objects but make a copy
        GameObject parent = new GameObject("computed");

        parent.SetActive(false);

        GameObject tmp_camera_object = new GameObject("tmp_camera");
        Camera     tmp_camera        = tmp_camera_object.AddComponent <Camera>();

        tmp_camera.clearFlags    = CameraClearFlags.Skybox;
        tmp_camera.nearClipPlane = 0.01f;
        tmp_camera.farClipPlane  = 300;

        //temporary storage for the sh coefficients
        Vector4[] coefficients = new Vector4[9];

        //64x64 cubemap should be enough
        Cubemap visibility_cubemap = new Cubemap(64, TextureFormat.RGBA32, false);

        //cycle the children renderers
        MeshRenderer[] to_compute = gameObject.GetComponentsInChildren <MeshRenderer>();

        //get the total number of vertex to compute
        int total_vertex     = 0;
        int completed_vertex = 0;

        foreach (MeshRenderer mr in to_compute)
        {
            if (mr.gameObject.isStatic)
            {
                total_vertex = mr.gameObject.GetComponent <MeshFilter>().sharedMesh.vertexCount;
            }
        }

        //shader for rendering the visibility (black = occluded)
        Shader black_shader = Shader.Find("SH/BlackShader");

        foreach (MeshRenderer mr in to_compute)
        {
            if (mr.gameObject.isStatic) //compute only static objects
            {
                //clone the original
                GameObject clone = Instantiate(mr.gameObject);
                clone.name = mr.gameObject.name;
                clone.transform.SetParent(parent.transform);

                Mesh      mesh     = Instantiate(mr.gameObject.GetComponent <MeshFilter>().sharedMesh);
                Vector3[] vertices = mesh.vertices;
                Vector3[] normals  = mesh.normals;
                Vector2[] uv2      = new Vector2[mesh.vertexCount];
                Vector2[] uv3      = new Vector2[mesh.vertexCount];
                Vector2[] uv4      = new Vector2[mesh.vertexCount];
                Color[]   colors   = new Color[mesh.vertexCount];

                for (int v = 0; v < mesh.vertexCount; ++v)
                {
                    //vertices in the mesh are in local space, transform to world coordinate
                    Vector3 vertex_world_position = clone.transform.localToWorldMatrix.MultiplyPoint(vertices[v]);
                    Vector3 world_normal          = clone.transform.localToWorldMatrix.MultiplyVector(normals[v]);
                    tmp_camera.transform.position = vertex_world_position + world_normal * 0.011f;  //offset the camera a little in the normal direction
                    cosine_skybox.SetVector("N", world_normal);

                    tmp_camera.SetReplacementShader(black_shader, "");
                    tmp_camera.RenderToCubemap(visibility_cubemap);
                    tmp_camera.ResetReplacementShader();

                    //project the cubemap to the spherical harmonic basis
                    SphericalHarmonics.GPU_Project_Uniform_9Coeff(visibility_cubemap, coefficients);

                    //put 4 coefficients in the vertex color, 2 in the uv2 and 2 in the uv3 and 1 in uv4
                    colors[v] = new Color(coefficients[0].x, coefficients[1].x, coefficients[2].x, coefficients[3].x);
                    uv2[v]    = new Vector2(coefficients[4].x, coefficients[5].x);
                    uv3[v]    = new Vector2(coefficients[6].x, coefficients[7].x);
                    uv4[v]    = new Vector2(coefficients[8].x, 0);

                    for (int i = 0; i < 9; ++i)
                    {
                        coefficients[i] = Vector4.zero;
                    }

                    completed_vertex++;
                }

                mesh.colors = colors;
                mesh.uv2    = uv2;
                mesh.uv3    = uv3;
                mesh.uv4    = uv4;
                mesh.UploadMeshData(true);

                //save the mesh
                AssetDatabase.CreateAsset(mesh, "Assets/ComputedMeshes/" + mr.name + ".asset");

                clone.GetComponent <MeshFilter>().sharedMesh = mesh;

                Material mat = new Material(Shader.Find("SH/SH_Shader"));
                clone.GetComponent <MeshRenderer>().material = mat;
            }
        }

        Object.DestroyImmediate(tmp_camera_object);

        gameObject.SetActive(false);
        parent.SetActive(true);

        RenderSettings.skybox = old_skybox;
    }