Twinside / Rasterific

A drawing engine in Haskell
BSD 3-Clause "New" or "Revised" License
140 stars 11 forks source link

Radial gradients with opacity less than 1 have jagged edges. #13

Closed jeffreyrosenbluth closed 10 years ago

jeffreyrosenbluth commented 10 years ago

image

Twinside commented 10 years ago

The problem seems to be with the gradient repeating, as your first and end color don't match, there is a discontinuity when repeating the gradient, which can't be avoided. Too wark around it, the colors can be "shifted" to get an identical start & end, or maybe use the mirror sampler.

The same issue can be seen in the SamplerRepeat documentation.

Firefox has the same trouble as visible here, and explained on the MDN repeat gradient page.

jeffreyrosenbluth commented 10 years ago

I don't know. The SVG of the same image looks quite different.

On Sat, Apr 19, 2014 at 1:09 AM, Vincent notifications@github.com wrote:

The problem seems to be with the gradient repeating, as your first and end color don't match, there is a discontinuity when repeating the gradient, which can't be avoided. Too avoid this problem, the colors can be "shifted" to get an identical start & end, or maybe use the mirror sampler.

Firefox has the same issue as visible herehttp://www.css3files.com/gradient/, and explained on the MDN repeat gradienthttps://developer.mozilla.org/en-US/docs/Web/CSS/repeating-linear-gradientpage.

— Reply to this email directly or view it on GitHubhttps://github.com/Twinside/Rasterific/issues/13#issuecomment-40863737 .

Twinside commented 10 years ago

Do you have a link to the corresponding svg? I'll see what I can do.

jeffreyrosenbluth commented 10 years ago

Sorry, i thought i had attached it.

http://pastebin.com/04JGV3HZ

Twinside commented 10 years ago

svg_total_confusion I don't know what to think right now, I'm using:

jeffreyrosenbluth commented 10 years ago

It seems even in Cairo has yet it's own problems with repeat and reflect. I think rasterific does what it should in these cases so I would not change it. I also did a bunch of jaggedness tests and rasterific does well here too. The only thing left that seems off is the orange color in the following, where rasterific seems more pale than both cairo and svg: Cairo ro_cairo Rasterific ro_rasterific

Twinside commented 10 years ago

With the following code:

gradientRadial :: IO ()
gradientRadial =
    writePng (outFolder </> "rad_opacity.png") $
        renderDrawing 500 500 back img
  where back = PixelRGBA8 255 255 255 255
        img = withTexture (withSampler SamplerRepeat
                          (radialGradientTexture gradDef
                          (V2 250 250) 100)) $
                          fill $ rectangle (V2 0 0) 500 500
        gradDef = 
            [(0  , PixelRGBA8 255 165 0 102)
            ,(0.5, PixelRGBA8 255 165 0 102)
            ,(0.5, PixelRGBA8 255 165 0 102)
            ,(0.525, PixelRGBA8 255 165 0 255)
            ,(0.675, PixelRGBA8 128 128 128 64)
            ,(0.75, PixelRGBA8 0 128 128 255)
            ,(1, PixelRGBA8 0 128 128 255)
            ]

I obtain: rad_opacity

With the gradient values extracted from the gradient definition in the SVG file, the colors don't looked washed like in the previous example, are you using Ratserific HEAD?

jeffreyrosenbluth commented 10 years ago

The bug was on my end the whole time, i was using a clear background color instead of white. Sorry about that, it's difficult to tell where the bugs are when both packages are new. :D

jeffreyrosenbluth commented 10 years ago

Actually, what I thought was the solution to my problem only created another one. The problem comes from the fact that I need to provide a background color to renderDrawing but I don't want a background color at all. If I try using a background color with 0 alpha the rgb values still effect the image? i.e PixelRGBA8 0 0 0 0 and PixelRGB8 255 255 255 0, as background colors give different images when using transparency

The reason your image from above looks that same as the svg is that svg's default background when displayed in a browser is white and you have back = PixelRGBA8 255 255 255 255

In the following code I would like to generate an image independent of the background color. I need a way to set background color to none.

import Codec.Picture( PixelRGBA8( .. ), writePng )
import Graphics.Rasterific
import Graphics.Rasterific.Texture

main :: IO ()
main = do
  let back = PixelRGBA8 255 255 255 255
      clr   = PixelRGBA8 255 165 0 102
      img = withTexture (uniformTexture clr) $
                        fillWithMethod FillWinding [LinePrim $ Line (V2 600.0 600.0) (V2 600.0 0.0),LinePrim $ Line (V2 600.0 0.0) (V2 0.0 0.0),LinePrim $ Line (V2 0.0 0.0) (V2 (-6.661338e-14) 600.0),LinePrim $ Line (V2 (-6.661338e-14) 600.0) (V2 600.0 600.0)]
  writePng "orange.png" (renderDrawing 400 400 back img)