예제 #1
0
        //!!!!
        //!!!!need per camera context
        //double smoothIntensityFactorLastUpdate;
        //double? smoothIntensityFactor;

        /////////////////////////////////////////

        protected override void OnRender(ViewportRenderingContext context, Component_RenderingPipeline.IFrameData frameData, ref Component_Image actualTexture)
        {
            base.OnRender(context, frameData, ref actualTexture);

            var cameraSettings = context.Owner.CameraSettings;

            bool    lightFound    = false;
            Vector3 lightPosition = Vector3.Zero;

            if (OverrideDirection.Value != Vector3.Zero)
            {
                lightFound    = true;
                lightPosition = cameraSettings.Position - OverrideDirection.Value.GetNormalize() * cameraSettings.FarClipDistance;
            }
            else
            {
                if (Light.ReferenceSpecified)
                {
                    var light = Light.Value;
                    if (light != null)
                    {
                        lightFound = true;
                        if (light.Type.Value == Component_Light.TypeEnum.Directional)
                        {
                            lightPosition = cameraSettings.Position - light.TransformV.Rotation.GetForward() * cameraSettings.FarClipDistance;
                        }
                        else
                        {
                            lightPosition = light.TransformV.Position;
                        }
                    }
                }
                else
                {
                    var frameData2 = frameData as Component_RenderingPipeline_Basic.FrameData;
                    if (frameData2 != null)
                    {
                        foreach (var lightIndex in frameData2.LightsInFrustumSorted)
                        {
                            var item = frameData2.Lights[lightIndex];
                            if (item.data.Type == Component_Light.TypeEnum.Directional)
                            {
                                lightFound    = true;
                                lightPosition = cameraSettings.Position - item.data.Rotation.GetForward() * (float)cameraSettings.FarClipDistance;
                                break;
                            }
                        }
                    }
                }
            }

            if (!lightFound)
            {
                return;
            }
            if (!context.Owner.CameraSettings.ProjectToScreenCoordinates(lightPosition, out var screenLightPosition))
            {
                return;
            }

            //calculate intensity factor by the sun position on the screen.
            double demandIntensityFactor = 0;
            {
                Degree angle = 0;
                if (lightPosition != cameraSettings.Position)
                {
                    angle = MathAlgorithms.GetVectorsAngle(cameraSettings.Rotation.GetForward(),
                                                           (lightPosition - cameraSettings.Position).GetNormalize()).InDegrees();
                }
                else
                {
                    angle = 10000;
                }

                var curve = new CurveLine();
                curve.AddPoint(0, new Vector3(1, 0, 0));
                curve.AddPoint(60, new Vector3(1, 0, 0));
                curve.AddPoint(75, new Vector3(0, 0, 0));
                curve.AddPoint(90, new Vector3(0, 0, 0));
                var angleFactor = curve.CalculateValueByTime(angle).X;

                var curve2 = new CurveLine();
                curve2.AddPoint(-0.2, new Vector3(0, 0, 0));
                curve2.AddPoint(-0.1, new Vector3(1, 0, 0));
                curve2.AddPoint(1.1, new Vector3(1, 0, 0));
                curve2.AddPoint(1.2, new Vector3(0, 0, 0));
                var heightFactor = curve2.CalculateValueByTime(screenLightPosition.Y).X;

                demandIntensityFactor = angleFactor * heightFactor;

                //const float screenFadingBorder = .1f;

                //double minDistance = 1;

                //for( int axis = 0; axis < 2; axis++ )
                //{
                //	if( screenLightPosition[ axis ] < screenFadingBorder )
                //	{
                //		var d = screenLightPosition[ axis ];
                //		if( d < minDistance )
                //			minDistance = d;
                //	}
                //	else if( screenLightPosition[ axis ] > 1.0f - screenFadingBorder )
                //	{
                //		var d = 1.0f - screenLightPosition[ axis ];
                //		if( d < minDistance )
                //			minDistance = d;
                //	}
                //}
                //needIntensityFactor = minDistance / screenFadingBorder;
                //MathEx.Saturate( ref needIntensityFactor );

                ////clamp screenLightPosition
                //if( !new Rectangle( 0, 0, 1, 1 ).Contains( screenLightPosition ) )
                //{
                //	if( MathAlgorithms.IntersectRectangleLine( new Rectangle( .0001f, .0001f, .9999f, .9999f ),
                //		new Vector2( .5f, .5f ), screenLightPosition, out var intersectPoint1, out var intersectPoint2 ) != 0 )
                //	{
                //		screenLightPosition = intersectPoint1;
                //	}
                //}
            }

            var smoothIntensityFactor = demandIntensityFactor;
            ////update smooth intensity factor
            //if( smoothIntensityFactor == null )
            //	smoothIntensityFactor = needIntensityFactor;
            //if( smoothIntensityFactorLastUpdate != context.Owner.LastUpdateTime )
            //{
            //	smoothIntensityFactorLastUpdate = context.Owner.LastUpdateTime;

            //	const double smoothSpeed = 1;
            //	var step = context.Owner.LastUpdateTimeStep * smoothSpeed;

            //	if( needIntensityFactor > smoothIntensityFactor )
            //	{
            //		smoothIntensityFactor += step;
            //		if( smoothIntensityFactor > needIntensityFactor )
            //			smoothIntensityFactor = needIntensityFactor;
            //	}
            //	else
            //	{
            //		smoothIntensityFactor -= step;
            //		if( smoothIntensityFactor < needIntensityFactor )
            //			smoothIntensityFactor = needIntensityFactor;
            //	}
            //}

            //get result intensity
            var resultIntensity = Intensity.Value * smoothIntensityFactor;

            if (resultIntensity <= 0)
            {
                return;
            }

            double divisor = 9.0 - Resolution;

            if (divisor <= 1)
            {
                divisor = 1;
            }
            var sizeFloat = actualTexture.Result.ResultSize.ToVector2() / divisor;
            var size      = new Vector2I((int)sizeFloat.X, (int)sizeFloat.Y);

            //scattering pass
            var scatteringTexture = context.RenderTarget2D_Alloc(size, PixelFormat.A8R8G8B8);              //!!!! PixelFormat.R8G8B8 );
            {
                context.SetViewport(scatteringTexture.Result.GetRenderTarget().Viewports[0]);

                CanvasRenderer.ShaderItem shader = new CanvasRenderer.ShaderItem();
                shader.VertexProgramFileName   = @"Base\Shaders\EffectsCommon_vs.sc";
                shader.FragmentProgramFileName = @"Base\Shaders\Effects\LightShafts\Scattering_fs.sc";

                context.objectsDuringUpdate.namedTextures.TryGetValue("depthTexture", out var depthTexture);
                if (depthTexture == null)
                {
                    //!!!!
                }

                shader.Parameters.Set(new ViewportRenderingContext.BindTextureData(0 /*"depthTexture"*/, depthTexture,
                                                                                   TextureAddressingMode.Clamp, FilterOption.Point, FilterOption.Point, FilterOption.None));
                shader.Parameters.Set("screenLightPosition", screenLightPosition.ToVector2F());
                shader.Parameters.Set("decay", (float)Decay);
                shader.Parameters.Set("density", (float)Density);

                context.RenderQuadToCurrentViewport(shader);
            }

            //blur pass
            var blurTexture = context.RenderTarget2D_Alloc(size, PixelFormat.A8R8G8B8);              //!!!! PixelFormat.R8G8B8 );

            {
                context.SetViewport(blurTexture.Result.GetRenderTarget().Viewports[0]);

                CanvasRenderer.ShaderItem shader = new CanvasRenderer.ShaderItem();
                shader.VertexProgramFileName   = @"Base\Shaders\EffectsCommon_vs.sc";
                shader.FragmentProgramFileName = @"Base\Shaders\Effects\LightShafts\Blur_fs.sc";

                //!!!!Linear?
                shader.Parameters.Set(new ViewportRenderingContext.BindTextureData(0 /*"scatteringTexture"*/, scatteringTexture,
                                                                                   TextureAddressingMode.Clamp, FilterOption.Linear, FilterOption.Linear, FilterOption.None));
                shader.Parameters.Set("color", Color.Value.ToVector3F());
                shader.Parameters.Set("screenLightPosition", screenLightPosition.ToVector2F());
                shader.Parameters.Set("blurFactor", (float)BlurFactor);

                context.RenderQuadToCurrentViewport(shader);
            }

            //free old textures
            context.DynamicTexture_Free(scatteringTexture);

            //create final
            var finalTexture = context.RenderTarget2D_Alloc(actualTexture.Result.ResultSize, actualTexture.Result.ResultFormat);

            {
                context.SetViewport(finalTexture.Result.GetRenderTarget().Viewports[0]);

                CanvasRenderer.ShaderItem shader = new CanvasRenderer.ShaderItem();
                shader.VertexProgramFileName   = @"Base\Shaders\EffectsCommon_vs.sc";
                shader.FragmentProgramFileName = @"Base\Shaders\Effects\LightShafts\Final_fs.sc";

                shader.Parameters.Set(new ViewportRenderingContext.BindTextureData(0 /*"sourceTexture"*/, actualTexture,
                                                                                   TextureAddressingMode.Clamp, FilterOption.Point, FilterOption.Point, FilterOption.None));
                shader.Parameters.Set(new ViewportRenderingContext.BindTextureData(1 /*"blurTexture"*/, blurTexture,
                                                                                   TextureAddressingMode.Clamp, FilterOption.Linear, FilterOption.Linear, FilterOption.None));
                shader.Parameters.Set("intensity", (float)resultIntensity);

                context.RenderQuadToCurrentViewport(shader);
            }

            //free old textures
            context.DynamicTexture_Free(actualTexture);
            context.DynamicTexture_Free(blurTexture);

            //update actual texture
            actualTexture = finalTexture;
        }
