web (engine): print the grain from the phone's own module
The web port carried a third copy of the grain shader, so it would have kept printing the old static, unseeded field after the phone stopped. It now imports GRAIN_SKSL and grainCell from src/utils/grainShader.ts, exactly like the phone's export, so there is one shader and one size rule for the whole pipeline. The floor is one output pixel here, which is the whole story on this path: a CanvasKit surface is rasterised in the pixels it is given, so no dp-to-device correction is needed the way the phone preview needs one. Typechecked only — no harness in the tree runs this file; the deployed app (docker/frontend) has its own engine and already prints the new grain.
This commit is contained in:
@@ -33,6 +33,7 @@ import {
|
||||
glowUniformArray,
|
||||
} from '../../../src/utils/toneShader';
|
||||
import { CINEMA_SKSL, getCinemaUniforms, cinemaIsActive } from '../../../src/utils/cinemaShader';
|
||||
import { GRAIN_SKSL, GRAIN_SEED, grainCell } from '../../../src/utils/grainShader';
|
||||
import {
|
||||
drawFrameOnCanvas,
|
||||
polaroidLayout,
|
||||
@@ -432,24 +433,13 @@ export async function renderPhoto(input: RenderInput): Promise<RenderResult | nu
|
||||
const grainPaint = own(Skia.Paint());
|
||||
grainPaint.setBlendMode(Skia.BlendMode.Overlay);
|
||||
grainPaint.setAlphaf(grainAmount / 20);
|
||||
const noiseEffect = own(Skia.RuntimeEffect.Make(`
|
||||
uniform float u;
|
||||
float grainHash(vec2 q) {
|
||||
return fract(sin(dot(q, vec2(12.9898, 78.233))) * 43758.5453);
|
||||
}
|
||||
vec4 main(vec2 pos) {
|
||||
vec2 p = pos.xy / max(u, 1.0);
|
||||
vec2 i = floor(p);
|
||||
vec2 f = p - i;
|
||||
f = f * f * (3.0 - 2.0 * f);
|
||||
float g00 = grainHash(i);
|
||||
float g10 = grainHash(i + vec2(1.0, 0.0));
|
||||
float g01 = grainHash(i + vec2(0.0, 1.0));
|
||||
float g11 = grainHash(i + vec2(1.0, 1.0));
|
||||
return vec4(vec3(mix(mix(g00, g10, f.x), mix(g01, g11, f.x), f.y)), 1.0);
|
||||
}
|
||||
`));
|
||||
const noiseShader = noiseEffect ? own(noiseEffect.makeShader([width / 1080])) : null;
|
||||
// Same shader and same cell rule as the phone's export and the preview
|
||||
// (see src/utils/grainShader.ts): one noise cell per 1/1080 of the
|
||||
// picture's width, floored at one output pixel.
|
||||
const noiseEffect = own(Skia.RuntimeEffect.Make(GRAIN_SKSL));
|
||||
const noiseShader = noiseEffect
|
||||
? own(noiseEffect.makeShader([grainCell(width), GRAIN_SEED[0], GRAIN_SEED[1]]))
|
||||
: null;
|
||||
if (noiseShader) {
|
||||
grainPaint.setShader(noiseShader);
|
||||
canvas.drawRect(Skia.XYWHRect(0, 0, width, height), grainPaint);
|
||||
|
||||
Reference in New Issue
Block a user