Created
August 26, 2012 18:23
-
-
Save Santarh/3482315 to your computer and use it in GitHub Desktop.
AOBench Kuin 書きかけ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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