Merge pull request #99407 from devloglogan/rec-resolution

Allow using custom `Rect2i` for rendering with OpenXR
This commit is contained in:
Rémi Verschelde
2025-01-10 23:05:46 +01:00
25 changed files with 215 additions and 19 deletions

View File

@ -194,6 +194,10 @@ Size2i XRInterface::get_velocity_target_size() {
return Size2i();
}
Rect2i XRInterface::get_render_region() {
return Rect2i();
}
PackedStringArray XRInterface::get_suggested_tracker_names() const {
PackedStringArray arr;

View File

@ -139,6 +139,7 @@ public:
virtual RID get_velocity_texture(); /* obtain velocity output texture (if applicable, used for spacewarp) */
virtual RID get_velocity_depth_texture();
virtual Size2i get_velocity_target_size();
virtual Rect2i get_render_region();
virtual void pre_render() {}
virtual bool pre_draw_viewport(RID p_render_target) { return true; } /* inform XR interface we are about to start our viewport draw process */
virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) = 0; /* inform XR interface we finished our viewport draw process */

View File

@ -40,8 +40,12 @@ void XRVRS::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_vrs_strength"), &XRVRS::get_vrs_strength);
ClassDB::bind_method(D_METHOD("set_vrs_strength", "strength"), &XRVRS::set_vrs_strength);
ClassDB::bind_method(D_METHOD("get_vrs_render_region"), &XRVRS::get_vrs_render_region);
ClassDB::bind_method(D_METHOD("set_vrs_render_region", "render_region"), &XRVRS::set_vrs_render_region);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "vrs_min_radius", PROPERTY_HINT_RANGE, "1.0,100.0,1.0"), "set_vrs_min_radius", "get_vrs_min_radius");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "vrs_strength", PROPERTY_HINT_RANGE, "0.1,10.0,0.1"), "set_vrs_strength", "get_vrs_strength");
ADD_PROPERTY(PropertyInfo(Variant::RECT2I, "vrs_render_region"), "set_vrs_render_region", "get_vrs_render_region");
ClassDB::bind_method(D_METHOD("make_vrs_texture", "target_size", "eye_foci"), &XRVRS::make_vrs_texture);
}
@ -88,6 +92,15 @@ void XRVRS::set_vrs_strength(float p_vrs_strength) {
}
}
Rect2i XRVRS::get_vrs_render_region() const {
return vrs_render_region;
}
void XRVRS::set_vrs_render_region(const Rect2i &p_vrs_render_region) {
vrs_render_region = p_vrs_render_region;
vrs_dirty = true;
}
RID XRVRS::make_vrs_texture(const Size2 &p_target_size, const PackedVector2Array &p_eye_foci) {
ERR_FAIL_COND_V(p_eye_foci.is_empty(), RID());
@ -123,19 +136,26 @@ RID XRVRS::make_vrs_texture(const Size2 &p_target_size, const PackedVector2Array
target_size = vrs_sizei;
eye_foci = p_eye_foci;
Size2 region_ratio = Size2(1.0, 1.0);
Point2i region_offset;
if (vrs_render_region != Rect2i()) {
region_ratio = (Size2)vrs_render_region.size / p_target_size;
region_offset = (Point2)vrs_render_region.position / p_target_size * vrs_sizei;
}
for (int i = 0; i < eye_foci.size() && i < RendererSceneRender::MAX_RENDER_VIEWS; i++) {
PackedByteArray data;
data.resize(vrs_sizei.x * vrs_sizei.y * 2);
uint8_t *data_ptr = data.ptrw();
Vector2i view_center;
view_center.x = int(vrs_size.x * (eye_foci[i].x + 1.0) * 0.5);
view_center.y = int(vrs_size.y * (eye_foci[i].y + 1.0) * 0.5);
view_center.x = int(vrs_size.x * (eye_foci[i].x + 1.0) * region_ratio.x * 0.5) + region_offset.x;
view_center.y = int(vrs_size.y * (eye_foci[i].y + 1.0) * region_ratio.y * 0.5) + region_offset.y;
int d = 0;
for (int y = 0; y < vrs_sizei.y; y++) {
for (int x = 0; x < vrs_sizei.x; x++) {
Vector2 offset = Vector2(x - view_center.x, y - view_center.y);
Vector2 offset = Vector2(x - view_center.x, y - view_center.y) / region_ratio;
real_t density = 255.0 * MAX(0.0, (Math::abs(offset.x) - min_radius) / outer_radius);
data_ptr[d++] = MIN(255, density);
density = 255.0 * MAX(0.0, (Math::abs(offset.y) - min_radius) / outer_radius);

View File

@ -44,6 +44,7 @@ class XRVRS : public Object {
private:
float vrs_min_radius = 20.0;
float vrs_strength = 1.0;
Rect2i vrs_render_region;
bool vrs_dirty = true;
RID vrs_texture;
@ -60,6 +61,8 @@ public:
void set_vrs_min_radius(float p_vrs_min_radius);
float get_vrs_strength() const;
void set_vrs_strength(float p_vrs_strength);
Rect2i get_vrs_render_region() const;
void set_vrs_render_region(const Rect2i &p_vrs_render_region);
RID make_vrs_texture(const Size2 &p_target_size, const PackedVector2Array &p_eye_foci);
};