Textured Raycaster [Multiple Levels! Door Covers! Jumping!]

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
Nixola
Inner party member
Posts: 1949
Joined: Tue Dec 06, 2011 7:11 pm
Location: Italy

Re: Textured Raycaster [Multiple Levels! Door Covers! Jumping!]

Post by Nixola »

Does the library use any canvas? Iirc they're cleared on setMode.
lf = love.filesystem
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Textured Raycaster [Multiple Levels! Door Covers! Jumping!]

Post by Jasoco »

No, it doesn't use canvases out of the box. And even if it did, canvases can be recreated. This library however will stop working completely as soon as setMode is called and will not work again even if required again. Believe me, I've tried.

I'm sure there's something that can be done.

Here's my modified version, comments and all:

Code: Select all

--By xXxMoNkEyMaNxXx
--[[Complete API----  This was made to be a module, PLEASE USE IT AS A MODULE

	.cw=false
	-Counter clockwise vertex order starting at top left.

	.cw=true
	-Clockwise vertex order starting at top left.


	.preload(loadup):

	-loadup==true sets pixel effect to polygon texturer,
	-loadup==false clears any pixel effect.
	*NOTE: preload(false) must be done to draw blank polygons after textured ones.


	.setRepeat(origin,size):
	-Makes the image repeat every 'size' starting at 'origin'.
	-The default is origin={0,0},size={1,1}.


	.quad(image,v1,v2,v3,v4) - Draws a polygon.

	-if 'image' is nil, the function will prepare to make it blank.


	.quad(v1,v2,v3,v4) - draws a polygon with no image.


	.fast(image,v1,v2,v3,v4) - draws a polygon with 'image' on it.
	-slightly(!!!) faster than quad.
	-Must include an image.
	-Must call .preload(true) beforehand.


	Info:
	Vertices are in the form {x,y}.
	Vertices go clockwise from the top left.

	v1---v2
	| img |
	v4---v3
--]]

