mirror of
https://github.com/bevyengine/bevy
synced 2024-11-23 05:03:47 +00:00
feedback
This commit is contained in:
parent
6e5446815f
commit
f2af2853a9
15 changed files with 88 additions and 88 deletions
|
@ -23,8 +23,8 @@ struct CASUniforms {
|
|||
sharpness: f32,
|
||||
};
|
||||
|
||||
@group(0) @binding(0) var screenTexture: texture_2d<f32>;
|
||||
@group(0) @binding(1) var textureSampler: sampler;
|
||||
@group(0) @binding(0) var screen_texture: texture_2d<f32>;
|
||||
@group(0) @binding(1) var samplr: sampler;
|
||||
@group(0) @binding(2) var<uniform> uniforms: CASUniforms;
|
||||
|
||||
// This is set at the limit of providing unnatural results for sharpening.
|
||||
|
@ -62,12 +62,12 @@ fn fragment(in: FullscreenVertexOutput) -> @location(0) vec4<f32> {
|
|||
// b
|
||||
// d e f
|
||||
// h
|
||||
let b = textureSample(screenTexture, textureSampler, in.uv, vec2<i32>(0, -1)).rgb;
|
||||
let d = textureSample(screenTexture, textureSampler, in.uv, vec2<i32>(-1, 0)).rgb;
|
||||
let b = textureSample(screen_texture, samplr, in.uv, vec2<i32>(0, -1)).rgb;
|
||||
let d = textureSample(screen_texture, samplr, in.uv, vec2<i32>(-1, 0)).rgb;
|
||||
// We need the alpha value of the pixel we're working on for the output
|
||||
let e = textureSample(screenTexture, textureSampler, in.uv).rgbw;
|
||||
let f = textureSample(screenTexture, textureSampler, in.uv, vec2<i32>(1, 0)).rgb;
|
||||
let h = textureSample(screenTexture, textureSampler, in.uv, vec2<i32>(0, 1)).rgb;
|
||||
let e = textureSample(screen_texture, samplr, in.uv).rgbw;
|
||||
let f = textureSample(screen_texture, samplr, in.uv, vec2<i32>(1, 0)).rgb;
|
||||
let h = textureSample(screen_texture, samplr, in.uv, vec2<i32>(0, 1)).rgb;
|
||||
// Min and max of ring.
|
||||
let mn4 = min(min(b, d), min(f, h));
|
||||
let mx4 = max(max(b, d), max(f, h));
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
#import bevy_core_pipeline::fullscreen_vertex_shader::FullscreenVertexOutput
|
||||
|
||||
@group(0) @binding(0) var screenTexture: texture_2d<f32>;
|
||||
@group(0) @binding(1) var textureSampler: sampler;
|
||||
@group(0) @binding(0) var screen_texture: texture_2d<f32>;
|
||||
@group(0) @binding(1) var samplr: sampler;
|
||||
|
||||
// Trims the algorithm from processing darks.
|
||||
#ifdef EDGE_THRESH_MIN_LOW
|
||||
|
@ -74,21 +74,21 @@ fn rgb2luma(rgb: vec3<f32>) -> f32 {
|
|||
// Performs FXAA post-process anti-aliasing as described in the Nvidia FXAA white paper and the associated shader code.
|
||||
@fragment
|
||||
fn fragment(in: FullscreenVertexOutput) -> @location(0) vec4<f32> {
|
||||
let resolution = vec2<f32>(textureDimensions(screenTexture));
|
||||
let resolution = vec2<f32>(textureDimensions(screen_texture));
|
||||
let inverseScreenSize = 1.0 / resolution.xy;
|
||||
let texCoord = in.position.xy * inverseScreenSize;
|
||||
|
||||
let centerSample = textureSampleLevel(screenTexture, textureSampler, texCoord, 0.0);
|
||||
let centerSample = textureSampleLevel(screen_texture, samplr, texCoord, 0.0);
|
||||
let colorCenter = centerSample.rgb;
|
||||
|
||||
// Luma at the current fragment
|
||||
let lumaCenter = rgb2luma(colorCenter);
|
||||
|
||||
// Luma at the four direct neighbors of the current fragment.
|
||||
let lumaDown = rgb2luma(textureSampleLevel(screenTexture, textureSampler, texCoord, 0.0, vec2<i32>(0, -1)).rgb);
|
||||
let lumaUp = rgb2luma(textureSampleLevel(screenTexture, textureSampler, texCoord, 0.0, vec2<i32>(0, 1)).rgb);
|
||||
let lumaLeft = rgb2luma(textureSampleLevel(screenTexture, textureSampler, texCoord, 0.0, vec2<i32>(-1, 0)).rgb);
|
||||
let lumaRight = rgb2luma(textureSampleLevel(screenTexture, textureSampler, texCoord, 0.0, vec2<i32>(1, 0)).rgb);
|
||||
let lumaDown = rgb2luma(textureSampleLevel(screen_texture, samplr, texCoord, 0.0, vec2<i32>(0, -1)).rgb);
|
||||
let lumaUp = rgb2luma(textureSampleLevel(screen_texture, samplr, texCoord, 0.0, vec2<i32>(0, 1)).rgb);
|
||||
let lumaLeft = rgb2luma(textureSampleLevel(screen_texture, samplr, texCoord, 0.0, vec2<i32>(-1, 0)).rgb);
|
||||
let lumaRight = rgb2luma(textureSampleLevel(screen_texture, samplr, texCoord, 0.0, vec2<i32>(1, 0)).rgb);
|
||||
|
||||
// Find the maximum and minimum luma around the current fragment.
|
||||
let lumaMin = min(lumaCenter, min(min(lumaDown, lumaUp), min(lumaLeft, lumaRight)));
|
||||
|
@ -103,10 +103,10 @@ fn fragment(in: FullscreenVertexOutput) -> @location(0) vec4<f32> {
|
|||
}
|
||||
|
||||
// Query the 4 remaining corners lumas.
|
||||
let lumaDownLeft = rgb2luma(textureSampleLevel(screenTexture, textureSampler, texCoord, 0.0, vec2<i32>(-1, -1)).rgb);
|
||||
let lumaUpRight = rgb2luma(textureSampleLevel(screenTexture, textureSampler, texCoord, 0.0, vec2<i32>(1, 1)).rgb);
|
||||
let lumaUpLeft = rgb2luma(textureSampleLevel(screenTexture, textureSampler, texCoord, 0.0, vec2<i32>(-1, 1)).rgb);
|
||||
let lumaDownRight = rgb2luma(textureSampleLevel(screenTexture, textureSampler, texCoord, 0.0, vec2<i32>(1, -1)).rgb);
|
||||
let lumaDownLeft = rgb2luma(textureSampleLevel(screen_texture, samplr, texCoord, 0.0, vec2<i32>(-1, -1)).rgb);
|
||||
let lumaUpRight = rgb2luma(textureSampleLevel(screen_texture, samplr, texCoord, 0.0, vec2<i32>(1, 1)).rgb);
|
||||
let lumaUpLeft = rgb2luma(textureSampleLevel(screen_texture, samplr, texCoord, 0.0, vec2<i32>(-1, 1)).rgb);
|
||||
let lumaDownRight = rgb2luma(textureSampleLevel(screen_texture, samplr, texCoord, 0.0, vec2<i32>(1, -1)).rgb);
|
||||
|
||||
// Combine the four edges lumas (using intermediary variables for future computations with the same values).
|
||||
let lumaDownUp = lumaDown + lumaUp;
|
||||
|
@ -174,8 +174,8 @@ fn fragment(in: FullscreenVertexOutput) -> @location(0) vec4<f32> {
|
|||
var uv2 = currentUv + offset; // * QUALITY(0); // (quality 0 is 1.0)
|
||||
|
||||
// Read the lumas at both current extremities of the exploration segment, and compute the delta wrt to the local average luma.
|
||||
var lumaEnd1 = rgb2luma(textureSampleLevel(screenTexture, textureSampler, uv1, 0.0).rgb);
|
||||
var lumaEnd2 = rgb2luma(textureSampleLevel(screenTexture, textureSampler, uv2, 0.0).rgb);
|
||||
var lumaEnd1 = rgb2luma(textureSampleLevel(screen_texture, samplr, uv1, 0.0).rgb);
|
||||
var lumaEnd2 = rgb2luma(textureSampleLevel(screen_texture, samplr, uv2, 0.0).rgb);
|
||||
lumaEnd1 = lumaEnd1 - lumaLocalAverage;
|
||||
lumaEnd2 = lumaEnd2 - lumaLocalAverage;
|
||||
|
||||
|
@ -193,12 +193,12 @@ fn fragment(in: FullscreenVertexOutput) -> @location(0) vec4<f32> {
|
|||
for (var i: i32 = 2; i < ITERATIONS; i = i + 1) {
|
||||
// If needed, read luma in 1st direction, compute delta.
|
||||
if (!reached1) {
|
||||
lumaEnd1 = rgb2luma(textureSampleLevel(screenTexture, textureSampler, uv1, 0.0).rgb);
|
||||
lumaEnd1 = rgb2luma(textureSampleLevel(screen_texture, samplr, uv1, 0.0).rgb);
|
||||
lumaEnd1 = lumaEnd1 - lumaLocalAverage;
|
||||
}
|
||||
// If needed, read luma in opposite direction, compute delta.
|
||||
if (!reached2) {
|
||||
lumaEnd2 = rgb2luma(textureSampleLevel(screenTexture, textureSampler, uv2, 0.0).rgb);
|
||||
lumaEnd2 = rgb2luma(textureSampleLevel(screen_texture, samplr, uv2, 0.0).rgb);
|
||||
lumaEnd2 = lumaEnd2 - lumaLocalAverage;
|
||||
}
|
||||
// If the luma deltas at the current extremities is larger than the local gradient, we have reached the side of the edge.
|
||||
|
@ -269,6 +269,6 @@ fn fragment(in: FullscreenVertexOutput) -> @location(0) vec4<f32> {
|
|||
}
|
||||
|
||||
// Read the color at the new UV coordinates, and use it.
|
||||
var finalColor = textureSampleLevel(screenTexture, textureSampler, finalUv, 0.0).rgb;
|
||||
var finalColor = textureSampleLevel(screen_texture, samplr, finalUv, 0.0).rgb;
|
||||
return vec4<f32>(finalColor, centerSample.a);
|
||||
}
|
||||
|
|
|
@ -180,7 +180,7 @@ impl NormedVectorSpace for f32 {
|
|||
///
|
||||
/// 3. Importantly, the interpolation must be *subdivision-stable*: for any interpolation curve
|
||||
/// between two (unnamed) values and any parameter-value pairs `(t0, p)` and `(t1, q)`, the
|
||||
/// interpolation curve between `p` and `q` must be the *linear* reparameterization of the original
|
||||
/// interpolation curve between `p` and `q` must be the *linear* reparametrization of the original
|
||||
/// interpolation curve restricted to the interval `[t0, t1]`.
|
||||
///
|
||||
/// The last of these conditions is very strong and indicates something like constant speed. It
|
||||
|
@ -191,13 +191,13 @@ impl NormedVectorSpace for f32 {
|
|||
/// ```text
|
||||
/// top curve = u.interpolate_stable(v, t)
|
||||
///
|
||||
/// t0 => p t1 => q
|
||||
/// t0 => p t1 => q
|
||||
/// |-------------|---------|-------------|
|
||||
/// 0 => u / \ 1 => v
|
||||
/// / \
|
||||
/// / \
|
||||
/// / linear \
|
||||
/// / reparameterization \
|
||||
/// / reparametrization \
|
||||
/// / t = t0 * (1 - s) + t1 * s \
|
||||
/// / \
|
||||
/// |-------------------------------------|
|
||||
|
|
|
@ -350,7 +350,7 @@ impl<P: VectorSpace> CyclicCubicGenerator<P> for CubicCardinalSpline<P> {
|
|||
}
|
||||
|
||||
// This would ordinarily be the last segment, but we pick it out so that we can make it first
|
||||
// in order to get a desirable parameterization where the first segment connects the first two
|
||||
// in order to get a desirable parametrization where the first segment connects the first two
|
||||
// control points instead of the second and third.
|
||||
let first_segment = {
|
||||
// We take the indices mod `len` in case `len` is very small.
|
||||
|
@ -482,7 +482,7 @@ impl<P: VectorSpace> CyclicCubicGenerator<P> for CubicBSpline<P> {
|
|||
.map(|(&a, &b, &c, &d)| CubicSegment::coefficients([a, b, c, d], self.char_matrix()))
|
||||
.collect_vec();
|
||||
|
||||
// Note that the parameterization is consistent with the one for `to_curve` but with
|
||||
// Note that the parametrization is consistent with the one for `to_curve` but with
|
||||
// the extra curve segments all tacked on at the end. This might be slightly counter-intuitive,
|
||||
// since it means the first segment doesn't go "between" the first two control points, but
|
||||
// between the second and third instead.
|
||||
|
|
|
@ -268,7 +268,7 @@ where
|
|||
}
|
||||
|
||||
/// A curve whose sample space is mapped onto that of some base curve's before sampling.
|
||||
/// Curves of this type are produced by [`Curve::reparameterize`].
|
||||
/// Curves of this type are produced by [`Curve::reparametrize`].
|
||||
#[derive(Clone)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(
|
||||
|
@ -362,8 +362,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// A curve that has had its domain changed by a linear reparameterization (stretching and scaling).
|
||||
/// Curves of this type are produced by [`Curve::reparameterize_linear`].
|
||||
/// A curve that has had its domain changed by a linear reparametrization (stretching and scaling).
|
||||
/// Curves of this type are produced by [`Curve::reparametrize_linear`].
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(
|
||||
|
@ -397,8 +397,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// A curve that has been reparameterized by another curve, using that curve to transform the
|
||||
/// sample times before sampling. Curves of this type are produced by [`Curve::reparameterize_by_curve`].
|
||||
/// A curve that has been reparametrized by another curve, using that curve to transform the
|
||||
/// sample times before sampling. Curves of this type are produced by [`Curve::reparametrize_by_curve`].
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(
|
||||
|
@ -497,7 +497,7 @@ where
|
|||
}
|
||||
|
||||
/// The curve that results from chaining one curve with another. The second curve is
|
||||
/// effectively reparameterized so that its start is at the end of the first.
|
||||
/// effectively reparametrized so that its start is at the end of the first.
|
||||
///
|
||||
/// For this to be well-formed, the first curve's domain must be right-finite and the second's
|
||||
/// must be left-finite.
|
||||
|
|
|
@ -424,14 +424,14 @@ impl<T> UnevenCore<T> {
|
|||
}
|
||||
|
||||
/// This core, but with the sample times moved by the map `f`.
|
||||
/// In principle, when `f` is monotone, this is equivalent to [`Curve::reparameterize`],
|
||||
/// In principle, when `f` is monotone, this is equivalent to [`Curve::reparametrize`],
|
||||
/// but the function inputs to each are inverses of one another.
|
||||
///
|
||||
/// The samples are re-sorted by time after mapping and deduplicated by output time, so
|
||||
/// the function `f` should generally be injective over the set of sample times, otherwise
|
||||
/// data will be deleted.
|
||||
///
|
||||
/// [`Curve::reparameterize`]: crate::curve::Curve::reparameterize
|
||||
/// [`Curve::reparametrize`]: crate::curve::Curve::reparametrize
|
||||
#[must_use]
|
||||
pub fn map_sample_times(mut self, f: impl Fn(f32) -> f32) -> UnevenCore<T> {
|
||||
let mut timed_samples = self
|
||||
|
|
|
@ -207,7 +207,7 @@ pub enum EaseFunction {
|
|||
/// `n` steps connecting the start and the end
|
||||
Steps(usize),
|
||||
|
||||
/// `f(omega,t) = 1 - (1 - t)²(2sin(omega * t) / omega + cos(omega * t))`, parameterized by `omega`
|
||||
/// `f(omega,t) = 1 - (1 - t)²(2sin(omega * t) / omega + cos(omega * t))`, parametrized by `omega`
|
||||
Elastic(f32),
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ use super::{ConstantCurve, Interval};
|
|||
/// but side-stepping issues with allocation on sampling. This happens when the size of an output
|
||||
/// array cannot be known statically.
|
||||
pub trait IterableCurve<T> {
|
||||
/// The interval over which this curve is parameterized.
|
||||
/// The interval over which this curve is parametrized.
|
||||
fn domain(&self) -> Interval;
|
||||
|
||||
/// Sample a point on this curve at the parameter value `t`, producing an iterator over values.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//! ## Overview
|
||||
//!
|
||||
//! At a high level, [`Curve`] is a trait that abstracts away the implementation details of curves,
|
||||
//! which comprise any kind of data parameterized by a single continuous variable. For example, that
|
||||
//! which comprise any kind of data parametrized by a single continuous variable. For example, that
|
||||
//! variable could represent time, in which case a curve would represent a value that changes over
|
||||
//! time, as in animation; on the other hand, it could represent something like displacement or
|
||||
//! distance, as in graphs, gradients, and curves in space.
|
||||
|
@ -14,7 +14,7 @@
|
|||
//!
|
||||
//! A primary goal of the trait is to allow interfaces to simply accept `impl Curve<T>` as input
|
||||
//! rather than requiring for input curves to be defined in data in any particular way. This is
|
||||
//! supported by a number of interface methods which allow [changing parameterizations], [mapping output],
|
||||
//! supported by a number of interface methods which allow [changing parametrizations], [mapping output],
|
||||
//! and [rasterization].
|
||||
//!
|
||||
//! ## Analogy with `Iterator`
|
||||
|
@ -25,7 +25,7 @@
|
|||
//! | Iterators | Curves |
|
||||
//! | :--------------- | :-------------- |
|
||||
//! | `map` | `map` |
|
||||
//! | `skip`/`step_by` | `reparameterize` |
|
||||
//! | `skip`/`step_by` | `reparametrize` |
|
||||
//! | `enumerate` | `graph` |
|
||||
//! | `chain` | `chain` |
|
||||
//! | `zip` | `zip` |
|
||||
|
@ -118,7 +118,7 @@
|
|||
//! you would like to make use of an interface that requires a curve that bears some logical relationship
|
||||
//! to one that you already have access to, but with different requirements or expectations. For example,
|
||||
//! the output type of the curves may differ, or the domain may be expected to be different. The `map`
|
||||
//! and `reparameterize` methods can help address this.
|
||||
//! and `reparametrize` methods can help address this.
|
||||
//!
|
||||
//! As a simple example of the kind of thing that arises in practice, let's imagine that we have a
|
||||
//! `Curve<Vec2>` that we want to use to describe the motion of some object over time, but the interface
|
||||
|
@ -137,18 +137,18 @@
|
|||
//! ```
|
||||
//!
|
||||
//! We might imagine further still that the interface expects the curve to have domain `[0, 1]`. The
|
||||
//! `reparameterize` methods can address this:
|
||||
//! `reparametrize` methods can address this:
|
||||
//! ```rust
|
||||
//! # use bevy_math::{vec2, prelude::*};
|
||||
//! # use std::f32::consts::TAU;
|
||||
//! # let ellipse_curve = FunctionCurve::new(interval(0.0, TAU).unwrap(), |t| vec2(t.cos(), t.sin() * 2.0));
|
||||
//! # let ellipse_motion_curve = ellipse_curve.map(|pos| pos.extend(0.0));
|
||||
//! // Change the domain to `[0, 1]` instead of `[0, TAU]`:
|
||||
//! let final_curve = ellipse_motion_curve.reparameterize_linear(Interval::UNIT).unwrap();
|
||||
//! let final_curve = ellipse_motion_curve.reparametrize_linear(Interval::UNIT).unwrap();
|
||||
//! ```
|
||||
//!
|
||||
//! Of course, there are many other ways of using these methods. In general, `map` is used for transforming
|
||||
//! the output and using it to drive something else, while `reparameterize` preserves the curve's shape but
|
||||
//! the output and using it to drive something else, while `reparametrize` preserves the curve's shape but
|
||||
//! changes the speed and direction in which it is traversed. For instance:
|
||||
//! ```rust
|
||||
//! # use bevy_math::{vec2, prelude::*};
|
||||
|
@ -161,12 +161,12 @@
|
|||
//! //
|
||||
//! // Start by stretching the line segment in parameter space so that it travels along its length
|
||||
//! // from `-1` to `1` instead of `0` to `1`:
|
||||
//! let stretched_segment = segment.reparameterize_linear(interval(-1.0, 1.0).unwrap()).unwrap();
|
||||
//! let stretched_segment = segment.reparametrize_linear(interval(-1.0, 1.0).unwrap()).unwrap();
|
||||
//!
|
||||
//! // Now, the *output* of `f32::sin` in `[-1, 1]` corresponds to the *input* interval of
|
||||
//! // `stretched_segment`; the sinusoid output is mapped to the input parameter and controls how
|
||||
//! // far along the segment we are:
|
||||
//! let back_and_forth_curve = stretched_segment.reparameterize(Interval::EVERYWHERE, f32::sin);
|
||||
//! let back_and_forth_curve = stretched_segment.reparametrize(Interval::EVERYWHERE, f32::sin);
|
||||
//! ```
|
||||
//!
|
||||
//! ## Combining curves
|
||||
|
@ -269,7 +269,7 @@
|
|||
//!
|
||||
//! [domain]: Curve::domain
|
||||
//! [sampled]: Curve::sample
|
||||
//! [changing parameterizations]: Curve::reparameterize
|
||||
//! [changing parametrizations]: Curve::reparametrize
|
||||
//! [mapping output]: Curve::map
|
||||
//! [rasterization]: Curve::resample
|
||||
//! [functions]: FunctionCurve
|
||||
|
@ -306,14 +306,14 @@ use derive_more::derive::{Display, Error};
|
|||
use interval::InvalidIntervalError;
|
||||
use itertools::Itertools;
|
||||
|
||||
/// A trait for a type that can represent values of type `T` parameterized over a fixed interval.
|
||||
/// A trait for a type that can represent values of type `T` parametrized over a fixed interval.
|
||||
///
|
||||
/// Typical examples of this are actual geometric curves where `T: VectorSpace`, but other kinds
|
||||
/// of output data can be represented as well. See the [module-level documentation] for details.
|
||||
///
|
||||
/// [module-level documentation]: self
|
||||
pub trait Curve<T> {
|
||||
/// The interval over which this curve is parameterized.
|
||||
/// The interval over which this curve is parametrized.
|
||||
///
|
||||
/// This is the range of values of `t` where we can sample the curve and receive valid output.
|
||||
fn domain(&self) -> Interval;
|
||||
|
@ -415,10 +415,10 @@ pub trait Curve<T> {
|
|||
/// ```
|
||||
/// # use bevy_math::curve::*;
|
||||
/// let my_curve = ConstantCurve::new(Interval::UNIT, 1.0);
|
||||
/// let scaled_curve = my_curve.reparameterize(interval(0.0, 2.0).unwrap(), |t| t / 2.0);
|
||||
/// let scaled_curve = my_curve.reparametrize(interval(0.0, 2.0).unwrap(), |t| t / 2.0);
|
||||
/// ```
|
||||
/// This kind of linear remapping is provided by the convenience method
|
||||
/// [`Curve::reparameterize_linear`], which requires only the desired domain for the new curve.
|
||||
/// [`Curve::reparametrize_linear`], which requires only the desired domain for the new curve.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
|
@ -427,14 +427,14 @@ pub trait Curve<T> {
|
|||
/// # use bevy_math::vec2;
|
||||
/// let my_curve = ConstantCurve::new(Interval::UNIT, 1.0);
|
||||
/// let domain = my_curve.domain();
|
||||
/// let reversed_curve = my_curve.reparameterize(domain, |t| domain.end() - (t - domain.start()));
|
||||
/// let reversed_curve = my_curve.reparametrize(domain, |t| domain.end() - (t - domain.start()));
|
||||
///
|
||||
/// // Take a segment of a curve:
|
||||
/// # let my_curve = ConstantCurve::new(Interval::UNIT, 1.0);
|
||||
/// let curve_segment = my_curve.reparameterize(interval(0.0, 0.5).unwrap(), |t| 0.5 + t);
|
||||
/// let curve_segment = my_curve.reparametrize(interval(0.0, 0.5).unwrap(), |t| 0.5 + t);
|
||||
/// ```
|
||||
#[must_use]
|
||||
fn reparameterize<F>(self, domain: Interval, f: F) -> ReparamCurve<T, Self, F>
|
||||
fn reparametrize<F>(self, domain: Interval, f: F) -> ReparamCurve<T, Self, F>
|
||||
where
|
||||
Self: Sized,
|
||||
F: Fn(f32) -> f32,
|
||||
|
@ -447,11 +447,11 @@ pub trait Curve<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Linearly reparameterize this [`Curve`], producing a new curve whose domain is the given
|
||||
/// Linearly reparametrize this [`Curve`], producing a new curve whose domain is the given
|
||||
/// `domain` instead of the current one. This operation is only valid for curves with bounded
|
||||
/// domains; if either this curve's domain or the given `domain` is unbounded, an error is
|
||||
/// returned.
|
||||
fn reparameterize_linear(
|
||||
fn reparametrize_linear(
|
||||
self,
|
||||
domain: Interval,
|
||||
) -> Result<LinearReparamCurve<T, Self>, LinearReparamError>
|
||||
|
@ -473,13 +473,13 @@ pub trait Curve<T> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Reparameterize this [`Curve`] by sampling from another curve.
|
||||
/// Reparametrize this [`Curve`] by sampling from another curve.
|
||||
///
|
||||
/// The resulting curve samples at time `t` by first sampling `other` at time `t`, which produces
|
||||
/// another sample time `s` which is then used to sample this curve. The domain of the resulting
|
||||
/// curve is the domain of `other`.
|
||||
#[must_use]
|
||||
fn reparameterize_by_curve<C>(self, other: C) -> CurveReparamCurve<T, Self, C>
|
||||
fn reparametrize_by_curve<C>(self, other: C) -> CurveReparamCurve<T, Self, C>
|
||||
where
|
||||
Self: Sized,
|
||||
C: Curve<f32>,
|
||||
|
@ -870,7 +870,7 @@ pub trait Curve<T> {
|
|||
/// let samples = my_curve.by_ref().map(|x| x * 2.0).resample_auto(100).unwrap();
|
||||
///
|
||||
/// // Do something else with `my_curve` since we retained ownership:
|
||||
/// let new_curve = my_curve.reparameterize_linear(interval(-1.0, 1.0).unwrap()).unwrap();
|
||||
/// let new_curve = my_curve.reparametrize_linear(interval(-1.0, 1.0).unwrap()).unwrap();
|
||||
/// ```
|
||||
fn by_ref(&self) -> &Self
|
||||
where
|
||||
|
@ -903,17 +903,17 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// An error indicating that a linear reparameterization couldn't be performed because of
|
||||
/// An error indicating that a linear reparametrization couldn't be performed because of
|
||||
/// malformed inputs.
|
||||
#[derive(Debug, Error, Display)]
|
||||
#[display("Could not build a linear function to reparameterize this curve")]
|
||||
#[display("Could not build a linear function to reparametrize this curve")]
|
||||
pub enum LinearReparamError {
|
||||
/// The source curve that was to be reparameterized had unbounded domain.
|
||||
/// The source curve that was to be reparametrized had unbounded domain.
|
||||
#[display("This curve has unbounded domain")]
|
||||
SourceCurveUnbounded,
|
||||
|
||||
/// The target interval for reparameterization was unbounded.
|
||||
#[display("The target interval for reparameterization is unbounded")]
|
||||
/// The target interval for reparametrization was unbounded.
|
||||
#[display("The target interval for reparametrization is unbounded")]
|
||||
TargetIntervalUnbounded,
|
||||
}
|
||||
|
||||
|
@ -1176,22 +1176,22 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn reparameterization() {
|
||||
fn reparametrization() {
|
||||
let curve = FunctionCurve::new(interval(1.0, f32::INFINITY).unwrap(), ops::log2);
|
||||
let reparameterized_curve = curve
|
||||
let reparametrized_curve = curve
|
||||
.by_ref()
|
||||
.reparameterize(interval(0.0, f32::INFINITY).unwrap(), ops::exp2);
|
||||
assert_abs_diff_eq!(reparameterized_curve.sample_unchecked(3.5), 3.5);
|
||||
assert_abs_diff_eq!(reparameterized_curve.sample_unchecked(100.0), 100.0);
|
||||
.reparametrize(interval(0.0, f32::INFINITY).unwrap(), ops::exp2);
|
||||
assert_abs_diff_eq!(reparametrized_curve.sample_unchecked(3.5), 3.5);
|
||||
assert_abs_diff_eq!(reparametrized_curve.sample_unchecked(100.0), 100.0);
|
||||
assert_eq!(
|
||||
reparameterized_curve.domain(),
|
||||
reparametrized_curve.domain(),
|
||||
interval(0.0, f32::INFINITY).unwrap()
|
||||
);
|
||||
|
||||
let reparameterized_curve = curve.by_ref().reparameterize(Interval::UNIT, |t| t + 1.0);
|
||||
assert_abs_diff_eq!(reparameterized_curve.sample_unchecked(0.0), 0.0);
|
||||
assert_abs_diff_eq!(reparameterized_curve.sample_unchecked(1.0), 1.0);
|
||||
assert_eq!(reparameterized_curve.domain(), Interval::UNIT);
|
||||
let reparametrized_curve = curve.by_ref().reparametrize(Interval::UNIT, |t| t + 1.0);
|
||||
assert_abs_diff_eq!(reparametrized_curve.sample_unchecked(0.0), 0.0);
|
||||
assert_abs_diff_eq!(reparametrized_curve.sample_unchecked(1.0), 1.0);
|
||||
assert_eq!(reparametrized_curve.domain(), Interval::UNIT);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1206,11 +1206,11 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_reparameterizations() {
|
||||
fn multiple_reparametrizations() {
|
||||
// Make sure these happen in the right order too.
|
||||
let curve = FunctionCurve::new(Interval::UNIT, ops::exp2);
|
||||
let first_reparam = curve.reparameterize(interval(1.0, 2.0).unwrap(), ops::log2);
|
||||
let second_reparam = first_reparam.reparameterize(Interval::UNIT, |t| t + 1.0);
|
||||
let first_reparam = curve.reparametrize(interval(1.0, 2.0).unwrap(), ops::log2);
|
||||
let second_reparam = first_reparam.reparametrize(Interval::UNIT, |t| t + 1.0);
|
||||
assert_abs_diff_eq!(second_reparam.sample_unchecked(0.0), 1.0);
|
||||
assert_abs_diff_eq!(second_reparam.sample_unchecked(0.5), 1.5);
|
||||
assert_abs_diff_eq!(second_reparam.sample_unchecked(1.0), 2.0);
|
||||
|
|
|
@ -285,7 +285,7 @@ impl<T, I> UnevenSampleCurve<T, I> {
|
|||
}
|
||||
|
||||
/// This [`UnevenSampleAutoCurve`], but with the sample times moved by the map `f`.
|
||||
/// In principle, when `f` is monotone, this is equivalent to [`Curve::reparameterize`],
|
||||
/// In principle, when `f` is monotone, this is equivalent to [`Curve::reparametrize`],
|
||||
/// but the function inputs to each are inverses of one another.
|
||||
///
|
||||
/// The samples are re-sorted by time after mapping and deduplicated by output time, so
|
||||
|
@ -343,7 +343,7 @@ impl<T> UnevenSampleAutoCurve<T> {
|
|||
}
|
||||
|
||||
/// This [`UnevenSampleAutoCurve`], but with the sample times moved by the map `f`.
|
||||
/// In principle, when `f` is monotone, this is equivalent to [`Curve::reparameterize`],
|
||||
/// In principle, when `f` is monotone, this is equivalent to [`Curve::reparametrize`],
|
||||
/// but the function inputs to each are inverses of one another.
|
||||
///
|
||||
/// The samples are re-sorted by time after mapping and deduplicated by output time, so
|
||||
|
|
|
@ -171,7 +171,7 @@ pub struct ViewLightProbesUniformOffset(u32);
|
|||
|
||||
/// Information that [`gather_light_probes`] keeps about each light probe.
|
||||
///
|
||||
/// This information is parameterized by the [`LightProbeComponent`] type. This
|
||||
/// This information is parametrized by the [`LightProbeComponent`] type. This
|
||||
/// will either be [`EnvironmentMapLight`] for reflection probes or
|
||||
/// [`IrradianceVolume`] for irradiance volumes.
|
||||
#[allow(dead_code)]
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
@group(0) @binding(10) var mip_10: texture_storage_2d<r32float, write>;
|
||||
@group(0) @binding(11) var mip_11: texture_storage_2d<r32float, write>;
|
||||
@group(0) @binding(12) var mip_12: texture_storage_2d<r32float, write>;
|
||||
@group(0) @binding(13) var textureSampler: sampler;
|
||||
@group(0) @binding(13) var samplr: sampler;
|
||||
struct Constants { max_mip_level: u32, view_width: u32 }
|
||||
var<push_constant> constants: Constants;
|
||||
|
||||
|
|
|
@ -129,7 +129,7 @@ pub struct StandardMaterial {
|
|||
/// 0.089 is the minimum floating point value that won't be rounded down to 0 in the
|
||||
/// calculations used.
|
||||
// Technically for 32-bit floats, 0.045 could be used.
|
||||
// See <https://google.github.io/filament/Filament.html#materialsystem/parameterization/>
|
||||
// See <https://google.github.io/filament/Filament.html#materialsystem/parametrization/>
|
||||
pub perceptual_roughness: f32,
|
||||
|
||||
/// How "metallic" the material appears, within `[0.0, 1.0]`.
|
||||
|
|
|
@ -288,7 +288,7 @@ fn calculate_diffuse_color(
|
|||
}
|
||||
|
||||
// Remapping [0,1] reflectance to F0
|
||||
// See https://google.github.io/filament/Filament.html#materialsystem/parameterization/remapping
|
||||
// See https://google.github.io/filament/Filament.html#materialsystem/parametrization/remapping
|
||||
fn calculate_F0(base_color: vec3<f32>, metallic: f32, reflectance: f32) -> vec3<f32> {
|
||||
return 0.16 * reflectance * reflectance * (1.0 - metallic) + base_color * metallic;
|
||||
}
|
||||
|
|
|
@ -104,14 +104,14 @@ impl AnimationInfo {
|
|||
// Each leg of the translation motion should take 3 seconds.
|
||||
let animation_domain = interval(0.0, 3.0).unwrap();
|
||||
|
||||
// The easing curve is parameterized over [0, 1], so we reparameterize it and
|
||||
// The easing curve is parametrized over [0, 1], so we reparametrize it and
|
||||
// then ping-pong, which makes it spend another 3 seconds on the return journey.
|
||||
let translation_curve = EasingCurve::new(
|
||||
vec3(-6., 2., 0.),
|
||||
vec3(6., 2., 0.),
|
||||
EaseFunction::CubicInOut,
|
||||
)
|
||||
.reparameterize_linear(animation_domain)
|
||||
.reparametrize_linear(animation_domain)
|
||||
.expect("this curve has bounded domain, so this should never fail")
|
||||
.ping_pong()
|
||||
.expect("this curve has bounded domain, so this should never fail");
|
||||
|
@ -124,7 +124,7 @@ impl AnimationInfo {
|
|||
Quat::from_rotation_y(FRAC_PI_2),
|
||||
EaseFunction::ElasticInOut,
|
||||
)
|
||||
.reparameterize_linear(interval(0.0, 4.0).unwrap())
|
||||
.reparametrize_linear(interval(0.0, 4.0).unwrap())
|
||||
.expect("this curve has bounded domain, so this should never fail");
|
||||
|
||||
animation_clip
|
||||
|
|
Loading…
Reference in a new issue