Попытка реализовать 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
}