Help with shaders!

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Phisilon_
Prole
Posts: 2
Joined: Wed Jun 07, 2023 6:33 pm

Help with shaders!

Post by Phisilon_ »

Hello! I'm a relatively new game dev and trying to make a doom style game called delta.

I decided to make a table of screen colors and use custom functions to draw rectangles, lines, circles, ect and render the screen to make it the same resolution on different computers in full screen. Unfortunately to do this I decided to render all the table values, and with the massive resolution of 480x270 I have to go though 129,600 pixels to do this. This is a pretty big task for my old CPU and I think I should use the GPU instead.

the code:

Code: Select all

   
   --resolution[1] is the width
   --resolution[2] is the height
   
   --render screen
   for y=1,resolution[2],1 do
        for x=1,resolution[1],1 do
            screen.r[x][y]=0
            screen.g[x][y]=0
            screen.b[x][y]=0
        end
    end
    
    --draw things
    
    --clear screen
    for y=1,resolution[2],1 do
        for x=1,resolution[1],1 do
            graphics.setColor(screen.r[x][y],screen.g[x][y],screen.b[x][y])
            graphics.rectangle('fill',(x-1)*(width/resolution[1]),(y-1)*(height/resolution[2]),(width/resolution[1]),(height/resolution[2]))
        end
    end
    
I do know you can do this using shaders but I have no idea how to do this. Can you help me make a shader for this.

Also anyway to lock the resolution in fullscreen with out doing all this then that would be preferred.


edit:Forgot to add the .love file lol,
Attachments
delta.love
(2.15 KiB) Downloaded 121 times
User avatar
zorg
Party member
Posts: 3468
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Help with shaders!

Post by zorg »

Look at the wiki, under love.image, you'll find ImageData; You should use that to manipulate pixels, then you can create an Image out of it once, and every time you modify the imagedata, you'll replace the pixels of the Image with the new data with the aptly named replacePixels method; this is probably the best way on how to achieve software rendering like what you want to do.

As a bonus, the Image can be scaled to whatever resolution by the GPU, so you don't need to do any calculations manually.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
Sasha264
Party member
Posts: 131
Joined: Mon Sep 08, 2014 7:57 am

Re: Help with shaders!

Post by Sasha264 »

Good day!
I will focus on CPU vs GPU part of the question.

CPU only:
The method you're currently using is CPU-intensive because you're manually iterating over every pixel to set its color, and then you're drawing each pixel as a rectangle. This is all being done on the CPU, which isn't designed to efficiently handle such per-pixel operations at high speeds. Well, there are some examples of pretty impressive realtime rendering purely on CPU on something like threadripper, but that involves mandatory multi-threading and preferrable use of SIMD instructions, which is difficult, and Love2d is not suited for that at all, because it basically use only 1 thread (1 CPU core) to draw things.

GPU only:
There are methods to draw things using GPU only. As I can see from your example, you have some background in math, so maybe you will enjoy the methods like raymarching, that is why I mention this. In raymarching you use a shader to calculate pixel colors based on virtual rays cast into a scene. It can be used in 2D, 3D, 4D... no big difference. These calculations are done on the GPU, which can handle thousands of these operations in parallel, greatly improving performance. It surely can be used to make a Doom-like style game. The main work here is in writing shaders, and the game engine works just like an entry point. Love2d can be used for that purpose easily, because it has good GLSL shader support.

To start understanding how to write basic shaders in Love2d you can read this:
https://blogs.love2d.org/content/beginn ... de-shaders
The basic shader examples are somewhat about only 10 lines of code, so pretty simple.

About the raymarching. This guy is awesome at both explaining the basics and in generating impressive complicated content:
https://iquilezles.org/
https://www.youtube.com/c/InigoQuilez
Just look at his youtube channel for the start.

There is this website, that provides you a way to develop shaders without even use any game engine, just in a browser:
https://www.shadertoy.com/
It's the same GLSL, and shaders written there could be relatively easily inserted into Love2d game.

The GLSL (openGL Shader Language) itself is very math-friendly and pleasurable to use. Much more then Lua or C++ or any other general-purpose language. For example here you can find all it's functions:
https://shaderific.com/glsl/common_functions.html
https://shaderific.com/glsl/trigonometr ... tions.html
https://shaderific.com/glsl/geometric_functions.html
Relatively short list, but extremely powerful.

Combined CPU & GPU:
The most common approach in modern games is to use a combination of CPU and GPU rendering, known as rasterization. Like 99% of games do exactly that. In this method, the CPU is responsible for setting up the scene, managing game logic, and sending instructions to the GPU. The GPU then takes over to draw the graphics. Most game engines (Love2d included) are designed with this pipeline in mind. Love2d has built-in functions for drawing textures and polygons. In this method, instead of counting pixels it is reasonable to count draw calls, it is good when draw calls count is less then 1000, it is bad, when draw calls count more then 10'000. In your example, when each "pixel" results in separate draw call (rectangle draw call), the amount of 129'600 draw calls is indeed to much for old CPUs to handle. Using this you can draw single wall segment with 1 draw call, which will result in a lot of pixels managed by the GPU. Or even draw the whole scene with just 1 draw call, depends on data structure and code organization.

While Love2d (oh, sorry, it is called LÖVE :rofl:) is not designed for 3d games generally, it relatively easily can be used for that purpose.
Here are some libraries / demos / extensions:
https://love2d.org/wiki/Love3D
Post Reply

Who is online

Users browsing this forum: No registered users and 5 guests