--Modified by RogueCarrot
local glsl=love.graphics.newShader[[
//Made by xXxMoNkEyMaNxXx

extern Image img;
extern Image img2;
extern vec2 v1;
extern vec2 v2;
extern vec2 v3;
extern vec2 v4;

extern vec2 p0;
extern vec2 rep;

//extern number SIZEY;//So annoying
extern number SIZEX;//So annoying
//extern number dim;
extern vec4 tint;

vec2 one=vec2(1.0,1.0);

number c(vec2 v1,vec2 v2)
{
	return v1.x*v2.y-v2.x*v1.y;
}
number intersect(vec2 v1,vec2 d1,vec2 v2,vec2 d2)
{
	//v1+d1*
	return c(v2-v1,d2)/c(d1,d2);
}
vec4 mask(vec4 base,vec4 over)
{
	return vec4(over.rgb*over.a+base.rgb*(1-over.a),over.a+base.a*(1-over.a));
}
vec4 effect(vec4 colour,Image UNUSED1,vec2 texture_coords,vec2 inverted)
{
	vec2 p=vec2(inverted.x*SIZEX,inverted.y);//SO ANNOYING

	vec2 A1=normalize(v2-v1);
	vec2 A2=normalize(v3-v4);

	vec2 B1=normalize(v2-v3);
	vec2 B2=normalize(v1-v4);

	number Adiv=c(A1,A2);
	number Bdiv=c(B1,B2);

	vec2 uv;

	bvec2 eq0=bvec2(abs(Adiv)<=0.0001,abs(Bdiv)<=0.0001);
	if(eq0.x && eq0.y){
		//Both edges are parallel, therefore the shape is a parallelogram (Isometric)
		number dis=dot(p-v1,A1);

		//cos theta
		number ct=dot(A1,B1);

		//Closest point on v1->A1 to p
		vec2 pA=v1+A1*dis;

		//uv
		number r=length(p-pA)/sqrt(1-ct*ct);
		uv=vec2(1-r/length(v2-v3),(dis+r*ct)/length(v2-v1));
	}else if(eq0.x){
		//One Vanishing point occurs in numerically set scenarios in 3D, and is a feature of 2.5D

		//Horizon is A1 (=A2) from B
		vec2 Vp=v3+B1*c(v4-v3,B2)/Bdiv;

		//Some point in the distance that diagonals go to
		vec2 D=Vp+A1*intersect(Vp,A1,v4,normalize(v2-v4));

		//uv
		number u=intersect(v1,A1,Vp,normalize(p-Vp));
		number v=intersect(v1,A1,D,normalize(p-D))-u;

		number len=length(v2-v1);
		uv=vec2(len-v,u)/len;//Reversed components to match up with other one
	}else if(eq0.y){
		//If the other edge is the parallel one
		vec2 Vp=v1+A1*c(v4-v1,A2)/Adiv;
		vec2 D=Vp+B1*intersect(Vp,B1,v4,normalize(v2-v4));
		number u=intersect(v3,B1,Vp,normalize(p-Vp));
		number len=length(v2-v3);
		uv=vec2(u,len-intersect(v3,B1,D,normalize(p-D))+u)/len;
	}else{
		//Else, two vanishing points

		//*intersect(v1,A1,v4,A2)
		//*intersect(v3,B1,v4,B2)

		//Vanishing points
		vec2 A=v1+A1*c(v4-v1,A2)/Adiv;
		vec2 B=v3+B1*c(v4-v3,B2)/Bdiv;

		//Horizon
		vec2 H=normalize(A-B);

		//Pixel
		uv=vec2(intersect(v4,-H,A,normalize(p-A))/intersect(v4,-H,v2,-A1),intersect(v4,H,B,normalize(p-B))/intersect(v4,H,v2,-B1));
	}
	vec4 tex2 = Texel(img,mod(uv*rep+vec2(p0.x-1,p0.y),one));
	vec4 tex3 = Texel(img2,one);
	vec4 tint2 = tint;

	if (tex2.r * 255 == 911) {
		tex2.r = 1;
		tex2.g = 1;
		tex2.b = 0;
	} else {
		vec4 diff;
		diff[0] = (tint2[0] - tex2.r) * tex3.a;
		diff[1] = (tint2[1] - tex2.g) * tex3.a;
		diff[2] = (tint2[2] - tex2.b) * tex3.a;

		tex2.r = tex2.r + diff[0] * tint2[3];
		tex2.g = tex2.g + diff[1] * tint2[3];
		tex2.b = tex2.b + diff[2] * tint2[3];
	}

	return mask(colour,tex2);
}
]]
local gl_send=glsl.send
local q=love.graphics.polygon
local win = love.window
local lgr = love.graphics
local tmr = love.timer
local setEffect=love.graphics.setShader
local print = print
gl_send(glsl,"SIZEX",1)--So annoying
-- gl_send(glsl,"SIZEY",love.graphics.getHeight())--So annoying
gl_send(glsl,"p0",{0,0})
gl_send(glsl,"rep",{1,1})

module(...)
local cw=true--clockwise
function preload(loadup)
	if loadup then
		setEffect(glsl)
	else
		setEffect()
	end
end
function setRepeat(origin,size)
	gl_send(glsl,"p0",origin)
	gl_send(glsl,"rep",size)
