Silverlight Tip of the Day #36 – How to Create Reflections and Shadows for Images and Text.
Reflections are a cool effect you can apply to images and text elements through the use of RenderTransforms. For example, take a look at this screen shot below of reflections which were rendered using Silverlight. The first reflection is done on a TextBlock, the second on an Image.
Figure 1. TextBlock and Image reflection
For game programming you can take this a step further and use it for object shadows and water reflections in your game. For example, take a look at this screen shot that shows a tree’s reflections on two different ground surfaces:
Figure 2. Tree with shadow
You can even apply a SkewTranform to the shadow to skew it the direction of the sun.
Figure 3. Shadow skewed in Sun Direction
And how about a little reflection on water:
Figure 4. Water reflections.
So how is all this done? Let’s start with the reflection of a TextBlock as show in Figure 1 above.
<TextBlock Text="REFLECTION EXAMPLE" Canvas.Left="145" Canvas.Top="12" Foreground="White" FontSize="30"></TextBlock>
<TextBlock Text="REFLECTION EXAMPLE" Canvas.Top="80" Canvas.Left="145" FontSize="30" RenderTransformOrigin="0.5,0.5" Opacity="0.6">
<TextBlock.RenderTransform>
<ScaleTransform ScaleY="-1"/>
</TextBlock.RenderTransform>
<TextBlock.Foreground>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1" >
<GradientStop Color="#FF000000" Offset="0.0"/>
<GradientStop Color="#FFFFFFFF" Offset="1.0"/>
</LinearGradientBrush>
</TextBlock.Foreground>
</TextBlock>
Few things to notice:
- We use two TextBlocks, one for the main TextBlock , one for the reflection.
- For the TextBlock that is reflecting we create a ScaleTransform and set the ScaleY = –1. This will make the TextBlock invert upside down.
- We create an OpacityMask for the purpose of fading the TextBlock out. We use a LinearGradientBrush for this OpacityMask which allows us to fade vertically by going from StartPoint “0.5,0” to EndPoint “0.5,1”
Now for the Image in Figure 1 we do the exact same thing except we are using the Image object:
<Image Source="Reflect.png" Canvas.Left="225" Canvas.Top="100" ></Image>
<Image Source="Reflect.png" Canvas.Left="225" Canvas.Top="385" RenderTransformOrigin="0.0,0.0">
<Image.RenderTransform>
<ScaleTransform ScaleY="-1"></ScaleTransform>
</Image.RenderTransform>
<Image.OpacityMask>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="#00000000" Offset="0.0"/>
<GradientStop Color="#FFFFFFFF" Offset="1.0"/>
</LinearGradientBrush>
</Image.OpacityMask>
</Image>
The trees use the same effect except that the tree used to reflect on the ground is a black & white mask of the color image (see Figure 5 below). For the water reflection, we keep the color image since water reflects color.
Figure 5. Color Image + B/W Mask.
Run a demo of this Tip here: http://silverlight.services.live.com/invoke/66033/Reflection%20and%20Shadows/iframe.html
Thank you,
--Mike Snow
Subscribe in a reader