加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
vct.lua 40.88 KB
一键复制 编辑 原始数据 按行查看 历史
FreeBlues 提交于 2016-11-28 12:19 . new file
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221
--# Main
function setup()
pi,cos,sin,rad,ti,max,min,floor,abs=math.pi,math.cos,math.sin,math.rad,table.insert,math.max,math.min,math.floor,math.abs
spriteMode(CORNER)
noSmooth()
parameter.watch("1/DeltaTime")
parameter.watch("math.floor(collectgarbage('count')*0.1)*10")
parameter.number("X",-15,15,2.5)
parameter.number("Y",-5,15,2)
parameter.number("Z",-15,15,8)
parameter.number("ROT",0,360,200)
parameter.color("LC",color(255))
parameter.number("CR",0,60,0)
parameter.integer("Lod",0,3,0)
--Inställningar
FAR=20
RES_DIV=5
--Initiering
RES=vec2(math.floor(WIDTH/RES_DIV),math.floor(HEIGHT/RES_DIV))
INV_RES=vec2(0.5/RES.x,0.5/RES.y)
Pos=vec3(X,Y,Z)
Eye=vec3(2,2,4) EyeR=vec2(0,-1.57)
--Klasser
Voxel:initialize(vec3(32,16,32))
Light:init(RES)
--Bilder
Depth=image(RES.x,RES.y)
NormDepth=image(RES.x*2,RES.y)
Screen=image(RES.x,RES.y)
M=mesh()
M.vertices={vec2(0,0),vec2(Screen.width,0),vec2(Screen.width,Screen.height),
vec2(Screen.width,Screen.height),vec2(0,Screen.height),vec2(0,0)}
M.texCoords={vec2(0,0),vec2(1,0),vec2(1,1),vec2(1,1),vec2(0,1),vec2(0,0)}
M.shader=shader(SFLV,SFLF)
M.shader.FAR=vec4(math.tan(math.rad(70/2)),RES.x/RES.y,RES.x*4,RES.y*2)
NM=mesh()
NM.vertices={vec2(0,0),vec2(Depth.width,0),vec2(Depth.width,Depth.height),
vec2(Depth.width,Depth.height),vec2(0,Depth.height),vec2(0,0)}
NM.texCoords={vec2(0,0),vec2(1,0),vec2(1,1),vec2(1,1),vec2(0,1),vec2(0,0)}
NM.shader=shader(SCNV,SCNF)
NM.shader.vg=INV_RES NM.shader.FA=vec2(math.tan(math.rad(70/2)),RES.x/RES.y)
--Scen
Scene={
Lego:block(vec3(0,0,0),vec3(8,2,8))--Floor
,Lego:block(vec3(0,12,0),vec3(4,2,4))--Ceiling
,Lego:block(vec3(0,2,1),vec3(1,10,3),color(255,0,0,255),1)--Red wall
,Lego:block(vec3(3,2,1),vec3(1,10,3),color(255,255,0,255),1)--Green wall
,Lego:block(vec3(0,2,0),vec3(4,10,1))--Wall back
,Create:Sphere(vec3(2,1,2),0.5,150)
,Lego:block(vec3(1,12,1.5),vec3(2,2,1),color(255,250))--Emissive
}
Voxel:Voxelize(Scene)
--Ljus
Light:spotlight(vec3(5000,0,0),20,vec3(2,2,0),vec3(0,1,0),75,500)
--Annat
t=1 LROT=0 LLC=color(0) LLY=0
M.shader.GI=Voxel.RES M.shader.IGI=Voxel.IRES M.shader.vcol=Voxel.colors
parameter.boolean("FirstBounce",true,function() SecondBounce=false Voxel:InjectLight() end)
parameter.boolean("SecondBounce",true,function() Voxel:InjectLight() end)
end
function draw()
t=t+1
--Pos=vec3(X,Y,Z)
---[[
EyeR.y=EyeR.y-RotationRate.y*0.1 EyeR.x=EyeR.x+RotationRate.x*0.1
if CurrentTouch.state==BEGAN or CurrentTouch.state==MOVING then Pos=Pos+vec3(cos(EyeR.y),EyeR.x,sin(EyeR.y))*0.08 end
Eye=Pos+vec3(cos(EyeR.y),EyeR.x,sin(EyeR.y))
--]]
Light.SLights[1][3]=vec3(LC.r,LC.g,LC.b)/127
Light:updatespotlight(1,vec3(4+cos(rad(-ROT))*6,4,4+sin(rad(-ROT))*6),vec3(4,0,4))
--lpp=vec3(4+cos(rad(-ROT))*2,2,4+sin(rad(-ROT))*2) Light:updatespotlight(1,lpp,lpp+vec3(lpp.x*0.25-1,-1,lpp.z*0.25-1))
if LROT~=ROT or LLC~=LC or LY~=LLY then Voxel:InjectLight() LROT=ROT LLC=LC LLY=LY end
if math.fmod(t,4)==0 then collectgarbage() end
--Rendering
setContext(Depth,true)
background(255, 255, 255, 255)
setCamera(Pos,Eye,70,RES.x/RES.y,0.1,FAR)
drawScene(FAR)
IVIEW=viewMatrix():inverse() VP=viewMatrix()*projectionMatrix()
setContext()
resetMatrix()
ortho()
viewMatrix(matrix())
--NORMALER
setContext(NormDepth)
background(255, 255, 255, 255)
sprite(Depth,Depth.width,0,Depth.width,Depth.height)
NM.shader.depth=Depth
NM.shader.iView=IVIEW
NM:draw()
setContext()
--LJUS
Light:draw(Pos,Eye)
resetMatrix()
ortho()
viewMatrix(matrix())
--FinalLight
smooth()
setContext(Screen)
background(0, 0, 0, 255)
M.shader.depth=NormDepth
M.shader.light=Light.map
M.shader.vlight=Voxel.light
M.shader.vmipmap1=Voxel.mipmap[1]
M.shader.vmipmap2=Voxel.mipmap[2]
M.shader.vmipmap3=Voxel.mipmap[3]
M.shader.iView=IVIEW
M.shader.Lod=Lod
M.shader.Time=ElapsedTime
M.shader.Player=Pos
M.shader.CR=sin(rad(CR*0.5))/(1-sin(rad(CR*0.5)))
M:draw()
setContext()
noSmooth()
sprite(Screen,WIDTH/8,HEIGHT/4,WIDTH-WIDTH/4,HEIGHT-HEIGHT/4)
--sprite(Voxel.colors,0,0,WIDTH,Voxel.colors.height*(WIDTH/Voxel.colors.width))
--sprite(Voxel.light,0,0,WIDTH,Voxel.light.height*(WIDTH/Voxel.light.width))
--sprite(Voxel.mipmap[1],0,0,WIDTH,Voxel.mipmap[1].height*(WIDTH/Voxel.mipmap[1].width))
--sprite(Voxel.mipmap[2],0,0,WIDTH,Voxel.mipmap[2].height*(WIDTH/Voxel.mipmap[2].width))
end
function setCamera(pos,eye,fov,aspect,n,f) perspective(fov,aspect,n,f) camera(pos.x,pos.y,pos.z,eye.x,eye.y,eye.z) end
function drawScene(far)
for i=1,#Scene do
Scene[i].shader.far=far
Scene[i]:draw()
end
end
function sm(v) local s={} for i,j in ipairs(v) do for h,g in ipairs(j) do table.insert(s,g) end end return s end
function normals(m) --Aint using this one
local normal={}
local v=m.vertices
for i=1,#v,3 do
local n=(v[i+1]-v[i]):cross(v[i+2]-v[i]):normalize()
normal[i]=n normal[i+1]=n normal[i+2]=n
end
return normal
end
SDV=[[
uniform mat4 modelViewProjection;
attribute vec4 position;
attribute vec2 texCoord;
varying vec4 Pos;
varying vec2 vt;
void main() {
Pos=modelViewProjection*position;
vt=texCoord;
gl_Position=Pos;
}
]]
SDF=[[
precision highp float;
varying vec4 Pos;
varying vec2 vt;
uniform float far;
vec3 encodeDepth(float d) {
vec3 enc=vec3(1.,255.,65025.)*d;
enc=fract(enc);
enc-=vec3(enc.y,enc.z,enc.z)*vec3(1./255.,1./255.,1./255.);
return enc;
}
void main() {
if (!gl_FrontFacing) discard;
gl_FragColor=vec4(encodeDepth(Pos.w/far),1.);
}
]]
SFLV=[[
#version 300 es
uniform mat4 modelViewProjection;
in vec4 position;
in vec2 texCoord;
out highp vec2 vt;
void main() {
vt=texCoord;
gl_Position=modelViewProjection*position;
}
]]
SFLF=[[
#version 300 es
precision highp float;
uniform sampler2D depth;
uniform sampler2D light;
uniform sampler2D vlight;
uniform sampler2D vcol;
uniform sampler2D vmipmap1;
uniform sampler2D vmipmap2;
uniform sampler2D vmipmap3;
uniform mat4 iView;
uniform vec4 FAR;
uniform vec3 GI;
uniform vec3 IGI;
uniform float Lod;
uniform float Time;
uniform vec3 Player;
uniform float CR;
in highp vec2 vt;
out vec4 FinalColor;
#define far 20.
#define DIM vec3(GI.x*0.25,GI.y*0.25,GI.z*0.25)
#define IDIM vec3(1./DIM.x,1./DIM.y,1./DIM.z)
#define sixth 1./6.
#define sixth2 2./6.
#define sixth3 3./6.
#define sixth4 4./6.
#define sixth5 5./6.
#define upperLimit GI.y*IGI.x
//MipMaps
#define GI2 vec3(GI.x*0.5,GI.y*0.5,GI.z*0.5)
#define IGI2 vec3(IGI.x*2.,IGI.y*2.,IGI.z*2.)
#define GI3 vec3(GI.x*0.25,GI.y*0.25,GI.z*0.25)
#define IGI3 vec3(IGI.x*4.,IGI.y*4.,IGI.z*4.)
#define GI4 vec3(GI.x*0.125,GI.y*0.125,GI.z*0.125)
#define IGI4 vec3(IGI.x*8.,IGI.y*8.,IGI.z*8.)
const highp vec2 Values=vec2(1./255.,1./65025.);
vec2 seed=vt*vec2(Time*34.69467);
float noise() {
seed+=vec2(-1.,1.);
return fract(sin(dot(seed.xy,vec2(12.9898,78.233)))*43758.5453);
}
float decodeDepth(vec3 c) { return dot(c,vec3(1.,Values.x,Values.y)); }
mat3 TBN(vec3 N) {
vec3 Nt,Nb;
Nt=(abs(N.x)>abs(N.y)-0.02)?(vec3(N.z,0.,-N.x)/sqrt(N.x*N.x+N.z*N.z)):
(vec3(0.,-N.z,N.y)/sqrt(N.y*N.y+N.z*N.z));
Nb=normalize(cross(N,Nt));
Nt=normalize(cross(N,Nb));
return mat3(Nt.x,Nb.x,N.x,Nt.y,Nb.y,N.y,Nt.z,Nb.z,N.z);
}
vec4 MIX(vec3 vP, vec2 bvt, vec2 frek, sampler2D img) {
float f=fract(vP.z*frek.x);
vec4 rvc=(f>0.5)?
mix(texture(img,bvt),texture(img,((bvt+vec2(frek.y,0.)).x>1.)?bvt:bvt+vec2(frek.y,0.)),f-0.5)
:mix(texture(img,((bvt-vec2(frek.y,0.)).x<0.)?bvt:bvt-vec2(frek.y,0.)),
texture(img,bvt),f+0.5);
return rvc;
}
vec4 VoxelFetch(vec2 pvt, vec3 vP, vec3 vD, vec2 frek, sampler2D img, vec3 bgi, vec3 ibgi) {
vec2 Min=vec2(floor(pvt.x*bgi.z)*ibgi.z+0.5*ibgi.z*ibgi.x,
floor(pvt.y*6.)*sixth+0.5*ibgi.y*sixth);
vec2 Max=vec2(Min.x+ibgi.z-ibgi.z*ibgi.x,
Min.y+sixth-ibgi.y*sixth);
pvt=clamp(pvt,Min,Max);
vec3 vDS=vD.xyz*vD.xyz; vec4 xC,yC,zC;
xC=(vD.x>0.)?MIX(vP,pvt+vec2(0,sixth),frek,img):
MIX(vP,pvt,frek,img);
if (xC.w==0.) return vec4(0.);
yC=(vD.y>0.)?MIX(vP,pvt+vec2(0,sixth3),frek,img):
MIX(vP,pvt+vec2(0,sixth2),frek,img);
zC=(vD.z>0.)?MIX(vP,pvt+vec2(0,sixth5),frek,img):
MIX(vP,pvt+vec2(0,sixth4),frek,img);
return xC*vDS.x+yC*vDS.y+zC*vDS.z;
}
vec4 GetVoxelI(vec3 vP, vec3 vD, float lod) {
if (lod<1.) {
float zf=floor(vP.z*4.)*IGI.z;
vec2 pvt=vec2(vP.x*IDIM.x*IGI.z+zf,vP.y*IDIM.y*sixth);
zf=floor(vP.z*2.)*IGI2.z;
vec2 pvt2=vec2(vP.x*IDIM.x*IGI2.z+zf,vP.y*IDIM.y*sixth);
return mix(
VoxelFetch(pvt,vP,vD,vec2(4.,IGI.z),vlight,GI,IGI),
VoxelFetch(pvt2,vP,vD,vec2(2.,IGI2.z),vmipmap1,GI2,IGI2),lod);
} else if (lod<2.) {
float zf=floor(vP.z*2.)*IGI2.z;
vec2 pvt=vec2(vP.x*IDIM.x*IGI2.z+zf,vP.y*IDIM.y*sixth);
zf=floor(vP.z)*IGI3.z;
vec2 pvt2=vec2(vP.x*IDIM.x*IGI3.z+zf,vP.y*IDIM.y*sixth);
return mix(VoxelFetch(pvt,vP,vD,vec2(2.,IGI2.z),vmipmap1,GI2,IGI2),
VoxelFetch(pvt2,vP,vD,vec2(1.,IGI3.z),vmipmap2,GI3,IGI3),lod-1.);
} else {
float zf=floor(vP.z)*IGI3.z;
vec2 pvt=vec2(vP.x*IDIM.x*IGI3.z+zf,vP.y*IDIM.y*sixth);
zf=floor(vP.z*0.5)*IGI4.z;
vec2 pvt2=vec2(vP.x*IDIM.x*IGI4.z+zf,vP.y*IDIM.y*sixth);
return mix(VoxelFetch(pvt,vP,vD,vec2(1.,IGI3.z),vmipmap2,GI3,IGI3),
VoxelFetch(pvt2,vP,vD,vec2(0.5,IGI4.z),vmipmap3,GI4,IGI4),min(1.,lod-2.));
}
}
vec4 Trace(vec3 vP, vec3 vD, float ConeRatio, float MaxD) {
vec4 fc=vec4(0.); float sL,sW,sD; vec4 sC; vec3 sP;
vec3 origin=vP*IDIM.x;
float dist=IGI.x+(fract(sin(dot(vt,vec2(12.9898, 78.233)))*43758.5453))*IGI.x*2.;
float sI=max(dist,dist*ConeRatio); float mD=IGI.x;
while (dist<MaxD && fc.w<0.9) {
sD=max(mD,dist*ConeRatio);
sP=origin+vD*dist;
if (sP.x<0. || sP.y<0. || sP.z<0. || sP.x>1. || sP.y>upperLimit || sP.z>1.) break;
sL=log2(sD*32.);
sC=GetVoxelI(sP*DIM.x,vD,sL);
sW=1.-fc.w;
fc+=sC*sW;
dist+=sD;
}
return fc;
}
vec3 ToPos(vec2 vt,float f) {
vec2 uv=vt*2.-1.;
highp float Z=f*far;
highp float X=uv.x*FAR.x*FAR.y*Z;
highp float Y=uv.y*FAR.x*Z;
highp vec4 fPos=iView*vec4(X,Y,-Z,1.);
return fPos.xyz/fPos.w;
}
void main() {
ivec2 ivt=ivec2(vt.x*FAR.z*0.5,vt.y*FAR.w);
float D=decodeDepth(texelFetch(depth,ivec2(ivt.x+int(FAR.z*0.5),ivt.y),0).xyz);
if (D>0.99) discard;
//Pos,Normal,bvt
vec3 P=ToPos(vt,D);
vec3 N=texelFetch(depth,ivt,0).xyz; N=normalize(N*2.-1.); mat3 NM=TBN(N);
P=P-N*0.05; float zf=floor(P.z*4.)*IGI.z; vec2 atvt=vec2(P.x*IDIM.x*IGI.z+zf,P.y*IDIM.y);
//Attributer
vec3 DirectL=texture(light,vt).xyz;
vec4 Albedo=texelFetch(vcol,ivec2(atvt.x*GI.x*GI.z,atvt.y*GI.y),0);
//Strålföljning
//*
if (Albedo.w*255.==250.)
FinalColor=vec4(Albedo.xyz,1.); //EMISSIVE
else {
P=P+N*0.25;
float j=0.8+(fract(sin(dot(vt,vec2(12.9898, 78.233)))*43758.5453))*0.4;
FinalColor=vec4((
(Trace(P,N,1.,1.5)
+Trace(P,normalize(vec3(j,0.,1.)*NM),1.,1.5)
+Trace(P,normalize(vec3(-j,0.,1.)*NM),1.,1.5)
+Trace(P,normalize(vec3(0.,j,1.)*NM),1.,1.5)
+Trace(P,normalize(vec3(0.,-j,1.)*NM),1.,1.5)*0.7).xyz*0.5
+((Albedo.w*255.==252.)?Trace(P,reflect(normalize(P-Player),-N),CR,1.5).xyz:vec3(0.))
+DirectL)*Albedo.xyz,1.);
}
//*/
//FinalColor=vec4(GetVoxelI(P-N*0.125,-N,Lod).xyz,1.); //Voxel
//P+=N*0.05;FinalColor=vec4(vec3(reflect(normalize(P-Player),-N).y),1.);
//Shadows
//P+=N*0.05; FinalColor=vec4(Trace(Player,normalize(P-Player),CR,1.5).xyz,1.);
}
]]
SCNV=[[
uniform mat4 modelViewProjection;
attribute vec4 position;
attribute vec2 texCoord;
varying vec2 vt;
void main() {
vt=texCoord;
gl_Position=modelViewProjection*position;
}
]]
SCNF=[[
precision highp float;
varying vec2 vt;
uniform sampler2D depth;
uniform vec2 FA;
uniform vec2 vg;
uniform mat4 iView;
#define far 20.
#define normh 0.1
const highp vec2 Values=vec2(1./255.,1./65025.);
float decodeDepth(vec3 c) { return dot(c,vec3(1.,Values.x,Values.y)); }
vec3 ToPos(vec2 vt,float f) {
vec2 uv=vt*2.-1.;
highp float Z=f*far;
highp float X=uv.x*FA.x*FA.y*Z;
highp float Y=uv.y*FA.x*Z;
highp vec4 fPos=iView*vec4(X,Y,-Z,1.);
return fPos.xyz/fPos.w;
}
vec3 ToNorm(vec2 vt, float D, vec3 P) {
vec2 vt1=vt+vec2(vg.x,0.);
float d1=decodeDepth(texture2D(depth,vt1).xyz);
float d11=decodeDepth(texture2D(depth,vt-vec2(vg.x,0.)).xyz);
if (abs(d1-D)*far>normh) { d1=(D-d11)+D; }
vec2 vt2=vt+vec2(0.,vg.y);
float d2=decodeDepth(texture2D(depth,vt2).xyz);
float d22=decodeDepth(texture2D(depth,vt-vec2(0.,vg.y)).xyz);
if (abs(d2-D)*far>normh) { d2=(D-d22)+D;}
vec3 p1=ToPos(vt1,d1);
vec3 p2=ToPos(vt2,d2);
vec3 norm=normalize(cross(p1-P,p2-P));
return norm;
}
void main() {
float D=decodeDepth(texture2D(depth,vt).xyz);
if (D>0.99) discard;
vec3 ppos=ToPos(vt,D);
highp vec3 norm=ToNorm(vt,D,ppos);
gl_FragColor=vec4(norm*0.5+0.5,1.);
}
]]
SMIPV=[[
uniform mat4 modelViewProjection;
attribute vec4 position;
attribute vec2 texCoord;
varying vec2 vt;
void main() {
vt=texCoord;
gl_Position=modelViewProjection*position;
}
]]
SMIPF=[[
precision highp float;
uniform vec4 vg[3];
uniform vec4 vgoffset[6];
uniform vec3 GI;
uniform vec3 IGI;
uniform sampler2D vlight;
varying vec2 vt;
void main() {
vec4 ivg=vg[int(floor(vt.y*3.))]; vec2 cvt;
vec4 vgoff=vgoffset[int(floor(vt.y*6.))];
vec2 pvt=vec2(floor(vt.x*GI.z)*IGI.z+fract(vt.x*GI.z)*IGI.z*0.5,vt.y)+vgoff.zw;
vec4 tex=texture2D(vlight,pvt);
vec4 col=(tex.w>0.)?tex:texture2D(vlight,pvt+vgoff.xy);
cvt=pvt+ivg.xy; tex=texture2D(vlight,cvt);
col+=(tex.w>0.)?tex:texture2D(vlight,cvt+vgoff.xy);
cvt=pvt+ivg.zw; tex=texture2D(vlight,cvt);
col+=(tex.w>0.)?tex:texture2D(vlight,cvt+vgoff.xy);
cvt=pvt+ivg.xy+ivg.zw; tex=texture2D(vlight,cvt);
col+=(tex.w>0.)?tex:texture2D(vlight,cvt+vgoff.xy);
gl_FragColor=col*0.25;
//gl_FragColor=vec4(col.xyz/col.w,col.w*0.25);
}
]]
SILV=[[
uniform mat4 modelViewProjection;
attribute vec4 position;
attribute vec2 texCoord;
varying vec2 vt;
void main() {
vt=texCoord;
gl_Position=modelViewProjection*position;
}
]]
SILF=[[
precision highp float;
uniform vec3 GI;
uniform vec3 IGI;
uniform vec3 normals[6];
uniform sampler2D colors;
uniform sampler2D shadow;
uniform vec3 lp;
uniform vec3 ld;
uniform vec3 lc;
uniform float lr;
uniform float spot;
uniform mat4 lmat;
varying vec2 vt;
#define DIM vec3(GI.x*0.25,GI.y*0.25,GI.z*0.25)
#define IDIM vec3(1./DIM.x,1./DIM.y,1./DIM.z)
const highp vec2 Values=vec2(1./255.,1./65025.);
float decodeDepth(vec3 c) { return dot(c,vec3(1.,Values.x,Values.y)); }
float Shadows(vec3 p) {
vec4 lppos=lmat*vec4(p,1.);
vec2 lvt=lppos.xy/lppos.w*0.5+0.5;
float lD=decodeDepth(texture2D(shadow,lvt).xyz);
return (lppos.z>lD*lr+0.02)?0.:1.;
}
void main() {
vec2 VT=vec2(vt.x,fract(vt.y*6.));
vec4 C=texture2D(colors,VT);
if (C.w==0.) {
gl_FragColor=vec4(0.);
} else if (C.w*255.==250.) {
gl_FragColor=vec4(C.xyz,1.);//ceil(C.w);
} else {
vec3 N=normals[int(floor(vt.y*6.))];
vec3 Pos=vec3(fract(VT.x*GI.z)*DIM.x,VT.y*DIM.y,floor(VT.x*GI.x)*IGI.x*DIM.z)+vec3(0.,0.,0.125);
vec3 vP=Pos+N*0.25;
float zf=floor(vP.z*4.)*IGI.z;
vec2 pvt=vec2(vP.x*IDIM.x*IGI.z+zf,vP.y*IDIM.y);
if (texture2D(colors,pvt).w==0.) {
//LIGHT
vec3 ltp=normalize(lp-Pos);
float dota=dot(ld,ltp);
float cosa=max(0.,1.-(1.-dota)/(1.-spot));
vec3 col=lc*C.xyz*max(dot(N,ltp),0.)*max(0.,1.-length(lp-Pos)/lr)*cosa
*Shadows(Pos+N.xyz*0.125);
gl_FragColor=vec4(col,1.);
} else gl_FragColor=vec4(0.,0.,0.,1.);
}
}
]]
SSBV=[[
#version 300 es
uniform mat4 modelViewProjection;
in vec4 position;
in vec2 texCoord;
out vec2 vt;
void main() {
vt=texCoord;
gl_Position=modelViewProjection*position;
}
]]
SSBF=[[
#version 300 es
precision highp float;
uniform sampler2D vlight;
uniform sampler2D vcol;
uniform sampler2D vmipmap1;
uniform sampler2D vmipmap2;
uniform sampler2D vmipmap3;
uniform vec3 normals[6];
uniform vec3 tangents[6];
uniform vec3 binormals[6];
uniform vec4 FAR;
uniform vec3 GI;
uniform vec3 IGI;
in vec2 vt;
out vec4 FinalColor;
#define far 20.
#define DIM vec3(GI.x*0.25,GI.y*0.25,GI.z*0.25)
#define IDIM vec3(1./DIM.x,1./DIM.y,1./DIM.z)
#define sixth 1./6.
#define sixth2 2./6.
#define sixth3 3./6.
#define sixth4 4./6.
#define sixth5 5./6.
//MipMaps
#define GI2 vec3(GI.x*0.5,GI.y*0.5,GI.z*0.5)
#define IGI2 vec3(IGI.x*2.,IGI.y*2.,IGI.z*2.)
#define GI3 vec3(GI.x*0.25,GI.y*0.25,GI.z*0.25)
#define IGI3 vec3(IGI.x*4.,IGI.y*4.,IGI.z*4.)
#define GI4 vec3(GI.x*0.125,GI.y*0.125,GI.z*0.125)
#define IGI4 vec3(IGI.x*8.,IGI.y*8.,IGI.z*8.)
const highp vec2 Values=vec2(1./255.,1./65025.);
float decodeDepth(vec3 c) { return dot(c,vec3(1.,Values.x,Values.y)); }
mat3 TBN(vec3 N, int Ni) {
vec3 Nt=tangents[Ni];
vec3 Nb=binormals[Ni];
return mat3(Nt.x,Nb.x,N.x,Nt.y,Nb.y,N.y,Nt.z,Nb.z,N.z);
}
/*
vec4 MIX(vec3 vP, vec2 bvt, vec2 frek, sampler2D img) {
float f=fract(vP.z*frek.x);
vec4 rvc=(f>0.5)?mix(texture(img,bvt),texture(img,bvt+vec2(frek.y,0.)),f-0.5)
:mix(texture(img,bvt-vec2(frek.y,0.)),texture(img,bvt),f+0.5);
return rvc;
}*/
vec4 MIX(vec3 vP, vec2 bvt, vec2 frek, sampler2D img) {
float f=fract(vP.z*frek.x);
vec4 rvc=(f>0.5)?
mix(texture(img,bvt),texture(img,((bvt+vec2(frek.y,0.)).x>1.)?bvt:bvt+vec2(frek.y,0.)),f-0.5)
:mix(texture(img,((bvt-vec2(frek.y,0.)).x<0.)?bvt:bvt-vec2(frek.y,0.)),
texture(img,bvt),f+0.5);
return rvc;
}
vec4 VoxelFetch(vec2 pvt, vec3 vP, vec3 vD, vec2 frek, sampler2D img, vec3 bgi, vec3 ibgi) {
vec2 Min=vec2(floor(pvt.x*bgi.z)*ibgi.z+0.5*ibgi.z*ibgi.x,
floor(pvt.y*6.)*sixth+0.5*ibgi.y*sixth);
vec2 Max=vec2(Min.x+ibgi.z-ibgi.z*ibgi.x,
Min.y+sixth-ibgi.y*sixth);
pvt=clamp(pvt,Min,Max);
vec3 vDS=vD.xyz*vD.xyz; vec4 xC,yC,zC;
xC=(vD.x>0.)?MIX(vP,pvt+vec2(0,sixth),frek,img):
MIX(vP,pvt,frek,img);
if (xC.w==0.) return vec4(0.);
yC=(vD.y>0.)?MIX(vP,pvt+vec2(0,sixth3),frek,img):
MIX(vP,pvt+vec2(0,sixth2),frek,img);
zC=(vD.z>0.)?MIX(vP,pvt+vec2(0,sixth5),frek,img):
MIX(vP,pvt+vec2(0,sixth4),frek,img);
return xC*vDS.x+yC*vDS.y+zC*vDS.z;
}
vec4 GetVoxel(vec3 vP, vec3 vD, float lod) {
if (lod<1.) {
float zf=floor(vP.z*4.)*IGI.z;
vec2 pvt=vec2(vP.x*IDIM.x*IGI.z+zf,vP.y*IDIM.y*sixth);
return VoxelFetch(pvt,vP,vD,vec2(4.,IGI.z),vlight,GI,IGI);
} else if (lod<2.) {
float zf=floor(vP.z*2.)*IGI2.z;
vec2 pvt=vec2(vP.x*IDIM.x*IGI2.z+zf,vP.y*IDIM.y*sixth);
return VoxelFetch(pvt,vP,vD,vec2(2.,IGI2.z),vmipmap1,GI2,IGI2);
} else if (lod<3.) {
float zf=floor(vP.z)*IGI3.z;
vec2 pvt=vec2(vP.x*IDIM.x*IGI3.z+zf,vP.y*IDIM.y*sixth);
return VoxelFetch(pvt,vP,vD,vec2(1.,IGI3.z),vmipmap2,GI3,IGI3);
} else {
float zf=floor(vP.z*0.5)*IGI4.z;
vec2 pvt=vec2(vP.x*IDIM.x*IGI4.z+zf,vP.y*IDIM.y*sixth);
return VoxelFetch(pvt,vP,vD,vec2(0.5,IGI4.z),vmipmap3,GI4,IGI4);
}
}
vec4 Trace60(vec3 vP, vec3 vD) {
vec4 sC,fc=vec4(0.); float sL=0.; vec3 sP; float vdist=0.25;
while (vdist<10. && fc.w<0.95) {
sP=vP+vD*vdist;
if (sP.x<0. || sP.y<0. || sP.z<0. || sP.x>DIM.x || sP.y>DIM.y || sP.z>DIM.z) break;
sC=GetVoxel(sP,vD,sL);
fc=fc+sC*(1.-fc.w);
sL=sL+1.;
vdist=min(vdist+1.,vdist*2.);
}
return fc;
}
void main() {
ivec2 ivt=ivec2(vt.x*GI.x*GI.z,fract(vt.y*6.)*GI.y);
vec4 Albedo=texelFetch(vcol,ivt,0);
if (Albedo.w==0.) discard;
int Ni=int(floor(vt.y*6.)); vec3 N=normals[Ni]; mat3 NM=TBN(N,Ni);
vec2 VT=vec2(vt.x,fract(vt.y*6.));
vec3 P=vec3(fract(VT.x*GI.z)*DIM.x,VT.y*DIM.y,floor(VT.x*GI.x)*IGI.x*DIM.z);
//Attributer
vec3 DirectL=texture(vlight,vt).xyz;
//Strålföljning
if (Albedo.w*255.==250.)
FinalColor=vec4(Albedo.xyz,1.); //EMISSIVE
else {
P=P+N*0.35;
FinalColor=vec4((Trace60(P,N)+Trace60(P,vec3(-0.866,0.,0.5)*NM)+
Trace60(P,vec3(0.866,0.,0.5)*NM)+Trace60(P,vec3(0.,0.886,0.5)*NM)+
Trace60(P,vec3(0.,-0.866,0.5)*NM)).xyz*0.32
*Albedo.xyz+DirectL,1.);
}
}
]]
SSPOTV=[[
uniform mat4 modelViewProjection;
attribute vec4 position;
attribute vec2 texCoord;
varying vec4 pos;
void main(){
pos=modelViewProjection*position;
gl_Position=modelViewProjection*position;
}
]]
SSPOTF=[[
precision highp float;
varying vec4 pos;
uniform sampler2D shadow;
uniform sampler2D depth;
uniform vec3 lp;
uniform vec3 lc;
uniform float lr;
uniform vec3 dir;
uniform float spot;
uniform vec2 FA;
uniform mat4 iView;
#define far 20.
const highp vec2 Values=vec2(1./255.,1./65025.);
uniform mat4 lmat;
float decodeDepth(vec3 c) { return dot(c,vec3(1.,Values.x,Values.y)); }
vec3 ToPos(vec2 vt,float f) {
vec2 uv=vt*2.-1.;
highp float Z=f*far;
highp float X=uv.x*FA.x*FA.y*Z;
highp float Y=uv.y*FA.x*Z;
highp vec4 fPos=iView*vec4(X,Y,-Z,1.);
return fPos.xyz/fPos.w;
}
void main() {
if (!gl_FrontFacing) discard;
vec2 vt=pos.xy/pos.w*0.5+0.5;
float D=decodeDepth(texture2D(depth,vec2(vt.x*0.5+0.5,vt.y)).xyz);
if (D>0.99) discard;
//Shadow
vec3 ppos=ToPos(vt,D);
vec4 lppos=lmat*vec4(ppos,1.);
vec2 lvt=lppos.xy/lppos.w*0.5+0.5;
float lD=decodeDepth(texture2D(shadow,lvt).xyz);
if (lppos.z>lD*lr+0.02) discard;
//Light
vec3 norm=texture2D(depth,vec2(vt.x*0.5,vt.y)).xyz; norm=norm*2.-1.;
vec3 ltp=normalize(lp-ppos);
float dota=dot(dir,ltp);
float cosa=max(0.,1.-(1.-dota)/(1.-spot));
vec3 col=lc*max(0.,dot(norm,ltp))*cosa*max(0.,1.-length(lp-ppos)/lr);
gl_FragColor=vec4(col,1.);
}
]]
SPV=[[
uniform mat4 modelViewProjection;
attribute vec4 position;
varying highp vec4 pos;
varying vec4 plp;
uniform vec3 lp;
uniform mat4 viewproj;
void main(){
plp=viewproj*vec4(lp,1.); plp.xy=(plp.xy/plp.w)*0.5+0.5;
pos=modelViewProjection*position;
gl_Position=pos;
}
]]
SPF=[[
precision highp float;
varying vec4 pos;
varying vec4 plp;
uniform sampler2D depth;
uniform vec3 lp;
uniform vec3 lc;
uniform float lr;
uniform vec2 FA;
uniform mat4 iView;
#define far 20.
#define normh far*0.002
const highp vec2 Values=vec2(1./255.,1./65025.);
float decodeDepth(vec3 c) { return dot(c,vec3(1.,Values.x,Values.y)); }
vec3 ToPos(vec2 vt,float f) {
vec2 uv=vt*2.-1.;
highp float Z=f*far;
highp float X=uv.x*FA.x*FA.y*Z;
highp float Y=uv.y*FA.x*Z;
highp vec4 fPos=iView*vec4(X,Y,-Z,1.);
return fPos.xyz/fPos.w;
}
void main() {
if (gl_FrontFacing) discard;
vec2 vt=(pos.xy/pos.w)*0.5+0.5;
float D=decodeDepth(texture2D(depth,vec2(vt.x*0.5+0.5,vt.y)).xyz);
if (D>0.99) discard;
float light=1.;
/*Shadows
float vpz=-(D*far);
float steps=35.;//ceil(length((vt-plp.xy)*vec2(124.,128.)));
float iste=1./steps;
vec2 dvt=(plp.xy-vt)*iste;
float dz=(plp.z+vpz)*iste;
vec2 cvt=vt; float cz=-vpz-0.01;
for (int i=0; i<int(steps)-2; i++) {
cvt=cvt+dvt; cz=cz+dz;
light*=cz>decodeDepth(texture2D(depth,vec2(cvt.x*0.5+0.5,cvt.y)).xyz)*far?0.:1.;
}
//*/
vec3 ppos=ToPos(vt,D);
vec3 norm=texture2D(depth,vec2(vt.x*0.5,vt.y)).xyz; norm=norm*2.-1.;
vec3 col=lc*max(0.,dot(norm,normalize(lp-ppos)))*max(0.,1.-length(lp-ppos)/lr);
gl_FragColor=vec4(col*light,1.);
}
]]
--# Light
Light=class()
--Funktioner-pointlights(utan skuggor/med), spotlight(inget indirekt ljus/ med)
function Light:init(RES)
self.map=image(RES.x,RES.y)
self.PLights={}
self.SLights={}
self.Shadows={}
self.MP=Create:Sphere(vec3(0,0,0),1,16)
self.MP.shader=shader(SPV,SPF)
self.MP.shader.FA=vec2(math.tan(math.rad(70/2)),RES.x/RES.y)
self.MS=Create:Cyl(vec3(0,0,0),1,1,16,0)
local verts=Create:Cyl(vec3(0,0,1),1,0,16,0).vertices
for i=1,#verts,3 do
vind=verts[i]
verts[i]=verts[i+2] verts[i+2]=vind
end
self.MS.vertices=sm({self.MS.vertices,verts})
self.MS.shader=shader(SSPOTV,SSPOTF)
self.MS.shader.FA=vec2(math.tan(math.rad(70/2)),RES.x/RES.y)
end
function Light:pointlight(p,r,c)
table.insert(self.PLights,{p,r,c})
return #self.PLights
end
function Light:spotlight(p,r,c,dir,spot,w)
N=-(dir-p):normalize()
local angley=math.deg(math.atan(-N.x,-N.z))
local anglex=math.deg(math.atan(N.y,vec2(N.z,N.x):len()))
table.insert(self.SLights,{p,r,c,N,cos(rad(spot/2)),r*math.tan(rad(spot/2)),angley,anglex,spot,dir})
table.insert(self.Shadows,{image(w,w),matrix()})
self:Shadow(#self.Shadows)
return #self.SLights
end
function Light:updatespotlight(i,pos,dir)
if pos~=self.SLights[i][1] or dir~=self.SLights[i][10] then
local N=-(dir-pos):normalize()
self.SLights[i][7]=math.deg(math.atan(-N.x,-N.z))
self.SLights[i][8]=math.deg(math.atan2(N.y,vec2(N.z,N.x):len()))
self.SLights[i][1]=pos self.SLights[i][4]=N self.SLights[i][10]=dir
self:Shadow(i)
end
end
function Light:Shadow(i)
resetMatrix()
setContext(self.Shadows[i][1],true)
setCamera(self.SLights[i][1],self.SLights[i][10],self.SLights[i][9],1,0.1,self.SLights[i][2])
drawScene(self.SLights[i][2])
self.Shadows[i][2]=viewMatrix()*projectionMatrix()
setContext()
resetMatrix()
end
function Light:draw(pos,eye)
setContext(self.map)
blendMode(ADDITIVE)
background(0, 0, 0, 255)
perspective(70,RES.x/RES.y,0.1,50)
camera(pos.x,pos.y,pos.z,eye.x,eye.y,eye.z,0,1,0)
for i=1,#self.PLights do
pushMatrix()
translate(self.PLights[i][1].x,self.PLights[i][1].y,self.PLights[i][1].z)
scale(self.PLights[i][2])
self.MP.shader.lp=self.PLights[i][1]
self.MP.shader.lr=self.PLights[i][2]
self.MP.shader.lc=self.PLights[i][3]
self.MP.shader.depth=NormDepth
self.MP.shader.iView=IVIEW
self.MP.shader.viewproj=VP
self.MP:draw()
popMatrix()
end
for i=1,#self.SLights do
pushMatrix()
translate(self.SLights[i][1].x,self.SLights[i][1].y,self.SLights[i][1].z)
rotate(self.SLights[i][7],0,1,0)
rotate(self.SLights[i][8],1,0,0)
scale(self.SLights[i][6],self.SLights[i][6],self.SLights[i][2])
self.MS.shader.lp=self.SLights[i][1]
self.MS.shader.lr=self.SLights[i][2]
self.MS.shader.lc=self.SLights[i][3]
self.MS.shader.dir=self.SLights[i][4]
self.MS.shader.spot=self.SLights[i][5]
self.MS.shader.lmat=self.Shadows[i][2]
self.MS.shader.shadow=self.Shadows[i][1]
self.MS.shader.depth=NormDepth
self.MS.shader.iView=IVIEW
self.MS:draw()
popMatrix()
end
setContext()
blendMode(NORMAL)
resetMatrix()
end
--# Create
Create=class()
function Create:Cyl(pos,width,length,poly,open,y)
local cyl=mesh()
local fc={}
local ac={}
local cs=cs or 360
local angle=cs/poly
if y==nil then
for i=1,poly+1 do
ti(fc,vec3(pos.x+open*width*cos(rad(angle*i)),pos.y+open*width*sin(rad(angle*i)),pos.z))
ti(ac,vec3(pos.x+width*cos(rad(angle*(i))),pos.y+width*sin(rad(angle*(i))),pos.z+length))
end
else
for i=1,poly+1 do
ti(fc,vec3(pos.x+width*cos(rad(angle*i)),pos.y,pos.z+width*sin(rad(angle*i))))
ti(ac,vec3(pos.x+open*width*cos(rad(angle*(i))),pos.y+length,pos.z+open*width*sin(rad(angle*(i)))))
end
end
local v={}
for k=1,poly do
ti(v,fc[k]) ti(v,ac[k]) ti(v,ac[k+1])
ti(v,ac[k+1]) ti(v,fc[k+1]) ti(v,fc[k])
end
cyl.vertices=v
cyl.shader=shader(SDV,SDF)
cyl.shader.far=FAR
cyl.dim=vec3(0,0,0)
return cyl
end
function Create:Sphere(pos,r,N)
local tab={}
for n=0,N-1 do
for m=0,N-1 do
x=pos.x+r*sin(pi*m/N)*cos(2*pi*n/N)
y=pos.y+r*sin(pi*m/N)*sin(2*pi*n/N)
z=pos.z+r*cos(pi*m/N)
x1=pos.x+r*sin(pi*m/N)*cos(2*pi*(n+1)/N)
y1=pos.y+r*sin(pi*m/N)*sin(2*pi*(n+1)/N)
z1=pos.z+r*cos(pi*m/N)
x2=pos.x+r*sin(pi*(m+1)/N)*cos(2*pi*(n+1)/N)
y2=pos.y+r*sin(pi*(m+1)/N)*sin(2*pi*(n+1)/N)
z2=pos.z+r*cos(pi*(m+1)/N)
x3=pos.x+r*sin(pi*(m+1)/N)*cos(2*pi*n/N)
y3=pos.y+r*sin(pi*(m+1)/N)*sin(2*pi*n/N)
z3=pos.z+r*cos(pi*(m+1)/N)
ti(tab,vec3(x1,y1,z1)) ti(tab,vec3(x,y,z)) ti(tab,vec3(x2,y2,z2))
ti(tab,vec3(x2,y2,z2)) ti(tab,vec3(x,y,z)) ti(tab,vec3(x3,y3,z3))
end
end
local sph=mesh()
sph.vertices=tab
sph.shader=shader(SDV,SDF)
sph.shader.far=FAR
sph.dim=vec3(0,0,0)
sph.sphere=1 sph.radius=r*4 sph.pos=pos*4
return sph
end
function Create:Box(p,pp)
local y=2
v={
vec3(p.x,p.y+pp.y,p.z),vec3(p.x,p.y+pp.y,p.z+pp.z),vec3(p.x+pp.x,p.y+pp.y,p.z+pp.z),
vec3(p.x+pp.x,p.y+pp.y,p.z+pp.z),vec3(p.x+pp.x,p.y+pp.y,p.z),vec3(p.x,p.y+pp.y,p.z),
vec3(p.x,p.y,p.z),vec3(p.x+pp.x,p.y,p.z+pp.z),vec3(p.x,p.y,p.z+pp.z),
vec3(p.x+pp.x,p.y,p.z+pp.z),vec3(p.x,p.y,p.z),vec3(p.x+pp.x,p.y,p.z),
vec3(p.x,p.y,p.z),vec3(p.x,p.y+pp.y,p.z),vec3(p.x+pp.x,p.y+pp.y,p.z),
vec3(p.x+pp.x,p.y+pp.y,p.z),vec3(p.x+pp.x,p.y,p.z),vec3(p.x,p.y,p.z),
vec3(p.x,p.y,p.z+pp.z),vec3(p.x+pp.x,p.y,p.z+pp.z),vec3(p.x+pp.x,p.y+pp.y,p.z+pp.z),
vec3(p.x+pp.x,p.y+pp.y,p.z+pp.z),vec3(p.x,p.y+pp.y,p.z+pp.z),vec3(p.x,p.y,p.z+pp.z),
vec3(p.x,p.y,p.z),vec3(p.x,p.y,p.z+pp.z),vec3(p.x,p.y+pp.y,p.z+pp.z),
vec3(p.x,p.y+pp.y,p.z+pp.z),vec3(p.x,p.y+pp.y,p.z),vec3(p.x,p.y,p.z),
vec3(p.x+pp.x,p.y,p.z),vec3(p.x+pp.x,p.y+pp.y,p.z),vec3(p.x+pp.x,p.y+pp.y,p.z+pp.z),
vec3(p.x+pp.x,p.y+pp.y,p.z+pp.z),vec3(p.x+pp.x,p.y,p.z+pp.z),vec3(p.x+pp.x,p.y,p.z)}
tex={
vec2(0,0),vec2(1,0),vec2(1,y),vec2(1,1),vec2(0,1),vec2(0,0),
vec2(0,0),vec2(1,1),vec2(1,0),vec2(1,1),vec2(0,0),vec2(0,1),
vec2(0,0),vec2(0,y),vec2(1,y),vec2(1,y),vec2(1,0),vec2(0,0),
vec2(0,0),vec2(1,0),vec2(1,y),vec2(1,y),vec2(0,y),vec2(0,0),
vec2(0,0),vec2(1,0),vec2(1,y),vec2(1,y),vec2(0,y),vec2(0,0),
vec2(0,0),vec2(0,y),vec2(1,y),vec2(1,y),vec2(1,0),vec2(0,0)}
local m=mesh()
m.vertices=v
m.texCoords=tex
--Shader
m.shader=shader(SDV,SDF)
m.shader.far=FAR
return m
end
--# Lego
Lego=class()
function Lego:block(p,pp,col,plupp)
col=col or color(255,255,255,255)
m=mesh()
verts={Create:Box(vec3(p.x,p.y*0.25,p.z)+vec3(0.01,0.01,0.01),vec3(pp.x,pp.y*0.25,pp.z)-vec3(0.02,0.02,0.02)).vertices}
--verts={Create:Box(vec3(p.x,p.y*0.25,p.z),vec3(pp.x,pp.y*0.25,pp.z)).vertices}
--[[
if plupp==nil then
for x=0,pp.x-1 do
for z=0,pp.z-1 do
table.insert(verts,Create:Cyl(vec3(p.x+x+0.5,p.y*0.25+pp.y*0.25-0.02,p.z+z+0.5),0.3,0.2,20,1,1).vertices)
table.insert(verts,Create:Cyl(vec3(p.x+x+0.5,p.y*0.25+pp.y*0.25+0.2-0.02,p.z+z+0.5),0.3,0,20,0,1).vertices)
end
end
end --]]
m.vertices=sm(verts)
m.dim=vec3(pp.x*4,pp.y,pp.z*4) m.pos=vec3(p.x*4,p.y,p.z*4) m.col=color(col.x,col.y,col.z,col.w) m.plupp=plupp
m.shader=shader(SDV,SDF)
m.shader.far=FAR
return m
end
--# Voxel
Voxel=class()
--/////FIXA
--Upsample 1/2|1/3|1/4 upplösning
--/////Lägga till
--Fixed cone directions 360 grader. Använd endast om inom hemisfär
--Lagra far-delen för koner genom att trace från voxeln och lagra
--Desamma för anisotropic texture-lookup
--SDF för enklare voxelisering/oändlig detalj/re(fra/fle)ktioner/mindre minne/kollisioner med roterade objekt
--/////Optimeringar
--Pos och Dir är i texture-Space
--Voxelisering constant/dynamic
--Skippa onödiga ljus-kalkylationer med ljus-volymer
function Voxel:initialize(res)
self.RES=res
self.IRES=vec3(1/res.x,1/res.y,1/res.z) self.HIR=vec2(1/(res.x*res.z),self.IRES.y/6)
self.light=image((res.x*res.z)*0.5,res.y*0.5*6)
self.colors=image(self.light.width,res.y*0.5)
--MipMaps
self.mipmap={image(self.light.width/4,self.light.height/2),
image(self.light.width/16,self.light.height/4),
image(self.light.width/64,self.light.height/8)}
self.mpBT={{vec4(self.IRES.z,0,0,self.HIR.y),vec4(self.IRES.z,0,self.HIR.x,0),vec4(self.HIR.x,0,0,self.HIR.y)},
{vec4(self.IRES.z*2,0,0,self.HIR.y*2),vec4(self.IRES.z*2,0,self.HIR.x*2,0),vec4(self.HIR.x*2,0,0,self.HIR.y*2)}
,{vec4(self.IRES.z*4,0,0,self.HIR.y*4),vec4(self.IRES.z*4,0,self.HIR.x*4,0),vec4(self.HIR.x*4,0,0,self.HIR.y*4)}}
self.mpOF={{
vec4(-self.HIR.x,0,self.HIR.x*0.5,-self.HIR.y*0.5),vec4(self.HIR.x,0,-self.HIR.x*0.5,-self.HIR.y*0.5),
vec4(0,-self.HIR.y,-self.HIR.x*0.5,self.HIR.y*0.5),vec4(0,self.HIR.y,-self.HIR.x*0.5,-self.HIR.y*0.5),
vec4(-self.IRES.z,0,self.IRES.z-self.HIR.x*0.5,-self.HIR.y*0.5),vec4(self.IRES.z,0,-self.HIR.x*0.5,-self.HIR.y*0.5)},
{
vec4(-self.HIR.x*2,0,self.HIR.x,-self.HIR.y),vec4(self.HIR.x*2,0,-self.HIR.x,-self.HIR.y),
vec4(0,-self.HIR.y*2,-self.HIR.x,self.HIR.y),vec4(0,self.HIR.y*2,-self.HIR.x,-self.HIR.y),
vec4(-self.IRES.z*2,0,self.IRES.z*2-self.HIR.x,-self.HIR.y),vec4(self.IRES.z*2,0,-self.HIR.x,-self.HIR.y)}
,{
vec4(-self.HIR.x*4,0,self.HIR.x*2,-self.HIR.y*2),vec4(self.HIR.x*4,0,-self.HIR.x*2,-self.HIR.y*2),
vec4(0,-self.HIR.y*4,-self.HIR.x*2,self.HIR.y*2),vec4(0,self.HIR.y*4,-self.HIR.x*2,-self.HIR.y*2),
vec4(-self.IRES.z*4,0,self.IRES.z*4-self.HIR.x*2,-self.HIR.y*2),vec4(self.IRES.z*4,0,-self.HIR.x*2,-self.HIR.y*2)}}
--Mesh INJECT LIGHT
self.IL=mesh()
self.IL.vertices={vec2(0,0),vec2(self.light.width,0),vec2(self.light.width,self.light.height),
vec2(self.light.width,self.light.height),vec2(0,self.light.height),vec2(0,0)}
self.IL.texCoords={vec2(0,0),vec2(1,0),vec2(1,1),vec2(1,1),vec2(0,1),vec2(0,0)}
self.IL.shader=shader(SILV,SILF)
self.IL.shader.GI=self.RES
self.IL.shader.IGI=self.IRES
self.IL.shader.normals={vec3(1,0,0),vec3(-1,0,0),vec3(0,1,0),vec3(0,-1,0),vec3(0,0,1),vec3(0,0,-1)}
--Mesh MIPMAP
self.MIP=mesh()
self.MIP.vertices={vec2(0,0),vec2(1,0),vec2(1,1),vec2(1,1),vec2(0,1),vec2(0,0)}
self.MIP.texCoords={vec2(0,0),vec2(1,0),vec2(1,1),vec2(1,1),vec2(0,1),vec2(0,0)}
self.MIP.shader=shader(SMIPV,SMIPF)
--First bounce
self.FB=mesh()
self.FB.vertices={vec2(0,0),vec2(self.light.width,0),vec2(self.light.width,self.light.height),
vec2(self.light.width,self.light.height),vec2(0,self.light.height),vec2(0,0)}
self.FB.texCoords={vec2(0,0),vec2(1,0),vec2(1,1),vec2(1,1),vec2(0,1),vec2(0,0)}
self.FB.shader=shader(SSBV,SSBF)
self.FB.shader.normals={vec3(1,0,0),vec3(-1,0,0),vec3(0,1,0),vec3(0,-1,0),vec3(0,0,1),vec3(0,0,-1)}
self.FB.shader.tangents={vec3(0,0,1),vec3(0,0,1),vec3(1,0,0),vec3(1,0,0),vec3(1,0,0),vec3(1,0,0)}
self.FB.shader.binormals={vec3(0,1,0),vec3(0,1,0),vec3(0,0,1),vec3(0,0,1),vec3(0,1,0),vec3(0,1,0)}
self.FB.shader.FAR=vec4(math.tan(math.rad(70/2)),RES.x/RES.y,RES.x*4,RES.y*2)
self.FB.shader.GI=self.RES
self.FB.shader.IGI=self.IRES
end
function Voxel:Voxelize(s)
collectgarbage()
setContext(self.colors) background(255,255,255,0) setContext()
setContext(self.light) background(0,0,0,0) setContext()
for i=1,#s do
m=s[i]
if m.dim~=nil then
for x=1,m.dim.x do
XX=m.pos.x+x
for z=1,m.dim.z do
ZZ=m.pos.z*self.RES.x+(z-1)*self.RES.x
for y=1,m.dim.y do
--if math.random(1,10)>9 then mcol=color(m.col.r,m.col.g,m.col.b,250) else mcol=m.col end
self.colors:rawSet(ZZ+XX,m.pos.y+y,m.col)
end
end
end
end
if m.sphere~=nil then
for x=-m.radius+1,m.radius do
for z=-m.radius+1,m.radius do
for y=-m.radius+1,m.radius do
--if (vec3(x,y,z)):len()<m.radius+0.25 then
self.colors:rawSet(floor(m.pos.x+x+m.pos.z*self.RES.x+(z-1)*self.RES.x),m.pos.y+y,color(255,252))
--end
end
end
end
end
--[[
if m.plupp==nil then
for x=1,m.dim.x/4 do
XX=m.pos.x*4+(x-1)*4+1
for z=1,m.dim.z/4 do
ZZ=m.pos.z*4*self.RES.z+(z-1)*4*self.RES.z+self.RES.z
vt=vec2(XX+ZZ,m.pos.y+m.dim.y+1)
self.colors:rawSet(vt.x+1,vt.y,m.col) self.colors:rawSet(vt.x+2,vt.y,m.col)
self.colors:rawSet(vt.x+1+self.RES.z,vt.y,m.col) self.colors:rawSet(vt.x+2+self.RES.z,vt.y,m.col)
--Alpha weighted
--self.colors:rawSet(vt.x,vt.y,m.col) self.colors:rawSet(vt.x+self.RES.z,vt.y,m.col)
--self.colors:rawSet(vt.x+3,vt.y,m.col) self.colors:rawSet(vt.x+3+self.RES.z,vt.y,m.col)
--self.colors:rawSet(vt.x-self.RES.z+1,vt.y,m.col) self.colors:rawSet(vt.x-self.RES.z+2,vt.y,m.col)
--self.colors:rawSet(vt.x+self.RES.z*2+1,vt.y,m.col) self.colors:rawSet(vt.x+self.RES.z*2+2,vt.y,m.col)
end
end
end--]]
end
end
function Voxel:InjectLight()
resetMatrix()
ortho()
viewMatrix(matrix())
setContext(self.light)
background(0, 0, 0, 0)
if FirstBounce then
self.IL.shader.colors=self.colors
self.IL.shader.lp=Light.SLights[1][1]
self.IL.shader.lr=Light.SLights[1][2]
self.IL.shader.lc=Light.SLights[1][3]
self.IL.shader.ld=Light.SLights[1][4]
self.IL.shader.spot=Light.SLights[1][5]
self.IL.shader.lmat=Light.Shadows[1][2]
self.IL.shader.shadow=Light.Shadows[1][1]
self.IL:draw()
end
setContext()
setContext(self.mipmap[1])
background(0, 0, 0, 0)
scale(self.mipmap[1].width,self.mipmap[1].height)
self.MIP.shader.vlight=self.light
self.MIP.shader.vg=self.mpBT[1]
self.MIP.shader.vgoffset=self.mpOF[1]
self.MIP.shader.GI=self.RES/2
self.MIP.shader.IGI=self.IRES*2
self.MIP:draw()
setContext()
resetMatrix()
setContext(self.mipmap[2])
background(0, 0, 0, 0)
scale(self.mipmap[2].width,self.mipmap[2].height)
self.MIP.shader.vlight=self.mipmap[1]
self.MIP.shader.vg=self.mpBT[2]
self.MIP.shader.vgoffset=self.mpOF[2]
self.MIP.shader.GI=self.RES/4
self.MIP.shader.IGI=self.IRES*4
self.MIP:draw()
setContext()
resetMatrix()
setContext(self.mipmap[3])
background(0, 0, 0, 0)
scale(self.mipmap[3].width,self.mipmap[3].height)
self.MIP.shader.vlight=self.mipmap[2]
self.MIP.shader.vg=self.mpBT[3]
self.MIP.shader.vgoffset=self.mpOF[3]
self.MIP.shader.GI=self.RES/8
self.MIP.shader.IGI=self.IRES*8
self.MIP:draw()
setContext()
resetMatrix()
if SecondBounce then
self.FB.shader.vlight=self.light
smooth()
setContext(self.light)
--background(0, 0, 0, 0)
self.FB.shader.vcol=self.colors
self.FB.shader.vmipmap1=self.mipmap[1]
self.FB.shader.vmipmap2=self.mipmap[2]
self.FB.shader.vmipmap3=self.mipmap[3]
self.FB:draw()
setContext()
noSmooth()
setContext(self.mipmap[1])
background(0, 0, 0, 0)
scale(self.mipmap[1].width,self.mipmap[1].height)
self.MIP.shader.vlight=self.light
self.MIP.shader.vg=self.mpBT[1]
self.MIP.shader.vgoffset=self.mpOF[1]
self.MIP.shader.GI=self.RES/2
self.MIP.shader.IGI=self.IRES*2
self.MIP:draw()
setContext()
resetMatrix()
setContext(self.mipmap[2])
background(0, 0, 0, 0)
scale(self.mipmap[2].width,self.mipmap[2].height)
self.MIP.shader.vlight=self.mipmap[1]
self.MIP.shader.vg=self.mpBT[2]
self.MIP.shader.vgoffset=self.mpOF[2]
self.MIP.shader.GI=self.RES/4
self.MIP.shader.IGI=self.IRES*4
self.MIP:draw()
setContext()
resetMatrix()
setContext(self.mipmap[3])
background(0, 0, 0, 0)
scale(self.mipmap[3].width,self.mipmap[3].height)
self.MIP.shader.vlight=self.mipmap[2]
self.MIP.shader.vg=self.mpBT[3]
self.MIP.shader.vgoffset=self.mpOF[3]
self.MIP.shader.GI=self.RES/8
self.MIP.shader.IGI=self.IRES*8
self.MIP:draw()
setContext()
resetMatrix()
end
end
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化