Ejemplo n.º 1
0
    //http://www.klayge.org/?p=3006
    public static Vector3[] GetRandomDirs_BlinnPhong_Importance(Vector3 faceNormal, Vector3 reflectDir, float smoothness, int num)
    {
        Vector3[] rlt = new Vector3[num];

        float reflectAngle = Mathf.Acos(Vector3.Dot(reflectDir, faceNormal)); //镜面反射线与法线夹角
        float mainAngle    = reflectAngle * smoothness;                       //粗糙反射线平均方向与法线夹角

        Vector3 axisTemp = Mathf.Abs(Vector3.Dot(faceNormal, Vector3.up)) > 0.9f ? Vector3.left : Vector3.up;
        Vector3 axis0    = Vector3.Cross(faceNormal, axisTemp);//任意垂直于faceNormal的方向
        Vector3 axis2    = -Vector3.Cross(reflectDir, faceNormal);

        if (axis2.sqrMagnitude == 0)
        {
            axis2 = axis0;
        }

        float shininess = Mathf.Pow(8192, smoothness);

        Quaternion finalRot = Quaternion.AngleAxis(UnityEngine.Random.Range(0f, 360f), faceNormal);

        for (int i = 0; i < num; i++)
        {
            float angle0 = Mathf.Acos(Mathf.Pow(1 - HaltonTool.Halton2(i, 0f, 1f) * (shininess + 1) / (shininess + 2), 1 / (shininess + 1)));
            angle0 *= Mathf.PI * 0.5f;//看起来上面公式的结果范围是0~1,所以加上这个修正一下,不知道原因
            Vector3 dir0 = Quaternion.AngleAxis(angle0 * Mathf.Rad2Deg, axis0) * faceNormal;
            Vector3 dir1 = Quaternion.AngleAxis(HaltonTool.Halton3(i, 0f, 360f), faceNormal) * dir0;
            Vector3 dir2 = Quaternion.AngleAxis(mainAngle * Mathf.Rad2Deg, axis2) * dir1;
            rlt[i] = dir2;
            //Debug.DrawLine(dir2 + Vector3.up * 5, dir2 + Vector3.up * 5 + dir2 * 0.02f, Color.red, 10000);
        }
        return(rlt);
    }
Ejemplo n.º 2
0
    //尝试瞎凑的公式
    public static Vector3[] GetRandomDirs_BRDF(Vector3 faceNormal, Vector3 reflectDir, float smoothness, int num)
    {
        Vector3[] rlt = new Vector3[num];

        //Vector3 mainOutDir = Vector3.Lerp(faceNormal, reflectDir, smoothness).normalized;
        float reflectAngle      = Mathf.Acos(Vector3.Dot(reflectDir, faceNormal)); //镜面反射线与法线夹角
        float mainAngle         = reflectAngle * smoothness;                       //粗糙反射线平均方向与法线夹角
        float distributionAngle = (Mathf.PI * 0.5f * (1 - smoothness));


        Vector3 axisTemp = Mathf.Abs(Vector3.Dot(faceNormal, Vector3.up)) > 0.9f ? Vector3.left : Vector3.up;
        Vector3 axis0    = Vector3.Cross(faceNormal, axisTemp);//任意垂直于faceNormal的方向
        Vector3 axis2    = -Vector3.Cross(reflectDir, faceNormal);

        if (axis2.sqrMagnitude == 0)
        {
            axis2 = axis0;
        }

        Quaternion finalRot = Quaternion.AngleAxis(UnityEngine.Random.Range(0f, 360f), faceNormal);

        for (int i = 0; i < num; i++)
        {
            float   angle0 = Mathf.Asin(Mathf.Sqrt(HaltonTool.Halton2(i, 0f, 1f))) * distributionAngle / (Mathf.PI / 2);
            Vector3 dir0   = Quaternion.AngleAxis(angle0 * Mathf.Rad2Deg, axis0) * faceNormal;
            Vector3 dir1   = Quaternion.AngleAxis(HaltonTool.Halton3(i, 0f, 360f), faceNormal) * dir0;
            Vector3 dir2   = Quaternion.AngleAxis(mainAngle * Mathf.Rad2Deg, axis2) * dir1;
            rlt[i] = dir2;
            //Debug.DrawLine(dir2 + Vector3.up * 5, dir2 + Vector3.up * 5 + dir2 * 0.02f, Color.red, 10000);
        }
        return(rlt);
    }
