Skip to content

Instantly share code, notes, and snippets.

@1xch
Created June 20, 2016 14:50
Show Gist options
  • Save 1xch/1ed1785ac6a902585595fb8cb52f0a16 to your computer and use it in GitHub Desktop.
Save 1xch/1ed1785ac6a902585595fb8cb52f0a16 to your computer and use it in GitHub Desktop.
package main
import (
"image"
"image/color"
"math"
mr "math/rand"
"time"
m "github.com/go-gl/mathgl/mgl64"
)
var (
iterations int = 17
magic float64 = 0.53
volSteps int = 20
stepSize float64 = 0.1
zoom float64 = 0.800
tile float64 = 0.850
speed float64 = 0.010
brightness float64 = 0.0015
darkMatter float64 = 0.300
distFading float64 = 0.730
saturation float64 = 0.850
frequencyVariation float64 = 1.3
sparsity float64 = 0.5
)
// https://www.shadertoy.com/view/XlfGRj
func Cosmic1(img *image.RGBA) {
size := img.Bounds().Size()
for x := 0; x < size.X; x++ {
for y := 0; y < size.Y; y++ {
// coords & direction
uv := m.Vec2{float64(x)/float64(size.X) - 0.5, float64(y)/float64(size.Y) - 0.5}
uv = m.Vec2{uv.X(), uv.Y() * float64(size.Y/size.X)}
dir := m.Vec3{uv[0] * zoom, uv[1] * zoom, 1.0}
time := float64(time.Now().UTC().Unix())*speed + 0.25
// rotation
a1 := .5 + float64(float64(mr.Intn(size.X))/3)/float64(mr.Intn(size.X))*2
a2 := .8 + float64(float64(mr.Intn(size.X))/2)/float64(mr.Intn(size.Y))*2
rot1 := m.Mat2{math.Cos(a1), math.Sin(a1), -(math.Sin(a1)), math.Cos(a1)}
rot2 := m.Mat2{math.Cos(a2), math.Sin(a2), -(math.Sin(a2)), math.Cos(a2)}
dir = m.Vec3{dir.X() * rot1.At(0, 0) * rot2.At(0, 0), dir.Y() * rot1.At(0, 1) * rot2.At(0, 1), dir.Z() * rot1.At(1, 0) * rot2.At(1, 0)}
from := m.Vec3{1, 0.5, 0.5}
from = from.Add(m.Vec3{time * 2, time, -2})
from = m.Vec3{from.X() * rot1.At(0, 0) * rot2.At(0, 0), from.Y() * rot1.At(0, 1) * rot2.At(0, 1), from.Z() * rot1.At(1, 0) * rot2.At(1, 0)}
// volumetric rendering
s := 0.1
fade := 1.0
v := m.Vec3{}
for r := 0; r < volSteps; r++ {
var p m.Vec3
p = from.Add(m.Vec3{s, s, s})
p = m.Vec3{p.X() * dir.X(), p.Y() * dir.Y(), p.Z() * dir.Z()}.Mul(.5)
p = m.Vec3{tile, 0, 0}.Sub(m.Vec3{math.Mod(p.X(), tile*2), p.Y(), p.Z()})
p = m.Vec3{math.Abs(p.X()), math.Abs(p.Y()), math.Abs(p.Z())}
var a, pa float64
for i := 0; i < iterations; i++ {
mv := p.Dot(p) - magic
p = m.Vec3{p.X() / mv, p.Y() / mv, p.Z() / mv}
a += math.Abs(p.Len() - pa)
pa = p.Len()
}
dm := math.Max(0, darkMatter-a*a*.001)
a *= a * a
if r > 6 {
fade *= 1 - dm
}
v = m.Vec3{v.X() + fade, v.Y() + fade, v.Z() + fade}
abf := a * brightness * fade
v = m.Vec3{v.X() + s*abf, v.Y() + s*s*abf, v.Z() + s*s*s*s*abf}
fade *= distFading
s += stepSize
}
//color adjust
cv := m.Vec3{v.Len(), 0, 0}
v = m.Vec3{lerp(v.X(), cv.X(), saturation), lerp(v.Y(), cv.Y(), saturation), lerp(v.Z(), cv.Z(), saturation)}
c := m.Vec4{v.X() * .01, v.Y() * .01, v.Z() * 01, 1}
color := color.RGBA{toUint8(c.X()), toUint8(c.Y()), toUint8(c.Z()), toUint8(c.W())}
img.Set(x, y, color)
}
}
}
func toUint8(in float64) uint8 {
return uint8(in * 255) /// 1)
}
func lerp(v0, v1 float64, t float64) float64 {
return (1.0-t)*v0 + t*v1
}
// https://casual-effects.blogspot.com/2013/08/starfield-shader.html
// problem: output image is always the same mono color
func Cosmic2(img *image.RGBA) {
size := img.Bounds().Size()
var resolution = m.Vec2{float64(size.X), float64(size.Y)}
var invResolution = m.Vec2{resolution.Y(), resolution.X()}
rrt := float64(mr.Intn(size.X))
rt := .5 + (rrt/3)/float64(size.X)*2
var rotate = m.Mat2{math.Cos(rt), math.Sin(rt), -(math.Sin(rt)), math.Cos(rt)}
for x := 0; x < size.X; x++ {
for y := 0; y < size.Y; y++ {
uv := m.Vec2{float64(size.X)*resolution.X() - 0.5, float64(size.Y)*resolution.Y() - 0.5*(resolution.Y()*invResolution.X())}
dir := m.Vec3{(uv.X() * zoom) * rotate.At(0, 0), uv.Y() * zoom, 1.0 * rotate.At(1, 0)}
s := 0.1
fade := 0.01
var c m.Vec3
var o m.Vec3
for r := 0; r < volSteps; r++ {
pp := m.Vec3{float64(x) + dir.X()*(s*0.5), float64(y) + dir.Y()*(s*0.5), dir.Z() * (s * 0.5)}
fv := func(in float64) float64 {
return math.Abs(frequencyVariation - math.Mod(in, (frequencyVariation*2)))
}
p := m.Vec3{fv(pp.X()), fv(pp.Y()), fv(pp.Z())}
prevLen := 0.0
a := 0.0
for i := 0; i < iterations; i++ {
p = m.Vec3{math.Abs(p.X()), math.Abs(p.Y()), math.Abs(p.Z())}
p = p.Mul(1.0/p.Dot(p) + (-sparsity))
l := p.Len()
a += math.Abs(l - prevLen)
prevLen = l
}
a *= a * a
tw := m.Vec3{s, s * s, s * s * s}
tw.Mul((a*brightness + 1.0))
tw.Mul(fade)
c = m.Vec3{c.X() + tw.X(), c.Y() + tw.Y(), c.Z() + tw.Z()}
fade *= distFading
s += stepSize
}
c = m.Vec3{math.Min(c.X(), 1.2), c.Y(), c.Z()}
intensity := math.Min((c.X() + c.Y() + c.Z()), 0.7)
sgn := m.Vec2{float64(x) + 1.0, float64(y) + 1.0}
sgn.Mul(2.0)
sgn.Sub(m.Vec2{1, 1})
gradient := m.Vec2{intensity * sgn.X(), intensity * sgn.Y()}
cutoff := math.Max(math.Max(gradient.X(), gradient.Y())-0.1, 0.0)
c.Mul(math.Max(1.0-cutoff*6.0, 0.3))
c = m.Vec3{lerp(c.X(), o.X(), intensity) - .004, lerp(c.Y(), o.Y(), intensity), lerp(c.Z(), o.Z(), intensity)}
o = c
clr := color.RGBA{toUint8(c.X()), toUint8(c.Y()), toUint8(c.Z()), toUint8(1)}
img.Set(x, y, clr)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment