WPF 3D transparent textures - clipping? - wpf

http://www.youtube.com/watch?v=gZNdfVwkttM - you can see all of the problem described on this video if you can't see pictures.
All of walls in all images below have a semitransparent PNG texture. Each square wall, floor and ceiling tile is a separate GeometryModel3D (I know that is no good for performance but...). The floor and the ceiling of the central cube have no any geometry and textures - so they have a color the same as Window.Background (black). But the effect considered appears in any way of transparency obtaining: texture for ImageBrush with transparency, Material.Color (for example DiffuseMAterial.Color) where Color has alpha channel, ImageBrush as material where ImageBrush has Opacity - all the way I have the same problem.
All of walls consists of two triangles. Where are no explicit normals , because I define triangle indices so normals culculated automatically by WPF.
http://imagepost.ru/images/i/ma/image00001.png
It also haven't any back material or extra triangles from the back side.
As you can see there is no problem if you look only from +Z to -Z (standing on the blue square and looking to the red square - that is the second picture).
But if you look backward (from red to blue - the first picture) there is no transparency!
Well, I desided to look from the yellow square (third picture).
And then I walked nearer - you can see what was happening (pictures from 4 to 6).
There are no geometry construction error or texture mapping error or lighting error! It is some kind of clipping, I guessed! In addition there are some interested pictures 7 and 8 to prove my guess.
The last picture shows the white background of the window that hosted Viewport3D (previous was black), and my guess about clipping confirmed - WPF just not painted this part of the scene and we can see the window background!
BUT! If this happens from various looks, why the look from +Z to -Z (second picture) seems well?!

You need to sort the triangles based on their distances from the viewpoint. Only then, wpf will be able to blend the transparent textures.
DirectX is able to blend triangles on top of each other but only when drawing them back to front
http://www.ericsink.com/wpf3d/2_Transparency.html

Related

Drawing in draw call-back and drawing outside draw call-back

Custom drawing in Gtk3 with Cairo is explained in https://developer.gnome.org/gtk3/stable/ch01s05.html
Here draw_brush in the handler for motion-notify-event draws small rectangles as the mouse is dragged. In the original code there is no other drawing. Suppose I draw a filled blue rectangle in draw_cb by adding the following code:
cairo_set_source_rgb(cr,0.1,0.1,0.8);
cairo_rectangle(cr,80,80,50,50);
cairo_fill(cr);
and similarly another filled red rectangle in clear_surface which is called from configure_event_cb, I get a strange behavior where the blue rectangle is not over-written by draw-brush, but the red rectangle gets over-written, as seen in the picture below:
Can anyone explain this behavior so that I can correctly make custom drawings in the application I am developing.
So, in clear_surface / configure_event_cb, you draw to surface, which is also the surface where the brush draws to. Since the brush is drawn later, it ends up ontop of the red rectangle that you draw here.
In draw_cb, this temporary surface that is used for the drawing is copied to the screen. If you draw a blue rectangle afterwards to the screen, this blue rectangle ends up ontop of what you drew before.
So basically: The reason is the two different targets for drawing that are used here. One is the "actual stuff" on screen, which can disappear at any time. The other is an internal surface created in configure_event_cb that does not go away unexpectedly.

How to implement halo effect with Wpf 3D?

I'm trying to build a 3D earth with Wpf Viewport3D. I have created the earth and it works pretty good. Then I want to add a halo effect around the earth like this attached image:
.
Some recommend to use diffuse material for the globe model. Then build a slight larger globe model with emissive material and little opacity. But the effect is not very good. It affects the color of diffusion material like this:
How can I implement the effect like the first screenshot?
I've done exactly this by creating a ring, inner radius the same radius as the planet and an outer radius to relect the atmospheric depth. Oriented to 'face me'. Using texture coordinates into a LinearGradientBrush to have the atmosphere fade from sky blue to transparent black.
Alternatively, there are some fairly good PNGs around of semi-transparent cloud layers you could use on the slightly larger sphere.

How can I create beveled corners on a border in WPF?