end
-- function fast(img,v1,v2,v3,v4)
-- 	gl_send(glsl,"img",img)
-- 	gl_send(glsl,"v1",v2)
-- 	gl_send(glsl,"v2",v3)
-- 	gl_send(glsl,"v3",v4)
-- 	gl_send(glsl,"v4",v1)
-- 	q("fill",v1[1],v1[2],v2[1],v2[2],v3[1],v3[2],v4[1],v4[2])
-- end
function quad(img,v1,v2,v3,v4,w,h,tint,can)
	local dim = dim or 1.0
	local tint = tint or {1,1,1,0}
	-- if h then gl_send(glsl,"SIZEY",h) end
	if w then gl_send(glsl,"SIZEX",w/lgr.getWidth()) end
	if img then
		setEffect(glsl)
		if can then gl_send(glsl,"img2", can) end
		gl_send(glsl,"img", img)
		gl_send(glsl,"tint", tint)
		gl_send(glsl,"v1",v2)
		gl_send(glsl,"v2",v3)
		gl_send(glsl,"v3",v4)
		gl_send(glsl,"v4",v1)
	end
	lgr.push()
	-- lgr.translate(0, lgr.getHeight() / 2)
	-- lgr.scale(1,-1)
	-- lgr.translate(0, -(lgr.getHeight() / 2))
	q("fill",v1[1],v1[2],v2[1],v2[2],v3[1],v3[2],v4[1],v4[2])
	lgr.pop()
	setEffect()
end
And here's the version from this project, as-is, comments and all:

Code: Select all

--By xXxMoNkEyMaNxXx
--[[Complete API----  This was made to be a module, PLEASE USE IT AS A MODULE

	.cw=false
	-Counter clockwise vertex order starting at top left.

	.cw=true
	-Clockwise vertex order starting at top left.


	.preload(loadup):

	-loadup==true sets pixel effect to polygon texturer,
	-loadup==false clears any pixel effect.
	*NOTE: preload(false) must be done to draw blank polygons after textured ones.


	.setRepeat(origin,size):
	-Makes the image repeat every 'size' starting at 'origin'.
	-The default is origin={0,0},size={1,1}.


	.quad(image,v1,v2,v3,v4) - Draws a polygon.

	-if 'image' is nil, the function will prepare to make it blank.


	.quad(v1,v2,v3,v4) - draws a polygon with no image.


	.fast(image,v1,v2,v3,v4) - draws a polygon with 'image' on it.
	-slightly(!!!) faster than quad.
	-Must include an image.
	-Must call .preload(true) beforehand.


	Info:
	Vertices are in the form {x,y}.
	Vertices go clockwise from the top left.

	v1---v2
	| img |
	v4---v3
--]]
local glsl=love.graphics.newShader[[
//Made by xXxMoNkEyMaNxXx

extern Image img;
extern vec2 v1;
extern vec2 v2;
extern vec2 v3;
extern vec2 v4;

extern vec2 p0;
extern vec2 rep;

vec2 one=vec2(1.0,1.0);

number c(vec2 v1,vec2 v2)
{
	return v1.x*v2.y-v2.x*v1.y;
}
number intersect(vec2 v1,vec2 d1,vec2 v2,vec2 d2)
{
	//v1+d1*
	return c(v2-v1,d2)/c(d1,d2);
}
vec4 mask(vec4 base,vec4 over)
{
	return vec4(over.rgb*over.a+base.rgb*(1-over.a),over.a+base.a*(1-over.a));
}
vec4 effect(vec4 colour,Image UNUSED1,vec2 UNUSED2,vec2 inverted)
{
	vec2 p=vec2(inverted.x,inverted.y);

	vec2 A1=normalize(v2-v1);
	vec2 A2=normalize(v3-v4);

	vec2 B1=normalize(v2-v3);
	vec2 B2=normalize(v1-v4);

	number Adiv=c(A1,A2);
	number Bdiv=c(B1,B2);

	vec2 uv;

	bvec2 eq0=bvec2(abs(Adiv)<=0.0001,abs(Bdiv)<=0.0001);
	if(eq0.x && eq0.y){
		//Both edges are parallel, therefore the shape is a parallelogram (Isometric)
		number dis=dot(p-v1,A1);

		//cos theta
		number ct=dot(A1,B1);

		//Closest point on v1->A1 to p
		vec2 pA=v1+A1*dis;

		//uv
		number r=length(p-pA)/sqrt(1-ct*ct);
		uv=vec2(1-r/length(v2-v3),(dis+r*ct)/length(v2-v1));
	}else if(eq0.x){
		//One Vanishing point occurs in numerically set scenarios in 3D, and is a feature of 2.5D

		//Horizon is A1 (=A2) from B
		vec2 Vp=v3+B1*c(v4-v3,B2)/Bdiv;

		//Some point in the distance that diagonals go to
		vec2 D=Vp+A1*intersect(Vp,A1,v4,normalize(v2-v4));

		//uv
		number u=intersect(v1,A1,Vp,normalize(p-Vp));
		number v=intersect(v1,A1,D,normalize(p-D))-u;

		number len=length(v2-v1);
		uv=vec2(len-v,u)/len;//Reversed components to match up with other one
	}else if(eq0.y){
		//If the other edge is the parallel one
		vec2 Vp=v1+A1*c(v4-v1,A2)/Adiv;
		vec2 D=Vp+B1*intersect(Vp,B1,v4,normalize(v2-v4));
		number u=intersect(v3,B1,Vp,normalize(p-Vp));
		number len=length(v2-v3);
		uv=vec2(u,len-intersect(v3,B1,D,normalize(p-D))+u)/len;
	}else{
		//Else, two vanishing points

		//*intersect(v1,A1,v4,A2)
		//*intersect(v3,B1,v4,B2)

		//Vanishing points
		vec2 A=v1+A1*c(v4-v1,A2)/Adiv;
		vec2 B=v3+B1*c(v4-v3,B2)/Bdiv;

		//Horizon
		vec2 H=normalize(A-B);

		//Pixel
		uv=vec2(intersect(v4,-H,A,normalize(p-A))/intersect(v4,-H,v2,-A1),intersect(v4,H,B,normalize(p-B))/intersect(v4,H,v2,-B1));
	}

	return mask(colour,Texel(img,mod(uv*rep+vec2(p0.x-1,p0.y),one)));
}
]]
local gl_send=glsl.send
local q=love.graphics.polygon
-- local lgr = love.graphics
local setEffect=love.graphics.setShader
gl_send(glsl,"p0",{0,0})
gl_send(glsl,"rep",{1,1})

