Skip to content

Commit

Permalink
Merge pull request #66 from alphastrata/v0-12
Browse files Browse the repository at this point in the history
v0.12 is tested
  • Loading branch information
alphastrata authored Nov 10, 2023
2 parents 5f0f8af + b69ed1a commit f2a2367
Show file tree
Hide file tree
Showing 10 changed files with 335 additions and 36 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ ______________________________________________________________________
- The shader will also be versioned, alongside that screenshot
- Rename and move the screenshot to `assets/screenshots/<NAME YOUR OWN DIR>/screenshot.png`
- Rename and move the versioned shader to `assets/shaders/<NAME YOUR OWN DIR/YOURSHADER.wgsl`
- Screenshots should **share the name** of the `wgsl` that creates them
- Add it to the #Gallery in the `README.md`

# Shadertoy ports:
Expand All @@ -75,5 +74,6 @@ ______________________________________________________________________
- put stuff in logical places.
- use iterators
- use `run_if()`s [see bevy docs](https://docs.rs/bevy/latest/bevy/prelude/trait.IntoSystemConfigs.html#method.run_if)
- I use bevy at my dayjob sometimes so am pretty sure between the two of us we'll be able to get your contribution merged :wink

Please note that contributions should follow the [Rust Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct).
11 changes: 6 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 4 additions & 12 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,13 @@ Shadplay is a simple, (WIP) application that provides a window where shader code

[features]
default = ["ui"]
wayland = []
wayland = ["bevy/wayland"]
ui = []

[dependencies]
bevy = { version = "0.12.0", features = [
"file_watcher",
"dynamic_linking",
"wayland",
"jpeg",
] }
bevy_egui = { git = "https://github.com/raffaeleragni/bevy_egui", branch = "bevy_0_12" } #, version = "0.22.0" }
bevy_panorbit_camera = { git = "https://github.com/Plonq/bevy_panorbit_camera", branch = "bevy-0.12" } #, version= "0.9.0"}
bevy = { version = "*", features = ["file_watcher", "dynamic_linking", "jpeg"] }
bevy_egui = { version = "0.23.0" }
bevy_panorbit_camera = { version = "0.9.0" }
chrono = "0.4.31"
copypasta = "0.10.0"
directories = "5.0.1"
Expand All @@ -32,8 +27,5 @@ toml = "0.8.6"
[profile.dev] # A little bit of optimisation for dev builds
opt-level = 1

[profile.dev.package."*"] # Always build dependencies with the highest level of optimisations possible.
opt-level = 3

[build-dependencies]
glob = "0.3.1"
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,21 @@

<center>artwork by Maz with SD</center>

[![Bevy tracking](https://img.shields.io/badge/Bevy%20tracking-main-lightblue)](https://github.com/bevyengine/bevy/blob/main/docs/plugins_guidelines.md#main-branch-tracking)

<!-- Badges to insert at some stage...
[![docs.rs](https://docs.rs/shadplay/badge.svg)](https://docs.rs/shadplay) SOME DAY...
[![License](https://img.shields.io/badge/license-MIT.svg)](https://github.com/shadplay/bevy#license)
[![Crates.io](https://img.shields.io/crates/v/bevy.svg)](https://crates.io/crates/bevy)
[![Downloads](https://img.shields.io/crates/d/bevy.svg)](https://crates.io/crates/bevy)
[![Docs](https://docs.rs/bevy/badge.svg)](https://docs.rs/bevy/latest/bevy/)
[![CI](https://github.com/bevyengine/bevy/workflows/CI/badge.svg)](https://github.com/bevyengine/bevy/actions)
-->

## Our [bevy-shader-cheatsheet](bevy-shaders-cheatsheet.md#Contents)

Shadplay is an app designed to help you learn `wgsl` with minimal friction, specifically for those wanting to learn `wgsl` to write shaders for Bevy.
The idea is to give one the minimal amount of bevy boilerplate etc possible to get started writing glsl asap, and provide a library of examples showing how some things are done, can be done etc.
The idea is to give one the minimal amount of bevy boilerplate etc possible to get started writing `wgsl` asap, and provide a library of examples showing how some things are done, can be done etc.

A secondary goal is to flesh out a relatively comprehensive 'port' of existing cool shader work from places like shadertoy etc -- because there's a few 'gotchas' around the differences in `glsl` and `wgsl` syntax, their respective builtins.

Expand Down Expand Up @@ -115,6 +126,8 @@ ______________________________________________________________________
- [glsl sandbox](https://glslsandbox.com/)
- [Shadertoy](https://www.shadertoy.com/)
- [pcf swap by DGriffin91](https://github.com/DGriffin91/bevy_mod_standard_material/tree/pcf)
- [GLSL2WGSL converter](https://eliotbo.github.io/glsl2wgsl/), it's a mixed bag..
- [bevy_shadertoy_wgsl](https://github.com/eliotbo/bevy_shadertoy_wgsl)

______________________________________________________________________

Expand Down Expand Up @@ -152,6 +165,16 @@ ______________________________________________________________________

______________________________________________________________________

# FAQ:

Q: I grabbed a shader from the examples, but it's not working!
A: It could be that the shader was contributed some time ago and was, likely made with a bevy version \< 0.12.x so it's likely a formatting thing -- if the naga (the thing which parses and compiles the .wgsl code) error doesn't tell you how to solve the issue please make a bug report and we'll try to get it updated!

Q: What version of bevy are you targeting?
A: `{version = "*"}`

______________________________________________________________________

# LICENSE:

This repository is licensed MIT, with the exception of code within the `assets/shaders/shadertoy-ports` directory, see those individual files' and the links to the original `glsl` code to ascertain their licensing requirements.
167 changes: 167 additions & 0 deletions assets/Gallery/light-spirals/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
## sailing-beyond

![photo](screenshot.png)

### fragment

// This is a port of `light spirals` by `felipetovarhenao` on shadertoy. https://www.shadertoy.com/view/DlccR7

```rust
#import bevy_sprite::mesh2d_view_bindings::globals
#import bevy_render::view::View
#import bevy_pbr::forward_io::VertexOutput;

@group(0) @binding(0) var<uniform> view: View;

const SPEED:f32 = 0.30;
const PI: f32 = 3.14159265359;
const TWO_PI = 6.2848;
const NUM_ITER = 8.0;

// This is a port of `light spirals` by `felipetovarhenao` on shadertoy. https://www.shadertoy.com/view/DlccR7
@fragment
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
var uv = (in.uv * 2.0) - 1.0;
let resolution = view.viewport.zw;
let t = globals.time * SPEED;
uv.x *= resolution.x / resolution.y;

//NOTE: we're not rotating, which allows us to remove the original's adjust_viewport
return spirals(uv, resolution, t);
}

// draw the 'spirals'
fn spirals(_uv: vec2f, resolution: vec2f, t: f32) -> vec4f {
var uv = _uv;
// Something blank to paint onto!
var col: vec3f = vec3(0.0, 0.0, 0.0);

// Setup a colour palette:
let c1: vec3f = vec3(0.5, 0.5, 0.5);
let c2: vec3f = vec3(0.5, 0.5, 0.5);
let c3: vec3f = vec3(0.1, 0.1, 0.1);
let c4: vec3f = vec3(0.6, 0.7, 0.8);

let mag: f32 = length(uv);

// `d` is distance, we'll get multiple 'distances' that we're interested in using them as we override them in the loop.
var d: f32 = 0.0;
for (var i: f32 = 0.0; i < NUM_ITER; i += 1.0) {
let h: f32 = i + 1.0;
let ph: f32 = t + noise_overload_3(uv);
let amp: f32 = pow(1.333, i);
let fq: f32 = uv.y * TWO_PI * h;
let sig: f32 = sin(fq + ph * h) * (0.333 / amp);
d = uv.x + sig;
d = abs(d);
let gap: f32 = cos(fq * 0.4 + t);
var a: f32 = abs(gap);
a = pow(a, 5.0);
d += a;
let lum: f32 = scale(sin(ph * h), -1.0, 1.0, 0.003, 0.007) * (NUM_ITER * 0.25 / h);
d = lum / abs(d);
col += d * gradient(h + t, c1, c2, c3, c4);
}

return vec4<f32>(col, 1.0);
}

// Helpers:
fn rand(x: f32, s: i32) -> f32 {
return fract(sin(x + f32(s)) * 43758.5453123);
}


//NOTE: wgsl doesn't support function overloading -- I know not whether or not there's a convention developing yet, so for now I've just enumerated them.
fn rand_overload_1(x: f32) -> f32 {
return rand(x, 0);
}

fn rand_overload_2(uv: vec2f, seed: i32) -> f32 {
return fract(sin(dot(uv.xy, vec2f(12.9898, 78.233)) + f32(seed)) * 43758.5453123);
}

fn rand_overload_3(uv: vec2f) -> f32 {
return rand_overload_2(uv, 0);
}

fn noise(x: f32, s: i32) -> f32 {
let xi = floor(x);
let xf = fract(x);
return mix(rand(xi, s), rand(xi + 1.0, s), smoothstep(0.0, 1.0, xf));
}

fn noise_overload_1(x: f32) -> f32 {
return noise(x, 0);
}

fn noise_overload_2(p: vec2f, s: i32) -> f32 {
let pi = floor(p);
let pf = fract(p);

let bl = rand_overload_2(pi, s);
let br = rand_overload_2(pi + vec2f(1.0, 0.0), s);
let tl = rand_overload_2(pi + vec2f(0.0, 1.0), s);
let tr = rand_overload_2(pi + vec2f(1.0), s);

let w = smoothstep(vec2f(0.0), vec2f(1.0), pf);

let t = mix(tl, tr, w.x);
let b = mix(bl, br, w.x);

return mix(b, t, w.y);
}

fn noise_overload_3(p: vec2f) -> f32 {
return noise_overload_2(p, 0);
}

fn scale(x: f32, a: f32, b: f32, c: f32, d: f32) -> f32 {
return (x - a) / (b - a) * (d - c) + c;
}

fn gradient(t: f32, a: vec3f, b: vec3f, c: vec3f, d: vec3f) -> vec3f {
return a + b * cos(TWO_PI * (c * t + d));
}

```

# Notes:

- The scale and gradient I think are really nice and useful little numbers to have!


### fn scale(x: f32, a: f32, b: f32, c: f32, d: f32) -> f32:
Takes x from a range of a..b and returns it as a range from c..d
This little python script may be more understandable:
```py
# The same logic as our scale function above in the wgsl example
def scale(x, a, b, c, d):
return (x-a)/(b-a)*(d-c)+c

# Generate 10 values between 0 and 1
values = [i/10 for i in range(11)]

# Scale values of `x` from 0..1 to 0..100
scaled_values = [scale(x, 0, 1, 0, 100) for x in values]

# Print the scaled values
for i, val in enumerate(scaled_values):
print(f'Original: {values[i]}, Scaled: {val}')
```
which gives you:
```
Original: 0.0, Scaled: 0.0
Original: 0.1, Scaled: 10.0
Original: 0.2, Scaled: 20.0
Original: 0.3, Scaled: 30.0
Original: 0.4, Scaled: 40.0
Original: 0.5, Scaled: 50.0
Original: 0.6, Scaled: 60.0
Original: 0.7, Scaled: 70.0
Original: 0.8, Scaled: 80.0
Original: 0.9, Scaled: 90.0
Original: 1.0, Scaled: 100.0
```
it seems to work bidirectionally which is cool.

Binary file added assets/Gallery/light-spirals/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 5 additions & 7 deletions assets/shaders/myshader_2d.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,17 @@
/// You can always get back to this with `python3 scripts/reset-2d.py` ///
/// ***************************** ///

#import bevy_pbr::{
forward_io::VertexOutput,
}
#import bevy_sprite::mesh2d_view_bindings globals
#import shadplay::shader_utils::common NEG_HALF_PI, shader_toy_default, rotate2D
#import bevy_sprite::mesh2d_view_bindings::globals
#import shadplay::shader_utils::common::{NEG_HALF_PI, shader_toy_default, rotate2D, TWO_PI}
#import bevy_render::view::View
#import bevy_pbr::forward_io::VertexOutput;

#import bevy_render::view View
@group(0) @binding(0) var<uniform> view: View;

const SPEED:f32 = 1.0;

@fragment
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
fn fragment(in: MeshVertexOutput) -> @location(0) vec4<f32> {
// ensure our uv coords match shadertoy/the-lil-book-of-shaders
var uv = (in.uv * 2.0) - 1.0;
let resolution = view.viewport.zw;
Expand Down
Loading

0 comments on commit f2a2367

Please sign in to comment.