Camera and rendering, how to? (SOLVED)

I tried but it doesn’t work :frowning: I have a script error on set_projection function
and lerp function.

I’ve copied the default.render et default.render_script to another place and renamed them as custom.*
Then I’ve changed the render in my game.project to custom.render.

Here is my collection:

My project contains 3 screens : 1 Main menu, 1 Levels menu and 1 Game screen (where the player plays :slight_smile: )
My camera is only present on my Game screen and follows the player

Here’s my camera.script:

screen_width = tonumber(sys.get_config("display.width"))
screen_height = tonumber(sys.get_config("display.height"))
    
function init()
    msg.post("#camera", "acquire_camera_focus")
end

function on_message(self, message_id, message, sender)
    if message_id == hash("follow") then
        local pos_x = message.position.x - (screen_width/ 2)
        if pos_x <= 0 then
            pos_x = 0
        elseif pos_x >= screen_width then 
            pos_x = screen_width
        end
        
        local pos_y = message.position.y - (screen_height / 2)
        if pos_y <= 0 then
            pos_y = 0
        elseif pos_y >= screen_height then 
            pos_y = screen_height
        end
                
        go.set_position(vmath.vector3(pos_x, pos_y, 0))
    end
end

My player.script just send a message “follow” to the camera.script to make it follow.

Here’s my custom.render_script:

function init(self)
    self.tile_pred = render.predicate({"tile"})
    self.gui_pred = render.predicate({"gui"})
    self.text_pred = render.predicate({"text"})
    self.particle_pred = render.predicate({"particle"})

    self.clear_color = vmath.vector4(0, 0, 0, 0)
    self.clear_color.x = sys.get_config("render.clear_color_red", 0)
    self.clear_color.y = sys.get_config("render.clear_color_green", 0)
    self.clear_color.z = sys.get_config("render.clear_color_blue", 0)
    self.clear_color.w = sys.get_config("render.clear_color_alpha", 0)

    self.view = vmath.matrix4()
end

function update(self)
    render.set_depth_mask(true)
    render.clear({[render.BUFFER_COLOR_BIT] = self.clear_color, [render.BUFFER_DEPTH_BIT] = 1, [render.BUFFER_STENCIL_BIT] = 0})

    render.set_viewport(0, 0, render.get_window_width(), render.get_window_height())
    render.set_view(self.view)

    render.set_depth_mask(false)
    render.disable_state(render.STATE_DEPTH_TEST)
    render.disable_state(render.STATE_STENCIL_TEST)
    render.enable_state(render.STATE_BLEND)
    render.set_blend_func(render.BLEND_SRC_ALPHA, render.BLEND_ONE_MINUS_SRC_ALPHA)
    render.disable_state(render.STATE_CULL_FACE)

    render.set_projection(self.projection)

    render.draw(self.tile_pred)
    render.draw(self.particle_pred)
    render.draw_debug3d()

    render.set_view(vmath.matrix4())
    render.set_projection(self.projection)

    render.enable_state(render.STATE_STENCIL_TEST)
    render.draw(self.gui_pred)
    render.draw(self.text_pred)
    render.disable_state(render.STATE_STENCIL_TEST)

    render.set_depth_mask(false)
    render.draw_debug2d()
end

function on_message(self, message_id, message)
    if message_id == hash("clear_color") then
        self.clear_color = message.color
    elseif message_id == hash("set_view_projection") then
        self.view = message.view
        self.projection = message.projection
    end
end

Up, nobody to help me… :frowning:
I just want to make my camera closer, that’s all, please :frowning:

Studying this version of the render script may help you - it’s from a 3d project example

main.render_script.lua (1.3 KB)

1 Like

To “zoom” an orthogonal camera you need to change the left, right, top and bottom values instead of the actual Z-position. Try playing around with the projection matrix like this:

local zoom_value = 0.5
local proj_mtx = vmath.matrix4_orthographic(-render.get_width() / 2.0 * zoom_value, render.get_width() / 2.0 * zoom_value, -render.get_height() / 2.0 * zoom_value, render.get_height() / 2.0 * zoom_value, -1, 1)
render.set_projection(proj_mtx)

(I haven’t had time to test this myself, so please excuse any errors in the code. :slight_smile: )

2 Likes

Thanks a lot Sven it works. I changed some of your value of course and now it’s fine :slight_smile: but one more thing, now my graphics are a bit “blurred” :confused: it’s a 2D game I make, with 128x128px tilemap, is there a way to avoid this blur thing ?

2 Likes

Awesome! :smiley:

I think what you encounter with blurred graphics is due to texture filtering, linear vs nearest, have a look at this post: Low resolution pixel art game

1 Like

Thanks I will take a look on it, and now I have to manage my render only to render when the player is playing ^^ and not on the main menu

1 Like

Can I have multiple render ? :slight_smile:

Depends on what you mean. You can have one render script, but that can include other files.

The render script can do arbitrary passes. You can do post processing, light/shadow passes, split screen or whatever you like.

1 Like

Oh ok I will you msg.post("@render",…) to change my rendering right ?

Now it’s not blurred anymore but it’s “too sharp” I mean it’s like there’s no antialiasing, even if I change the “samples” settings in my game.project it doesn’t change anything

All messages you send to @render: will arrive in the on_message() function in your render script and you can react to it as you see fit.

2 Likes

Yes I’ve done that and it works fine :slight_smile: thanks

I’m working on the “too sharp” thing now :confused:

Can you give us an screenshot that highlights this sharpness? :slight_smile:

Here is it:

it looks like every strokes who are not straight aren’t clean.

FYI: if I don’t zoom with my camera all strokes looks normal, neither too blurred neither too sharp

I think it’s something that happens if you zoom on something that uses nearest as filtering… :frowning: How did it look with linear? Does it look better if you have nearest and zoom at exactly x2 (0.5 in my example)?

Are the sprites scaled btw?

With linear, it’s a bit blurred (I’m at 1.5 in my case):

With zoom x2 (0.5):

And my sprite is not scaled, the character is at 1,1,1 and for the ground I use tilemaps.

Try to zoom/scale only at whole number values?

1 Like

I think the strange artefacts you are experiencing with nearest filtering has to do with the zoom not equalling whole number values, as @Pkeod points out.

In your example with 1.5 zoom this means you are essentially trying to render 1.5 pixels into 2 pixels… With linear filtering the two pixels would get linearly interpolated values from the “1.5 pixels” they cover, which could be interpreted as “blurred”. :slight_smile: With nearest there is no real interpolation going on, instead each of the 2 pixels has to pick one color from the covering image that are closest to their position, which will be a problem if there is no 1-to-1 coverage.

Ok, that was a really bad explanation sorry! But hope you can gather some knowledge from it anyway… :wink: Maybe have a look at some articles talking about texture filtering, like; https://en.wikipedia.org/wiki/Texture_filtering

2 Likes

Well, I’ve changed the way to “zoom” in my game, I’ve just changed the scale of my tilemap from 0.5 to 1 and changed my player sprite size. So now I don’t zoom with my camera anymore :slight_smile: and it’s all smooth now !

Thanks a lot for your help guys.

3 Likes