module(...)
cw=true--clockwise
function preload(loadup)
	if loadup then
		setEffect(glsl)
	else
		setEffect()
	end
end
function setRepeat(origin,size)
	gl_send(glsl,"p0",origin)
	gl_send(glsl,"rep",size)
end
function fast(img,v1,v2,v3,v4)
	gl_send(glsl,"img",img)
	gl_send(glsl,"v1",v2)
	gl_send(glsl,"v2",v3)
	gl_send(glsl,"v3",v4)
	gl_send(glsl,"v4",v1)
	q("fill",v1[1],v1[2],v2[1],v2[2],v3[1],v3[2],v4[1],v4[2])
end
function quad(img,v1,v2,v3,v4,h)
	if h then gl_send(glsl,"SIZEY",h) end
	if img and v4 then
		setEffect(glsl)
		gl_send(glsl,"img",img)
		if cw then
			gl_send(glsl,"v1",v2)
			gl_send(glsl,"v2",v3)
			gl_send(glsl,"v3",v4)
			gl_send(glsl,"v4",v1)
		else
			gl_send(glsl,"v1",v2)
			gl_send(glsl,"v2",v1)
			gl_send(glsl,"v3",v4)
			gl_send(glsl,"v4",v3)
		end
	else
		setEffect()
	end
	-- lgr.setBlendMode("premultiplied")
	if v4 then
		q("fill",v1[1],v1[2],v2[1],v2[2],v3[1],v3[2],v4[1],v4[2])
	else--img acts as a vertex
		q("fill",img[1],img[2],v1[1],v1[2],v2[1],v2[2],v3[1],v3[2])
	end
	-- lgr.setBlendMode("alpha")
	setEffect()
end
They're different because they were based on the same library, but we went different directions. Mine includes a "colorization" feature for fog and darkness or ambient lighting. (Since I was originally using it for my older 3D rail shooter projects and such.)
User avatar
Davidobot
Party member
Posts: 1226
Joined: Sat Mar 31, 2012 5:18 am
Location: Oxford, UK
Contact:

