#Rendering a Sprite3D inside a SubViewport, ignoring a shader

1 messages · Page 1 of 1 (latest)

lapis nova
#

I have a SubViewportContainer set to stretch shrink to create a pixelated 3D effect with an outline.
My player is inside the viewport, how do I render a sprite that moves with the player that would be unaffected by the shader?
shader: https://pastebin.com/9ZrGg0VN (too long for discord post)

I essentially render to a mesh that is in front of the camera with full screensize, I wanna flag some elements to be rendered before the shader processing

lapis nova
#

bumping this, still looking for some answers

marble valley
#

I'm not entirely sure if it's possible to flag them, I've wanted something similar myself and never found a solution in 4.2. But I believe there's a compositor effect system underway in 4.3 (saw the request on Github, and page in docs) which -might- allow something like it. But I'm not entirely sure. Would be nice if someone more knowledgeable commented in this!

lapis nova
#

bumping again, hopefully more people online right now 😄

soft silo
#

The solution in the case of fullscreen quad postprocessing involves rendering all the objects you want masked to a separate viewport, using that viewport as a texture, and in your main postprocessing script, use that viewport texture to mask. I think your case its more complicated though

#

I've done it in 4.1 without recompiling the engine but it was hacky

lapis nova
#

if I takee the sprite3D, and take its screen position to render a TextureRect above the shader that could work 🤔

soft silo
#

If you can put your sprites in a 2d layer outside the effect, I'd recommend it

lapis nova
#

I can, I just need to unproject the 3D position of the ui element

soft silo
#

I can try to put together a minimal example of the masked postprocessing if you think it would be useful though

lapis nova
#

so that I can make it follow approximately with the player

lapis nova
soft silo
#

But if you dont need the sprite to be 3d in worldspace, a 2d sprite following the player is probably much simpler

lapis nova
#

the purpose of this, is that I need to draw a button prompt in 3D space, at full resolution

#

when you are close to something to interact with, I want to display whatever button is bound to the interaction

soft silo
#

And its important that it's a button in 3d space rather than a 2d button thats next to the interactible object in screen space?

lapis nova
#

not exactly, because the lowered resolution im trying to make it look like 3d pixelart

#

rendering some windows above the viewport I ahve my general UI, but attaching a sprite3D to a mesh (inside the viewport) caused it to make the pixelart even more low resolution

#

makign the button "E" in my current case barely readible

#

therefore, I take the 3D position, convert it to 2D space relative to the camera and draw at that position

#

there wont be more than one at a time, so I doubt unprojecting in a _process loop will cause any bottleneck

soft silo
#

Yeah, rendering the sprite outside the viewport makes way more sense than trying to mask the effect imo

lapis nova
#

yeah, if I wanted to render different elements at different resolutions that would be vastly different

soft silo
lapis nova
#

actually, that sounds like a fun project lol

#

I appreciate the input 😄 time to get cracking on that. shouldnt be too hard

#

this should do it even 🤔 ```swift
func _process(delta):
reposition()

func reposition():
position = camera.unproject_position(target.global_position)
visible = !camera.is_position_behind(target.global_position)

lapis nova
#

hmm, seems like im getting it wrong to convert that position

#
class_name WSD extends Control

@export var element: TextureRect;

@export var rect_controller: Rect2 = Rect2(80, 144, 16, 16);
@export var rect_keyboard: Rect2 = Rect2(305 ,33, 13, 14);

var _target: Node3D;

func _process(_delta: float):
    if _target:
        element.global_position = Manager.instance.camera_controller.camera.unproject_position(_target.global_position)
        element.visible = !Manager.instance.camera_controller.camera.is_position_behind(_target.global_position)
    else:
        element.visible = false;

func show_rect(target: Node3D):
    _target = target;
    element.visible = true;

func handle_rect(_b: bool):
    (element.texture as AtlasTexture).region = rect_keyboard if Manager.instance.input_mode_is_keyboard else rect_controller;

func _ready():
    Manager.instance.input_mode_changed.connect(handle_rect);
#

ah, its the shader that was interefering with it