Skip to content

Commit b18b3ff

Browse files
authored
feat: Ramp (#219)
1 parent cbd51e4 commit b18b3ff

File tree

3 files changed

+193
-0
lines changed

3 files changed

+193
-0
lines changed

docs/effects/ramp.mdx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
title: Ramp
3+
nav: 1
4+
---
5+
6+
Ramp effect for linear and radial color gradients, as well as masking of effects before it in the effect array.
7+
8+
```jsx
9+
import { Ramp, RampType } from '@react-three/postprocessing'
10+
11+
return (
12+
<Ramp
13+
rampType={RampType.Linear}
14+
rampStart={[0.5, 0.5]}
15+
rampEnd={[1.0, 1.0]}
16+
startColor={[0, 0, 0, 1]}
17+
endColor={[1, 1, 1, 1]}
18+
rampBias={0.5}
19+
rampGain={0.5}
20+
rampMask={false}
21+
rampInvert={false}
22+
/>
23+
)
24+
```
25+
26+
## Example
27+
28+
<Codesandbox id="zdpzei" />
29+
30+
## Props
31+
32+
| Name | Type | Default | Description |
33+
| ---------- | -------------------------------------------- | --------------- | -------------------------------------------------------------------------------------------------------------- |
34+
| rampType | RampType | RampType.Linear | Type of ramp gradient. |
35+
| rampStart | [x: number, y: number] | [0.5, 0.5] | Starting point of the ramp gradient in normalized coordinates. |
36+
| rampEnd | [x: number, y: number] | [1.0, 1.0] | Ending point of the ramp gradient in normalized coordinates. |
37+
| startColor | [r: number, g: number, b: number, a: number] | [0, 0, 0, 1] | Color at the starting point of the gradient. |
38+
| endColor | [r: number, g: number, b: number, a: number] | [1, 1, 1, 1] | Color at the ending point of the gradient. |
39+
| rampBias | number | 0.5 | Bias for the interpolation curve when both bias and gain are 0.5. |
40+
| rampGain | number | 0.5 | Gain for the interpolation curve when both bias and gain are 0.5. |
41+
| rampMask | boolean | false | When enabled, the ramp gradient is used as an effect mask, and colors are ignored. |
42+
| rampInvert | boolean | false | Controls whether the ramp gradient is inverted. When disabled, rampStart is transparent and rampEnd is opaque. |

src/effects/Ramp.tsx

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import { Uniform } from 'three'
2+
import { Effect } from 'postprocessing'
3+
import { wrapEffect } from '../util'
4+
5+
const RampShader = {
6+
fragmentShader: /* glsl */ `
7+
uniform int rampType;
8+
9+
uniform vec2 rampStart;
10+
uniform vec2 rampEnd;
11+
12+
uniform vec4 startColor;
13+
uniform vec4 endColor;
14+
15+
uniform float rampBias;
16+
uniform float rampGain;
17+
18+
uniform bool rampMask;
19+
uniform bool rampInvert;
20+
21+
float getBias(float time, float bias) {
22+
return time / (((1.0 / bias) - 2.0) * (1.0 - time) + 1.0);
23+
}
24+
25+
float getGain(float time, float gain) {
26+
if (time < 0.5)
27+
return getBias(time * 2.0, gain) / 2.0;
28+
else
29+
return getBias(time * 2.0 - 1.0, 1.0 - gain) / 2.0 + 0.5;
30+
}
31+
32+
void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {
33+
vec2 centerPixel = uv * resolution;
34+
vec2 startPixel = rampStart * resolution;
35+
vec2 endPixel = rampEnd * resolution;
36+
37+
float rampAlpha;
38+
39+
if (rampType == 1) {
40+
vec2 fuv = centerPixel / resolution.y;
41+
vec2 suv = startPixel / resolution.y;
42+
vec2 euv = endPixel / resolution.y;
43+
44+
float radius = length(suv - euv);
45+
float falloff = length(fuv - suv);
46+
rampAlpha = smoothstep(0.0, radius, falloff);
47+
} else {
48+
float radius = length(startPixel - endPixel);
49+
vec2 direction = normalize(vec2(endPixel.x - startPixel.x, -(startPixel.y - endPixel.y)));
50+
51+
float fade = dot(centerPixel - startPixel, direction);
52+
if (rampType == 2) fade = abs(fade);
53+
54+
rampAlpha = smoothstep(0.0, 1.0, fade / radius);
55+
}
56+
57+
rampAlpha = abs((rampInvert ? 1.0 : 0.0) - getBias(rampAlpha, rampBias) * getGain(rampAlpha, rampGain));
58+
59+
if (rampMask) {
60+
vec4 inputBuff = texture2D(inputBuffer, uv);
61+
outputColor = mix(inputBuff, inputColor, rampAlpha);
62+
} else {
63+
outputColor = mix(startColor, endColor, rampAlpha);
64+
}
65+
}
66+
`,
67+
}
68+
69+
export enum RampType {
70+
Linear,
71+
Radial,
72+
MirroredLinear,
73+
}
74+
75+
export class RampEffect extends Effect {
76+
constructor({
77+
/**
78+
* Type of ramp gradient.
79+
*/
80+
rampType = RampType.Linear,
81+
/**
82+
* Starting point of the ramp gradient in normalized coordinates.
83+
*
84+
* Ranges from `[0 - 1]` as `[x, y]`. Default is `[0.5, 0.5]`.
85+
*/
86+
rampStart = [0.5, 0.5],
87+
/**
88+
* Ending point of the ramp gradient in normalized coordinates.
89+
*
90+
* Ranges from `[0 - 1]` as `[x, y]`. Default is `[1, 1]`
91+
*/
92+
rampEnd = [1, 1],
93+
/**
94+
* Color at the starting point of the gradient.
95+
*
96+
* Default is black: `[0, 0, 0, 1]`
97+
*/
98+
startColor = [0, 0, 0, 1],
99+
/**
100+
* Color at the ending point of the gradient.
101+
*
102+
* Default is white: `[1, 1, 1, 1]`
103+
*/
104+
endColor = [1, 1, 1, 1],
105+
/**
106+
* Bias for the interpolation curve when both bias and gain are 0.5.
107+
*
108+
* Ranges from `[0 - 1]`. Default is `0.5`.
109+
*/
110+
rampBias = 0.5,
111+
/**
112+
* Gain for the interpolation curve when both bias and gain are 0.5.
113+
*
114+
* Ranges from `[0 - 1]`. Default is `0.5`.
115+
*/
116+
rampGain = 0.5,
117+
/**
118+
* When enabled, the ramp gradient is used as an effect mask, and colors are ignored.
119+
*
120+
* Default is `false`.
121+
*/
122+
rampMask = false,
123+
/**
124+
* Controls whether the ramp gradient is inverted.
125+
*
126+
* When disabled, rampStart is transparent and rampEnd is opaque.
127+
*
128+
* Default is `false`.
129+
*/
130+
rampInvert = false,
131+
...params
132+
} = {}) {
133+
super('RampEffect', RampShader.fragmentShader, {
134+
...params,
135+
uniforms: new Map<string, Uniform>([
136+
['rampType', new Uniform(rampType)],
137+
['rampStart', new Uniform(rampStart)],
138+
['rampEnd', new Uniform(rampEnd)],
139+
['startColor', new Uniform(startColor)],
140+
['endColor', new Uniform(endColor)],
141+
['rampBias', new Uniform(rampBias)],
142+
['rampGain', new Uniform(rampGain)],
143+
['rampMask', new Uniform(rampMask)],
144+
['rampInvert', new Uniform(rampInvert)],
145+
]),
146+
})
147+
}
148+
}
149+
150+
export const Ramp = /* @__PURE__ */ wrapEffect(RampEffect)

src/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export * from './effects/Sepia'
2525
export * from './effects/SSAO'
2626
export * from './effects/SMAA'
2727
export * from './effects/FXAA'
28+
export * from './effects/Ramp'
2829
export * from './effects/Texture'
2930
export * from './effects/ToneMapping'
3031
export * from './effects/Vignette'

0 commit comments

Comments
 (0)