예제 #2
0
        public static void GenerateTorus(int axis, double radius, int segments, Degree circumference, double tubeRadius, int tubeSegments, Degree tubeCircumference, /*bool smooth, */ bool insideOut, out Vector3[] positions, out Vector3[] normals, out Vector4[] tangents, out Vector2[] texCoords, out int[] indices, out Face[] faces)
        {
            if (radius < tubeRadius)
            {
                tubeRadius = radius;
            }
            bool loopOfLegs = Math.Abs(circumference.ToDouble() - 360) < 1e-5;
            bool endCapes   = !loopOfLegs;

            if (radius <= 0 || tubeRadius <= 0 || segments < 3 || tubeSegments < 3 || circumference <= 0 || tubeCircumference <= 0)
            {
                GetEmptyData(out positions, out normals, out tangents, out texCoords, out indices, out faces);
                return;
            }

            ReplaceAxes(out int axis0, out int axis1, axis);

            int nextVertex = 0;

            Point[] polygon = GenerateCircleZ(tubeSegments + 1, tubeRadius, tubeCircumference, ref nextVertex);
            FromZAxisToAxis(polygon, axis0);               //сечение тора
            Matrix4[] m    = GetTransformsOfRotationCircle(segments + 1, axis, circumference, (radius - tubeRadius) * GetAxisVector(axis1));
            var       legs = GenerateLegs(polygon, m, nextVertex, loopOfLegs);

            int rawVertexCount = CommonPipeBuilder.GetLegsRawVertexCount(legs) + (endCapes ? 2 * CommonPipeBuilder.GetPolygonAdaptiveRawVertexCount(polygon) : 0);
            var builder        = new CommonPipeBuilder(rawVertexCount, (legs.Length - 1) * tubeSegments + (endCapes ? 2 : 0), true);

            builder.AddLegs(legs, insideOut, 1);

            //ToDo ?? Нужны ли крышки когда circumference<360 ?  Может опцию endCapes ?
            //Add capes
            if (endCapes)
            {
                nextVertex *= legs.Length;
                Point center0 = new Point(m[0] * Vector3.Zero, nextVertex++);
                Point center1 = new Point(m[m.Length - 1] * Vector3.Zero, nextVertex++);

                builder.AddPolygonAdaptive(legs[0], center0, !insideOut, !insideOut);                     //normal противоположна от направления смещения legs поэтому !insideOut
                builder.AddPolygonAdaptive(legs[legs.Length - 1], center1, insideOut, insideOut);
            }

            builder.GetData(out positions, out normals, out tangents, out texCoords, out indices, out faces);
        }