Re: Textured Raycaster [Multiple Levels! Door Covers! Jumping!]

Post by Davidobot »

Jasoco wrote: Wed Mar 29, 2017 10:01 pmThe problem I'm talking about here is a completely unrelated one related to setMode. Really I should put this in a new thread. But I'll instead work on trying to rewrite the library and post a thread if I can't fix it. Maybe it's a bug. Since it doesn't seem to affect any other shaders, I don't know why it affects this one specifically.

Maybe David and I can look into it together. He seems really good at bettering me anyway. Haha.
The setMode bug is very annoying. Although, I do have a version of pers.lua that does begin working again after being re-required. It's not ideal, but it works. I'm currently on a cycling trip, so I'll manage to fish the code out in around 10 hours.

I am currently also looking into rewriting the library. Look forward to working with you. :awesome:
PM me on here or elsewhere if you'd like to discuss porting your game to Nintendo Switch via mazette!
personal page and a raycaster
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Textured Raycaster [Multiple Levels! Door Covers! Jumping!]

Post by Jasoco »

Davidobot wrote: Thu Mar 30, 2017 7:04 am The setMode bug is very annoying. Although, I do have a version of pers.lua that does begin working again after being re-required. It's not ideal, but it works. I'm currently on a cycling trip, so I'll manage to fish the code out in around 10 hours.

I am currently also looking into rewriting the library. Look forward to working with you. :awesome:
Are you on Windows or Mac? How do you reload it to get it to work?
User avatar
Davidobot
Party member
Posts: 1226
Joined: Sat Mar 31, 2012 5:18 am
Location: Oxford, UK
Contact:

Re: Textured Raycaster [Multiple Levels! Door Covers! Jumping!]

Post by Davidobot »

Jasoco wrote: Thu Mar 30, 2017 2:38 pm Are you on Windows or Mac? How do you reload it to get it to work?
I'm on Windows. The problem with the thing not reloading has to do with the following part of the library:

Code: Select all

module(...)
So if you declare the pers thing as a table and all the functions as part of the table:

Code: Select all

