Попытка реализовать FXAA, но понятия не имею, что это даже правильный код

Вот код, он ужасно неправильный, но я надеюсь, что он уловил идею ac

на основе https://gist.github.com/purringChaos/0d157c2a57a0cc75edegob1d60f45101ca

пытаясь реализовать его без OpenGL трудно, просто хотим , чтобы сделать линии более гладкой Даже лучше Algo для использования было бы хорошо, вот скриншот оа спирали изображения сглаженного изображения оа спираль

      package main

import (
    "fmt"
    "github.com/purringChaos/SpiralGo/vec/vec2"
    "github.com/purringChaos/SpiralGo/vec/vec3"
    "image"
    "image/color"
    "math"
)

func rgbaToVec3(i color.NRGBA) vec3.Vec3 {
    return vec3.Vec3{float64(i.R), float64(i.G), float64(i.B)}
}
func vec3ToNRGBA(i vec3.Vec3) color.NRGBA {
    return color.NRGBA{uint8(i.X), uint8(i.Y), uint8(i.Z), 255}
}

var lumaVec = vec3.Vec3{0.299, 0.587, 0.114}

var FXAA_SPAN_MAX = 1.0
var FXAA_REDUCE_MUL = 1.0 / 8.0
var FXAA_REDUCE_MIN = 1.0 / 128.0

func getRelToVector(i *image.NRGBA, x int, y int, v vec2.Vec2) color.NRGBA {
    return i.NRGBAAt(x+int(v.X), y+int(v.Y))
}

func getRelToVectorVec(i *image.NRGBA, x int, y int, v vec2.Vec2) vec3.Vec3 {
    newVec := vec2.Vec2{
        roundAndNegative(v.X),
        roundAndNegative(v.Y),
    }
    return rgbaToVec3(getRelToVector(i, x, y, newVec))
}

func getInbetween(col1 vec3.Vec3, col2 vec3.Vec3) vec3.Vec3 {
    return vec3.Mul(vec3.Add(col1, col2), 1.0/2.0)
}


func areSameColor(c1, c2 color.NRGBA) bool {
    return c1.R == c2.R && c1.G == c2.G && c1.B == c2.B
}

func roundAndNegative(a float64) float64 {
    if a > FXAA_REDUCE_MIN {
        return math.Ceil(a)
    } else if a < FXAA_REDUCE_MIN*-1 {
        return math.Floor(a)
    }
    return 0
}

func doFXAA(i *image.NRGBA) *image.NRGBA {
    bounds := i.Bounds()
    newImage := image.NewNRGBA(bounds)
    newImage.Pix = i.Pix[:]

    for y := bounds.Min.Y + 1; y < bounds.Max.Y-1; y++ {
        for x := bounds.Min.X + 1; x < bounds.Max.X-1; x++ {

            // RGB values at diagonals
            // North West
            rgbNW := rgbaToVec3(i.NRGBAAt(x-1, y-1))
            // North East
            rgbNE := rgbaToVec3(i.NRGBAAt(x+1, y-1))
            // South West
            rgbSW := rgbaToVec3(i.NRGBAAt(x-1, y+1))
            // South East
            rgbSE := rgbaToVec3(i.NRGBAAt(x+1, y+1))
            // Current Pixel
            rgbM := rgbaToVec3(i.NRGBAAt(x, y))

            // Luma Values at all.
            lumaNW := rgbNW.Dot(lumaVec)
            lumaNE := rgbNE.Dot(lumaVec)
            lumaSW := rgbSW.Dot(lumaVec)
            lumaSE := rgbSE.Dot(lumaVec)
            lumaM := rgbM.Dot(lumaVec)

            // MinMax Luma
            lumaMin := math.Min(lumaM, math.Min(math.Min(lumaNW, lumaNE), math.Min(lumaSW, lumaSE)))
            lumaMax := math.Max(lumaM, math.Max(math.Max(lumaNW, lumaNE), math.Max(lumaSW, lumaSE)))

            // Luma Direction Change
            dir := vec2.Vec2{
                X: -((lumaNW + lumaNE) - (lumaSW + lumaSE)),
                Y: ((lumaNW + lumaSW) - (lumaNE + lumaSE)),
            }
            if dir.X == 0 && dir.Y == 0 {
                continue
            }

            dirReduce := math.Max(
                (lumaNW+lumaNE+lumaSW+lumaSE)*(0.25*FXAA_REDUCE_MUL),
                FXAA_REDUCE_MIN)

            rcpDirMin := 1.0 / (math.Min(math.Abs(dir.X), math.Abs(dir.Y)) + dirReduce)

            dir = vec2.Min(
                vec2.Vec2{FXAA_SPAN_MAX, FXAA_SPAN_MAX},
                vec2.Max(
                    vec2.Vec2{-FXAA_SPAN_MAX, -FXAA_SPAN_MAX},
                    vec2.Mul(dir, rcpDirMin),
                ),
            )

            rgbA := getInbetween(
                getRelToVectorVec(i, x, y, vec2.Mul(dir, 1.0/3.0-0.5)),
                getRelToVectorVec(i, x, y, vec2.Mul(dir, 2.0/3.0-0.5)),
            )

            rgbB := vec3.Add(
                vec3.Mul(
                    rgbA,
                    (1.0/2.0),
                ),
                vec3.Mul(
                    vec3.Add(
                        getRelToVectorVec(i, x, y, vec2.Mul(dir, 1.0/4.0)),
                        getRelToVectorVec(i, x, y, vec2.Mul(dir, 3.0/3.0-0.5)),
                    ),
                    (1.0/4.0),
                ),
            )

            lumaB := rgbB.Dot(lumaVec)

            var colorToSet color.NRGBA

            if (lumaB < lumaMin) || (lumaB > lumaMax) {
                colorToSet = vec3ToNRGBA(rgbA)
            } else {
                colorToSet = vec3ToNRGBA(rgbB)
            }

            if !areSameColor(i.NRGBAAt(x, y), colorToSet) {
                fmt.Println("OWO")
                newImage.Set(x, y, colorToSet)
            }
        }
    }

    return newImage
}

0 ответов

Другие вопросы по тегам