<p>I'm trying to render sprites/textures in my raycasting engine, but I don't quite understand the math behind drawing the columns of the texture I intend to project. I've tried looking at several tutorials, e.g., <a href="https://lodev.org/cgtutor/raycasting3.html" rel="nofollow noreferrer">lodev</a>, <a href="https://wynnliam.github.io/raycaster/news/tutorial/2019/04/03/raycaster-part-02.html" rel="nofollow noreferrer">Wynnliam</a>, and <a href="https://www.allegro.cc/forums/thread/355015" rel="nofollow noreferrer">several posts</a> on Allegro.cc, but none of them seem to explain the sprite-casting component in an easy-to-digest way. Can anyone help? Note that I'm currently drawing a yellow square in the location of the sprite and it appears as if the sprite is not positioned in the correct spot... My main problem is that I don’t understand how to compute the column of the texture to render. Once I figure this out, I can easily add z-depth sorting, but I really have no idea how to do this step.</p>
<pre><code>        final int TEXTURE_SIZE = 64;
        final int PROJ_HEIGHT = 640;
        final int PROJ_WIDTH = 640;
        ArrayList&lt;TextureSprite&gt; sprites = this.RAYCASTER_PANEL.getTileMap().getSprites();
        for (int s = 0; s &lt; sprites.size(); s++) {
            TextureSprite sp = sprites.get(s);
            // computes the distance and angle of the sprite...
            double fov = this.RAYCASTER_PANEL.getCamera().getFov();
            double ca = this.getCamera().getCurrentAngle();
            double dx = sp.getX() - this.RAYCASTER_PANEL.getCamera().getX();
            double dy = sp.getY() - this.RAYCASTER_PANEL.getCamera().getY();
            double d = Point2D.distanceSq(sp.getX(), sp.getY(), this.RAYCASTER_PANEL.getCamera().getX(), this.RAYCASTER_PANEL.getCamera().getY());
            double theta_temp = Math.toDegrees(Math.atan2(dy, dx));
            if(theta_temp &lt; 0) theta_temp += 360;
            if (theta_temp &gt; 360) theta_temp -= 360;

            double y = ca + fov/2 - theta_temp;

            if(theta_temp &gt; 270 &amp;&amp; ca &lt; 90) y = ca + fov/2 - theta_temp + 360;
            if(ca &gt; 270 &amp;&amp; theta_temp &lt; 90) y = ca + fov/2 - theta_temp - 360;
     
            // attempt to compute the sprite's x, y, width, and height
            double sw = (TEXTURE_SIZE / Math.sqrt(d)) * this.getCamera().getDistanceToProjectionPlane();
            double sh = sw;
            double sx = (y * PROJ_HEIGHT / fov) - sw/2.f;
            double sy = (PROJ_HEIGHT / 2.f) - (TEXTURE_SIZE / 2.f);

            // Just a temporary until I understand how to draw the textures themselves...
            g2.setColor(Color.YELLOW);
            g2.fillRect((int)sx,(int)sy,(int)sw,(int)sh);
</code></pre>
<p><a href="https://i.sstatic.net/aJ489.gif" rel="nofollow noreferrer">Example of the problem</a></p>
<p>Code after @lightxbulb's post suggestion:</p>
<pre><code>            final int PROJ_WIDTH=1280; // changed 
            TextureSprite sp = sprites.get(s);
            double fov = this.getCamera().getFov();
            double ca = this.getCamera().getCurrentAngle();
            double px = this.getCamera().getX();
            double py = this.getCamera().getY();
            double sx = sp.getX();
            double sy = sp.getY();

            double dx = sx - px;
            double dy = sy - py;
            double sprite_dir = Math.toDegrees(Math.atan2(dy, dx));
            while (sprite_dir - ca &gt; 180) sprite_dir -= 360;
            while (sprite_dir - ca &lt; -180) sprite_dir += 360;

            double sprite_dist = Math.sqrt(Math.pow(px - sp.getX(), 2) + Math.pow(py - sp.getY(), 2));
            double sprite_screen_size = Math.min(2000, PROJ_HEIGHT / sprite_dist);
            int h_offset = (int) ((sprite_dir - ca) * (PROJ_WIDTH/2) / (fov) + (PROJ_WIDTH/2)/2 - sprite_screen_size / 2);
            int v_offset = (int) (PROJ_HEIGHT/2 - sprite_screen_size / 2);
            g2.setColor(Color.YELLOW);
            for (int i = 0; i &lt; sprite_screen_size; i++) {
                // Adding these range guards prevents any rendering whatsoever
                if (h_offset+i&lt;0||h_offset+i&gt;PROJ_WIDTH/2) continue;
                for (int j = 0; j &lt; sprite_screen_size; j++) {
                    g2.fillRect(PROJ_WIDTH/2+h_offset+i,v_offset+j,1,1);
                }
            }
</code></pre>

CC BY-SA 4.0
2022-07-16T09:46:45.543Z
I can recommend this: https://github.com/ssloy/tinyraycaster/wiki/Part-1:-crude-3D-renderings
lightxbulb
CC BY-SA 4.0
2022-07-16T13:18:34.000Z
@lightxbulb So, I tried following their tutorial and my code still isn't rendering the shapes correctly. Even when just trying to draw a simple square on the screen, it doesn't show up at all if I try to add the bounds (e.g., if (h_offset + i < 0 || ...). If I remove those, the square shows up but it's never rendered correctly. I can move up close to it and it'll zoom in really fast then fade out... I've added my new code to the post.
Joshua Crotts
<depth-map><ray><occlusion><java>
How to sprite cast in a raycasting engine?
Joshua Crotts
# How to sprite cast in a raycasting engine?

(Asked by: username_0 on 2022-07-16)

I'm trying to render sprites/textures in my raycasting engine, but I don't quite understand the math behind drawing the columns of the texture I intend to project. I've tried looking at several tutorials, e.g., [lodev](https://lodev.org/cgtutor/raycasting3.html), [Wynnliam](https://wynnliam.github.io/raycaster/news/tutorial/2019/04/03/raycaster-part-02.html), and [several posts](https://www.allegro.cc/forums/thread/355015) on Allegro.cc, but none of them seem to explain the sprite-casting component in an easy-to-digest way. Can anyone help? Note that I'm currently drawing a yellow square in the location of the sprite and it appears as if the sprite is not positioned in the correct spot... My main problem is that I don’t understand how to compute the column of the texture to render. Once I figure this out, I can easily add z-depth sorting, but I really have no idea how to do this step.

```
        final int TEXTURE_SIZE = 64;
        final int PROJ_HEIGHT = 640;
        final int PROJ_WIDTH = 640;
        ArrayList<TextureSprite> sprites = this.RAYCASTER_PANEL.getTileMap().getSprites();
        for (int s = 0; s < sprites.size(); s++) {
            TextureSprite sp = sprites.get(s);
            // computes the distance and angle of the sprite...
            double fov = this.RAYCASTER_PANEL.getCamera().getFov();
            double ca = this.getCamera().getCurrentAngle();
            double dx = sp.getX() - this.RAYCASTER_PANEL.getCamera().getX();
            double dy = sp.getY() - this.RAYCASTER_PANEL.getCamera().getY();
            double d = Point2D.distanceSq(sp.getX(), sp.getY(), this.RAYCASTER_PANEL.getCamera().getX(), this.RAYCASTER_PANEL.getCamera().getY());
            double theta_temp = Math.toDegrees(Math.atan2(dy, dx));
            if(theta_temp < 0) theta_temp += 360;
            if (theta_temp > 360) theta_temp -= 360;

            double y = ca + fov/2 - theta_temp;

            if(theta_temp > 270 && ca < 90) y = ca + fov/2 - theta_temp + 360;
            if(ca > 270 && theta_temp < 90) y = ca + fov/2 - theta_temp - 360;
     
            // attempt to compute the sprite's x, y, width, and height
            double sw = (TEXTURE_SIZE / Math.sqrt(d)) * this.getCamera().getDistanceToProjectionPlane();
            double sh = sw;
            double sx = (y * PROJ_HEIGHT / fov) - sw/2.f;
            double sy = (PROJ_HEIGHT / 2.f) - (TEXTURE_SIZE / 2.f);

            // Just a temporary until I understand how to draw the textures themselves...
            g2.setColor(Color.YELLOW);
            g2.fillRect((int)sx,(int)sy,(int)sw,(int)sh);

```

[Example of the problem](https://i.sstatic.net/aJ489.gif)

Code after @username_1's post suggestion:

```
            final int PROJ_WIDTH=1280; // changed 
            TextureSprite sp = sprites.get(s);
            double fov = this.getCamera().getFov();
            double ca = this.getCamera().getCurrentAngle();
            double px = this.getCamera().getX();
            double py = this.getCamera().getY();
            double sx = sp.getX();
            double sy = sp.getY();

            double dx = sx - px;
            double dy = sy - py;
            double sprite_dir = Math.toDegrees(Math.atan2(dy, dx));
            while (sprite_dir - ca > 180) sprite_dir -= 360;
            while (sprite_dir - ca < -180) sprite_dir += 360;

            double sprite_dist = Math.sqrt(Math.pow(px - sp.getX(), 2) + Math.pow(py - sp.getY(), 2));
            double sprite_screen_size = Math.min(2000, PROJ_HEIGHT / sprite_dist);
            int h_offset = (int) ((sprite_dir - ca) * (PROJ_WIDTH/2) / (fov) + (PROJ_WIDTH/2)/2 - sprite_screen_size / 2);
            int v_offset = (int) (PROJ_HEIGHT/2 - sprite_screen_size / 2);
            g2.setColor(Color.YELLOW);
            for (int i = 0; i < sprite_screen_size; i++) {
                // Adding these range guards prevents any rendering whatsoever
                if (h_offset+i<0||h_offset+i>PROJ_WIDTH/2) continue;
                for (int j = 0; j < sprite_screen_size; j++) {
                    g2.fillRect(PROJ_WIDTH/2+h_offset+i,v_offset+j,1,1);
                }
            }

```

**Tags:** depth-map, ray, occlusion, java

> **Comments:**
> **username_1**: I can recommend this: https://github.com/ssloy/tinyraycaster/wiki/Part-1:-crude-3D-renderings  
> **username_0**: @username_1 So, I tried following their tutorial and my code still isn't rendering the shapes correctly. Even when just trying to draw a simple square on the screen, it doesn't show up at all if I try to add the bounds (e.g., if (h_offset + i < 0 || ...). If I remove those, the square shows up but it's never rendered correctly. I can move up close to it and it'll zoom in really fast then fade out... I've added my new code to the post.  

---

## 0 answers

