1
0
mirror of https://github.com/flutter/samples.git synced 2026-04-27 01:48:21 +00:00

Next Gen UI demo (#1778)

First pass at a Next Generation UI demo app. The UI needs work, feedback
gratefully accepted.

## Pre-launch Checklist

- [x] I read the [Flutter Style Guide] _recently_, and have followed its
advice.
- [x] I signed the [CLA].
- [x] I read the [Contributors Guide].
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-devrel
channel on [Discord].

<!-- Links -->
[Flutter Style Guide]:
https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo
[CLA]: https://cla.developers.google.com/
[Discord]: https://github.com/flutter/flutter/wiki/Chat
[Contributors Guide]:
https://github.com/flutter/samples/blob/main/CONTRIBUTING.md
This commit is contained in:
Brett Morgan
2023-05-17 12:45:47 +10:00
committed by GitHub
parent e2ada7a698
commit aec29f869b
187 changed files with 11174 additions and 0 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,93 @@
Copyright 2017 The Exo Project Authors (https://github.com/NDISCOVER/Exo-1.0)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,16 @@
// Copyright 2023 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#define M_PI 3.14159265
#define M_INVPI 0.31830989
float hash_1d(float v) {
float u = 50.0 * sin(v * 3000.0);
return 2.0 * fract(2.0 * u * u) - 1.0;
}
float hash_2d(vec2 pos) {
vec2 uv = 50.0 * fract(pos * M_INVPI);
return 2.0 * fract(uv.x * uv.y * (uv.x + uv.y)) - 1.0;
}

View File

@@ -0,0 +1,332 @@
// Copyright 2023 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#version 460 core
#include "common/common.glsl"
#include <flutter/runtime_effect.glsl>
#define RAY_STEPS 30
uniform vec2 uResolution;
uniform vec4 uPackedData;
float uTime = uPackedData[0];
float uExposure = uPackedData[1];
float uFov = uPackedData[2];
float uRoughness = uPackedData[3];
uniform float uMetalness;
uniform vec3 uLightDir;
uniform float uLightR;
uniform vec3 uLightLumP;
uniform vec3 uAlbedo;
uniform float uIor;
uniform float uLightQuadAtt;
uniform vec3 uAmbientLight;
uniform float uAmbientLightDepthFactor;
uniform float uEnergy;
out vec4 oColor;
float noise_2d(vec2 pos) {
vec2 g = floor(pos);
float a = hash_2d(g);
float b = hash_2d(g + vec2(1.0, 0.0));
float c = hash_2d(g + vec2(0.0, 1.0));
float d = hash_2d(g + vec2(1.0, 1.0));
vec2 fp = pos - g;
vec2 sfp = smoothstep(vec2(0.0), vec2(1.0), fp);
return a + (b - a) * sfp.x + (c - a) * sfp.y +
(a - b - c + d) * sfp.x * sfp.y;
}
vec3 closest_point_on_disc(vec3 center, vec3 normal, float radius, vec3 p) {
vec3 r = p - center;
vec3 pr = r - dot(r, normal) * normal;
return center + normalize(pr) * min(length(pr), radius);
}
// Compute area light illuminance from: Moving Frostbite to Physically Based
// Rendering 3.0, Siggraph 2014
float illuminanceSphereOrDisk(float cosTheta, float sinSigmaSqr) {
float cosThetaSqr = cosTheta * cosTheta;
float sinTheta = sqrt(1.0 - cosThetaSqr);
float illuminance = 0.0;
if (cosThetaSqr > sinSigmaSqr) {
illuminance = M_PI * sinSigmaSqr * clamp(cosTheta, 0.0, 1.0);
} else {
float x = sqrt(1.0 / sinSigmaSqr - 1.0);
float y = -x * (cosTheta / sinTheta);
float sinThetaSqrtY = sinTheta * sqrt(1.0 - y * y);
illuminance = (cosTheta * acos(y) - x * sinThetaSqrtY) * sinSigmaSqr +
atan(sinThetaSqrtY / x);
}
return max(illuminance, 0.0);
}
float evalIlluminanceDisk(vec3 N, vec3 L, vec3 lightN, float lightRadius,
float lightDistSqr) {
float cosTheta = dot(N, L);
float lightRSqr = lightRadius * lightRadius;
float sinSigmaSqr = lightRSqr / (lightRSqr + max(lightRSqr, lightDistSqr));
float illuminance = illuminanceSphereOrDisk(cosTheta, sinSigmaSqr) *
clamp(dot(lightN, -L), 0.0, 1.0);
return illuminance;
}
float distribution_ggx(vec3 N, vec3 H, float roughness) {
float a = roughness * roughness;
float a2 = a * a;
float NdotH = max(dot(N, H), 0.0);
float NdotH2 = NdotH * NdotH;
float nom = a2;
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
denom = M_PI * denom * denom;
return nom / denom;
}
float geometry_schlick_ggx(float NdotV, float roughness) {
float r = (roughness + 1.0);
float k = (r * r) / 8.0;
float nom = NdotV;
float denom = NdotV * (1.0 - k) + k;
return nom / denom;
}
float geometry_smith(vec3 N, vec3 V, float cosTheta, float roughness) {
float NdotV = max(dot(N, V), 0.0);
float ggx2 = geometry_schlick_ggx(NdotV, roughness);
float ggx1 = geometry_schlick_ggx(cosTheta, roughness);
return ggx1 * ggx2;
}
vec3 fresnel_schlick(float cosTheta, vec3 F0) {
return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
}
vec3 brdf_eval(vec3 N, vec3 L, vec3 H, vec3 V, vec3 albedo, float roughness,
float metalness, vec3 Li) {
roughness = max(0.2, roughness);
float cosTheta = max(dot(N, L), 0.0);
// Diffuse color
vec3 F0 = vec3(0.04);
F0 = mix(F0, albedo, metalness);
float NDF = distribution_ggx(N, H, roughness);
float G = geometry_smith(N, V, cosTheta, roughness);
vec3 F = fresnel_schlick(max(dot(H, V), 0.0), F0);
vec3 num = NDF * G * F;
float denom = 4.0 * max(dot(N, V), 0.0) * cosTheta;
vec3 spec = num / max(denom, 0.001);
vec3 kS = F;
vec3 kD = 1.0 - kS;
kD *= (1.0 - metalness);
vec3 Lo = (kD * albedo / M_PI + spec) * Li * cosTheta;
return Lo;
}
vec3 btdf_eval(vec3 N, vec3 L, vec3 albedo, vec3 Li) {
vec3 Lo = albedo * Li * max(dot(N, L), 0.0);
return Lo;
}
vec2 oct_encode(vec3 d) {
vec3 octant = sign(d);
// Compute l1-norm version of the direction vector
float sum = dot(d, octant);
vec3 octahedron = d / sum;
if (octahedron.z < 0.0) {
vec3 a = abs(octahedron);
octahedron.xy = octant.xy * (vec2(1.0) - a.yx);
}
return octahedron.xy * 0.5 + 0.5;
}
const mat2 octM0 = mat2(1.0, 0.0, 0.0, 1.0);
const mat2 octM1 = mat2(0.809017, 0.587785, -0.587785, 0.809017);
const mat2 octM2 = mat2(0.309017, 0.951057, -0.951057, 0.309017);
const mat2 octM3 = mat2(-0.309017, 0.951057, -0.951057, -0.309017);
float fbm(vec2 pos) {
float sum = 0.0;
sum += noise_2d(octM0 * pos);
sum += 0.5 * noise_2d(2.0 * octM1 * pos);
sum += 0.25 * noise_2d(4.0 * octM2 * pos);
sum += 0.125 * noise_2d(8.0 * octM3 * pos);
return sum;
}
vec2 fbm_sphere_sdf(vec3 center, float radius, vec3 pos) {
vec3 toP = pos - center;
radius = radius * mix(0.5, 1.0, uEnergy);
float d = length(toP);
vec2 uv = oct_encode(toP);
float amp = mix(0.1, 0.6, uEnergy);
float dd = fbm(uv * 15.0 + uTime * vec2(1.0, -0.4)) * amp;
return vec2(d + dd - radius,
mix(0.4, 1.0, float(d - (radius + 1.0 * amp) > 0.0)));
}
vec2 sample_scene(vec3 pos) {
return fbm_sphere_sdf(vec3(0.0, 0.0, -10.0), 2.0, pos);
}
const float sampleScale = 1.0 / sqrt(3.0) * 0.0005;
vec3 sample_normal(vec3 pos) {
#define NORMAL_SDF_SAMPLE_COUNT 4
vec3 normalSampleOffsets[NORMAL_SDF_SAMPLE_COUNT];
normalSampleOffsets[0] = vec3(1.0, -1.0, -1.0);
normalSampleOffsets[1] = vec3(-1.0, -1.0, 1.0);
normalSampleOffsets[2] = vec3(-1.0, 1.0, -1.0);
normalSampleOffsets[3] = vec3(1.0, 1.0, 1.0);
vec3 result = vec3(0.0);
for (int i = 0; i < NORMAL_SDF_SAMPLE_COUNT; ++i) {
result += normalSampleOffsets[i] * sampleScale *
sample_scene(pos + normalSampleOffsets[i]).x;
}
return normalize(result);
}
float raymarch(vec3 start, vec3 dir) {
float tMin = 8.0;
float tMax = 15.0;
float t = tMin;
float result = -1.0;
for (int i = 0; i < RAY_STEPS; ++i) {
if (t >= tMax)
break;
vec2 d = sample_scene(start + dir * t);
if (d.x < 0.0002) {
result = t;
break;
}
t += d.x * d.y;
}
return result;
}
void look_at(out mat3 cam, in vec3 eye, in vec3 center, in vec3 up) {
// Construct an ortho-normal basis for the camera
vec3 forward = normalize(center - eye);
vec3 right = cross(forward, up);
up = cross(right, forward);
cam = mat3(right, up, forward);
}
void sample_camera_ray(out vec3 origin, out vec3 direction, in mat3 cam,
vec3 eye, vec2 uv) {
uv *= 2.0;
uv -= 1.0;
uv.y *= -1.0;
float aspectRatio = uResolution.y / uResolution.x;
float vWidth = tan(uFov / 2.0);
float vHeight = vWidth * aspectRatio;
vec3 forward = cam * vec3(0.0, 0.0, 1.0);
vec3 rayDir = cam * vec3(uv.x * vWidth, uv.y * vHeight, 1.0);
origin = eye;
direction = normalize(rayDir);
}
vec3 sample_disk_light(out vec3 L, vec3 P, vec3 N, vec3 lightP, vec3 lightN,
float lightR, vec3 lightAtt, vec3 lightLumP) {
vec3 toL = closest_point_on_disc(lightP, lightN, lightR, P) - P;
L = normalize(toL);
toL *= lightAtt.x;
float illuminance = evalIlluminanceDisk(N, L, lightN, lightR, dot(toL, toL));
vec3 Li = lightLumP * illuminance;
return Li;
}
vec4 pixel_color(vec3 o, vec3 d, vec3 lightP, vec3 lightN, float lightR,
vec3 lightAtt, vec3 lightLumP) {
float t = raymarch(o, d);
vec4 result = vec4(0.0);
if (t >= 0.0) {
vec3 P = o + d * t;
vec3 N = sample_normal(P);
vec3 V = -d;
vec3 R = refract(-V, N, uIor);
float z = dot(vec3(0.0, 0.0, -1.0), P);
float zd = smoothstep(mix(0.0, 11.0, uAmbientLightDepthFactor), 14.0, z);
vec3 Lo = vec3(0.0);
vec3 L, Li;
vec3 S = fresnel_schlick(max(dot(N, V), 0.0), vec3(0.02));
Li =
sample_disk_light(L, P, R, lightP, lightN, lightR, lightAtt, lightLumP);
Lo += (1.0 - S) * brdf_eval(-N, L, normalize(L + R), R, uAlbedo, uRoughness,
uMetalness, Li);
Lo += zd * uAlbedo * uAmbientLight;
result = vec4(Lo, 1.0);
}
return result;
}
void main() {
vec2 uv = vec2(FlutterFragCoord().xy) / uResolution;
vec3 lightN = normalize(-uLightDir);
vec3 lightP = vec3(0.0, 0.0, -10.0) + uLightDir;
vec3 lightAtt = vec3(uLightQuadAtt, 0.0, 1.0);
vec3 eye = vec3(0.0, 0.0, 1.0);
vec3 center = vec3(0.0, 0.0, 0.0);
vec3 up = vec3(0.0, 1.0, 0.0);
mat3 cam;
look_at(cam, eye, center, up);
vec3 o, d;
sample_camera_ray(o, d, cam, eye, uv);
vec4 hdrColor =
abs(pixel_color(o, d, lightP, lightN, uLightR, lightAtt, uLightLumP));
vec3 ldrColor = vec3(1.0) - exp(min(-(hdrColor.rgb) * uExposure, 0.0));
oColor = vec4(ldrColor, hdrColor.a);
}

View File

@@ -0,0 +1,68 @@
// Copyright 2023 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#version 460 core
#include "common/common.glsl"
#include <flutter/runtime_effect.glsl>
uniform vec2 uResolution;
uniform float uTime;
uniform sampler2D uTex;
out vec4 oColor;
float cubicPulse(float c, float w, float x) {
x = abs(x - c);
if (x > w)
return 0.0;
x /= w;
return 1.0 - x*x*(3.0 - 2.0*x);
}
float twoSin(float x) {
x = 6.49*x - 0.65;
float t = -0.7*sin(6.8*x) + 1.4*sin(2.9*x);
t = t/4.1 + 0.5;
return t;
}
void main() {
vec2 uv = vec2(FlutterFragCoord().xy) / uResolution;
float t_2 = cubicPulse(.5, .05, fract(uTime / 4.0));
float t_1 = twoSin(fract(uTime / 5.0));
float glitchScale = mix(0.0, 8.0, t_1 + t_2);
float aberrationSize = mix(0.0, 5.0, t_1 + t_2);
float h = hash_1d(uv.y);
float hs = sign(h);
h = max(h, 0.0);
h = h * h;
h = round(h) * hs;
uv += vec2(h * glitchScale, 0.0) / uResolution;
vec2 redOffset = vec2(aberrationSize, 0.0) / uResolution;
vec2 greenOffset = vec2(0.0, 0.0) / uResolution;
vec2 blueOffset = vec2(-aberrationSize, 0.0) / uResolution;
vec2 redUv = uv + redOffset;
vec2 greenUv = uv + greenOffset;
vec2 blueUv = uv + blueOffset;
vec2 ra = texture(uTex, redUv).ra;
vec2 ga = texture(uTex, greenUv).ga;
vec2 ba = texture(uTex, blueUv).ba;
// Convert from pre-multiplied alpha
ra.x /= ra.y;
ga.x /= ga.y;
ba.x /= ba.y;
float alpha = max(ra.y, max(ga.y, ba.y));
oColor = vec4(ra.x, ga.x, ba.x, 1.0) * alpha;
}