--By xXxMoNkEyMaNxXx
--[[Complete API----  This was made to be a module, PLEASE USE IT AS A MODULE

   .cw=false
   -Counter clockwise vertex order starting at top left.

   .cw=true
   -Clockwise vertex order starting at top left.


   .preload(loadup):

   -loadup==true sets pixel effect to polygon texturer,
   -loadup==false clears any pixel effect.
   *NOTE: preload(false) must be done to draw blank polygons after textured ones.


   .setRepeat(origin,size):
   -Makes the image repeat every 'size' starting at 'origin'.
   -The default is origin={0,0},size={1,1}.


   .quad(image,v1,v2,v3,v4) - Draws a polygon.

   -if 'image' is nil, the function will prepare to make it blank.


   .quad(v1,v2,v3,v4) - draws a polygon with no image.


   .fast(image,v1,v2,v3,v4) - draws a polygon with 'image' on it.
   -slightly(!!!) faster than quad.
   -Must include an image.
   -Must call .preload(true) beforehand.


   Info:
   Vertices are in the form {x,y}.
   Vertices go clockwise from the top left.

   v1---v2
   | img |
   v4---v3
--]]
local glsl=love.graphics.newShader[[
//Made by xXxMoNkEyMaNxXx

extern Image img;
extern vec2 v1;
extern vec2 v2;
extern vec2 v3;
extern vec2 v4;

extern vec2 p0;
extern vec2 rep;

vec2 one=vec2(1.0,1.0);

number c(vec2 v1,vec2 v2)
{
   return v1.x*v2.y-v2.x*v1.y;
}
number intersect(vec2 v1,vec2 d1,vec2 v2,vec2 d2)
{
   //v1+d1*
   return c(v2-v1,d2)/c(d1,d2);
}
vec4 mask(vec4 base,vec4 over)
{
   return base * over;
}
vec4 effect(vec4 colour,Image UNUSED1,vec2 UNUSED2,vec2 inverted)
{
   vec2 p=vec2(inverted.x,inverted.y);

   vec2 A1=normalize(v2-v1);
   vec2 A2=normalize(v3-v4);

   vec2 B1=normalize(v2-v3);
   vec2 B2=normalize(v1-v4);

   number Adiv=c(A1,A2);
   number Bdiv=c(B1,B2);

   vec2 uv;

   bvec2 eq0=bvec2(abs(Adiv)<=0.0001,abs(Bdiv)<=0.0001);
   if(eq0.x && eq0.y){
      //Both edges are parallel, therefore the shape is a parallelogram (Isometric)
      number dis=dot(p-v1,A1);

      //cos theta
      number ct=dot(A1,B1);

      //Closest point on v1->A1 to p
      vec2 pA=v1+A1*dis;

      //uv
      number r=length(p-pA)/sqrt(1-ct*ct);
      uv=vec2(1-r/length(v2-v3),(dis+r*ct)/length(v2-v1));
   }else if(eq0.x){
      //One Vanishing point occurs in numerically set scenarios in 3D, and is a feature of 2.5D

      //Horizon is A1 (=A2) from B
      vec2 Vp=v3+B1*c(v4-v3,B2)/Bdiv;

      //Some point in the distance that diagonals go to
      vec2 D=Vp+A1*intersect(Vp,A1,v4,normalize(v2-v4));

      //uv
      number u=intersect(v1,A1,Vp,normalize(p-Vp));
      number v=intersect(v1,A1,D,normalize(p-D))-u;

      number len=length(v2-v1);
      uv=vec2(len-v,u)/len;//Reversed components to match up with other one
   }else if(eq0.y){
      //If the other edge is the parallel one
      vec2 Vp=v1+A1*c(v4-v1,A2)/Adiv;
      vec2 D=Vp+B1*intersect(Vp,B1,v4,normalize(v2-v4));
      number u=intersect(v3,B1,Vp,normalize(p-Vp));
      number len=length(v2-v3);
      uv=vec2(u,len-intersect(v3,B1,D,normalize(p-D))+u)/len;
   }else{
      //Else, two vanishing points

      //*intersect(v1,A1,v4,A2)
      //*intersect(v3,B1,v4,B2)

      //Vanishing points
      vec2 A=v1+A1*c(v4-v1,A2)/Adiv;
      vec2 B=v3+B1*c(v4-v3,B2)/Bdiv;

      //Horizon
      vec2 H=normalize(A-B);

      //Pixel
      uv=vec2(intersect(v4,-H,A,normalize(p-A))/intersect(v4,-H,v2,-A1),intersect(v4,H,B,normalize(p-B))/intersect(v4,H,v2,-B1));
   }

   return mask(colour,Texel(img,mod(uv*rep+vec2(p0.x-1,p0.y),one)));
}
]]
pers = {}
local gl_send=glsl.send
local q=love.graphics.polygon
-- local lgr = love.graphics
local setEffect=love.graphics.setShader
gl_send(glsl,"p0",{1,1})
gl_send(glsl,"rep",{1,1})

pers.cw=true -- Clockwise
pers.flip=false -- Flip the image
function pers.preload(loadup)
   if loadup then
      setEffect(glsl)
   else
      setEffect()
   end
end
function pers.setRepeat(origin,size)
   gl_send(glsl,"p0",origin)
   gl_send(glsl,"rep",size)
end
function pers.fast(img,v1,v2,v3,v4)
   gl_send(glsl,"img",img)
   gl_send(glsl,"v1",v2)
   gl_send(glsl,"v2",v3)
   gl_send(glsl,"v3",v4)
   gl_send(glsl,"v4",v1)
   q("fill",v1[1],v1[2],v2[1],v2[2],v3[1],v3[2],v4[1],v4[2])
