Ported the rain vertex shader to wgsl.

This commit is contained in:
Rezmason
2021-10-30 18:07:07 -07:00
parent 923992660c
commit d8701c9408
3 changed files with 47 additions and 34 deletions

View File

@@ -2,8 +2,7 @@ TODO:
WebGPU WebGPU
First decent rainRender First decent rainRender
Port render pass 100% Is there a way to whittle out quadSize?
For now, use noise instead of the data texture
Port compute pass 100% Port compute pass 100%
Compute entry point can live in the same wgsl file, I think Compute entry point can live in the same wgsl file, I think
use textureLoad for texel access in render pipeline use textureLoad for texel access in render pipeline

View File

@@ -86,7 +86,7 @@ export default async (canvas, config) => {
{ name: "density", type: "f32", value: density }, { name: "density", type: "f32", value: density },
{ name: "numQuadColumns", type: "i32", value: numQuadColumns }, { name: "numQuadColumns", type: "i32", value: numQuadColumns },
{ name: "numQuadRows", type: "i32", value: numQuadRows }, { name: "numQuadRows", type: "i32", value: numQuadRows },
{ name: "quadSize", type: "f32", value: quadSize }, { name: "quadSize", type: "vec2<f32>", value: quadSize },
{ name: "slantScale", type: "f32", value: slantScale }, { name: "slantScale", type: "f32", value: slantScale },
{ name: "slantVec", type: "vec2<f32>", value: slantVec }, { name: "slantVec", type: "vec2<f32>", value: slantVec },
{ name: "volumetric", type: "i32", value: volumetric }, { name: "volumetric", type: "i32", value: volumetric },

View File

@@ -40,7 +40,7 @@ let SQRT_5:f32 = 2.23606797749979;
density : f32; density : f32;
numQuadColumns : i32; numQuadColumns : i32;
numQuadRows : i32; numQuadRows : i32;
quadSize : f32; quadSize : vec2<f32>;
slantScale : f32; slantScale : f32;
slantVec : vec2<f32>; slantVec : vec2<f32>;
volumetric : i32; volumetric : i32;
@@ -108,47 +108,59 @@ fn wobble(x:f32) -> f32 {
[[stage(vertex)]] fn vertMain(input: VertInput) -> VertOutput { [[stage(vertex)]] fn vertMain(input: VertInput) -> VertOutput {
var timePlaceholder = time.seconds; var volumetric = bool(config.volumetric);
var i = i32(input.index); var i = i32(input.index);
var quadIndex = i / NUM_VERTICES_PER_QUAD; var quadIndex = i / NUM_VERTICES_PER_QUAD;
var cornerPosition = vec2<f32>( var quadCorner = vec2<f32>(
f32(i % 2), f32(i % 2),
f32(((i + 1) % NUM_VERTICES_PER_QUAD / 3)) f32((i + 1) % NUM_VERTICES_PER_QUAD / 3)
); );
var quadPosition = vec2<i32>( var quadPosition = vec2<f32>(
quadIndex % config.numQuadColumns, f32(quadIndex % config.numQuadColumns),
quadIndex / config.numQuadColumns f32(quadIndex / config.numQuadColumns)
); );
var position = cornerPosition; var vUV = (quadPosition + quadCorner) * config.quadSize;
position = position + vec2<f32>(quadPosition); var vGlyph = vec4<f32>(1.0, 0.15, randomFloat(vec2<f32>(quadPosition.x, 1.0)), 0.0); // TODO: texture2D(state, quadPosition * config.quadSize);
position = position / vec2<f32>(
f32(config.numQuadColumns),
f32(config.numQuadRows)
);
position = 1.0 - position * 2.0;
// position = position * scene.screenSize; // Calculate the world space position
var quadDepth = 0.0;
if (volumetric && !bool(config.showComputationTexture)) {
quadDepth = fract(vGlyph.b + time.seconds * config.animationSpeed * config.forwardSpeed);
vGlyph.b = quadDepth;
}
var position = (quadPosition * vec2<f32>(1.0, config.glyphVerticalSpacing) + quadCorner * vec2<f32>(config.density, 1.0)) * config.quadSize;
var pos = vec4<f32>((position - 0.5) * 2.0, quadDepth, 1.0);
var depth:f32 = 0.0; pos.y = -pos.y;
// depth = -0.5 // "Resurrected" columns are in the green channel,
// + sin(time.seconds * 2.0 + f32(quadPosition.x) / f32(config.numQuadColumns) * 10.0) * 0.2 // and are vertically flipped (along with their glyphs)
// + sin(time.seconds * 2.0 + f32(quadPosition.y) / f32(config.numQuadRows) * 10.0) * 0.2; var vChannel = vec3<f32>(1.0, 0.0, 0.0);
if (volumetric && randomFloat(vec2<f32>(quadPosition.x, 0.0)) < config.resurrectingCodeRatio) {
pos.y = -pos.y;
vChannel = vec3<f32>(0.0, 1.0, 0.0);
}
var pos:vec4<f32> = vec4<f32>(position, depth, 1.0); vChannel = vec3<f32>(1.0); // TODO: remove
pos.x = pos.x / config.glyphHeightToWidth;
pos = scene.camera * scene.transform * pos; // Convert the world space position to screen space
if (volumetric) {
pos.x = pos.x / config.glyphHeightToWidth;
pos = scene.camera * scene.transform * pos;
} else {
pos.x = pos.x * scene.screenSize.x;
pos.y = pos.y * scene.screenSize.y;
}
return VertOutput( return VertOutput(
pos, pos,
cornerPosition, vUV,
vec3<f32>(1.0), // channel vChannel,
vec4<f32>(1.0) // glyph vGlyph
); );
} }
@@ -167,11 +179,12 @@ fn getSymbolUV(glyphCycle:f32) -> vec2<f32> {
[[stage(fragment)]] fn fragMain(input: VertOutput) -> FragOutput { [[stage(fragment)]] fn fragMain(input: VertOutput) -> FragOutput {
var volumetric = bool(config.volumetric);
var uv = input.uv; var uv = input.uv;
// In normal mode, derives the current glyph and UV from vUV // In normal mode, derives the current glyph and UV from vUV
if (config.volumetric == 0) { if (!volumetric) {
if (config.isPolar == 1) { if (bool(config.isPolar)) {
// Curved space that makes letters appear to radiate from up above // Curved space that makes letters appear to radiate from up above
uv = (uv - 0.5) * 0.5; uv = (uv - 0.5) * 0.5;
uv.y = uv.y - 0.5; uv.y = uv.y - 0.5;
@@ -190,11 +203,12 @@ fn getSymbolUV(glyphCycle:f32) -> vec2<f32> {
// Unpack the values from the data texture // Unpack the values from the data texture
var glyph:vec4<f32>; var glyph:vec4<f32>;
if (config.volumetric == 1) { if (volumetric) {
glyph = input.glyph; glyph = input.glyph;
} else { } else {
glyph = vec4<f32>(1.0); // TODO: texture2D(state, uv); glyph = vec4<f32>(1.0); // TODO: texture2D(state, uv);
} }
glyph = input.glyph; // TODO: remove
var brightness = glyph.r; var brightness = glyph.r;
var symbolUV = getSymbolUV(glyph.g); var symbolUV = getSymbolUV(glyph.g);
var quadDepth = glyph.b; var quadDepth = glyph.b;
@@ -202,7 +216,7 @@ fn getSymbolUV(glyphCycle:f32) -> vec2<f32> {
brightness = max(effect, brightness); brightness = max(effect, brightness);
// In volumetric mode, distant glyphs are dimmer // In volumetric mode, distant glyphs are dimmer
if (config.volumetric == 1) { if (volumetric) {
brightness = brightness * min(1.0, quadDepth); brightness = brightness * min(1.0, quadDepth);
} }
@@ -220,7 +234,7 @@ fn getSymbolUV(glyphCycle:f32) -> vec2<f32> {
var output:FragOutput; var output:FragOutput;
if (config.showComputationTexture == 1) { if (bool(config.showComputationTexture)) {
output.color = vec4<f32>(glyph.rgb * alpha, 1.0); output.color = vec4<f32>(glyph.rgb * alpha, 1.0);
} else { } else {
output.color = vec4<f32>(input.channel * brightness * alpha, 1.0); output.color = vec4<f32>(input.channel * brightness * alpha, 1.0);