📝 update docs
This commit is contained in:
parent
ad87298737
commit
2c851613ce
50
README.md
50
README.md
|
@ -337,9 +337,8 @@ and the debugger will print this:
|
|||
|
||||
```javascript
|
||||
source code:
|
||||
--> var fib=func(x)
|
||||
{
|
||||
if(x<2) return x;
|
||||
--> var fib = func(x) {
|
||||
if (x<2) return x;
|
||||
return fib(x-1)+fib(x-2);
|
||||
}
|
||||
for(var i=0;i<31;i+=1)
|
||||
|
@ -347,16 +346,16 @@ source code:
|
|||
|
||||
|
||||
next bytecode:
|
||||
0x000848 4a 00 00 01 callfv 0x1(std/lib.nas:427)
|
||||
0x000849 3d 00 00 00 pop 0x0(std/lib.nas:427)
|
||||
0x00084a 07 00 00 00 pnil 0x0(std/lib.nas:423)
|
||||
0x00084b 56 00 00 00 ret 0x0(std/lib.nas:423)
|
||||
0x00084c 03 00 00 5e loadg 0x5e(std/lib.nas:423)
|
||||
--> 0x00084d 0b 00 08 51 newf 0x851(test/fib.nas:1)
|
||||
0x00084e 02 00 00 03 intl 0x3(test/fib.nas:1)
|
||||
0x00084f 0d 00 00 08 para 0x8 (x)(test/fib.nas:1)
|
||||
0x0003a8 07:00 00 00 00 00 00 00 00 pnil 0x0 (std/lib.nas:413)
|
||||
0x0003a9 56:00 00 00 00 00 00 00 00 ret 0x0 (std/lib.nas:413)
|
||||
0x0003aa 03:00 00 00 00 00 00 00 56 loadg 0x56 (std/lib.nas:413)
|
||||
--> 0x0003ab 0b:00 00 00 00 00 00 03 af newf 0x3af (test/fib.nas:1)
|
||||
0x0003ac 02:00 00 00 00 00 00 00 03 intl 0x3 (test/fib.nas:1)
|
||||
0x0003ad 0d:00 00 00 00 00 00 00 22 para 0x22 (x) (test/fib.nas:1)
|
||||
0x0003ae 3e:00 00 00 00 00 00 03 be jmp 0x3be (test/fib.nas:1)
|
||||
0x0003af 45:00 00 00 00 00 00 00 01 calll 0x1 (test/fib.nas:2)
|
||||
|
||||
stack (0x55ccd0a1b9d0, limit 10, total 0)
|
||||
vm stack (0x7fca7e9f1010, limit 16, total 0)
|
||||
>>
|
||||
```
|
||||
|
||||
|
@ -371,9 +370,8 @@ This will help you debugging or learning how the vm works:
|
|||
|
||||
```javascript
|
||||
source code:
|
||||
var fib=func(x)
|
||||
{
|
||||
--> if(x<2) return x;
|
||||
var fib = func(x) {
|
||||
--> if (x<2) return x;
|
||||
return fib(x-1)+fib(x-2);
|
||||
}
|
||||
for(var i=0;i<31;i+=1)
|
||||
|
@ -381,24 +379,24 @@ source code:
|
|||
|
||||
|
||||
next bytecode:
|
||||
0x000850 3e 00 08 60 jmp 0x860(test/fib.nas:1)
|
||||
--> 0x000851 45 00 00 01 calll 0x1(test/fib.nas:3)
|
||||
0x000852 39 00 00 07 lessc 0x7 (2)(test/fib.nas:3)
|
||||
0x000853 40 00 08 56 jf 0x856(test/fib.nas:3)
|
||||
0x000854 45 00 00 01 calll 0x1(test/fib.nas:3)
|
||||
0x000855 56 00 00 00 ret 0x0(test/fib.nas:3)
|
||||
0x000856 44 00 00 5f callg 0x5f(test/fib.nas:4)
|
||||
0x000857 45 00 00 01 calll 0x1(test/fib.nas:4)
|
||||
0x0003a8 07:00 00 00 00 00 00 00 00 pnil 0x0 (std/lib.nas:413)
|
||||
0x0003a9 56:00 00 00 00 00 00 00 00 ret 0x0 (std/lib.nas:413)
|
||||
0x0003aa 03:00 00 00 00 00 00 00 56 loadg 0x56 (std/lib.nas:413)
|
||||
0x0003ab 0b:00 00 00 00 00 00 03 af newf 0x3af (test/fib.nas:1)
|
||||
0x0003ac 02:00 00 00 00 00 00 00 03 intl 0x3 (test/fib.nas:1)
|
||||
0x0003ad 0d:00 00 00 00 00 00 00 22 para 0x22 (x) (test/fib.nas:1)
|
||||
0x0003ae 3e:00 00 00 00 00 00 03 be jmp 0x3be (test/fib.nas:1)
|
||||
--> 0x0003af 45:00 00 00 00 00 00 00 01 calll 0x1 (test/fib.nas:2)
|
||||
|
||||
stack (0x55ccd0a1b9d0, limit 10, total 8)
|
||||
0x000007 | pc | 0x869
|
||||
vm stack (0x7fca7e9f1010, limit 16, total 8)
|
||||
0x000007 | pc | 0x3c7
|
||||
0x000006 | addr | 0x0
|
||||
0x000005 | nil |
|
||||
0x000004 | nil |
|
||||
0x000003 | num | 0
|
||||
0x000002 | nil |
|
||||
0x000001 | nil |
|
||||
0x000000 | func | <0x55ccd0a58fa0> entry:0x487
|
||||
0x000000 | func | <0x5573f66ef5f0> func(elems...) {..}
|
||||
>>
|
||||
```
|
||||
|
||||
|
|
|
@ -322,9 +322,8 @@ local (0x55dcb5b43190 <+7>)
|
|||
|
||||
```javascript
|
||||
source code:
|
||||
--> var fib=func(x)
|
||||
{
|
||||
if(x<2) return x;
|
||||
--> var fib = func(x) {
|
||||
if (x<2) return x;
|
||||
return fib(x-1)+fib(x-2);
|
||||
}
|
||||
for(var i=0;i<31;i+=1)
|
||||
|
@ -332,16 +331,16 @@ source code:
|
|||
|
||||
|
||||
next bytecode:
|
||||
0x000848 4a 00 00 01 callfv 0x1(std/lib.nas:427)
|
||||
0x000849 3d 00 00 00 pop 0x0(std/lib.nas:427)
|
||||
0x00084a 07 00 00 00 pnil 0x0(std/lib.nas:423)
|
||||
0x00084b 56 00 00 00 ret 0x0(std/lib.nas:423)
|
||||
0x00084c 03 00 00 5e loadg 0x5e(std/lib.nas:423)
|
||||
--> 0x00084d 0b 00 08 51 newf 0x851(test/fib.nas:1)
|
||||
0x00084e 02 00 00 03 intl 0x3(test/fib.nas:1)
|
||||
0x00084f 0d 00 00 08 para 0x8 (x)(test/fib.nas:1)
|
||||
0x0003a8 07:00 00 00 00 00 00 00 00 pnil 0x0 (std/lib.nas:413)
|
||||
0x0003a9 56:00 00 00 00 00 00 00 00 ret 0x0 (std/lib.nas:413)
|
||||
0x0003aa 03:00 00 00 00 00 00 00 56 loadg 0x56 (std/lib.nas:413)
|
||||
--> 0x0003ab 0b:00 00 00 00 00 00 03 af newf 0x3af (test/fib.nas:1)
|
||||
0x0003ac 02:00 00 00 00 00 00 00 03 intl 0x3 (test/fib.nas:1)
|
||||
0x0003ad 0d:00 00 00 00 00 00 00 22 para 0x22 (x) (test/fib.nas:1)
|
||||
0x0003ae 3e:00 00 00 00 00 00 03 be jmp 0x3be (test/fib.nas:1)
|
||||
0x0003af 45:00 00 00 00 00 00 00 01 calll 0x1 (test/fib.nas:2)
|
||||
|
||||
stack (0x55ccd0a1b9d0, limit 10, total 0)
|
||||
vm stack (0x7fca7e9f1010, limit 16, total 0)
|
||||
>>
|
||||
```
|
||||
|
||||
|
@ -356,9 +355,8 @@ stack (0x55ccd0a1b9d0, limit 10, total 0)
|
|||
|
||||
```javascript
|
||||
source code:
|
||||
var fib=func(x)
|
||||
{
|
||||
--> if(x<2) return x;
|
||||
var fib = func(x) {
|
||||
--> if (x<2) return x;
|
||||
return fib(x-1)+fib(x-2);
|
||||
}
|
||||
for(var i=0;i<31;i+=1)
|
||||
|
@ -366,24 +364,24 @@ source code:
|
|||
|
||||
|
||||
next bytecode:
|
||||
0x000850 3e 00 08 60 jmp 0x860(test/fib.nas:1)
|
||||
--> 0x000851 45 00 00 01 calll 0x1(test/fib.nas:3)
|
||||
0x000852 39 00 00 07 lessc 0x7 (2)(test/fib.nas:3)
|
||||
0x000853 40 00 08 56 jf 0x856(test/fib.nas:3)
|
||||
0x000854 45 00 00 01 calll 0x1(test/fib.nas:3)
|
||||
0x000855 56 00 00 00 ret 0x0(test/fib.nas:3)
|
||||
0x000856 44 00 00 5f callg 0x5f(test/fib.nas:4)
|
||||
0x000857 45 00 00 01 calll 0x1(test/fib.nas:4)
|
||||
0x0003a8 07:00 00 00 00 00 00 00 00 pnil 0x0 (std/lib.nas:413)
|
||||
0x0003a9 56:00 00 00 00 00 00 00 00 ret 0x0 (std/lib.nas:413)
|
||||
0x0003aa 03:00 00 00 00 00 00 00 56 loadg 0x56 (std/lib.nas:413)
|
||||
0x0003ab 0b:00 00 00 00 00 00 03 af newf 0x3af (test/fib.nas:1)
|
||||
0x0003ac 02:00 00 00 00 00 00 00 03 intl 0x3 (test/fib.nas:1)
|
||||
0x0003ad 0d:00 00 00 00 00 00 00 22 para 0x22 (x) (test/fib.nas:1)
|
||||
0x0003ae 3e:00 00 00 00 00 00 03 be jmp 0x3be (test/fib.nas:1)
|
||||
--> 0x0003af 45:00 00 00 00 00 00 00 01 calll 0x1 (test/fib.nas:2)
|
||||
|
||||
stack (0x55ccd0a1b9d0, limit 10, total 8)
|
||||
0x000007 | pc | 0x869
|
||||
vm stack (0x7fca7e9f1010, limit 16, total 8)
|
||||
0x000007 | pc | 0x3c7
|
||||
0x000006 | addr | 0x0
|
||||
0x000005 | nil |
|
||||
0x000004 | nil |
|
||||
0x000003 | num | 0
|
||||
0x000002 | nil |
|
||||
0x000001 | nil |
|
||||
0x000000 | func | <0x55ccd0a58fa0> entry:0x487
|
||||
0x000000 | func | <0x5573f66ef5f0> func(elems...) {..}
|
||||
>>
|
||||
```
|
||||
|
||||
|
|
|
@ -1,13 +1,29 @@
|
|||
# runtime.nas
|
||||
# 2023 by ValKmjolnir
|
||||
# runtime gives us some functions that we could manage it manually.
|
||||
|
||||
# command line arguments
|
||||
var argv = func() {
|
||||
return globals.arg;
|
||||
}
|
||||
|
||||
var gc = {
|
||||
extend: func(type) {return __gcextd;},
|
||||
info: func() {return __gcinfo;}
|
||||
};
|
||||
# runtime.nas
|
||||
# 2023 by ValKmjolnir
|
||||
# runtime gives us some functions that we could manage it manually.
|
||||
|
||||
# command line arguments
|
||||
var argv = func() {
|
||||
return globals.arg;
|
||||
}
|
||||
|
||||
var _gc_extend = func(type) {
|
||||
return __gcextd;
|
||||
}
|
||||
|
||||
var gc = {
|
||||
extend: func(type, times = 1) {
|
||||
if (times<=0) {
|
||||
return nil;
|
||||
}
|
||||
if (times>16) {
|
||||
times = 16;
|
||||
}
|
||||
|
||||
for(var i = 0; i<times; i+=1) {
|
||||
_gc_extend(type);
|
||||
}
|
||||
return nil;
|
||||
},
|
||||
info: func() {return __gcinfo;}
|
||||
};
|
||||
|
|
|
@ -1,252 +1,250 @@
|
|||
# ray tracing example
|
||||
# modified from Artem Yashin's project Console3D
|
||||
|
||||
# MIT License
|
||||
# Copyright (c) 2021 Artem Yashin
|
||||
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
use module.libmat;
|
||||
use std.runtime;
|
||||
use std.math;
|
||||
|
||||
func() {
|
||||
# allocate more spaces
|
||||
for(var i = 0; i<10; i+=1) {
|
||||
runtime.gc.extend("str");
|
||||
runtime.gc.extend("vec");
|
||||
}
|
||||
}();
|
||||
|
||||
var (max,min,sqrt,sin,cos,abs)=(
|
||||
math.max,
|
||||
math.min,
|
||||
math.sqrt,
|
||||
math.sin,
|
||||
math.cos,
|
||||
math.abs
|
||||
);
|
||||
|
||||
var (vec2,vec3)=(
|
||||
libmat.vec2.new,
|
||||
libmat.vec3.new
|
||||
);
|
||||
|
||||
var (vec2add,vec2sub,vec2mul,vec2div,vec2len)=(
|
||||
libmat.vec2.add,
|
||||
libmat.vec2.sub,
|
||||
libmat.vec2.mul,
|
||||
libmat.vec2.div,
|
||||
libmat.vec2.len
|
||||
);
|
||||
|
||||
var (vec3add,vec3sub,vec3mul,vec3div,vec3neg,vec3norm,vec3len,vec3dot)=(
|
||||
libmat.vec3.add,
|
||||
libmat.vec3.sub,
|
||||
libmat.vec3.mul,
|
||||
libmat.vec3.div,
|
||||
libmat.vec3.neg,
|
||||
libmat.vec3.norm,
|
||||
libmat.vec3.len,
|
||||
libmat.vec3.dot
|
||||
);
|
||||
|
||||
var (rotateX,rotateY,rotateZ)=(
|
||||
libmat.vec3.rx,
|
||||
libmat.vec3.ry,
|
||||
libmat.vec3.rz,
|
||||
);
|
||||
|
||||
var use_raw = func() {
|
||||
vec2 = func(x,y) {return [x,y];}
|
||||
vec2add = func(v1,v2) {return [v1[0]+v2[0],v1[1]+v2[1]];}
|
||||
vec2sub = func(v1,v2) {return [v1[0]-v2[0],v1[1]-v2[1]];}
|
||||
vec2mul = func(v1,v2) {return [v1[0]*v2[0],v1[1]*v2[1]];}
|
||||
vec2div = func(v1,v2) {return [v1[0]/v2[0],v1[1]/v2[1]];}
|
||||
vec3 = func(x,y,z) {return [x,y,z];}
|
||||
vec3add = func(v1,v2) {return [v1[0]+v2[0],v1[1]+v2[1],v1[2]+v2[2]];}
|
||||
vec3sub = func(v1,v2) {return [v1[0]-v2[0],v1[1]-v2[1],v1[2]-v2[2]];}
|
||||
vec3mul = func(v1,v2) {return [v1[0]*v2[0],v1[1]*v2[1],v1[2]*v2[2]];}
|
||||
vec3div = func(v1,v2) {return [v1[0]/v2[0],v1[1]/v2[1],v1[2]/v2[2]];}
|
||||
vec3neg = func(v) {return [-v[0],-v[1],-v[2]];}
|
||||
vec2len = func(v) {var (x,y)=(v[0],v[1]); return sqrt(x*x+y*y);}
|
||||
vec3len = func(v) {var (x,y,z)=(v[0],v[1],v[2]); return sqrt(x*x+y*y+z*z);}
|
||||
vec3norm = func(v) {var t=vec3len(v); return vec3div(v,[t,t,t]);}
|
||||
vec3dot = func(a,b) {return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];}
|
||||
rotateX = func(a,angle) {return [a[0],a[2]*sin(angle)+a[1]*cos(angle),a[2]*cos(angle)-a[1]*sin(angle)];}
|
||||
rotateY = func(a,angle) {return [a[0]*cos(angle)-a[2]*sin(angle),a[1],a[0]*sin(angle)+a[2]*cos(angle)];}
|
||||
rotateZ = func(a,angle) {return [a[0]*cos(angle)-a[1]*sin(angle),a[0]*sin(angle)+a[1]*cos(angle),a[2]];}
|
||||
}
|
||||
|
||||
var clamp = func(value,_min,_max) {
|
||||
return max(min(value,_max),_min);
|
||||
}
|
||||
var sign = func(a) {
|
||||
return (0<a)-(a<0);
|
||||
}
|
||||
var step = func(edge,x) {
|
||||
return x>edge;
|
||||
}
|
||||
|
||||
var vec3abs = func(v) {
|
||||
return [abs(v[0]),abs(v[1]),abs(v[2])];
|
||||
}
|
||||
var vec3sign = func(v) {
|
||||
return [sign(v[0]),sign(v[1]),sign(v[2])];
|
||||
}
|
||||
var vec3step = func(edge,v) {
|
||||
return [step(edge[0],v[0]),step(edge[1],v[1]),step(edge[2],v[2])];
|
||||
}
|
||||
var vec3reflect = func(rd,n) {
|
||||
var d=vec3dot(n,rd);
|
||||
return vec3sub(rd,vec3mul(n,vec3mul([2,2,2],[d,d,d])));
|
||||
}
|
||||
|
||||
var sphere = func(ro,rd,r) {
|
||||
var b=vec3dot(ro,rd);
|
||||
var c=vec3dot(ro,ro)-r*r;
|
||||
var h=b*b-c;
|
||||
if (h<0.0) return [-1.0,-1.0];
|
||||
h=sqrt(h);
|
||||
return [-b-h,-b+h];
|
||||
}
|
||||
|
||||
var box = func(ro,rd,boxSize,outNormal) {
|
||||
var m=vec3div([1.0,1.0,1.0],rd);
|
||||
var n=vec3mul(m,ro);
|
||||
var k=vec3mul(vec3abs(m),boxSize);
|
||||
var t1=vec3sub(vec3neg(n),k);
|
||||
var t2=vec3add(vec3neg(n),k);
|
||||
var tN=max(max(t1[0],t1[1]),t1[2]);
|
||||
var tF=min(min(t2[0],t2[1]),t2[2]);
|
||||
if (tN>tF or tF<0.0) return [-1.0,-1.0];
|
||||
var yzx=[t1[1],t1[2],t1[0]];
|
||||
var zxy=[t1[2],t1[0],t1[1]];
|
||||
var tmp=vec3mul(vec3mul(vec3neg(vec3sign(rd)), vec3step(yzx,t1)),vec3step(zxy,t1));
|
||||
outNormal[0]=tmp[0];
|
||||
outNormal[1]=tmp[1];
|
||||
outNormal[2]=tmp[2];
|
||||
return [tN, tF];
|
||||
}
|
||||
|
||||
var plane = func(ro,rd,p,w) {
|
||||
return -(vec3dot(ro,p)+w)/vec3dot(rd,p);
|
||||
}
|
||||
|
||||
var main = func(frame) {
|
||||
|
||||
var height=15*2;
|
||||
var width=int(height*1/0.618)*2;
|
||||
|
||||
var aspect=width/height;
|
||||
var pixelAspect=11.0/24.0;
|
||||
|
||||
var gradient=split(""," .:!/r(l1Z4H9W8$");
|
||||
var gradientSize=size(gradient)-1;
|
||||
|
||||
var screen=[];
|
||||
setsize(screen,width*height);
|
||||
|
||||
var light=vec3norm([-0.5,0.5,-1.0]);
|
||||
var spherePos=[0,3,0];
|
||||
var vec2_2_2=[2,2];
|
||||
var vec2_1_1=[1,1];
|
||||
var vec3_000=[0,0,0];
|
||||
var vec3_00n1=[0,0,-1];
|
||||
var vec3_111=[1,1,1];
|
||||
|
||||
print("\e[2J");
|
||||
var stamp=maketimestamp();
|
||||
for(var t=0;t<frame;t+=1) {
|
||||
stamp.stamp();
|
||||
for(var i=0;i<width;i+=1) {
|
||||
for(var j=0;j<height;j+=1) {
|
||||
var uv=vec2sub(vec2mul(vec2div([i,j],[width,height]),vec2_2_2),vec2_1_1);
|
||||
uv[0]*=aspect*pixelAspect;
|
||||
var ro=[-6,0,0];
|
||||
var rd=vec3norm([2,uv[0],uv[1]]);
|
||||
ro=rotateY(ro,0.25);
|
||||
rd=rotateY(rd,0.25);
|
||||
ro=rotateZ(ro,t*0.03);
|
||||
rd=rotateZ(rd,t*0.03);
|
||||
var diff=1;
|
||||
for (var k=0;k<5;k+=1) {
|
||||
var minIt=99999;
|
||||
var intersection=sphere(vec3sub(ro,spherePos),rd,1);
|
||||
var n=vec3_000;
|
||||
var albedo=1;
|
||||
if (intersection[0]>0) {
|
||||
var itPoint=vec3add(vec3sub(ro,spherePos),vec3mul(rd,[intersection[0],intersection[0],intersection[0]]));
|
||||
minIt=intersection[0];
|
||||
n=vec3norm(itPoint);
|
||||
}
|
||||
var boxN=[0,0,0];
|
||||
intersection=box(ro,rd,vec3_111,boxN);
|
||||
if (intersection[0]>0 and intersection[0]<minIt) {
|
||||
minIt=intersection[0];
|
||||
n=boxN;
|
||||
}
|
||||
var tmp=plane(ro,rd,vec3_00n1,1);
|
||||
intersection=[tmp,tmp];
|
||||
if (intersection[0]>0 and intersection[0]<minIt) {
|
||||
minIt=intersection[0];
|
||||
n=vec3_00n1;
|
||||
albedo=0.5;
|
||||
}
|
||||
if (minIt<99999) {
|
||||
diff*=(vec3dot(n,light)*0.5+0.5)*albedo;
|
||||
ro=vec3add(ro,vec3mul(rd,[minIt-0.01,minIt-0.01,minIt-0.01]));
|
||||
rd=vec3reflect(rd,n);
|
||||
}
|
||||
else break;
|
||||
}
|
||||
var color=int(diff*20);
|
||||
color=clamp(color,0,gradientSize);
|
||||
screen[i+j*width]=gradient[color];
|
||||
}
|
||||
}
|
||||
var s="";
|
||||
forindex(var index;screen) {
|
||||
s~=screen[index];
|
||||
if (index+1-int((index+1)/width)*width==0)
|
||||
s~="\n";
|
||||
}
|
||||
var elt=stamp.elapsedMSec()/1000;
|
||||
print("\e[H",int(1/elt)," fps \n",s);
|
||||
}
|
||||
}
|
||||
|
||||
var st=maketimestamp();
|
||||
var run=[0,0];
|
||||
var frame=1e3;
|
||||
if (size(runtime.argv())!=0) {
|
||||
var n=num(runtime.argv()[0]);
|
||||
if (!math.isnan(n)) {
|
||||
frame=n;
|
||||
}
|
||||
}
|
||||
st.stamp();
|
||||
main(frame);
|
||||
run[0]=st.elapsedMSec();
|
||||
use_raw();
|
||||
st.stamp();
|
||||
main(frame);
|
||||
run[1]=st.elapsedMSec();
|
||||
|
||||
println("test 0: ",run[0]/1000,"s ",frame*1000/run[0]," fps");
|
||||
# ray tracing example
|
||||
# modified from Artem Yashin's project Console3D
|
||||
|
||||
# MIT License
|
||||
# Copyright (c) 2021 Artem Yashin
|
||||
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
use module.libmat;
|
||||
use std.runtime;
|
||||
use std.math;
|
||||
|
||||
func() {
|
||||
# allocate more spaces
|
||||
runtime.gc.extend("str", 8);
|
||||
runtime.gc.extend("vec", 8);
|
||||
}();
|
||||
|
||||
var (max,min,sqrt,sin,cos,abs)=(
|
||||
math.max,
|
||||
math.min,
|
||||
math.sqrt,
|
||||
math.sin,
|
||||
math.cos,
|
||||
math.abs
|
||||
);
|
||||
|
||||
var (vec2,vec3)=(
|
||||
libmat.vec2.new,
|
||||
libmat.vec3.new
|
||||
);
|
||||
|
||||
var (vec2add,vec2sub,vec2mul,vec2div,vec2len)=(
|
||||
libmat.vec2.add,
|
||||
libmat.vec2.sub,
|
||||
libmat.vec2.mul,
|
||||
libmat.vec2.div,
|
||||
libmat.vec2.len
|
||||
);
|
||||
|
||||
var (vec3add,vec3sub,vec3mul,vec3div,vec3neg,vec3norm,vec3len,vec3dot)=(
|
||||
libmat.vec3.add,
|
||||
libmat.vec3.sub,
|
||||
libmat.vec3.mul,
|
||||
libmat.vec3.div,
|
||||
libmat.vec3.neg,
|
||||
libmat.vec3.norm,
|
||||
libmat.vec3.len,
|
||||
libmat.vec3.dot
|
||||
);
|
||||
|
||||
var (rotateX,rotateY,rotateZ)=(
|
||||
libmat.vec3.rx,
|
||||
libmat.vec3.ry,
|
||||
libmat.vec3.rz,
|
||||
);
|
||||
|
||||
var use_raw = func() {
|
||||
vec2 = func(x,y) {return [x,y];}
|
||||
vec2add = func(v1,v2) {return [v1[0]+v2[0],v1[1]+v2[1]];}
|
||||
vec2sub = func(v1,v2) {return [v1[0]-v2[0],v1[1]-v2[1]];}
|
||||
vec2mul = func(v1,v2) {return [v1[0]*v2[0],v1[1]*v2[1]];}
|
||||
vec2div = func(v1,v2) {return [v1[0]/v2[0],v1[1]/v2[1]];}
|
||||
vec3 = func(x,y,z) {return [x,y,z];}
|
||||
vec3add = func(v1,v2) {return [v1[0]+v2[0],v1[1]+v2[1],v1[2]+v2[2]];}
|
||||
vec3sub = func(v1,v2) {return [v1[0]-v2[0],v1[1]-v2[1],v1[2]-v2[2]];}
|
||||
vec3mul = func(v1,v2) {return [v1[0]*v2[0],v1[1]*v2[1],v1[2]*v2[2]];}
|
||||
vec3div = func(v1,v2) {return [v1[0]/v2[0],v1[1]/v2[1],v1[2]/v2[2]];}
|
||||
vec3neg = func(v) {return [-v[0],-v[1],-v[2]];}
|
||||
vec2len = func(v) {var (x,y)=(v[0],v[1]); return sqrt(x*x+y*y);}
|
||||
vec3len = func(v) {var (x,y,z)=(v[0],v[1],v[2]); return sqrt(x*x+y*y+z*z);}
|
||||
vec3norm = func(v) {var t=vec3len(v); return vec3div(v,[t,t,t]);}
|
||||
vec3dot = func(a,b) {return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];}
|
||||
rotateX = func(a,angle) {return [a[0],a[2]*sin(angle)+a[1]*cos(angle),a[2]*cos(angle)-a[1]*sin(angle)];}
|
||||
rotateY = func(a,angle) {return [a[0]*cos(angle)-a[2]*sin(angle),a[1],a[0]*sin(angle)+a[2]*cos(angle)];}
|
||||
rotateZ = func(a,angle) {return [a[0]*cos(angle)-a[1]*sin(angle),a[0]*sin(angle)+a[1]*cos(angle),a[2]];}
|
||||
}
|
||||
|
||||
var clamp = func(value,_min,_max) {
|
||||
return max(min(value,_max),_min);
|
||||
}
|
||||
var sign = func(a) {
|
||||
return (0<a)-(a<0);
|
||||
}
|
||||
var step = func(edge,x) {
|
||||
return x>edge;
|
||||
}
|
||||
|
||||
var vec3abs = func(v) {
|
||||
return [abs(v[0]),abs(v[1]),abs(v[2])];
|
||||
}
|
||||
var vec3sign = func(v) {
|
||||
return [sign(v[0]),sign(v[1]),sign(v[2])];
|
||||
}
|
||||
var vec3step = func(edge,v) {
|
||||
return [step(edge[0],v[0]),step(edge[1],v[1]),step(edge[2],v[2])];
|
||||
}
|
||||
var vec3reflect = func(rd,n) {
|
||||
var d=vec3dot(n,rd);
|
||||
return vec3sub(rd,vec3mul(n,vec3mul([2,2,2],[d,d,d])));
|
||||
}
|
||||
|
||||
var sphere = func(ro,rd,r) {
|
||||
var b=vec3dot(ro,rd);
|
||||
var c=vec3dot(ro,ro)-r*r;
|
||||
var h=b*b-c;
|
||||
if (h<0.0) return [-1.0,-1.0];
|
||||
h=sqrt(h);
|
||||
return [-b-h,-b+h];
|
||||
}
|
||||
|
||||
var box = func(ro,rd,boxSize,outNormal) {
|
||||
var m=vec3div([1.0,1.0,1.0],rd);
|
||||
var n=vec3mul(m,ro);
|
||||
var k=vec3mul(vec3abs(m),boxSize);
|
||||
var t1=vec3sub(vec3neg(n),k);
|
||||
var t2=vec3add(vec3neg(n),k);
|
||||
var tN=max(max(t1[0],t1[1]),t1[2]);
|
||||
var tF=min(min(t2[0],t2[1]),t2[2]);
|
||||
if (tN>tF or tF<0.0) return [-1.0,-1.0];
|
||||
var yzx=[t1[1],t1[2],t1[0]];
|
||||
var zxy=[t1[2],t1[0],t1[1]];
|
||||
var tmp=vec3mul(vec3mul(vec3neg(vec3sign(rd)), vec3step(yzx,t1)),vec3step(zxy,t1));
|
||||
outNormal[0]=tmp[0];
|
||||
outNormal[1]=tmp[1];
|
||||
outNormal[2]=tmp[2];
|
||||
return [tN, tF];
|
||||
}
|
||||
|
||||
var plane = func(ro,rd,p,w) {
|
||||
return -(vec3dot(ro,p)+w)/vec3dot(rd,p);
|
||||
}
|
||||
|
||||
var main = func(frame) {
|
||||
|
||||
var height=15*2;
|
||||
var width=int(height*1/0.618)*2;
|
||||
|
||||
var aspect=width/height;
|
||||
var pixelAspect=11.0/24.0;
|
||||
|
||||
var gradient=split(""," .:!/r(l1Z4H9W8$");
|
||||
var gradientSize=size(gradient)-1;
|
||||
|
||||
var screen=[];
|
||||
setsize(screen,width*height);
|
||||
|
||||
var light=vec3norm([-0.5,0.5,-1.0]);
|
||||
var spherePos=[0,3,0];
|
||||
var vec2_2_2=[2,2];
|
||||
var vec2_1_1=[1,1];
|
||||
var vec3_000=[0,0,0];
|
||||
var vec3_00n1=[0,0,-1];
|
||||
var vec3_111=[1,1,1];
|
||||
|
||||
print("\e[2J");
|
||||
var stamp=maketimestamp();
|
||||
for(var t=0;t<frame;t+=1) {
|
||||
stamp.stamp();
|
||||
for(var i=0;i<width;i+=1) {
|
||||
for(var j=0;j<height;j+=1) {
|
||||
var uv=vec2sub(vec2mul(vec2div([i,j],[width,height]),vec2_2_2),vec2_1_1);
|
||||
uv[0]*=aspect*pixelAspect;
|
||||
var ro=[-6,0,0];
|
||||
var rd=vec3norm([2,uv[0],uv[1]]);
|
||||
ro=rotateY(ro,0.25);
|
||||
rd=rotateY(rd,0.25);
|
||||
ro=rotateZ(ro,t*0.03);
|
||||
rd=rotateZ(rd,t*0.03);
|
||||
var diff=1;
|
||||
for (var k=0;k<5;k+=1) {
|
||||
var minIt=99999;
|
||||
var intersection=sphere(vec3sub(ro,spherePos),rd,1);
|
||||
var n=vec3_000;
|
||||
var albedo=1;
|
||||
if (intersection[0]>0) {
|
||||
var itPoint=vec3add(vec3sub(ro,spherePos),vec3mul(rd,[intersection[0],intersection[0],intersection[0]]));
|
||||
minIt=intersection[0];
|
||||
n=vec3norm(itPoint);
|
||||
}
|
||||
var boxN=[0,0,0];
|
||||
intersection=box(ro,rd,vec3_111,boxN);
|
||||
if (intersection[0]>0 and intersection[0]<minIt) {
|
||||
minIt=intersection[0];
|
||||
n=boxN;
|
||||
}
|
||||
var tmp=plane(ro,rd,vec3_00n1,1);
|
||||
intersection=[tmp,tmp];
|
||||
if (intersection[0]>0 and intersection[0]<minIt) {
|
||||
minIt=intersection[0];
|
||||
n=vec3_00n1;
|
||||
albedo=0.5;
|
||||
}
|
||||
if (minIt<99999) {
|
||||
diff*=(vec3dot(n,light)*0.5+0.5)*albedo;
|
||||
ro=vec3add(ro,vec3mul(rd,[minIt-0.01,minIt-0.01,minIt-0.01]));
|
||||
rd=vec3reflect(rd,n);
|
||||
}
|
||||
else break;
|
||||
}
|
||||
var color=int(diff*20);
|
||||
color=clamp(color,0,gradientSize);
|
||||
screen[i+j*width]=gradient[color];
|
||||
}
|
||||
}
|
||||
var s="";
|
||||
forindex(var index;screen) {
|
||||
s~=screen[index];
|
||||
if (index+1-int((index+1)/width)*width==0)
|
||||
s~="\n";
|
||||
}
|
||||
var elt=stamp.elapsedMSec()/1000;
|
||||
print("\e[H",int(1/elt)," fps \n",s);
|
||||
}
|
||||
}
|
||||
|
||||
var st=maketimestamp();
|
||||
var run=[0,0];
|
||||
var frame=1e3;
|
||||
if (size(runtime.argv())!=0) {
|
||||
var n=num(runtime.argv()[0]);
|
||||
if (!math.isnan(n)) {
|
||||
frame=n;
|
||||
}
|
||||
}
|
||||
st.stamp();
|
||||
main(frame);
|
||||
run[0]=st.elapsedMSec();
|
||||
use_raw();
|
||||
st.stamp();
|
||||
main(frame);
|
||||
run[1]=st.elapsedMSec();
|
||||
|
||||
println("test 0: ",run[0]/1000,"s ",frame*1000/run[0]," fps");
|
||||
println("test 1: ",run[1]/1000,"s ",frame*1000/run[1]," fps");
|
Loading…
Reference in New Issue