示例#1
0
    private void GenerateSamples(int amount = 10)
    {
        meshCollider.sharedMesh = currentPointCloud.mesh.mesh;

        var camRay = camera.ScreenPointToRay(Input.mousePosition);
        var dir    = camRay.direction;

        var(dist, _) = PolySurface.RayMarch(coefficients, camRay.origin, dir, 1000.0f, surface.Center);
        var hit = camRay.origin + (dist + 0.001f) * camRay.direction;

        hit = currentCenter - currentNormal * 0.001f;
        dir = -currentNormal;

        int count = 0;

        while (count < amount)
        {
            int stepCount = 0;
            var exit      = TestDataGenerator.SimulatePath(
                samplesRandom,
                surface.Coefficients,
                hit, dir,
                surface.Center,
                surface.g, surface.SigmaSReduced, surface.sigmaT,
                distScale,
                null,
                ref stepCount);

            if (exit != null)
            {
                count += 1;
                var ray = new Ray(exit.Value, -PolySurface.GetNormalAt(surface.Coefficients, exit.Value, surface.Center));
                if (autoProjectSamples && meshCollider.Raycast(ray, out var h, float.MaxValue))
                {
                    var go = GameObject.Instantiate(samplePointPrefab, transform);
                    go.transform.position = h.point;
                    samples.Add(go);

                    //samples.Add(new MeshDBSample
                    //{
                    //    position = h.point,
                    //    gradient = -ray.direction,
                    //});
                }
                else
                {
                    var go = GameObject.Instantiate(samplePointPrefab, transform);
                    go.transform.position = exit.Value;
                    samples.Add(go);
                    //samples.Add(new MeshDBSample
                    //{
                    //    position = exit.Value,
                    //    gradient = -ray.direction
                    //});
                }
            }
        }
示例#2
0
    private void GetSamplesFromModel(Vector3 center, Vector3 normal, Vector3 direction)
    {
        Debug.Log("Start generator");
        foreach (var go in samples)
        {
            GameObject.Destroy(go);
        }
        samples.Clear();

        var coefficients = surface.Coefficients.ToArray();

        var normalToZ    = new Frame(normal);
        var zToDirection = new Frame(-direction).Invert();

        TestDataGenerator.RotatePolynomial(coefficients, normalToZ.x, normalToZ.y, normalToZ.z);

        if (!incidentIsNormal)
        {
            TestDataGenerator.RotatePolynomial(coefficients, zToDirection.x, zToDirection.y, zToDirection.z);
        }

        string[] arguments = null;
        string   fileExe   = null;

        var model = string.IsNullOrWhiteSpace(modelVersion) ? $"{modelName}/final" : $"{modelName}/{modelVersion}";

        switch (sampleSource)
        {
        case SampleSource.Cpp:
            fileExe   = @"D:\Bachelorarbeit\CppModelTest\x64\Release\CppModelTest.exe";
            arguments = new string[]
            {
                model,
                samplesToGenerate.ToString(),
                modelStddev.ToString(),
                $"{string.Join(",", coefficients)},{surface.alphaEff},{surface.g},{surface.ior}"
            };
            break;

        case SampleSource.Python:
            fileExe   = "python.exe";
            arguments = new string[]
            {
                @"D:\Bachelorarbeit\Bachelorarbeit\Model\generate_samples.py",
                model,
                samplesToGenerate.ToString(),
                modelStddev.ToString(),
                $"{string.Join(",", coefficients)},{surface.alphaEff},{surface.g},{surface.ior}"
            };
            break;

        default:
            fileExe   = @"D:\Bachelorarbeit\CppModelTest\x64\Release\CppModelTest.exe";
            arguments = new string[]
            {
                model,
                samplesToGenerate.ToString(),
                modelStddev.ToString(),
                $"{string.Join(",", coefficients)},{surface.alphaEff},{surface.g},{surface.ior}"
            };
            break;
        }

        var p = new System.Diagnostics.Process();

        p.StartInfo.FileName               = fileExe;
        p.StartInfo.WindowStyle            = System.Diagnostics.ProcessWindowStyle.Hidden;
        p.StartInfo.WorkingDirectory       = @"D:\Bachelorarbeit\Bachelorarbeit\Model";
        p.StartInfo.UseShellExecute        = false;
        p.StartInfo.CreateNoWindow         = true;
        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.Arguments              = string.Join(" ", arguments.Select(a => $"\"{a}\""));

        Debug.Log(p.StartInfo.Arguments);

        var r = new System.Random();

        p.OutputDataReceived += (sender, args) => {
            if (args.Data != null && args.Data.StartsWith("# "))
            {
                var parts = args.Data.Substring(2).Split(',').Select(s => float.Parse(s)).ToArray();
                var pos   = new Vector3(parts[0], parts[1], parts[2]);
                var n     = PolySurface.GetNormalAt(coefficients, pos, Vector3.zero);

                //pos = new Vector3(0, 0, (float)r.NextDouble());

                if (!incidentIsNormal)
                {
                    pos = zToDirection.ToMatrix() * pos;
                    n   = zToDirection.ToMatrix() * n;
                }
                pos = normalToZ.ToMatrix() * pos;
                n   = normalToZ.ToMatrix() * n;

                pos += center;

                samplesTemp.Add(new MeshDBSample
                {
                    position = pos,
                    gradient = n
                });
            }
        };

        p.Start();
        p.BeginOutputReadLine();

        process = p;
    }
    public static Vector3?SimulatePath(System.Random random, float[] coefficients, Vector3 origin, Vector3 direction, Vector3 center, float g, float sigmaSRed, float sigmaA, float distScale, Action <PathPoint> onInteraction, ref int stepCount)
    {
        direction = direction.normalized;

        float maxDist = float.MaxValue;

        maxDist = GetScatterDistance(random, sigmaSRed) * distScale;

        float throughput = 1.0f;

        for (int i = 0; i < 500; i++)
        {
            stepCount += 1;

            var(dist, inside) = PolySurface.RayMarch(coefficients, origin, direction, maxDist, center);
            var newPoint = origin + direction * dist;
            var point    = new PathPoint {
                position  = newPoint,
                direction = direction
            };

            var normal = PolySurface.GetNormalAt(coefficients, newPoint, center);
            origin = newPoint - normal * PolySurface.SURF_DIST * 2;

            if (!inside)
            {
                // exited surface
                return(newPoint);
            }


            direction = GetRandomNewDirection(random, g, direction);
            // still inside, set random direction and maxDist
            //if (g == 0) {
            //    direction = OnUnitSphere(random);
            //} else {
            //    float rand = RandomRange(random, 0.0f, 1.0f);
            //    float cosAngle = InvIntPhaseFunction(rand, g);
            //    float theta = Mathf.Acos(cosAngle);
            //    float d = 1 / Mathf.Tan(theta);

            //    // Debug.Log($"rand: {rand}, cosAngle: {cosAngle}, theta: {theta}, d: {d}");

            //    if (d == float.PositiveInfinity) {
            //        // do nothing
            //        //direction = direction;
            //    } else if (d == float.NegativeInfinity) {
            //        direction = -direction;
            //    } else {
            //        var right = GetPerpendicular(direction).normalized;
            //        var up = Vector3.Cross(right, direction).normalized;
            //        var uv = InsideUnitCircle(random);

            //        point.uv = uv;
            //        point.right = right;
            //        point.up = up;

            //        // Debug.Log($"right: {right}, up: {up}, uv: {uv}");

            //        direction = uv.x * right + uv.y * up + d * direction;
            //        direction = direction.normalized;
            //    }
            //}

            // Debug.Log($"direction: {direction}");

            maxDist         = GetScatterDistance(random, sigmaSRed) * distScale;
            point.direction = point.direction * Vector3.Dot(point.direction, direction * maxDist);

            onInteraction?.Invoke(point);

            float transmission = Mathf.Exp(-sigmaA * maxDist);

            throughput = throughput * transmission;

            // russian roulette
            if (i > 5)
            {
                if ((float)random.NextDouble() > throughput)
                {
                    return(null);
                }
                throughput = 1;
            }
        }

        // reached max steps, ray counts as absorbed
        return(null);
    }