I'm trying to do simple drawing in a subclass of a decorator, similar to what they're doing here...
How can I draw a border with squared corners in wpf?
...except with a single-pixel border thickness instead of the two they're using there. However, no matter what I do, WPF decides it needs to do its 'smoothing' (e.g. instead of rendering a single-pixel line, it renders a two-pixel line with each 'half' about 50% of the opacity.) In other words, it's trying to anti-alias the drawing. I do not want anti-aliased drawing. I want to say if I draw a line from 0,0 to 10,0 that I get a single-pixel-wide line that's exactly 10 pixels long without smoothing.
Now I know WPF does that, but I thought that's specifically why they introduced SnapsToDevicePixels and UseLayoutRounding, both of which I've set to 'True' in the XAML. I'm also making sure that the numbers I'm using are actual integers and not fractional numbers, but still I'm not getting the nice, crisp, one-pixel-wide lines I'm hoping for.
Help!!!
Mark
Aaaaah.... got it! WPF considers a line from 0,0 to 10,0 to literally be on that logical line, not the row of pixels as it is in GDI. To better explain, think of the coordinates in WPF being representative of the lines drawn on a piece of graph paper whereas the pixels are the squares those lines make up (assuming 96 DPI that is. You'd need to adjust accordingly if they are different.)
So... to get the drawing to refer to the pixel locations, we need to shift the drawing from the lines themselves to be the center of the pixels (squares on graph paper) so we shift all drawing by 0.5, 0.5 (again, assuming a DPI of 96)
So if it is a 96 DPI setting, simply adding this in the OnRender method worked like a charm...
drawingContext.PushTransform(new TranslateTransform(.5, .5));
Hope this helps others!
M
Have a look at this article: Draw lines exactly on physical device pixels
UPD
Some valuable quotes from the link:
The reason why the lines appear blurry, is that our points are center
points of the lines not edges. With a pen width of 1 the edges are
drawn excactly between two pixels.
A first approach is to round each point to an integer value (snap to a
logical pixel) an give it an offset of half the pen width. This
ensures, that the edges of the line align with logical pixels.
Fortunately the developers of the milcore (MIL stands for media
integration layer, that's WPFs rendering engine) give us a way to
guide the rendering engine to align a logical coordinate excatly on a
physical device pixels. To achieve this, we need to create a
GuidelineSet
protected override void OnRender(DrawingContext drawingContext)
{
Pen pen = new Pen(Brushes.Black, 1);
Rect rect = new Rect(20,20, 50, 60);
double halfPenWidth = pen.Thickness / 2;
// Create a guidelines set
GuidelineSet guidelines = new GuidelineSet();
guidelines.GuidelinesX.Add(rect.Left + halfPenWidth);
guidelines.GuidelinesX.Add(rect.Right + halfPenWidth);
guidelines.GuidelinesY.Add(rect.Top + halfPenWidth);
guidelines.GuidelinesY.Add(rect.Bottom + halfPenWidth);
drawingContext.PushGuidelineSet(guidelines);
drawingContext.DrawRectangle(null, pen, rect);
drawingContext.Pop();
}

Light Map projection

What i'm trying to do is making a "light projector" with visible ray(like with fog) also called volumetric light;
and which project a image (bitmap) ;
Because i would like to keep this project connected with a wpf application ( to get brush, position, rotation from data), i've choose to use WPF 3D
But it seem that WPF can't handle light projection or render ray.
So to do that, i have extruded each pixel of my source bitmap into a polygon colored by a solidColorBrush of the pixel color.
and keep the pixel order with (x,y) position.
For performance issue, i've set all the bitmaps to 32x32 px ( 1024 polygon for only one light !!)
But the result is too pixelated as you can see on the picture.
Moreover, it probably take much memory for nothing ...
my question is, how can i make it smooth or even rethink the extrusion system to optimize performance ...
Is any other tehnology that can be integrated into a wpf application and do that better or easier ?
Thanks, and sorry my English is pretty bad ...
alt text http://www.visualdmx.fr/pic_example.png

Converting equations of motion to pixels for display on Silverlight canvas

Can anyone point me in the direction of some information to understand this. I have a Canvas that displays an ellipse. I can move the ellipse around using the keyboard but I want to simulate a "jump", so I thought I'd use Newtons equations of motion to move the ellipse up and then down when the user presses the up arrow. All these equations are defined in metres where as the TranslateTransform on the UserControl is in pixels.
Can I get the resolution in SL to convert from metres to pixels?
Not really, no. Silverlight doesn't understand pixels.
There are 96 units in an inch (no matter the dpi of the display). That suggests there are 3779.5 silverlight units in a metre. I'd think about applying a ScaleTransform to any area you're displaying so you can give Silverlight metres and get the right visuals out if that matters to you.

Resources