Ejemplo n.º 1
0
        private void    GenerateRays(int _RaysCount, RendererManaged.StructuredBuffer <RendererManaged.float3> _Target)
        {
            _RaysCount = Math.Min(MAX_THREADS, _RaysCount);

            // Half-Life 2 basis
            RendererManaged.float3[] HL2Basis = new RendererManaged.float3[] {
                new RendererManaged.float3((float)Math.Sqrt(2.0 / 3.0), 0.0f, (float)Math.Sqrt(1.0 / 3.0)),
                new RendererManaged.float3(-(float)Math.Sqrt(1.0 / 6.0), (float)Math.Sqrt(1.0 / 2.0), (float)Math.Sqrt(1.0 / 3.0)),
                new RendererManaged.float3(-(float)Math.Sqrt(1.0 / 6.0), -(float)Math.Sqrt(1.0 / 2.0), (float)Math.Sqrt(1.0 / 3.0))
            };

            float CenterTheta = (float)Math.Acos(HL2Basis[0].z);

            float[] CenterPhi = new float[] {
                (float)Math.Atan2(HL2Basis[0].y, HL2Basis[0].x),
                (float)Math.Atan2(HL2Basis[1].y, HL2Basis[1].x),
                (float)Math.Atan2(HL2Basis[2].y, HL2Basis[2].x),
            };

            for (int RayIndex = 0; RayIndex < _RaysCount; RayIndex++)
            {
                double Phi = (Math.PI / 3.0) * (2.0 * WMath.SimpleRNG.GetUniform() - 1.0);

                // Stratified version
                double Theta = (Math.Acos(Math.Sqrt((RayIndex + WMath.SimpleRNG.GetUniform()) / _RaysCount)));

//              // Don't give a shit version (a.k.a. melonhead version)
// //				double	Theta = Math.Acos( Math.Sqrt(WMath.SimpleRNG.GetUniform() ) );
//              double	Theta = 0.5 * Math.PI * WMath.SimpleRNG.GetUniform();

                Theta = Math.Min(0.499f * Math.PI, Theta);


                double CosTheta = Math.Cos(Theta);
                double SinTheta = Math.Sin(Theta);

                double LengthFactor = 1.0 / SinTheta;           // The ray is scaled so we ensure we always walk at least a texel in the texture
                CosTheta *= LengthFactor;
                SinTheta *= LengthFactor;                       // Yeah, yields 1... :)

                _Target.m[0 * MAX_THREADS + RayIndex].Set((float)(Math.Cos(CenterPhi[0] + Phi) * SinTheta),
                                                          (float)(Math.Sin(CenterPhi[0] + Phi) * SinTheta),
                                                          (float)CosTheta);
                _Target.m[1 * MAX_THREADS + RayIndex].Set((float)(Math.Cos(CenterPhi[1] + Phi) * SinTheta),
                                                          (float)(Math.Sin(CenterPhi[1] + Phi) * SinTheta),
                                                          (float)CosTheta);
                _Target.m[2 * MAX_THREADS + RayIndex].Set((float)(Math.Cos(CenterPhi[2] + Phi) * SinTheta),
                                                          (float)(Math.Sin(CenterPhi[2] + Phi) * SinTheta),
                                                          (float)CosTheta);
            }

            _Target.Write();
        }
Ejemplo n.º 2
0
        private void    GenerateRays(int _RaysCount, float _MaxConeAngle, RendererManaged.StructuredBuffer <RendererManaged.float3> _Target)
        {
            _RaysCount = Math.Min(MAX_THREADS, _RaysCount);

            WMath.Hammersley hammersley = new WMath.Hammersley();
            double[,]                       sequence = hammersley.BuildSequence(_RaysCount, 2);
            WMath.Vector[] rays = hammersley.MapSequenceToSphere(sequence, 0.5f * _MaxConeAngle);
            for (int RayIndex = 0; RayIndex < _RaysCount; RayIndex++)
            {
                WMath.Vector ray = rays[RayIndex];

//              // Scale the ray so we ensure to always walk at least a texel in the texture
//              float	SinTheta = (float) Math.Sqrt( 1.0 - ray.y * ray.y );
//              float	LengthFactor = 1.0f / SinTheta;
//              ray *= LengthFactor;

                _Target.m[RayIndex].Set(ray.x, -ray.z, ray.y);
            }

            _Target.Write();
        }