bit-tech.net

Go Back   bit-tech.net Forums > Technology > Software

Reply
 
Thread Tools
Old 6th Jul 2006, 23:36   #1
NiHiLiST
New-born car whore
 
NiHiLiST's Avatar
 
Join Date: Aug 2001
Location: Manchester
Posts: 3,987
NiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run Crysis
PHP "raycaster" 3D renderer

I mentioned recently that I was looking for an interesting PHP project. This evening I remembered an idea I had a while ago to make a 3D renderer in PHP (and if anyone's tempted to ask - "because I can" ). I did a bit of reading on old 3D engines, as I didn't want something modern and slow, and found out that the "raycaster" rendering used in Wolfenstein 3D is ridiculously easy to implement. A few hours later and it's up and running I've not run any proper speed tests yet, but the images load up pretty much instantaneously. I have a couple of ideas of what this could be used for, so watch this space

Sample render:


Works off axis too of course:


And on the vertical:


The code is currently just over 300 lines long. It could be compressed down a lot (maybe even to half it's current size) just to show how stupidly simple things are with PHP. It will bulk out marginally once I get all of the functions in place for setting up the render size, camera position, angle, FOV etc as they are currently all just variables set in __construct. Even the map is just being randomly generated and thrown in.

Next real things to do will be to expand the texture mapping somewhat (at the moment it's just 1 for each of walls, floor and ceiling) and get it showing sprites. Then maybe HDR and anisotropic filtering
__________________
Flickr

Last edited by NiHiLiST; 6th Jul 2006 at 23:57.
NiHiLiST is offline   Reply With Quote
Old 6th Jul 2006, 23:57   #2
JazzXP
Eh! Steve
 
JazzXP's Avatar
 
Join Date: Apr 2002
Location: Melbourne - Australia
Posts: 1,485
JazzXP - it's over 9000!!!!!!!!1!1!1!!!JazzXP - it's over 9000!!!!!!!!1!1!1!!!JazzXP - it's over 9000!!!!!!!!1!1!1!!!JazzXP - it's over 9000!!!!!!!!1!1!1!!!JazzXP - it's over 9000!!!!!!!!1!1!1!!!JazzXP - it's over 9000!!!!!!!!1!1!1!!!JazzXP - it's over 9000!!!!!!!!1!1!1!!!JazzXP - it's over 9000!!!!!!!!1!1!1!!!JazzXP - it's over 9000!!!!!!!!1!1!1!!!JazzXP - it's over 9000!!!!!!!!1!1!1!!!JazzXP - it's over 9000!!!!!!!!1!1!1!!!
Wow, that's awesome. That could be used for some great stuff. 3d website, HTML based RPG, stuff like that!
__________________
-= JazzXP =-

There are three kinds of lies: Lies, damned lies, and benchmarks.

there is no such thing as "Fool-Proof" just "Idiot resistant" - Pflumingo
JazzXP is offline   Reply With Quote
Old 7th Jul 2006, 00:04   #3
hitman012
Super Moderator
Moderator
 
Join Date: May 2005
Location: London, UK
Posts: 4,877
hitman012 has yet to learn the way of the Dremelhitman012 has yet to learn the way of the Dremelhitman012 has yet to learn the way of the Dremel
Wow - very nice work! Reminds me of the 3D Maze screensaver that you used to get with Win95
__________________
"Nothing is more practical than a good theory"
- Kurt Lewin
hitman012 is offline   Reply With Quote
Old 7th Jul 2006, 00:05   #4
Nath
Your appeal has already been filed.
 
Nath's Avatar
 
Join Date: Dec 2003
Location: UK
Posts: 2,409
Nath has yet to learn the way of the Dremel
Awesome, can't wait to see what you get up to with this!
__________________
om nom nom nom
Nath is offline   Reply With Quote
Old 7th Jul 2006, 00:06   #5
NiHiLiST
New-born car whore
 
NiHiLiST's Avatar
 
Join Date: Aug 2001
Location: Manchester
Posts: 3,987
NiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run Crysis
Thanks, Jazz. I did consider it could be used to add some visual depth to those HTML-based RPG games. Would be pretty easy to do, but until I've run some load tests I couldn't say how it would affect the server, it might get pretty intensive if the site's getting a lot of hits.

One of the big overheads at the moment is that the textures have to be loaded from disk each time, and there are a lot of sin/cos/tan calculations. It's currently using lookup tables for those, but again, it's having to either generate or load those each time the script runs so some persistent memory or suchlike may need to be looked at

Of course if you wanted this kind of thing on a large site it would make more sense to just code the renderer in C or something and have your scripts execute the program when necessary. PHP's not bad for things like this, but it's far from being the fastest.
__________________
Flickr
NiHiLiST is offline   Reply With Quote
Old 7th Jul 2006, 00:08   #6
NiHiLiST
New-born car whore
 
NiHiLiST's Avatar
 
Join Date: Aug 2001
Location: Manchester
Posts: 3,987
NiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run Crysis
Eeee, 2 more replies whilst I was writing my last one Thanks hitman, Nath.
__________________
Flickr
NiHiLiST is offline   Reply With Quote
Old 7th Jul 2006, 00:18   #7
RTT
#parp
 
RTT's Avatar
 
Join Date: Mar 2001
Location: London
Posts: 14,022
RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.
Surely you're loading .dlls and just calling functions from within the DLL using PHP?

I'm not denying that it's cool - it is - but if i'm right then PHP isn't doing the fun stuff

Please tell me I'm 110% wrong!
RTT is offline   Reply With Quote
Old 7th Jul 2006, 00:21   #8
NiHiLiST
New-born car whore
 
NiHiLiST's Avatar
 
Join Date: Aug 2001
Location: Manchester
Posts: 3,987
NiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run Crysis
No I'm not, RTT, that would be silly The only thing I'm using is mathematical functions, binary operators and the GD library. No extensions, no DLLs, just classic software rendering.
__________________
Flickr
NiHiLiST is offline   Reply With Quote
Old 7th Jul 2006, 00:23   #9
RTT
#parp
 
RTT's Avatar
 
Join Date: Mar 2001
Location: London
Posts: 14,022
RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.
Cor blimey Color me impressed!
RTT is offline   Reply With Quote
Old 7th Jul 2006, 00:26   #10
NiHiLiST
New-born car whore
 
NiHiLiST's Avatar
 
Join Date: Aug 2001
Location: Manchester
Posts: 3,987
NiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run Crysis
Here are the functions used RTT :
require_once
mt_rand
sin
cos
tan
pi
sqrt
pow
imagecreatetruecolor
imagecreatefrompng
imagecopy
imagedestroy
imagepng
imagecolorat
imagesetpixel
header

Plus of course the functions in the class I've written.
__________________
Flickr

Last edited by NiHiLiST; 8th Jul 2006 at 18:34.
NiHiLiST is offline   Reply With Quote
Old 7th Jul 2006, 00:31   #11
RotoSequence
Lazy Lurker
 
RotoSequence's Avatar
 
Join Date: Jan 2004
Location: 'States
Posts: 4,588
RotoSequence has yet to learn the way of the Dremel
Add sprites!
__________________
Technology Schmecnology
RotoSequence is offline   Reply With Quote
Old 7th Jul 2006, 00:35   #12
NiHiLiST
New-born car whore
 
NiHiLiST's Avatar
 
Join Date: Aug 2001
Location: Manchester
Posts: 3,987
NiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run Crysis
Quote:
Originally Posted by RotoSequence
Add sprites!
Right now I'm going to bed, but maybe tonight (Friday) I'll get a chance to, if I'm not out pimping of course
__________________
Flickr
NiHiLiST is offline   Reply With Quote
Old 7th Jul 2006, 00:47   #13
RTT
#parp
 
RTT's Avatar
 
Join Date: Mar 2001
Location: London
Posts: 14,022
RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.RTT is the Cheesecake. Relix smiles down upon them.
Quote:
Originally Posted by NiHiLiST
Here are the functions used RTT :
...
require_once aint a function

Hehe... can't wait for updates on this. Some source wouldn't go amiss either /curious
RTT is offline   Reply With Quote
Old 7th Jul 2006, 07:36   #14
Fusen
Supermodder
 
Join Date: Jan 2004
Location: Kent Uni
Posts: 351
Fusen has yet to learn the way of the Dremel
some source and a demo would be awesome ;D
Fusen is offline   Reply With Quote
Old 7th Jul 2006, 10:42   #15
FredsFriend
Supermodder
 
FredsFriend's Avatar
 
Join Date: Jul 2005
Location: Peadobrough
Posts: 486
FredsFriend has yet to learn the way of the Dremel
This is teh funkey, seconded on the intrest ub the source it would be interesting to look through.
__________________
BOO
FredsFriend is offline   Reply With Quote
Old 8th Jul 2006, 16:38   #16
NiHiLiST
New-born car whore
 
NiHiLiST's Avatar
 
Join Date: Aug 2001
Location: Manchester
Posts: 3,987
NiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run Crysis
Quote:
Originally Posted by RTT
require_once aint a function

Hehe... can't wait for updates on this. Some source wouldn't go amiss either /curious
True, I was tired - functions and language constructs blur into one when it's bedtime
__________________
Flickr
NiHiLiST is offline   Reply With Quote
Old 8th Jul 2006, 18:28   #17
NiHiLiST
New-born car whore
 
NiHiLiST's Avatar
 
Join Date: Aug 2001
Location: Manchester
Posts: 3,987
NiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run CrysisNiHiLiST can run Crysis
Code for those who were asking:
PHP Code:
    public function render() {
        
        
// find which map block the camera is in
        
        
$cameraBlockX $this->camX >> 6;
        
$cameraBlockY $this->camY >> 6;

        
$offset 0;

        
// clamp angle for lookup tables

        
if ($this->camAngle 0)        $this->camAngle += pi() * 2;
        if (
$this->camAngle pi() * 2$this->camAngle -= pi() * 2;

        
$angle $this->camAngle $this->camFov 0.5;
        if (
$angle pi() * 2$angle -= pi() * 2;
        
        
$width $this->width;

        
$this->camPCentre $this->height $this->camRoll;
            
        
$ang = ($this->camAngle $this->divisor) | 0;
        
        
$invertZ 64 $this->camZ;

        
// loop through each vertical strip

        
while ($width-- > 0) {

            
// set nearest face to practical infinity

            
$nearestFace 4294967296;

            
$angleLookup = ($angle $this->divisor);

            
// find oriented face aligned to X axis of map

            
$x $cameraBlockX;
            
$y $cameraBlockY;

            if (
$this->sin[$angleLookup] < 0) {

                while (
$y > -&& $x > -&& $x $this->mapWidth) {
                    
$absY $y << 6;
                    
$absX $this->camX + ($absY $this->camY) / $this->tan[$angleLookup];
                    
$x    $absX >> 6;

                    
// check if there is a block here

                    
if ($this->map[$x][--$y]) {
                        
$nearestFace pow($absX $this->camX2) + pow($absY $this->camY2);
                        
$offset $absX 63;
                        break;
                    }
                }

            } else {

                while (
$y++ < $this->mapHeight && $x > -&& $x $this->mapWidth) {
                    
$absY $y << 6;
                    
$absX $this->camX + ($absY $this->camY) / $this->tan[$angleLookup];
                    
$x    $absX >> 6;
                    
                    
// check if there is a block here
                    
                    
if ($this->map[$x][$y]) {
                        
$nearestFace pow($absX $this->camX2) + pow($absY $this->camY2);
                        
$offset 64 $absX 63;
                        break;
                    }
                }

            }

            
// find closest face oriented to Y axis of map

            
$x $cameraBlockX;
            
$y $cameraBlockY;

            if (
$this->cos[$angleLookup] < 0) {

                while (
$x > -&& $y > -&& $y $this->mapHeight) {
                    
$absX $x << 6;
                    
$absY $this->camY + ($absX $this->camX) * $this->tan[$angleLookup];
                    
$y    $absY >> 6;
                    
                    
// check if there is a block here

                    
if ($this->map[--$x][$y]) {
                        
$distance pow($absX $this->camX2) + pow($absY $this->camY2);

                        if (
$distance $nearestFace) {
                            
$nearestFace $distance;
                            
$offset 64 $absY 63;
                        }
                        break;
                    }
                }

            } else {

                while (
$x++ < $this->mapWidth && $y > -&& $y $this->mapHeight) {
                    
$absX $x << 6;
                    
$absY $this->camY + ($absX $this->camX) * $this->tan[$angleLookup];
                    
$y    $absY >> 6;
                    
                    
// check if there is a block here
                    
                    
if ($this->map[$x][$y]) {
                        
$distance pow($absX $this->camX2) + pow($absY $this->camY2);

                        if (
$distance $nearestFace) {
                            
$nearestFace $distance;
                            
$offset $absY 63;
                        }
                        break;
                    }
                }

            }

            
// check whether the current strip is looking left or right of centre angle

            
if ($angleLookup $ang)    {
                
$distort $this->camDistance $this->cos[7200 $angleLookup $ang];
            } else {
                
$distort $this->camDistance $this->cos[$angleLookup $ang];
            }

            
$wallHeight $distort sqrt($nearestFace);

            
$distanceFloor   $invertZ $distort;
            
$distanceCeiling $this->camZ $distort;

            
$floorLevel = (int) ($this->camPCentre $wallHeight $this->camZ 0.5);
            
$wallLevel  = (int) ($this->camPCentre $wallHeight $invertZ);

            
$height $this->height;

            
// draw floor

            
while (--$height $floorLevel && $height >= 0) {
                
$distance $distanceFloor / ($height $this->camPCentre);
                
imagesetpixel($this->canvas$width$heightimagecolorat($this->texFloor, ($this->camX $this->cos[$angleLookup] * $distance) & 63, ($this->camY $this->sin[$angleLookup] * $distance) & 63));
            }

            
// draw wall

            
while (--$height $wallLevel && $height >= 0) {
                
imagesetpixel($this->canvas$width$heightimagecolorat($this->texWall$offset, ($height $wallLevel) / $wallHeight));
            }

            
// draw ceiling

            
while (--$height > -1) {
                
$distance $distanceCeiling / ($this->camPCentre $height);
                
imagesetpixel($this->canvas$width$heightimagecolorat($this->texCeil, ($this->camX $this->cos[$angleLookup] * $distance) & 63, ($this->camY $this->sin[$angleLookup] * $distance) & 63));
            }

            
$angle -= $this->camPerRayAngle;
            
            if (
$angle 0$angle += pi() * 2;
        }
    } 
The rest of the class needs some work before it's really presentable
__________________
Flickr
NiHiLiST is offline   Reply With Quote
Old 8th Jul 2006, 23:40   #18
Hwulex
I Mod, Therefore I Own
 
Hwulex's Avatar
 
Join Date: Feb 2002
Location: Whistler, BC
Posts: 4,007
Hwulex has yet to learn the way of the Dremel
Wow, very impressive. I wouldn't even know where to begin with soemthing like this.

Damn I hate sucking at math.
__________________
Clickr my Flickr
Hwulex is offline   Reply With Quote
Old 9th Jul 2006, 10:49   #19
korhojoa
durr
 
Join Date: Oct 2003
Location: Vaasa, Finland
Posts: 162
korhojoa has yet to learn the way of the Dremel
Whoa, VERY Nice!
(Oh yes, and you got dugg.)
__________________
the world is not enough, i gotta have modding too.
korhojoa is offline   Reply With Quote
Old 9th Jul 2006, 11:33   #20
Rexxie
Multimodder
 
Join Date: Nov 2002
Location: Norway
Posts: 198
Rexxie has yet to learn the way of the Dremel
That's pretty awesome. Nice work!

Oh and yeah, you got dugg
__________________
- Rexxie
Sanity is a full time job.
Rexxie is offline   Reply With Quote
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 08:33.
Powered by: vBulletin Version 3
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.