end
function pers.quad(img,v1,v2,v3,v4,h)
   if h then gl_send(glsl,"SIZEY",h) end
   if img and v4 then
      setEffect(glsl)
      gl_send(glsl,"img",img)
      if pers.cw and not pers.flip then
         gl_send(glsl,"v1",v2)
         gl_send(glsl,"v2",v3)
         gl_send(glsl,"v3",v4)
         gl_send(glsl,"v4",v1)
      elseif pers.cw and pers.flip then
         gl_send(glsl,"v1",v1)
         gl_send(glsl,"v2",v4)
         gl_send(glsl,"v3",v3)
         gl_send(glsl,"v4",v2)
      else
         gl_send(glsl,"v1",v2)
         gl_send(glsl,"v2",v1)
         gl_send(glsl,"v3",v4)
         gl_send(glsl,"v4",v3)
      end
   else
      setEffect()
   end
   -- lgr.setBlendMode("premultiplied")
   if v4 then
      q("fill",v1[1],v1[2],v2[1],v2[2],v3[1],v3[2],v4[1],v4[2])
   else--img acts as a vertex
      q("fill",img[1],img[2],v1[1],v1[2],v2[1],v2[2],v3[1],v3[2])
   end
   -- lgr.setBlendMode("alpha")
   setEffect()
end
You can then re-require it by doing:

Code: Select all

love.filesystem.load("pers.lua")()
Also, I think xXxMoNkEyMaNxXx messed up the colour masking of the pixels. As you know, the shader does not take into account love.graphics.setColor. To fix this, replace the mask function of the pers.lua (as it is already done in my example) with:

Code: Select all

vec4 mask(vec4 base,vec4 over)
{
   return base * over;
}
Hope this helps!

EDIT:
Started experimenting with the playmat library. So much tinkering around. I think I might be getting somewhere, but I'm not sure.
Image

EDIT 2:
I remember running into very similar issues with projection when I was integrating your floor drawing quad library thing into mine. I should have a version of the my project with that code in there. I'll try to find it tomorrow and see if it helps.
Note to self: try drawing the floor canvas with the image size (32), not the expected size. Adjust player coordinates accordingly. Investigate exactly what "zoom" is in playmat. Could be that setting it to 32 and drawing image size as 32 will make things work.
Last edited by Davidobot on Thu Mar 30, 2017 10:33 pm, edited 2 times in total.
PM me on here or elsewhere if you'd like to discuss porting your game to Nintendo Switch via mazette!
personal page and a raycaster
Cruhan
Prole
Posts: 4
Joined: Sat Mar 18, 2017 3:45 pm

Re: Textured Raycaster [Multiple Levels! Door Covers! Jumping!]

Post by Cruhan »

woah, thx it works.

Also as I see this shader thing is really a hit and miss thing. Until we get a perspective correct texture mapping mesh draw this will be a recurring problem.
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Textured Raycaster [Multiple Levels! Door Covers! Jumping!]

Post by Jasoco »