Ejemplo n.º 3
0
    public static Vector3[] GetRandomDirs(Vector3 faceNormal, int num)
    {
        Vector3[] rlt      = new Vector3[num];
        Vector3   axisTemp = Mathf.Abs(Vector3.Dot(faceNormal, Vector3.up)) > 0.9f ? Vector3.left : Vector3.up;
        Vector3   axis0    = Vector3.Cross(faceNormal, axisTemp);

        for (int i = 0; i < num; i++)
        {
            float      angle0   = Mathf.Acos(HaltonTool.Halton2(i, 0f, 1f)) * Mathf.Rad2Deg;
            Vector3    dir      = Quaternion.AngleAxis(angle0, axis0) * faceNormal;
            Quaternion finalRot = Quaternion.AngleAxis(UnityEngine.Random.Range(0f, 360f), faceNormal);
            dir = finalRot * dir;
            //Debug.DrawLine(dir + Vector3.up * 5, dir + Vector3.up * 5 + dir * 0.02f, Color.red, 10000);
            rlt[i] = dir;
        }
        return(rlt);
    }
Ejemplo n.º 4
0
    public static Vector3[] GetRandomDirs_RoundProj(Vector3 faceNormal, int num)
    {
        Vector3[]  rlt      = new Vector3[num];
        Vector3    axisTemp = Mathf.Abs(Vector3.Dot(faceNormal, Vector3.up)) > 0.9f ? Vector3.left : Vector3.up;
        Vector3    axis0    = Vector3.Cross(faceNormal, axisTemp);
        Quaternion finalRot = Quaternion.AngleAxis(UnityEngine.Random.Range(0f, 360f), faceNormal);

        for (int i = 0; i < num; i++)
        {
            float lenght0 = Mathf.Sqrt(HaltonTool.Halton2(i, 0f, 1f));
            //float lenght0 = Mathf.Sin(Mathf.PI * 0.5f * Mathf.Sqrt(HaltonTool.Halton2(i, 0f, 1f)));
            Vector3 pos0 = axis0 * lenght0;
            Vector3 pos1 = Quaternion.AngleAxis(HaltonTool.Halton3(i, 0f, 360f), faceNormal) * pos0;
            Vector3 dir  = pos1 + faceNormal * (Mathf.Sqrt(1 - lenght0 * lenght0));
            //Debug.DrawLine(dir + Vector3.up * 5, dir + Vector3.up * 5 + faceNormal * 0.02f, Color.red, 10000);
            dir    = finalRot * dir;
            rlt[i] = dir;
        }
        return(rlt);
    }
Ejemplo n.º 5
0
    //http://www.klayge.org/?p=3006
    public static Vector3[] GetRandomDirs_BlinnPhong_Importance2(Vector3 faceNormal, Vector3 reflectDir, float smoothness, int num)
    {
        Vector3[] rlt = new Vector3[num];

        Vector3 w = Vector3.Lerp(faceNormal, reflectDir, smoothness).normalized;
        Vector3 u = Vector3.Cross(new Vector3(w.y, w.z, w.x), w);
        Vector3 v = Vector3.Cross(w, u);

        float shininess = Mathf.Pow(8192, smoothness);

        for (int i = 0; i < num; i++)
        {
            float a = Mathf.Acos(Mathf.Pow(1 - HaltonTool.Halton2(i, 0f, 1f) * (shininess + 1) / (shininess + 2), 1 / (shininess + 1)));
            a *= Mathf.PI * 0.5f;//看起来上面公式的结果范围是0~1,所以加上这个修正一下,不知道原因
            float phi = HaltonTool.Halton3(i, 0f, Mathf.PI * 2);
            rlt[i] = (u * Mathf.Cos(phi) + v * Mathf.Sin(phi)) * Mathf.Sin(a) + w * Mathf.Cos(a);
            //Debug.DrawLine(rlt[i] + Vector3.up * 5, rlt[i] + Vector3.up * 5 + rlt[i] * 0.02f, Color.red, 10000);
        }
        return(rlt);
    }
