Ejemplo n.º 1
0
        public void PixelShaderEffect_FeatureLevelValidation()
        {
            const string hlsl =
                @"
                float4 main() : SV_Target
                {
                    return 0;
                }
            ";

            var effect93 = new PixelShaderEffect(ShaderCompiler.CompileShader(hlsl, "ps_4_0_level_9_3"));
            var effect40 = new PixelShaderEffect(ShaderCompiler.CompileShader(hlsl, "ps_4_0"));

            using (var featureLevel93Device = DeviceCreator.CreateDevice(useFeatureLevel93: true))
                using (var canvasDevice = CanvasDevice.CreateFromDirect3D11Device(featureLevel93Device))
                {
                    Assert.IsTrue(effect93.IsSupported(canvasDevice));
                    Assert.IsFalse(effect40.IsSupported(canvasDevice));

                    using (var renderTarget = new CanvasRenderTarget(canvasDevice, 1, 1, 96))
                        using (var drawingSession = renderTarget.CreateDrawingSession())
                        {
                            drawingSession.DrawImage(effect93);

                            Utils.AssertThrowsException <COMException>(
                                () => drawingSession.DrawImage(effect40),
                                "This shader requires a higher Direct3D feature level than is supported by the device. Check PixelShaderEffect.IsSupported before using it.");
                        }
                }
        }
Ejemplo n.º 2
0
        // For matrix types that are accessed as component arrays (int or bool matrix + float matrices other than 3x2 and 4x4).
        void TestMatrixPropertyType <T>(string hlsl, T[] initialValue, T[] initialArray, T[] newValue, T[] newArray)
        {
            var effect = new PixelShaderEffect(ShaderCompiler.CompileShader(hlsl, "ps_4_0"));

            // Verify initial values.
            CollectionAssert.AreEqual(initialValue, (T[])effect.Properties["value_row"]);
            CollectionAssert.AreEqual(initialValue, (T[])effect.Properties["value_col"]);

            CollectionAssert.AreEqual(initialArray, (T[])effect.Properties["array_row"]);
            CollectionAssert.AreEqual(initialArray, (T[])effect.Properties["array_col"]);

            // Set new values.
            effect.Properties["value_row"] = newValue;
            effect.Properties["value_col"] = newValue;

            effect.Properties["array_row"] = newArray;
            effect.Properties["array_col"] = newArray;

            // Read back the modified values.
            CollectionAssert.AreEqual(newValue, (T[])effect.Properties["value_row"]);
            CollectionAssert.AreEqual(newValue, (T[])effect.Properties["value_col"]);

            CollectionAssert.AreEqual(newArray, (T[])effect.Properties["array_row"]);
            CollectionAssert.AreEqual(newArray, (T[])effect.Properties["array_col"]);
        }
Ejemplo n.º 3
0
        async Task canvas_CreateResourcesAsync(CanvasAnimatedControl sender)
        {
            DissolveEffect = new PixelShaderEffect(await ReadAllBytes("Assets/Shaders/WipeUp.bin"));
            //DissolveEffect.Properties["feather"] = 0.1f;
            DissolveMask = await CreateRippleEffect();

            CanvasSourceImageLarge1 = await CanvasBitmap.LoadAsync(sender, new Uri("ms-appx:///" + "Assets/Images/beautiful-bloom-blooming-blossom-414083.jpg"));

            CanvasSourceImageLarge2 = await CanvasBitmap.LoadAsync(sender, new Uri("ms-appx:///" + "Assets/Images/nature-red-forest-leaves-33109.jpg"));

            CanvasSourceImageSmall1 = await CanvasBitmap.LoadAsync(sender, new Uri("ms-appx:///" + "Assets/Images/beach-birds-calm-clouds-219998.jpg"));

            CanvasSourceImageSmall2 = await CanvasBitmap.LoadAsync(sender, new Uri("ms-appx:///" + "Assets/Images/photography-of-trees-covered-with-snow-773594.jpg"));

            try
            {
                var info = Windows.Graphics.Display.DisplayInformation.GetForCurrentView();
                DissolveEffect.Properties["dpi"]    = info.LogicalDpi;
                DissolveEffect.Properties["height"] = 369f;
                //DissolveEffect.Properties["progress"] = (float)ProgressSlider.Value;
                DissolveEffect.Source1 = CanvasSourceImageSmall1;
                //DissolveEffect.Source2 = CanvasSourceImageSmall2;
            }
            catch { }
        }
