GodotVR / godot-xr-tools

Support scenes for AR and VR in Godot
MIT License
471 stars 64 forks source link

added collision fade #626

Closed DigitalN8m4r3 closed 3 months ago

DigitalN8m4r3 commented 3 months ago

this adds fade upon collision

https://github.com/GodotVR/godot-xr-tools/assets/56046022/79597692-75e9-4fbc-9226-48df14a8e97b

walk up a wall to experience the fade upon collision.

how to setup your environment for the fader:

  • select all the static bodys that you wish to influence the fader
  • set their collision layer to = 2

how to add it to your scenes:

  • drag and drop the fader.tscn - scene as child of the camera
  • drag and drop the fade_in_out.tscn and the fade_collision.tscn - scene as children of the fader

based upon @Malcolmnixon work from 2022 which was made for a earlier version of xr tools for godot 3.5, link is below https://github.com/Malcolmnixon/godot-xr-tools-experiments

DigitalN8m4r3 commented 3 months ago

currently the above is fully functional except the fade_area part which i was not able to convert properly from the godot 3.5 version, if anyone wants to chime in and fix it, would be great!

Malcolmnixon commented 3 months ago

Strategy

This PR is fundamentally promoting "fading" from being a special-purpose thing we have in staging used for scene-switching, and promoting it to an effect usable in multiple areas. As such I think we should locate the core fading effects code in addons/godot-xr-tools/effects.

Fundamentally what we want from fading is:

  1. The staging machinery provides fading out of the box (already achieved by the Fade node in staging)
  2. The user can add the Fade node to any scene if not using the staging machinery)
  3. Any node (or even multiple nodes) can request fading
  4. Fading can be to any color - not just black (E.G. fade to red for death)

Fade Shader/Node/Script

The fade machinery implemented in staging has a fair number of improvements which make it work on both gl_compatibility and vulkan shaders. We want to incorporate those improvements...

The existing addons/godot-xr-tools/staging/fade.gdshader can only fade to black, whereas the new fade.gdshader can fade to any color. I think we want to use the shader type, mode, and vertex function from the staging-shader, but use the albedo color uniform and fragment shader from the new file.

The Fade node should follow the approach used in the staging.tscn Fade node - a 2x2 quad with a custom AABB of [-5000,-5000,-5000], [10000,10000,10000] to ensure it's not culled.

The following is a proposed script to provide access to fading from anywhere. This is a 'push' model rather than a 'pull' model, and so should be much faster than the group-based approach; although it does require Godot 4.2 for static fields:

class_name Fade
extends MeshInstance3D

# Dictionary of fade requests
var _faders : Dictionary = {}

# Fade update flag
var _update : bool = false

# Fade material
var _material : ShaderMaterial

# Static fade instance
static var instance : Fade

func _ready() -> void:
    instance = self
    _material = get_surface_override_material(0) as ShaderMaterial

func _exit_tree() -> void:
    instance = null

func _process(_delta : float) -> void:
    # Skip if nothing to update
    if not _update:
        return

    # Calculate the cumulative shade color
    var fade := Color(1, 1, 1, 1)
    var show := false
    for whom in _faders:
        var color : Color = _faders[whom]
        fade *= color
        show = true

    # Set the shader and show if necessary
    _material.set_shader_parameter("albedo", fade)
    visible = show
    _update = false

static func set_fade(p_whom : Variant, p_color : Color) -> void:
    if instance:
        instance._faders[p_whom] = p_color
        instance._update = true

static func clear_fade(p_whom : Variant) -> void:
    if instance:
        if instance._faders.erase(p_whom):
            instance._update = true

With this code all code requiring shading can now simply call Fade.set_fade(<whom>, <color>) or Fade.clear_fade(<whom>) where <whom> can be the self of the requesting node, or some string identifier.

Fade Requests

The set_fade method in addons/godot-xr-tools/staging/staging.gd can be switched to:

func set_fade(p_value : float) -> void:
    Fade.set_fade("staging", Color(0, 0, 0, p_value)

The other fade providers should use similar calls, although they should probably use self for the whom rather than a fixed name as there may be multiple instances.

DigitalN8m4r3 commented 3 months ago

closing since #631 is adding the above more in the lines of the xr tools