예제 #3
0
 public static void GenerateTorus(int axis, double radius, int segments, Degree circumference, double tubeRadius, int tubeSegments, Degree tubeCircumference, /*bool smooth, */ bool insideOut, out Vector3F[] positions, out Vector3F[] normals, out Vector4F[] tangents, out Vector2F[] texCoords, out int[] indices, out Face[] faces)
 {
     GenerateTorus(axis, radius, segments, circumference, tubeRadius, tubeSegments, tubeCircumference, /*smooth, */ insideOut, out Vector3[] positionsD, out Vector3[] normalsD, out Vector4[] tangentsD, out Vector2[] texCoordsD, out indices, out faces);
예제 #4
0
 public static Degree Generate(Degree minValue, Degree maxValue)
 {
     lock (_static)
         return(_static.Next(minValue, maxValue));
 }
예제 #5
0
 public static void GenerateArch(int axis, double radius, double thickness, double depth, int segments, int segmentsDepth, Degree circumference, bool endCapes, bool insideOut, out Vector3F[] positions, out Vector3F[] normals, out Vector4F[] tangents, out Vector2F[] texCoords, out int[] indices, out Face[] faces)
 {
     GenerateArch(axis, radius, thickness, depth, segments, segmentsDepth, circumference, endCapes, insideOut, out Vector3[] positionsD, out Vector3[] normalsD, out Vector4[] tangentsD, out Vector2[] texCoordsD, out indices, out faces);
예제 #6
0
        //ToDo : Логичнее когда главное направление для оси, в направлении входа. При axis=1,2 арка стоит, при axis=2 лежит на боку - тогда задать default axis=2
        //ToDo ??? Надо ли сделать чтобы нижние поверхности были паралельны земле при circumference<180 ?(тогда угол у внутреннего кольца будет меньше).
        public static void GenerateArch(int axis, double radius, double thickness, double depth, int segments, int segmentsDepth, Degree circumference, bool endCapes, bool insideOut, out Vector3[] positions, out Vector3[] normals, out Vector4[] tangents, out Vector2[] texCoords, out int[] indices, out Face[] faces)
        {
            if (radius < thickness)
            {
                thickness = radius;
            }

            if (radius <= 0 || segments < 2 || segmentsDepth < 0 || circumference <= 0)
            {
                GetEmptyData(out positions, out normals, out tangents, out texCoords, out indices, out faces);
                return;
            }

            //ToDo ??? endCapes это передняя/задняя или нижние поверхности ?
            bool frontBack = endCapes && 1e-8 < thickness;
            bool bottom    = endCapes;

            int legPointCount = segments + 1;
            int nextVertex    = 0;

            double startAngle = ((Math.PI - circumference.InRadians()) / 2);

            Point[] outer = GenerateCircleZ(legPointCount, radius, circumference, ref nextVertex, startAngle);
            FromZAxisToAxis(outer, axis);
            Point[] inner = GenerateCircleZ(legPointCount, radius - thickness, circumference, ref nextVertex, startAngle);
            FromZAxisToAxis(inner, axis);
            Point[] down1 = { inner[0], outer[0] };
            Point[] down2 = { outer[outer.Length - 1], inner[inner.Length - 1] };

            var halfVector = 0.5 * depth * GetAxisVector(axis);

            Matrix4[] m = GetTransformsOfLinePath(segmentsDepth + 1, -halfVector, halfVector);

            var legsOuter = GenerateLegs(outer, m, nextVertex, false);
            var legsInner = GenerateLegs(inner, m, nextVertex, false);

            Point[][] legsDown1 = null;
            Point[][] legsDown2 = null;
            if (bottom)
            {
                legsDown1 = GenerateLegs(down1, m, nextVertex, false);
                legsDown2 = GenerateLegs(down2, m, nextVertex, false);
            }

            int rawVertexCount = 2 * CommonPipeBuilder.GetLegsRawVertexCount(legsOuter) +
                                 (legsDown1 == null ? 0 : 2 * CommonPipeBuilder.GetLegsRawVertexCount(legsDown1)) +
                                 (frontBack ? 2 * CommonPipeBuilder.GetPolygon2RawVertexCount(outer) : 0);
            int faceCount = 2 * segments * (legsOuter.Length - 1) + 2 * (bottom ? legsOuter.Length - 1 : 0) + (frontBack ? 2 : 0);
            var builder   = new CommonPipeBuilder(rawVertexCount, faceCount, true);

            builder.AddLegs(legsOuter, insideOut, 1);
            builder.AddLegs(legsInner, !insideOut, 1);

            if (bottom)
            {
                builder.AddLegs(legsDown1, insideOut);
                builder.AddLegs(legsDown2, insideOut);
            }

            if (frontBack)
            {
                builder.AddPolygon2(legsOuter[0], legsInner[0], !insideOut, !insideOut);                       //normal противоположна от направления смещения legs поэтому !insideOut
                builder.AddPolygon2(legsOuter[legsOuter.Length - 1], legsInner[legsInner.Length - 1], insideOut, insideOut);
            }

            builder.GetData(out positions, out normals, out tangents, out texCoords, out indices, out faces);
        }