Skip to content

Commit

Permalink
Merge development (#112)
Browse files Browse the repository at this point in the history
* started implementing rhi

* UR-244: Fix reimport

* UR-245: Remove RiveViewport client, replaced RiveWidget for fixed UI blending; Removed UI Blend Mode

* fix includes for release build

* ensure all Initialization paths listen for RiveFile delegates; Artboard file code cleanup

* 4b4529a continued: "ensure all Initialization paths listen for RiveFile delegates; Artboard file code cleanup"

* expose OnRiveReady for RiveTextureObject

* UR-247: Artboard / State machine dropdowns implemented across RiveWidget, RiveTextureObject, RiveActorComponent

* rive audio changes

* editor-only: reset rive textures on editor begin play

* RiveWidget audio convience

* win,android: update rive to b192f37856b249fbd6247700bf13d07d9b064c47

* macOS, iOS: update rive to b192f37856b249fbd6247700bf13d07d9b064c47

* Runtime Asset swapping (#105)

RiveAsset class was broken into 3 classes
        RiveAudioAsset
        RiveImageAsset, contains runtime compatible functions:
            LoadImageBytes (accepting an array of bytes in png, webp, jpg format)
            LoadTexture (not yet implemented fully, as we wait on Rive to allow us to submit bitmap data)
        RiveFontAsset, contains runtime compatible functions:
            LoadFontFace (loads an Unreal font face, if the font face's load policy is set to Inline)
            LoadFontBytes (accepting an array of bytes in ttf/otf format)
    RiveFile now supports a function "GetRiveAssetById", returning a base RiveAsset which can later be cast to one of the specific asset types to operate on
***
* asset overrides

* load image bytes call

* cleanup

* Ensure RiveWidget setup is called a short time after init

* Fixed Artboards. (#104)

* Fixed Artboards.

- No more phantom artboards during PIE.
- Artboards in the level reset on PIE begin.

* Made PR suggested changes.

- Moved Artboard check/creation to URiveTextureObject::RiveReady
- Removed EditorBeginPlay() and bHasBegunPlay

* working imagemesh without background

* missed some headers

* UR-249: Improve UMG widget handling, with minimum sizes based on selected artboard as the initial size

* imageRect now working

* win,android: update rive to 14d13c3ded7b141d5130c0246901008dc070c9fe

* macOS, iOS: update rive to 14d13c3ded7b141d5130c0246901008dc070c9fe

* fix a few includes

* fix filehelper include

* add another include

* replaced forward with include; fixing a peculiar compilation issue

* add SetTextValueAtPath, and GetStringValueAtPath

* updated to work with new rive layout

* basic rendering and shader permutations working

* made work with main

* win,android refactor update rive to bc8ed46e56b3c312f0333aa82f0486838a898739

* missing files

* macOS, iOS refactor update rive to bc8ed46e56b3c312f0333aa82f0486838a898739

* remove unused components and content

* header fixes for packaging

* update plugin icon with Rive graphic

* android rendertarget slip

* some cleanup and exports for gms

* more cleanup

* UR-207: Rive on Metal looks washed out

* commit basic FilterPlugin

* removed uneeded guards

* updated to latest runtime

* added rive rhi shaders

* removed dupliocate calls in render target

* allow some UTextures to be used as targets for runtime asset overriding

* fixed some compiler warnings and added flag to ignore shader warnings

* add rive renderer settings

* remvoe duplicate include

* added default load action instead of silencing warning

* updated to use the enable tech preview setting

* addressed PR comments

* move editor specific settings to RiveEditor module

* Use RiveFile initialization delegate before completing rivetextureobject init

* added webp loading, fixed issues with packaging the plugin

---------

Co-authored-by: blakdragan7 <jcopela4@gmail.com>
Co-authored-by: Tod-Rive <tod@rive.app>
  • Loading branch information
3 people authored Sep 25, 2024
1 parent 2937d21 commit fea91e9
Show file tree
Hide file tree
Showing 149 changed files with 23,042 additions and 166 deletions.
8 changes: 8 additions & 0 deletions Config/FilterPlugin.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[FilterPlugin]
; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and
; may include "...", "*", and "?" wildcards to match directories, files, and individual characters respectively.
;
; Examples:
; /README.txt
; /Extras/...
; /Binaries/ThirdParty/*.dll
270 changes: 270 additions & 0 deletions Shaders/Private/Rive/Generated/advanced_blend.minified.ush
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
/*
* Copyright 2022 Rive
*/

// From the KHR_blend_equation_advanced spec:
//
// The advanced blend equations are those listed in tables X.1 and X.2. When
// using one of these equations, blending is performed according to the
// following equations:
//
// R = f(Rs',Rd')*p0(As,Ad) + Y*Rs'*p1(As,Ad) + Z*Rd'*p2(As,Ad)
// G = f(Gs',Gd')*p0(As,Ad) + Y*Gs'*p1(As,Ad) + Z*Gd'*p2(As,Ad)
// B = f(Bs',Bd')*p0(As,Ad) + Y*Bs'*p1(As,Ad) + Z*Bd'*p2(As,Ad)
// A = X*p0(As,Ad) + Y*p1(As,Ad) + Z*p2(As,Ad)
//
// where the function f and terms X, Y, and Z are specified in the table.
// The R, G, and B components of the source color used for blending are
// considered to have been premultiplied by the A component prior to
// blending. The base source color (Rs',Gs',Bs') is obtained by dividing
// through by the A component:
//
// (Rs', Gs', Bs') =
// (0, 0, 0), if As == 0
// (Rs/As, Gs/As, Bs/As), otherwise
//
// The destination color components are always considered to have been
// premultiplied by the destination A component and the base destination
// color (Rd', Gd', Bd') is obtained by dividing through by the A component:
//
// (Rd', Gd', Bd') =
// (0, 0, 0), if Ad == 0
// (Rd/Ad, Gd/Ad, Bd/Ad), otherwise
//
// When blending using advanced blend equations, we expect that the R, G, and
// B components of premultiplied source and destination color inputs be
// stored as the product of non-premultiplied R, G, and B components and the
// A component of the color. If any R, G, or B component of a premultiplied
// input color is non-zero and the A component is zero, the color is
// considered ill-formed, and the corresponding component of the blend result
// will be undefined.
//
// The weighting functions p0, p1, and p2 are defined as follows:
//
// p0(As,Ad) = As*Ad
// p1(As,Ad) = As*(1-Ad)
// p2(As,Ad) = Ad*(1-As)
//
// In these functions, the A components of the source and destination colors
// are taken to indicate the portion of the pixel covered by the fragment
// (source) and the fragments previously accumulated in the pixel
// (destination). The functions p0, p1, and p2 approximate the relative
// portion of the pixel covered by the intersection of the source and
// destination, covered only by the source, and covered only by the
// destination, respectively. The equations defined here assume that there
// is no correlation between the source and destination coverage.
//

#ifdef FRAGMENT

#ifdef ENABLE_KHR_BLEND
layout(
#ifdef ENABLE_HSL_BLEND_MODES
blend_support_all_equations
#else
blend_support_multiply,
blend_support_screen,
blend_support_overlay,
blend_support_darken,
blend_support_lighten,
blend_support_colordodge,
blend_support_colorburn,
blend_support_hardlight,
blend_support_softlight,
blend_support_difference,
blend_support_exclusion
#endif
) out;
#endif // ENABLE_KHR_BLEND

#ifdef ENABLE_ADVANCED_BLEND
#ifdef ENABLE_HSL_BLEND_MODES
// When using one of the HSL blend equations in table X.2 as the blend equation, the RGB color
// components produced by the function f() are effectively obtained by converting both the
// non-premultiplied source and destination colors to the HSL (hue, saturation, luminosity) color
// space, generating a new HSL color by selecting H, S, and L components from the source or
// destination according to the blend equation, and then converting the result back to RGB. The HSL
// blend equations are only well defined when the values of the input color components are in the
// range [0..1].
half minv3(half3 c) { return min(min(c.x, c.y), c.z); }
half maxv3(half3 c) { return max(max(c.x, c.y), c.z); }
half lumv3(half3 c) { return dot(c, make_half3(.30, .59, .11)); }
half satv3(half3 c) { return maxv3(c) - minv3(c); }

// If any color components are outside [0,1], adjust the color to get the components in range.
half3 clip_color(half3 color)
{
half lum = lumv3(color);
half mincol = minv3(color);
half maxcol = maxv3(color);
if (mincol < .0)
color = lum + ((color - lum) * lum) / (lum - mincol);
if (maxcol > 1.)
color = lum + ((color - lum) * (1. - lum)) / (maxcol - lum);
return color;
}

// Take the base RGB color <cbase> and override its luminosity with that of the RGB color <clum>.
half3 set_lum(half3 cbase, half3 clum)
{
half lbase = lumv3(cbase);
half llum = lumv3(clum);
half ldiff = llum - lbase;
half3 color = cbase + make_half3(ldiff);
return clip_color(color);
}

// Take the base RGB color <cbase> and override its saturation with that of the RGB color <csat>.
// The override the luminosity of the result with that of the RGB color <clum>.
half3 set_lum_sat(half3 cbase, half3 csat, half3 clum)
{
half minbase = minv3(cbase);
half sbase = satv3(cbase);
half ssat = satv3(csat);
half3 color;
if (sbase > .0)
{
// Equivalent (modulo rounding errors) to setting the smallest (R,G,B) component to 0, the
// largest to <ssat>, and interpolating the "middle" component based on its original value
// relative to the smallest/largest.
color = (cbase - minbase) * ssat / sbase;
}
else
{
color = make_half3(.0);
}
return set_lum(color, clum);
}
#endif // ENABLE_HSL_BLEND_MODES

half4 advanced_blend(half4 src, half4 dst, ushort mode)
{
// The function f() operates on un-multiplied rgb values and dictates the look of the advanced
// blend equations.
half3 f = make_half3(.0);
switch (mode)
{
case BLEND_MODE_MULTIPLY:
f = src.xyz * dst.xyz;
break;
case BLEND_MODE_SCREEN:
f = src.xyz + dst.xyz - src.xyz * dst.xyz;
break;
case BLEND_MODE_OVERLAY:
{
for (int i = 0; i < 3; ++i)
{
if (dst[i] <= .5)
f[i] = 2. * src[i] * dst[i];
else
f[i] = 1. - 2. * (1. - src[i]) * (1. - dst[i]);
}
break;
}
case BLEND_MODE_DARKEN:
f = min(src.xyz, dst.xyz);
break;
case BLEND_MODE_LIGHTEN:
f = max(src.xyz, dst.xyz);
break;
case BLEND_MODE_COLORDODGE:
// ES3 spec, 4.5.1 Range and Precision: dividing a non-zero by 0 results in the
// appropriately signed IEEE Inf.
f = mix(min(dst.xyz / (1. - src.xyz), make_half3(1.)),
make_half3(.0),
lessThanEqual(dst.xyz, make_half3(.0)));
break;
case BLEND_MODE_COLORBURN:
// ES3 spec, 4.5.1 Range and Precision: dividing a non-zero by 0 results in the
// appropriately signed IEEE Inf.
f = mix(1. - min((1. - dst.xyz) / src.xyz, 1.),
make_half3(1., 1., 1.),
greaterThanEqual(dst.xyz, make_half3(1.)));
break;
case BLEND_MODE_HARDLIGHT:
{
for (int i = 0; i < 3; ++i)
{
if (src[i] <= .5)
f[i] = 2. * src[i] * dst[i];
else
f[i] = 1. - 2. * (1. - src[i]) * (1. - dst[i]);
}
break;
}
case BLEND_MODE_SOFTLIGHT:
{
for (int i = 0; i < 3; ++i)
{
if (src[i] <= 0.5)
f[i] = dst[i] - (1. - 2. * src[i]) * dst[i] * (1. - dst[i]);
else if (dst[i] <= .25)
f[i] =
dst[i] + (2. * src[i] - 1.) * dst[i] * ((16. * dst[i] - 12.) * dst[i] + 3.);
else
f[i] = dst[i] + (2. * src[i] - 1.) * (sqrt(dst[i]) - dst[i]);
}
break;
}
case BLEND_MODE_DIFFERENCE:
f = abs(dst.xyz - src.xyz);
break;
case BLEND_MODE_EXCLUSION:
f = src.xyz + dst.xyz - 2. * src.xyz * dst.xyz;
break;
#ifdef ENABLE_HSL_BLEND_MODES
// The HSL blend equations are only well defined when the values of the input color
// components are in the range [0..1].
case BLEND_MODE_HUE:
if (ENABLE_HSL_BLEND_MODES)
{
src.xyz = clamp(src.xyz, make_half3(.0), make_half3(1.));
f = set_lum_sat(src.xyz, dst.xyz, dst.xyz);
}
break;
case BLEND_MODE_SATURATION:
if (ENABLE_HSL_BLEND_MODES)
{
src.xyz = clamp(src.xyz, make_half3(.0), make_half3(1.));
f = set_lum_sat(dst.xyz, src.xyz, dst.xyz);
}
break;
case BLEND_MODE_COLOR:
if (ENABLE_HSL_BLEND_MODES)
{
src.xyz = clamp(src.xyz, make_half3(.0), make_half3(1.));
f = set_lum(src.xyz, dst.xyz);
}
break;
case BLEND_MODE_LUMINOSITY:
if (ENABLE_HSL_BLEND_MODES)
{
src.xyz = clamp(src.xyz, make_half3(.0), make_half3(1.));
f = set_lum(dst.xyz, src.xyz);
}
break;
#endif
}

// The weighting functions p0, p1, and p2 are defined as follows:
//
// p0(As,Ad) = As*Ad
// p1(As,Ad) = As*(1-Ad)
// p2(As,Ad) = Ad*(1-As)
//
half3 p = make_half3(src.w * dst.w, src.w * (1. - dst.w), (1. - src.w) * dst.w);

// When using one of these equations, blending is performed according to the following
// equations:
//
// R = f(Rs',Rd')*p0(As,Ad) + Y*Rs'*p1(As,Ad) + Z*Rd'*p2(As,Ad)
// G = f(Gs',Gd')*p0(As,Ad) + Y*Gs'*p1(As,Ad) + Z*Gd'*p2(As,Ad)
// B = f(Bs',Bd')*p0(As,Ad) + Y*Bs'*p1(As,Ad) + Z*Bd'*p2(As,Ad)
// A = X*p0(As,Ad) + Y*p1(As,Ad) + Z*p2(As,Ad)
//
// NOTE: (X,Y,Z) always == (1,1,1), so it is ignored in this implementation.
return MUL(make_half3x4(f, 1., src.xyz, 1., dst.xyz, 1.), p);
}
#endif // ENABLE_ADVANCED_BLEND

#endif // FRAGMENT
Loading

0 comments on commit fea91e9

Please sign in to comment.