Ejemplo n.º 4
0
        void ValidateSourceProperty(PixelShaderEffect effect, Func <IGraphicsEffectSource> getter, Action <IGraphicsEffectSource> setter, int expectedSourceCount, int whichSource)
        {
            // Should be initially null.
            Assert.IsNull(getter());

            // Should always be able to set to null.
            setter(null);
            Assert.IsNull(getter());

            var source = new ColorSourceEffect();

            if (whichSource <= expectedSourceCount)
            {
                // Should be able to set and get non-null values for this source of the shader.
                setter(source);

                Assert.AreEqual(source, getter());
            }
            else
            {
                // Should not be able to set this source.
                Utils.AssertThrowsException <ArgumentException>(
                    () => setter(source),
                    "Source" + whichSource + " must be null when using this pixel shader (shader inputs: " + expectedSourceCount + ").");
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Renders a texture that contains surface normals
        /// in the R, G and B channels and height information in
        /// the A channel based on the specified height map.
        /// </summary>
        /// <param name="resourceCreator">Resource creator</param>
        /// <param name="heightMap">Height map</param>
        /// <returns>A combination of a normal map and the height map</returns>
        private static async Task <CanvasBitmap> RenderNormalHeightMapAsync(ICanvasResourceCreatorWithDpi resourceCreator, CanvasBitmap heightMap, float heightDifference)
        {
            var bytes = await Utilities.ReadBytesFromUriAsync(new Uri("ms-appx:///Shaders/NormalMapFromHeightMapShader.bin"));

            var heightMapConverterEffect = new PixelShaderEffect(bytes)
            {
                Source1          = heightMap,
                Source1Mapping   = SamplerCoordinateMapping.Offset,
                MaxSamplerOffset = 1,
            };

            heightMapConverterEffect.Properties["dpi"]    = resourceCreator.Dpi;
            heightMapConverterEffect.Properties["height"] = heightDifference;

            var normalHeightMap = new CanvasRenderTarget(
                resourceCreator,
                (float)heightMap.Size.Width,
                (float)heightMap.Size.Height,
                heightMap.Dpi);

            using (var g = normalHeightMap.CreateDrawingSession())
            {
                g.DrawImage(heightMapConverterEffect);
            }

            return(normalHeightMap);
        }
Ejemplo n.º 6
0
        public void PixelShaderEffect_PropertiesDictionary_Methods()
        {
            const string hlsl =
                @"
                float foo = 23;
                int i = 42;

                float4 main() : SV_Target
                {
                    return foo * i;
                }
            ";

            var effect = new PixelShaderEffect(ShaderCompiler.CompileShader(hlsl, "ps_4_0"));

            // Test the various dictionary methods that are forwarded from our
            // Map<> implementation via PixelShaderEffectPropertyMapTraits.

            // Count.
            Assert.AreEqual(2, effect.Properties.Count);

            // HasKey.
            Assert.IsTrue(effect.Properties.ContainsKey("foo"));
            Assert.IsTrue(effect.Properties.ContainsKey("i"));

            Assert.IsFalse(effect.Properties.ContainsKey("bar"));
            Assert.IsFalse(effect.Properties.ContainsKey("I"));
            Assert.IsFalse(effect.Properties.ContainsKey(string.Empty));

            // Lookup.
            Assert.AreEqual(23.0f, effect.Properties["foo"]);
            Assert.AreEqual(42, effect.Properties["i"]);

            object value;

            Utils.AssertThrowsException <ArgumentException>(
                () => value = effect.Properties["bar"],
                "Shader does not have a property named 'bar'.");

            Utils.AssertThrowsException <ArgumentException>(
                () => value = effect.Properties[string.Empty],
                "Shader does not have a property named ''.");

            // GetKeyValuePairs.
            var array = effect.Properties.ToArray();

            Assert.AreEqual(2, array.Length);

            Assert.AreEqual("foo", array[0].Key);
            Assert.AreEqual(23.0f, array[0].Value);

            Assert.AreEqual("i", array[1].Key);
            Assert.AreEqual(42, array[1].Value);

            // Remove and Clear are not supported.
            Assert.ThrowsException <NotImplementedException>(() => effect.Properties.Remove("foo"));
            Assert.ThrowsException <NotImplementedException>(() => effect.Properties.Clear());
        }
Ejemplo n.º 7
0
        public void PixelShaderEffect_ShaderReflectionSetsCoordinateMappingDefaults()
        {
            const string hlsl =
                @"
                texture2D t0;
                sampler s0;

                texture2D t1;
                sampler s1;

                texture2D t2;
                sampler s2;

                texture2D t3;
                sampler s3;

                float4 main(float4 texcoord0 : TEXCOORD0, 
                            float4 texcoord1 : TEXCOORD1, 
                            float4 texcoord2 : TEXCOORD2, 
                            float4 texcoord3 : TEXCOORD3) : SV_Target
                {
                    return t0.Sample(s0, texcoord0) +
                           t1.Sample(s1, texcoord1) +
                           t2.Sample(s2, texcoord2) +
                           t3.Sample(s3, texcoord3);
                }

                export float4 ShaderLinkingFunction(float4 input0    : INPUT0, 
                                                    float4 texcoord1 : TEXCOORD1, 
                                                    float4 texcoord2 : TEXCOORD2, 
                                                    float4 input3    : INPUT3)
                {
                    return input0 +
                           t1.Sample(s1, texcoord1) +
                           t2.Sample(s2, texcoord2) +
                           input3;
                }
            ";

            // If we compile without support for shader linking, all mappings default to Unknown.
            var effect = new PixelShaderEffect(ShaderCompiler.CompileShader(hlsl, "ps_4_0"));

            Assert.AreEqual(SamplerCoordinateMapping.Unknown, effect.Source1Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.Unknown, effect.Source2Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.Unknown, effect.Source3Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.Unknown, effect.Source4Mapping);

            // But if we include a shader linking function, reflection now has enough
            // info to detect which inputs are simple. These are set to OneToOne mapping.
            effect = new PixelShaderEffect(ShaderCompiler.CompileShaderAndEmbedLinkingFunction(hlsl));

            Assert.AreEqual(SamplerCoordinateMapping.OneToOne, effect.Source1Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.Unknown, effect.Source2Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.Unknown, effect.Source3Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.OneToOne, effect.Source4Mapping);
        }
Ejemplo n.º 8
0
        async Task <PixelShaderEffect> CreateRippleEffect()
        {
            var ripplesPixelShaderEffect = new PixelShaderEffect(await ReadAllBytes("Assets/Shaders/Ripples.bin"));

            ripplesPixelShaderEffect.Properties["frequency"] = 0.05f;
            ripplesPixelShaderEffect.Properties["dpi"]       = 96f;
            ripplesPixelShaderEffect.Properties["offset"]    = 0f;
            ripplesPixelShaderEffect.Properties["center"]    = new Vector2(1280f / 2f, 853 / 2f);
            return(ripplesPixelShaderEffect);
        }
Ejemplo n.º 9
0
        public void PixelShaderEffect_MaxOffsetAndOffsetMappingValidation()
        {
            const string hlsl =
                @"
                texture2D t1;
                sampler s1;

                float4 main() : SV_Target
                {
                    return t1.Sample(s1, 0);
                }
            ";

            var effect = new PixelShaderEffect(ShaderCompiler.CompileShader(hlsl, "ps_4_0"))
            {
                Source1 = new ColorSourceEffect()
            };

            var device       = new CanvasDevice();
            var renderTarget = new CanvasRenderTarget(device, 1, 1, 96);

            // It's an error to draw with Offset mapping mode but MaxSamplerOffset not set.
            effect.Source1Mapping   = SamplerCoordinateMapping.Offset;
            effect.MaxSamplerOffset = 0;

            Utils.AssertThrowsException <ArgumentException>(() =>
            {
                using (var ds = renderTarget.CreateDrawingSession())
                {
                    ds.DrawImage(effect);
                }
            }, "When PixelShaderEffect.Source1Mapping is set to Offset, MaxSamplerOffset should also be set.");

            // Also an error to draw with MaxSamplerOffset but no Offset mapping mode.
            effect.Source1Mapping   = SamplerCoordinateMapping.OneToOne;
            effect.MaxSamplerOffset = 1;

            Utils.AssertThrowsException <ArgumentException>(() =>
            {
                using (var ds = renderTarget.CreateDrawingSession())
                {
                    ds.DrawImage(effect);
                }
            }, "When PixelShaderEffect.MaxSamplerOffset is set, at least one source should be using SamplerCoordinateMapping.Offset.");

            // Ok if we have both.
            effect.Source1Mapping   = SamplerCoordinateMapping.Offset;
            effect.MaxSamplerOffset = 1;

            using (var ds = renderTarget.CreateDrawingSession())
            {
                ds.DrawImage(effect);
            }
        }
Ejemplo n.º 10
0
        async Task Canvas_CreateResourcesAsync(CanvasAnimatedControl sender)
        {
            bitmapTiger = await CanvasBitmap.LoadAsync(sender, "imageTiger.jpg");

            tigerSize = bitmapTiger.Size.ToVector2();

            // The Sketch shader has two input textures:
            //
            //  - First is the image that will be processed by the sketch effect.
            //    The sketch shader applies a 3x3 edge detection filter kernel to this input,
            //    so we specify Offset coordinate mapping mode with a max offset of 1 dip.
            //
            //  - Second is an overlay containing a pencil sketch texture. The JitterX and JitterY
            //    properties offset this by randomly varying amounts, so we specify Unknown mapping
            //    mode to indicate that the entire image must be made available to the shader.

            sketchEffect = new PixelShaderEffect(await Utils.ReadAllBytes("Shaders/Sketch.bin"))
            {
                Source1           = bitmapTiger,
                Source1BorderMode = EffectBorderMode.Hard,
                Source1Mapping    = SamplerCoordinateMapping.Offset,
                MaxSamplerOffset  = (int)Math.Ceiling(sender.Dpi / 96),

                Source2        = await CanvasBitmap.LoadAsync(sender, "Shaders/SketchTexture.jpg"),
                Source2Mapping = SamplerCoordinateMapping.Unknown
            };

            sketchEffect.Properties["EdgeOffset"] = sender.Dpi / 96;

            // The Dissolve shader has two input textures:
            //
            //  - The first is an image that will be dissolved away to nothing.
            //
            //  - The second is a dissolve mask whose red channel controls the order in which pixels
            //    of the first image disappear as the dissolveAmount property is animated.
            //
            // This example selects different dissolve masks depending on the CurrentEffect.

            dissolveEffect = new PixelShaderEffect(await Utils.ReadAllBytes("Shaders/Dissolve.bin"));

            // The Ripples shader has no input textures.
            // It generates an animatable series of concentric circles.
            // This is used as a mask input to the dissolveEffect.
            rippleEffect = new PixelShaderEffect(await Utils.ReadAllBytes("Shaders/Ripples.bin"));

            rippleEffect.Properties["frequency"] = 0.15f;
            rippleEffect.Properties["dpi"]       = sender.Dpi;
            rippleEffect.Properties["center"]    = tigerSize / 3;

            // Create other dissolve mask images.
            CreateTurbulence();
            CreateLinearGradient(sender);
            CreateRadialGradient(sender);
        }
Ejemplo n.º 11
0
        public void InitializeShaders()
        {
            string[] shaderList = System.IO.Directory.GetFiles(compiledShadersDir, "*.ps");

            foreach (string curString in shaderList)
            {
                string name = System.IO.Path.GetFileName(curString);
                PixelShaderEffect newShaderEffect = new PixelShaderEffect(name);

                this.PixelShaders.Add(name, newShaderEffect);
            }
        }
Ejemplo n.º 12
0
        void ValidateSourceProperties(string hlsl, int expectedSourceCount)
        {
            var effect = new PixelShaderEffect(ShaderCompiler.CompileShader(hlsl, "ps_4_0"));

            ValidateSourceProperty(effect, () => effect.Source1, (s) => effect.Source1 = s, expectedSourceCount, 1);
            ValidateSourceProperty(effect, () => effect.Source2, (s) => effect.Source2 = s, expectedSourceCount, 2);
            ValidateSourceProperty(effect, () => effect.Source3, (s) => effect.Source3 = s, expectedSourceCount, 3);
            ValidateSourceProperty(effect, () => effect.Source4, (s) => effect.Source4 = s, expectedSourceCount, 4);
            ValidateSourceProperty(effect, () => effect.Source5, (s) => effect.Source5 = s, expectedSourceCount, 5);
            ValidateSourceProperty(effect, () => effect.Source6, (s) => effect.Source6 = s, expectedSourceCount, 6);
            ValidateSourceProperty(effect, () => effect.Source7, (s) => effect.Source7 = s, expectedSourceCount, 7);
            ValidateSourceProperty(effect, () => effect.Source8, (s) => effect.Source8 = s, expectedSourceCount, 8);
        }
Ejemplo n.º 13
0
        async Task Canvas_CreateResourcesAsync(CanvasAnimatedControl sender)
        {
            bmpImage = await CanvasBitmap.LoadAsync(sender, "Assets/grumpy.jpg");

            grumpySize = bmpImage.Size.ToVector2();

            // See Win2D custom effect example
            dissolveEffect = new PixelShaderEffect(await ReadAllBytes("Shaders/Dissolve.bin"));
            rippleEffect   = new PixelShaderEffect(await ReadAllBytes("Shaders/Ripples.bin"));

            rippleEffect.Properties["dpi"]    = sender.Dpi;
            rippleEffect.Properties["center"] = grumpySize / 2;

            dissolveEffect.Properties["dissolveAmount"] = 0.5f;
        }
Ejemplo n.º 14
0
        public void PixelShaderEffect_CoordinateMappingAccessors()
        {
            const string hlsl =
                @"
                float4 main() : SV_Target
                {
                    return 0;
                }
            ";

            var effect = new PixelShaderEffect(ShaderCompiler.CompileShader(hlsl, "ps_4_0"));

            // Check defaults.
            Assert.AreEqual(SamplerCoordinateMapping.Unknown, effect.Source1Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.Unknown, effect.Source2Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.Unknown, effect.Source3Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.Unknown, effect.Source4Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.Unknown, effect.Source5Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.Unknown, effect.Source6Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.Unknown, effect.Source7Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.Unknown, effect.Source8Mapping);

            Assert.AreEqual(0, effect.MaxSamplerOffset);

            // Setters.
            effect.Source1Mapping = SamplerCoordinateMapping.OneToOne;
            effect.Source2Mapping = SamplerCoordinateMapping.Offset;
            effect.Source3Mapping = SamplerCoordinateMapping.OneToOne;
            effect.Source4Mapping = SamplerCoordinateMapping.Offset;
            effect.Source5Mapping = SamplerCoordinateMapping.OneToOne;
            effect.Source6Mapping = SamplerCoordinateMapping.Offset;
            effect.Source7Mapping = SamplerCoordinateMapping.OneToOne;
            effect.Source8Mapping = SamplerCoordinateMapping.Offset;

            effect.MaxSamplerOffset = 23;

            // Getters.
            Assert.AreEqual(SamplerCoordinateMapping.OneToOne, effect.Source1Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.Offset, effect.Source2Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.OneToOne, effect.Source3Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.Offset, effect.Source4Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.OneToOne, effect.Source5Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.Offset, effect.Source6Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.OneToOne, effect.Source7Mapping);
            Assert.AreEqual(SamplerCoordinateMapping.Offset, effect.Source8Mapping);

            Assert.AreEqual(23, effect.MaxSamplerOffset);
        }
Ejemplo n.º 15
0
        async Task Canvas_CreateResourcesAsync(CanvasVirtualControl sender)
        {
            mandelbrotEffect = new PixelShaderEffect(await Utils.ReadAllBytes("Shaders/Mandelbrot.bin"));

            // The Mandelbrot pixel shader outputs grayscale values. To make the result more interesting,
            // we run it through a TableTransferEffect. This applies a color gradient that goes from black
            // through blue, cyan, green, yellow, red, magenta, blue again, and finally back toward cyan.

            colorizeEffect = new TableTransferEffect
            {
                Source = mandelbrotEffect,

                RedTable   = new float[] { 0, 0, 0, 0, 1, 1, 0.67f, 0, 0    },
                GreenTable = new float[] { 0, 0, 1, 1, 1, 0, 0,     0, 0.5f },
                BlueTable  = new float[] { 0, 1, 1, 0, 0, 0, 1,     1, 1    },
            };
        }
        async Task Canvas_CreateResourcesAsync(CanvasVirtualControl sender)
        {
            mandelbrotEffect = new PixelShaderEffect(await Utils.ReadAllBytes("Shaders/Mandelbrot.bin"));

            // The Mandelbrot pixel shader outputs grayscale values. To make the result more interesting,
            // we run it through a TableTransferEffect. This applies a color gradient that goes from black
            // through blue, cyan, green, yellow, red, magenta, blue again, and finally back toward cyan.

            colorizeEffect = new TableTransferEffect
            {
                Source = mandelbrotEffect,

                RedTable   = new float[] { 0, 0, 0, 0, 1, 1, 0.67f, 0, 0 },
                GreenTable = new float[] { 0, 0, 1, 1, 1, 0, 0, 0, 0.5f },
                BlueTable  = new float[] { 0, 1, 1, 0, 0, 0, 1, 1, 1 },
            };
        }
Ejemplo n.º 17
0
        async Task Canvas_CreateResourcesAsync(CanvasAnimatedControl sender)
        {
            bitmapTiger = await CanvasBitmap.LoadAsync(sender, "imageTiger.jpg");
            bitmapSize = bitmapTiger.Size.ToVector2();

            // The Dissolve shader has two input textures:
            //
            //  - The first is an image that will be dissolved away to nothing.
            //
            //  - The second is a dissolve mask whose red channel controls the order in which pixels
            //    of the first image disappear as the dissolveAmount property is animated.
            //
            // This example selects different dissolve masks depending on the CurrentEffect.

            dissolveEffect = new PixelShaderEffect(await Utils.ReadAllBytes("Shaders/Dissolve.bin"))
            {
                Source1 = bitmapTiger
            };

            // The Ripples shader has no input textures.
            // It generates an animatable series of concentric circles.
            // This is used as a mask input to the dissolveEffect.
            rippleEffect = new PixelShaderEffect(await Utils.ReadAllBytes("Shaders/Ripples.bin"));

            rippleEffect.Properties["frequency"] = 0.15f;
            rippleEffect.Properties["dpi"] = sender.Dpi;
#if WINDOWS_UWP
            rippleEffect.Properties["center"] = bitmapSize / 3;
#else
            rippleEffect.Properties["center"] = (Microsoft.Graphics.Canvas.Numerics.Vector2)(bitmapSize / 3);

            // When compiling for Windows 8.1, we must explicitly convert vector and matrix values
            // from System.Numerics to their Microsoft.Graphics.Canvas.Numerics equivalents before
            // passing them to PixelShaderEffect.Properties. This is not neccessary when targetting
            // UWP, which handles the conversion automatically. For more info, see the article:
            // http://blogs.msdn.com/b/win2d/archive/2015/06/02/winrt-vector-and-matrix-types-in-windows-10.aspx
#endif

            // Create other dissolve mask images.
            CreateTurbulence();
            CreateLinearGradient(sender);
            CreateRadialGradient(sender);
        }
Ejemplo n.º 18
0
        public void PixelShaderEffect_Realize_NoConstants()
        {
            const string hlsl =
                @"
                float4 main() : SV_Target
                {
                    return 0;
                }
            ";

            var effect = new PixelShaderEffect(ShaderCompiler.CompileShader(hlsl, "ps_4_0"));

            using (var canvasDevice = new CanvasDevice())
                using (var renderTarget = new CanvasRenderTarget(canvasDevice, 1, 1, 96))
                    using (var drawingSession = renderTarget.CreateDrawingSession())
                    {
                        drawingSession.DrawImage(effect);
                    }
        }
Ejemplo n.º 19
0
        public void PixelShaderEffect_OneElementArraysAppearAsArraysNotScalars()
        {
            const string hlsl =
                @"
                float foo[1] = { 23 };

                float4 main() : SV_Target
                {
                    return foo[0];
                }
            ";

            var effect = new PixelShaderEffect(ShaderCompiler.CompileShader(hlsl, "ps_4_0"));

            CollectionAssert.AreEqual(new float[] { 23 }, (float[])effect.Properties["foo"]);

            effect.Properties["foo"] = new float[] { 42 };

            CollectionAssert.AreEqual(new float[] { 42 }, (float[])effect.Properties["foo"]);
        }
Ejemplo n.º 20
0
        private async Task OnCreateResourcesAsync(EngineCreateResourcesEventArgs e)
        {
            var grass     = GrassSprite.Resolve(Entity);
            var snow      = SnowSprite.Resolve(Entity);
            var rock      = RockSprite.Resolve(Entity);
            var heightMap = _terrain.HeightMap.Resolve(Entity);

            if (!heightMap.IsPreScaled || !grass.IsPreScaled || !snow.IsPreScaled || !rock.IsPreScaled)
            {
                throw new ArgumentException("The heightmap, grass, snow and rock textures must be prescaled in order to be used for terrain rendering");
            }

            // Calculate average colors (these are used at small zoom levels)
            _grassColor = GetAverageColor(e.Sender, grass.Image);
            _snowColor  = GetAverageColor(e.Sender, snow.Image);
            _rockColor  = GetAverageColor(e.Sender, rock.Image);

            _normalHeightMap = await RenderNormalHeightMapAsync(e.Sender, heightMap.Image, _terrain.Height - _terrain.BaseHeight);

            var wrap       = CanvasEdgeBehavior.Wrap;
            var grassTiled = new BorderEffect {
                Source = grass.Image, ExtendX = wrap, ExtendY = wrap, CacheOutput = true
            };
            var snowTiled = new BorderEffect {
                Source = snow.Image, ExtendX = wrap, ExtendY = wrap, CacheOutput = true
            };
            var rockTiled = new BorderEffect {
                Source = rock.Image, ExtendX = wrap, ExtendY = wrap, CacheOutput = true
            };

            var shaderBytes = await Utilities.ReadBytesFromUriAsync(new Uri("ms-appx:///Shaders/TerrainShader.bin"));

            _terrainMap = new PixelShaderEffect(shaderBytes)
            {
                Source1     = _normalHeightMap,
                Source2     = grassTiled,
                Source3     = snowTiled,
                Source4     = rockTiled,
                CacheOutput = true
            };
        }
Ejemplo n.º 21
0
        public void PixelShaderEffect_OneElementVectorsAndMatricesAppearAsScalarsNotArrays()
        {
            const string hlsl =
                @"
                float1 foo = { 23 };
                float1x1 bar = { 42 };

                float4 main() : SV_Target
                {
                    return foo * bar;
                }
            ";

            var effect = new PixelShaderEffect(ShaderCompiler.CompileShader(hlsl, "ps_4_0"));

            Assert.AreEqual(23f, effect.Properties["foo"]);
            Assert.AreEqual(42f, effect.Properties["bar"]);

            effect.Properties["foo"] = 1f;
            effect.Properties["bar"] = 2f;

            Assert.AreEqual(1f, effect.Properties["foo"]);
            Assert.AreEqual(2f, effect.Properties["bar"]);
        }
Ejemplo n.º 22
0
        public void PixelShaderEffect_PropertiesDictionary_InsertErrorCases()
        {
            const string hlsl =
                @"
                float foo;
                int i;
                float array[5];

                float4 main() : SV_Target
                {
                    return foo * array[i];
                }
            ";

            var effect = new PixelShaderEffect(ShaderCompiler.CompileShader(hlsl, "ps_4_0"));

            // Setting valid types should work.
            effect.Properties["foo"]   = 1f;
            effect.Properties["i"]     = 1;
            effect.Properties["array"] = new float[5];

            // Try to insert an unknown property.
            Utils.AssertThrowsException <ArgumentException>(
                () => effect.Properties["bar"] = 1,
                "Shader does not have a property named 'bar'.");

            Utils.AssertThrowsException <ArgumentException>(
                () => effect.Properties[string.Empty] = 1,
                "Shader does not have a property named ''.");

            // Pass wrong property types.
            Utils.AssertThrowsException <ArgumentException>(
                () => effect.Properties["foo"] = 1,
                "Wrong type. Shader property 'foo' is of type Single.");

            Utils.AssertThrowsException <ArgumentException>(
                () => effect.Properties["foo"] = new Vector3[1],
                "Wrong type. Shader property 'foo' is of type Single.");

            Utils.AssertThrowsException <ArgumentException>(
                () => effect.Properties["i"] = 1f,
                "Wrong type. Shader property 'i' is of type Int32.");

            Utils.AssertThrowsException <ArgumentException>(
                () => effect.Properties["i"] = new Matrix3x2[1],
                "Wrong type. Shader property 'i' is of type Int32.");

            Utils.AssertThrowsException <ArgumentException>(
                () => effect.Properties["array"] = 1,
                "Wrong type. Shader property 'array' is an array of Single.");

            Utils.AssertThrowsException <ArgumentException>(
                () => effect.Properties["array"] = new bool[1],
                "Wrong type. Shader property 'array' is an array of Single.");

            // Pass a wrong array size.
            Utils.AssertThrowsException <ArgumentException>(
                () => effect.Properties["array"] = new float[4],
                "Wrong array size. Shader property 'array' is an array of 5 elements.");

            // Insert null.
            Utils.AssertThrowsException <ArgumentException>(
                () => effect.Properties["foo"] = null,
                "Wrong type. Shader property 'foo' is of type Single.");
        }
Ejemplo n.º 23
0
        async Task Canvas_CreateResourcesAsync(CanvasAnimatedControl sender)
        {
            bitmapTiger = await CanvasBitmap.LoadAsync(sender, "imageTiger.jpg");
            tigerSize = bitmapTiger.Size.ToVector2();

            // The Sketch shader has two input textures:
            //
            //  - First is the image that will be processed by the sketch effect.
            //    The sketch shader applies a 3x3 edge detection filter kernel to this input,
            //    so we specify Offset coordinate mapping mode with a max offset of 1 dip.
            //
            //  - Second is an overlay containing a pencil sketch texture. The JitterX and JitterY
            //    properties offset this by randomly varying amounts, so we specify Unknown mapping
            //    mode to indicate that the entire image must be made available to the shader.

            sketchEffect = new PixelShaderEffect(await Utils.ReadAllBytes("Shaders/Sketch.bin"))
            {
                Source1 = bitmapTiger,
                Source1BorderMode = EffectBorderMode.Hard,
                Source1Mapping = SamplerCoordinateMapping.Offset,
                MaxSamplerOffset = (int)Math.Ceiling(sender.Dpi / 96),

                Source2 = await CanvasBitmap.LoadAsync(sender, "Shaders/SketchTexture.jpg"),
                Source2Mapping = SamplerCoordinateMapping.Unknown
            };

            sketchEffect.Properties["EdgeOffset"] = sender.Dpi / 96;

            // The Dissolve shader has two input textures:
            //
            //  - The first is an image that will be dissolved away to nothing.
            //
            //  - The second is a dissolve mask whose red channel controls the order in which pixels
            //    of the first image disappear as the dissolveAmount property is animated.
            //
            // This example selects different dissolve masks depending on the CurrentEffect.

            dissolveEffect = new PixelShaderEffect(await Utils.ReadAllBytes("Shaders/Dissolve.bin"));

            // The Ripples shader has no input textures.
            // It generates an animatable series of concentric circles.
            // This is used as a mask input to the dissolveEffect.
            rippleEffect = new PixelShaderEffect(await Utils.ReadAllBytes("Shaders/Ripples.bin"));

            rippleEffect.Properties["frequency"] = 0.15f;
            rippleEffect.Properties["dpi"] = sender.Dpi;
#if WINDOWS_UWP
            rippleEffect.Properties["center"] = tigerSize / 3;
#else
            rippleEffect.Properties["center"] = (Microsoft.Graphics.Canvas.Numerics.Vector2)(tigerSize / 3);

            // When compiling for Windows 8.1, we must explicitly convert vector and matrix values
            // from System.Numerics to their Microsoft.Graphics.Canvas.Numerics equivalents before
            // passing them to PixelShaderEffect.Properties. This is not neccessary when targetting
            // UWP, which handles the conversion automatically. For more info, see the article:
            // http://blogs.msdn.com/b/win2d/archive/2015/06/02/winrt-vector-and-matrix-types-in-windows-10.aspx
#endif

            // Create other dissolve mask images.
            CreateTurbulence();
            CreateLinearGradient(sender);
            CreateRadialGradient(sender);
        }
Ejemplo n.º 24
0
        async Task Canvas_CreateResourcesAsync(CanvasAnimatedControl sender)
        {
            bitmapTiger = await CanvasBitmap.LoadAsync(sender, "imageTiger.jpg");

            tigerSize = bitmapTiger.Size.ToVector2();

            // The Sketch shader has two input textures:
            //
            //  - First is the image that will be processed by the sketch effect.
            //    The sketch shader applies a 3x3 edge detection filter kernel to this input,
            //    so we specify Offset coordinate mapping mode with a max offset of 1 dip.
            //
            //  - Second is an overlay containing a pencil sketch texture. The JitterX and JitterY
            //    properties offset this by randomly varying amounts, so we specify Unknown mapping
            //    mode to indicate that the entire image must be made available to the shader.

            sketchEffect = new PixelShaderEffect(await Utils.ReadAllBytes("Shaders/Sketch.bin"))
            {
                Source1           = bitmapTiger,
                Source1BorderMode = EffectBorderMode.Hard,
                Source1Mapping    = SamplerCoordinateMapping.Offset,
                MaxSamplerOffset  = (int)Math.Ceiling(sender.Dpi / 96),

                Source2        = await CanvasBitmap.LoadAsync(sender, "Shaders/SketchTexture.jpg"),
                Source2Mapping = SamplerCoordinateMapping.Unknown
            };

            sketchEffect.Properties["EdgeOffset"] = sender.Dpi / 96;

            // The Dissolve shader has two input textures:
            //
            //  - The first is an image that will be dissolved away to nothing.
            //
            //  - The second is a dissolve mask whose red channel controls the order in which pixels
            //    of the first image disappear as the dissolveAmount property is animated.
            //
            // This example selects different dissolve masks depending on the CurrentEffect.

            dissolveEffect = new PixelShaderEffect(await Utils.ReadAllBytes("Shaders/Dissolve.bin"));

            // The Ripples shader has no input textures.
            // It generates an animatable series of concentric circles.
            // This is used as a mask input to the dissolveEffect.
            rippleEffect = new PixelShaderEffect(await Utils.ReadAllBytes("Shaders/Ripples.bin"));

            rippleEffect.Properties["frequency"] = 0.15f;
            rippleEffect.Properties["dpi"]       = sender.Dpi;
#if WINDOWS_UWP
            rippleEffect.Properties["center"] = tigerSize / 3;
#else
            rippleEffect.Properties["center"] = (Microsoft.Graphics.Canvas.Numerics.Vector2)(tigerSize / 3);

            // When compiling for Windows 8.1, we must explicitly convert vector and matrix values
            // from System.Numerics to their Microsoft.Graphics.Canvas.Numerics equivalents before
            // passing them to PixelShaderEffect.Properties. This is not neccessary when targetting
            // UWP, which handles the conversion automatically. For more info, see the article:
            // http://blogs.msdn.com/b/win2d/archive/2015/06/02/winrt-vector-and-matrix-types-in-windows-10.aspx
#endif

            // Create other dissolve mask images.
            CreateTurbulence();
            CreateLinearGradient(sender);
            CreateRadialGradient(sender);
        }
Ejemplo n.º 25
0
 internal async Task CreateResources()
 {
     _dissolveEffect = new PixelShaderEffect(await ReadAllBytes("Assets/Dissolve.bin"));
     UpdateMask();
 }
Ejemplo n.º 26
0
        public void PixelShaderEffect_InputRectTooBigError()
        {
            const string hlsl =
                @"
                texture2D t1;
                sampler s1;

                float4 main() : SV_Target
                {
                    return t1.Sample(s1, 0);
                }
            ";

            var effect = new PixelShaderEffect(ShaderCompiler.CompileShader(hlsl, "ps_4_0"))
            {
                Source1Mapping = SamplerCoordinateMapping.Unknown
            };

            var device       = new CanvasDevice();
            var renderTarget = new CanvasRenderTarget(device, 1, 1, 96);

            // Drawing with a fixed size input is ok.
            effect.Source1 = new CanvasRenderTarget(device, 1, 1, 96);

            using (var ds = renderTarget.CreateDrawingSession())
            {
                ds.DrawImage(effect);
            }

            // Drawing with an infinite sized input is not!
            effect.Source1 = new ColorSourceEffect();

            Utils.AssertThrowsException <Exception>(() =>
            {
                using (var ds = renderTarget.CreateDrawingSession())
                {
                    ds.DrawImage(effect);
                }
            }, "Drawing this effect would require too big an intermediate surface. Make sure PixelShaderEffect.Source1Mapping is set correctly, or wrap the source image with a CropEffect to reduce its size.");

            // But it's ok if we clamp the input back down to finite size.
            effect.Source1 = new CropEffect
            {
                Source          = new ColorSourceEffect(),
                SourceRectangle = new Rect(0, 0, 100, 100)
            };

            using (var ds = renderTarget.CreateDrawingSession())
            {
                ds.DrawImage(effect);
            }

            // Also ok if we change our mapping mode to something other than infinite.
            effect.Source1        = new ColorSourceEffect();
            effect.Source1Mapping = SamplerCoordinateMapping.OneToOne;

            using (var ds = renderTarget.CreateDrawingSession())
            {
                ds.DrawImage(effect);
            }
        }