Ejemplo n.º 6
0
    public void Init()
    {
        Instance = this;
        updateProgress(0);
        HaltonTool.InitHaltonSequence();

        Debug.Log("Start Time : " + Time.realtimeSinceStartup);

        scene = new SimpleScene();

        RayTrace.Init();
        SimpleMaterial.textures.Clear();

        scene.lights = GameObject.FindObjectsOfType <Light>();

        Camera cam = GetComponent <Camera>();

        if (cam)
        {
            MeshRenderer[] renderers = GameObject.FindObjectsOfType <MeshRenderer>();
            foreach (MeshRenderer r in renderers)
            {
                bool isLayerVisible = ((1 << r.gameObject.layer) & cam.cullingMask) != 0;
                if (r.isVisible && isLayerVisible)
                {
                    MeshFilter filter = r.gameObject.GetComponent <MeshFilter>();
                    if (filter && filter.sharedMesh)
                    {
                        for (int i = 0; i < filter.sharedMesh.subMeshCount; i++)
                        {
                            Mesh  mesh      = filter.sharedMesh;
                            int[] triangles = filter.sharedMesh.GetTriangles(i);
                            RayTrace.AddMesh(filter.gameObject.transform, mesh.vertexCount, triangles.Length, mesh.vertices, triangles, 1);
                            SimpleModel model = new SimpleModel(r.gameObject.transform, filter.sharedMesh, i, r.sharedMaterials[i]);
                            model.lights = RayTraceTool.GetActivityLights(r, scene);
                            scene.models.Add(model);
                        }
                    }
                }
            }
            Terrain[] terrains = GameObject.FindObjectsOfType <Terrain>();
            foreach (Terrain terrain in terrains)
            {
                bool isLayerVisible = ((1 << terrain.gameObject.layer) & cam.cullingMask) != 0;
                if (terrain.gameObject.activeInHierarchy && isLayerVisible)
                {
                    int   w          = terrain.terrainData.heightmapWidth;
                    int   h          = terrain.terrainData.heightmapHeight;
                    float realWidth  = terrain.terrainData.size.x * (1 + 1f / w);
                    float realHeight = terrain.terrainData.size.z * (1 + 1f / h);
                    float[,] heights = terrain.terrainData.GetHeights(0, 0, w, h);
                    Vector3[] vertices  = new Vector3[w * h];
                    Vector2[] uvs       = new Vector2[vertices.Length];
                    Vector3[] normals   = new Vector3[vertices.Length];
                    int[]     triangles = new int[(w - 1) * (h - 1) * 2 * 3];
                    for (int i = 0; i < w; i++)
                    {
                        for (int j = 0; j < h; j++)
                        {
                            Vector3 pos = new Vector3(i * realWidth / w, heights[j, i] * terrain.terrainData.size.y, j * realHeight / h);
                            vertices[j * w + i] = pos;
                            uvs[j * w + i]      = new Vector2(i / (float)w, j / (float)h);
                            normals[j * w + i]  = terrain.terrainData.GetInterpolatedNormal(i / (float)w, j / (float)h);
                        }
                    }

                    for (int i = 0; i < w - 1; i++)
                    {
                        for (int j = 0; j < h - 1; j++)
                        {
                            int index = (j * (w - 1) + i) * 6;
                            triangles[index + 0] = (i + 0) + (j + 0) * w;
                            triangles[index + 1] = (i + 1) + (j + 1) * w;
                            triangles[index + 2] = (i + 1) + (j + 0) * w;
                            triangles[index + 3] = (i + 0) + (j + 0) * w;
                            triangles[index + 4] = (i + 0) + (j + 1) * w;
                            triangles[index + 5] = (i + 1) + (j + 1) * w;
                        }
                    }

                    RayTrace.AddMesh(terrain.transform, vertices.Length, triangles.Length, vertices, triangles, 1);
                    SimpleModel model = new SimpleModel();
                    model.mesh     = new SimpleMesh(triangles, uvs, vertices, normals);
                    model.material = new SimpleTerrainMaterial(terrain.terrainData);
                    model.rst      = new RayTrace.RST(terrain.transform.rotation, terrain.transform.lossyScale, terrain.transform.position);
                    model.lights.AddRange(scene.lights);
                    scene.models.Add(model);
                }
            }
        }

        RayTrace.Commit();

        texture = new Texture2D(width, height, TextureFormat.ARGB32, true);
        //viewResult.sharedMaterial.mainTexture = texture;
    }