Skip to content

Instantly share code, notes, and snippets.

@Santarh
Created August 26, 2012 18:23
Show Gist options
  • Save Santarh/3482315 to your computer and use it in GitHub Desktop.
Save Santarh/3482315 to your computer and use it in GitHub Desktop.
AOBench Kuin 書きかけ
func Init(cfg : Kuin@CCfg)
do cfg.Title :: "AOBench"
do cfg.FullScr :: false
do cfg.PadNum :: 1
do cfg.WaitTime :: 60
end func
func Main()
var ao : AOBench@AOBench
do ao :: @new AOBench@AOBench
do ao.Init(256, 256)
do ao.Calc()
while (true)
do Kuin@Act()
do ao.Render()
end while
do Kuin@Stop()
end func
class Vector3
var X : float
var Y : float
var Z : float
func Init(x : float, y : float, z : float)
do this.X :: x
do this.Y :: y
do this.Z :: z
end func
func Clone() : AOBench@Vector3
var v : AOBench@Vector3 :: @new AOBench@Vector3
do v.Init(this.X, this.Y, this.Z)
return v
end func
end class
func VecAdd(a : AOBench@Vector3, b : AOBench@Vector3) : AOBench@Vector3
var v : AOBench@Vector3 :: @new AOBench@Vector3
do v.X :: a.X + b.X
do v.Y :: a.Y + b.Y
do v.Z :: a.Z + b.Z
return v
end func
func VecSub(a : AOBench@Vector3, b : AOBench@Vector3) : AOBench@Vector3
var v : AOBench@Vector3 :: @new AOBench@Vector3
do v.X :: a.X - b.X
do v.Y :: a.Y - b.Y
do v.Z :: a.Z - b.Z
return v
end func
func VecCross(a : AOBench@Vector3, b : AOBench@Vector3) : AOBench@Vector3
var v : AOBench@Vector3 :: @new AOBench@Vector3
do v.X :: a.Y * b.Z - a.Z * b.Y
do v.Y :: a.Z * b.X - a.X * b.Z
do v.Z :: a.X * b.Y - a.Y * b.X
return v
end func
func VecDot(a : AOBench@Vector3, b : AOBench@Vector3) : float
return a.X * b.X + a.Y * b.Y + a.Z * b.Z
end func
func VecLength(a : AOBench@Vector3) : float
return Math@Sqrt(a.X * a.X + a.Y * a.Y + a.Z * a.Z)
end func
func VecNormalize(a : AOBench@Vector3) : AOBench@Vector3
var len : float :: AOBench@VecLength(a)
var v : AOBench@Vector3 :: a.Clone()
if (len > 0.00000000000000001)
do v.X :/ len
do v.Y :/ len
do v.Z :/ len
end if
return v
end func
class AOBench
class Isect
var T : float
var Hit : bool
var Pos : AOBench@Vector3
var Norm : AOBench@Vector3
func Init()
do this.T :: 1000000.0
do this.Hit :: false
do this.Pos :: @new AOBench@Vector3
do this.Pos.Init(0.0, 0.0, 0.0)
do this.Norm :: @new AOBench@Vector3
do this.Norm.Init(0.0, 0.0, 0.0)
end func
end class
class Ray
var Org : AOBench@Vector3
var Dir : AOBench@Vector3
func Init(o : AOBench@Vector3, d : AOBench@Vector3)
do this.Org :: o.Clone()
do this.Dir :: d.Clone()
end func
end class
class Sphere
var Center : AOBench@Vector3
var Radius : float
func Init(c : AOBench@Vector3, r : float)
do this.Center :: c.Clone()
do this.Radius :: r
end func
func Intersect(ray : Ray, isect : Isect)
var rs : AOBench@Vector3 :: AOBench@VecSub(ray.Org, this.Center)
var B : float :: AOBench@VecDot(rs, ray.Dir)
var C : float :: AOBench@VecDot(rs, rs) - (this.Radius * this.Radius)
var D : float :: B * B - C
if (D > 0.0)
var t : float :: -B - Math@Sqrt(D)
if ((t > 0.0) & (t < isect.T))
do isect.T :: t
do isect.Hit :: true
do isect.Pos :: @new AOBench@Vector3
do isect.Pos.X :: ray.Org.X + ray.Dir.X * t
do isect.Pos.Y :: ray.Org.Y + ray.Dir.Y * t
do isect.Pos.Z :: ray.Org.Z + ray.Dir.Z * t
var n : AOBench@Vector3 :: AOBench@VecSub(isect.Pos, this.Center)
do isect.Norm :: AOBench@VecNormalize(n)
end if
end if
end func
end class
class Plane
var Pos : AOBench@Vector3
var Norm : AOBench@Vector3
func Init(p : AOBench@Vector3, n : AOBench@Vector3)
do this.Pos :: p.Clone()
do this.Norm :: n.Clone()
end func
func Intersect(ray : Ray, isect : Isect)
var d : float :: - AOBench@VecDot(this.Pos, this.Norm)
var v : float :: AOBench@VecDot(ray.Dir, this.Norm)
if ((-0.00000000000000001 < v) & (v < 0.00000000000000001))
return
end if
var t : float :: - (AOBench@VecDot(ray.Org, this.Norm) + d) / v
if ((t > 0.0) & (t < isect.T))
do isect.Hit :: true
do isect.T :: t
do isect.Norm :: this.Norm.Clone()
do isect.Pos.X :: ray.Org.X + ray.Dir.X * t
do isect.Pos.Y :: ray.Org.Y + ray.Dir.Y * t
do isect.Pos.Z :: ray.Org.Z + ray.Dir.Z * t
end if
end func
end class
var Width : int
var Height : int
var SubSamples : int
var AoSamples : int
var Eps : float
var Phi : int
var Theta : int
var AllRay : int
var Spheres : []Sphere
var Floor : Plane
var Output : [][]float
func Init(x : int, y : int)
do this.Width :: x
do this.Height :: y
do this.SubSamples :: 2
do this.AoSamples :: 8
do this.Eps :: 0.0001
do this.Phi :: this.AoSamples
do this.Theta :: this.AoSamples
do this.AllRay :: this.AoSamples * this.AoSamples
do this.Spheres :: @new [3]Sphere
for i(0, 2)
do this.Spheres[i] :: @new Sphere
end for
var rad : float :: 0.5
var center : AOBench@Vector3 :: @new AOBench@Vector3
do center.Init(-2.0, 0.0, -3.5)
do this.Spheres[0].Init(center, rad)
do center.Init(-0.5, 0.0, -3.0)
do this.Spheres[1].Init(center, rad)
do center.Init(1.0, 0.0, -2.2)
do this.Spheres[2].Init(center, rad)
var pos : AOBench@Vector3 :: @new AOBench@Vector3
do pos.Init(0.0, -0.5, 0.0)
var norm : AOBench@Vector3 :: @new AOBench@Vector3
do norm.Init(0.0, 1.0, 0.0)
do this.Floor :: @new Plane
do this.Floor.Init(pos, norm)
do this.Output :: @new [this.Width][]float
for i(0, this.Width - 1)
do this.Output[i] :: @new [this.Height]float
for j(0, this.Height - 1)
do this.Output[i][j] :: 0.0
end for
end for
end func
func OrthoBasis(basis : []Vector3, n : AOBench@Vector3)
for i(0, 2)
do basis[i] :: @new AOBench@Vector3
do basis[i].Init(0.0, 0.0, 0.0)
end for
do basis[2] :: n.Clone()
if ((n.X < 0.6) & (n.X > -0.6))
do basis[1].X :: 1.0
elif ((n.Y < 0.6) & (n.Y > -0.6))
do basis[1].Y :: 1.0
elif ((n.Z < 0.6) & (n.Z > -0.6))
do basis[1].Z :: 1.0
else
do basis[1].X :: 1.0
end if
do basis[0] :: AOBench@VecNormalize(AOBench@VecCross(basis[1], basis[2]))
do basis[1] :: AOBench@VecNormalize(AOBench@VecCross(basis[2], basis[0]))
end func
func Random() : float
var r : float :: Kuin@Rand(0, 1000)$float
do r :/ 1000.0
return r
end func
var OcculusionResult : float
func AmbientOcculusion(isect : Isect) : float
var basis : []Vector3 :: @new [3]Vector3
do this.OrthoBasis(basis, isect.Norm)
var p : AOBench@Vector3 :: @new AOBench@Vector3
do p.X :: isect.Pos.X + this.Eps * isect.Norm.X
do p.Y :: isect.Pos.Y + this.Eps * isect.Norm.Y
do p.Z :: isect.Pos.Z + this.Eps * isect.Norm.Z
var occlusion : int :: 0
for j(0, this.Phi)
for i(0, this.Theta)
var theta : float :: Math@Sqrt(this.Random())
var phi : float :: 2.0 * Math@Pi * this.Random()
var x : float :: Math@Cos(phi) * theta
var y : float :: Math@Sin(phi) * theta
var z : float :: Math@Sqrt(1.0 - theta * theta)
{ local -> global }
var rx : float :: x * basis[0].X + y * basis[1].X + z * basis[2].X
var ry : float :: x * basis[0].Y + y * basis[1].Y + z * basis[2].Y
var rz : float :: x * basis[0].Z + y * basis[1].Z + z * basis[2].Z
var rayDir : AOBench@Vector3 :: @new AOBench@Vector3
do rayDir.Init(rx, ry, rz)
var ray : Ray :: @new Ray
do ray.Init(p, rayDir)
var occIsect : Isect :: @new Isect
do occIsect.Init()
for i(0, 2)
do this.Spheres[i].Intersect(ray, occIsect)
end for
do this.Floor.Intersect(ray, occIsect)
if (occIsect.Hit)
do occlusion :+ 1
end if
end for
end for
var occ : float :: (this.AllRay - occlusion)$float / this.AllRay$float
do this.OcculusionResult :: occ
return occ
end func
func Calc()
var half_w : float :: this.Width$float * 0.5
var half_h : float :: this.Height$float * 0.5
for y(0, this.Height - 1)
for x(0, this.Width - 1)
var px : float :: (x$float - half_w)/half_w
var py : float :: -(y$float - half_h)/half_h
var eye : AOBench@Vector3 :: @new AOBench@Vector3
do eye.Init(px, py, -1.0)
do eye :: AOBench@VecNormalize(eye)
var zero : AOBench@Vector3 :: @new AOBench@Vector3
do zero.Init(0.0, 0.0, 0.0)
var ray : Ray :: @new Ray
do ray.Init(zero, eye)
var isect : Isect :: @new Isect
do isect.Init()
for i(0, 2)
do this.Spheres[i].Intersect(ray, isect)
end for
do this.Floor.Intersect(ray, isect)
var col : float :: 0.0
if (isect.Hit)
do this.AmbientOcculusion(isect)
{
AmbientOcclusion() 関数の返り値が返ってこない。
}
do col :: this.OcculusionResult
end if
do this.Output[x][y] :: col
end for
do Kuin@Dbg(y.ToStr() ~ "/" ~ (this.Height - 1).ToStr())
end for
end func
func Render()
var half_w : float :: this.Width$float * 0.5
var half_h : float :: this.Height$float * 0.5
for y(0, this.Height - 1)
for x(0, this.Width - 1)
var x0 : float :: x$float
var y0 : float :: y$float
var x1 : float :: x$float + 1.0
var y1 : float :: y$float + 1.0
var col : float :: this.Output[x][y]
do D3D@DrawRect(x0, y0, x1, y1, col, col, col, 1.0)
end for
end for
end func
end class
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment