Why is label invisible when rotated between 270 and 360? (SOLVED)

Solution by @Dragosha : The label component blink when rotation GO over Y axes (SOLVED)

EDIT: It seems that the label is being hidden by a sprite behind it. For some reason rotating by +10 degrees affects the render order differently than rotating by -10 (or even +1/-1).
EDIT2: render.enable_state(render.STATE_DEPTH_TEST) did not help

I am using rendercam (perspective camera) and when I am rotating a label between 270 and 360 the label disappears. It works fine between 0 to 90. I have set cull face to render FRONT, which seems to work for sprites, but labels are hidden even when they should be visible.

I am rotating the object by calling go.set(“test”, “euler.y”, 300) on a game object called test that has one label.

I think I have an issue in my render script, but I can’t figure out what…

This is my modified rendercam render script

    local rendercam = require "rendercam.rendercam"
    local vp = rendercam.viewport

    local IDENTITY_MATRIX = vmath.matrix4()
    local CLEAR_COLOR = hash("clear_color")
    local WINDOW_RESIZED = hash("window_resized")
    local UPDATE_WINDOW = hash("update window")


    local function update_window(self)
    	rendercam.update_window(render.get_window_width(), render.get_window_height())
    	self.gui_proj = vmath.matrix4_orthographic(0, rendercam.window.x, 0, rendercam.window.y, -1, 1)
    end

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

    	self.clear_color = vmath.vector4(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)

    	rendercam.configWin.x = render.get_width();  rendercam.configWin.y = render.get_height()
    	rendercam.update_window_size(render.get_window_width(), render.get_window_height())
    	update_window(self)
    end

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

    	render.set_viewport(vp.x, vp.y, vp.width, vp.height)

    	render.set_view(rendercam.calculate_view())
    	render.set_projection(rendercam.calculate_proj())

    	-- Sprite and particle rendering
    	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.enable_state(render.STATE_CULL_FACE)	
    	render.set_cull_face(render.FACE_FRONT)

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

    	-- Model rendering
    	render.set_blend_func(render.BLEND_SRC_ALPHA, render.BLEND_ONE_MINUS_SRC_ALPHA)	
    	render.enable_state(render.STATE_CULL_FACE)
    	render.set_cull_face(render.FACE_BACK) -- TODO Fix
    	render.enable_state(render.STATE_DEPTH_TEST)
    	render.set_depth_mask(true)
    	render.draw(self.model_pred)

    	-- Debug rendering - physics debug, draw_line
    	render.disable_state(render.STATE_DEPTH_TEST)
    	render.disable_state(render.STATE_CULL_FACE)
    	render.draw_debug3d()

    	-- GUI Rendering
    	render.set_viewport(0, 0, rendercam.window.x, rendercam.window.y)
    	render.set_view(IDENTITY_MATRIX)
    	render.set_projection(self.gui_proj) -- gui_proj only calculated on update_window

    	render.enable_state(render.STATE_STENCIL_TEST)
    	render.draw(self.gui_pred)
    	render.draw(self.text_pred) -- Includes debug text from "draw_text" messages.
    	render.disable_state(render.STATE_STENCIL_TEST)
    end

    function on_message(self, message_id, message)
    	if message_id == CLEAR_COLOR then
    		self.clear_color = message.color
    	elseif message_id == WINDOW_RESIZED then -- sent by engine
    		update_window(self)
    	elseif message_id == UPDATE_WINDOW then -- sent by rendercam when a camera is activated ("window_resized" engine message requires data)
    	update_window(self)
    end
    end

thanks for the help

I think labels have wrong normal vector, with face culling enabled they become invisible until rotated 180 degree.

Screencast from 2021-04-21 20:35:49.m4v (152.4 KB)
I’ve made a video of this problem
com-gif-maker

Is the Label offset from the card at all ? have you tested with card disabled?

Check Sven example: The label component blink when rotation GO over Y axes (SOLVED)

3 Likes

@MasterMind yes there is an offset. The label is visible if there are not sprites behind it.
I’ve made an example codebase:


@Dragosha Unfortunately that example doesn’t use the angles I need. I tried Depth test as well, but it doesn’t seem to help. (see example above)

There is no matter which angles are you use. Because an example uses predicates for labels and background sprite. Also check render_script.

1 Like

@Dragosha I beg to differ. The angle does matter.
I integrated that script with rendercam (result is the same without rendercam!)

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

render.set_viewport(vp.x, vp.y, vp.width, vp.height)
render.set_view(rendercam.calculate_view())
render.set_projection(rendercam.calculate_proj())

render.set_depth_mask(true)
render.enable_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.enable_state(render.STATE_CULL_FACE)
render.set_cull_face(render.FACE_FRONT)

render.set_depth_func(render.COMPARE_FUNC_LEQUAL)

render.draw(self.tile_pred)

And this is the result:
test_label

The label shows, but now it has a black background for some reason.

Well. You added one part (render script), would you implement another part, and the most important part - predicates. Just give a chance to this example :sob:

4 Likes

@Dragosha Yes I am working on it :sweat_smile: I am a little bit behind.

1 Like

Thanks. It looks good now.

label_test3

4 Likes