If you can get Playmat working and compatible with the same variables we use (My eye height is more like .75 off the ground instead of .5 so it's not directly centered) it would probably speed things up quite a bit. So much less drawing, shader calling and calculating.
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Textured Raycaster [Multiple Levels! Door Covers! Jumping!]

Post by Jasoco »

Davidobot wrote: Thu Mar 30, 2017 4:21 pm
Jasoco wrote: Thu Mar 30, 2017 2:38 pm Are you on Windows or Mac? How do you reload it to get it to work?
I'm on Windows. The problem with the thing not reloading has to do with the following part of the library:

Code: Select all

module(...)
[/code]

EDIT:
Started experimenting with the playmat library. So much tinkering around. I think I might be getting somewhere, but I'm not sure.
Image

EDIT 2:
I remember running into very similar issues with projection when I was integrating your floor drawing quad library thing into mine. I should have a version of the my project with that code in there. I'll try to find it tomorrow and see if it helps.
Note to self: try drawing the floor canvas with the image size (32), not the expected size. Adjust player coordinates accordingly. Investigate exactly what "zoom" is in playmat. Could be that setting it to 32 and drawing image size as 32 will make things work.
I knew it was that module() line. That's why it needs to be rewritten.

If you can get Playmat working and compatible with the same variables we use (My eye height is more like .75 off the ground instead of .5 so it's not directly centered) it would probably speed things up quite a bit. So much less drawing, shader calling and calculating.
Cruhan wrote: Thu Mar 30, 2017 8:15 pm woah, thx it works.

Also as I see this shader thing is really a hit and miss thing. Until we get a perspective correct texture mapping mesh draw this will be a recurring problem.
I really don't want it to be meshes. They're too complicated. I'd much rather it be done in a simple extension of the polygon function. Something that accepts an image or an image/quad pair and a bunch of points and does what this does without the need for shaders.

Alternatively, fix meshes so they correct texture distortion properly instead of going all PlayStation on us if we have to use meshes.
User avatar
Davidobot
Party member
Posts: 1226
Joined: Sat Mar 31, 2012 5:18 am
Location: Oxford, UK
Contact:

Re: Textured Raycaster [Multiple Levels! Door Covers! Jumping!]

Post by Davidobot »

Jasoco wrote: Fri Mar 31, 2017 4:01 am ...
So after experimenting with playmat for around 5 hours today, I came to the conclusion that using playmat is not going to work out for raycasting. I believe this has to do with the difference in the method of projection between raycasting and mode7. So as a conclusion - I'm not going down that rabbit hole. I will, however, attempt to rewrite the polygon library.
PM me on here or elsewhere if you'd like to discuss porting your game to Nintendo Switch via mazette!
personal page and a raycaster
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Textured Raycaster [Multiple Levels! Door Covers! Jumping!]

Post by Jasoco »

Yeah, it looks way too complicated to get working perfectly. It's best for Mario Kart/F-Zero clones and stuff.

I suggest making sure the new one keeps my ability to "shade" the texture to a certain color. It's very useful for fog and darkness shading. Just go ahead and steal it from the code I posted above. If not, I'll just end up putting it back in anyway.

Basically you replace this one line at the end of the shader:

Code: Select all

 return mask(colour,Texel(img,mod(uv*rep+vec2(p0.x-1,p0.y),one)));
With this: (Edited to remove some weird code that didn't seem to do anything but make it look more complicated.)

Code: Select all

vec4 tex2 = Texel(img,mod(uv*rep+vec2(p0.x-1,p0.y),one));
vec4 tex3 = Texel(img2,one);

vec4 diff;
diff[0] = (tint[0] - tex2.r) * tex3.a;
diff[1] = (tint[1] - tex2.g) * tex3.a;
diff[2] = (tint[2] - tex2.b) * tex3.a;

tex2.r = tex2.r + diff[0] * tint[3];
tex2.g = tex2.g + diff[1] * tint[3];
tex2.b = tex2.b + diff[2] * tint[3];

return mask(colour,tex2);
And it will accept a vec4 with the RGB of the color you want to shade it and the alpha value will be the intensity. It's extremely useful. If I could, I'd change it to allow for four tint values for each corner and have it gradient between them like a mesh would. But that's way too complicated for my feeble "failed algebra in high school" brain. So this works fine for now.

A better solution would be if Löve gained this ability to "correct" texture warping built-into the mesh functions. Perhaps as a special mode. But I'd prefer a love.graphics.texturedPolygon() function instead.

Edit: Also note that I also modified my copy to allow for sending a different render resolution to allow for rendering to lower resolutions than the window resolution. So that would need to stay. Though I just tested it and maybe it's not needed anymore.

But there's also some code I put in that allows you to send a secondary image with alpha values that would be merged with the original image apparently? I don't even know. I've added so much code to make it fit my projects.
Post Reply

Who is online

Users browsing this forum: No registered users and 13 guests