diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 4ea00da43f..919d94470a 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -28,20 +28,20 @@ cross = ["wgc/cross"] [target.'cfg(not(target_arch = "wasm32"))'.dependencies.wgc] package = "wgpu-core" git = "https://github.com/gfx-rs/wgpu" -rev = "b7ba481a9170e5b9c6364b2eb16080e527462039" +rev = "41f106d7fc8e2ca49b21aed0919fa6cc67317f7f" features = ["raw-window-handle"] [target.'cfg(target_arch = "wasm32")'.dependencies.wgc] package = "wgpu-core" git = "https://github.com/gfx-rs/wgpu" -rev = "b7ba481a9170e5b9c6364b2eb16080e527462039" +rev = "41f106d7fc8e2ca49b21aed0919fa6cc67317f7f" features = ["raw-window-handle"] optional = true [dependencies.wgt] package = "wgpu-types" git = "https://github.com/gfx-rs/wgpu" -rev = "b7ba481a9170e5b9c6364b2eb16080e527462039" +rev = "41f106d7fc8e2ca49b21aed0919fa6cc67317f7f" [dependencies] arrayvec = "0.5" @@ -70,13 +70,13 @@ env_logger = "0.8" # used to test all the example shaders [dev-dependencies.naga] git = "https://github.com/gfx-rs/naga" -tag = "gfx-18" +tag = "gfx-19" features = ["wgsl-in"] # used to generate SPIR-V for the Web target [target.'cfg(target_arch = "wasm32")'.dependencies.naga] git = "https://github.com/gfx-rs/naga" -tag = "gfx-18" +tag = "gfx-19" features = ["wgsl-in", "spv-out"] [[example]] diff --git a/wgpu/examples/README.md b/wgpu/examples/README.md index f2e178edbd..f893d173bf 100644 --- a/wgpu/examples/README.md +++ b/wgpu/examples/README.md @@ -12,7 +12,7 @@ All framework-based examples render to the window. ## Feature matrix | Feature | boids | cube | mipmap | msaa-line | shadow | skybox | texture-arrays | water | conservative-raster | | ---------------------------- | ------ | ------ | ------ | --------- | ------ | ------ | -------------- | ------ | ------------------- | -| WGSL shaders | :star: | :star: | :star: | :star: | :star: | :star: | | | :star: | +| WGSL shaders | :star: | :star: | :star: | :star: | :star: | :star: | | :star: | :star: | | vertex attributes | :star: | :star: | | :star: | :star: | :star: | :star: | :star: | | | instancing | :star: | | | | | | | | | | lines and points | | | | :star: | | | | | :star: | diff --git a/wgpu/examples/boids/compute.wgsl b/wgpu/examples/boids/compute.wgsl index 43c354d266..4a5bc6bb09 100644 --- a/wgpu/examples/boids/compute.wgsl +++ b/wgpu/examples/boids/compute.wgsl @@ -1,7 +1,6 @@ // This should match `NUM_PARTICLES` on the Rust side. const NUM_PARTICLES: u32 = 1500u; -[[block]] struct Particle { pos : vec2; vel : vec2; diff --git a/wgpu/examples/shadow/shader.wgsl b/wgpu/examples/shadow/shader.wgsl index fb0305542e..f23bba68ab 100644 --- a/wgpu/examples/shadow/shader.wgsl +++ b/wgpu/examples/shadow/shader.wgsl @@ -43,7 +43,6 @@ fn vs_main( // fragment shader -[[block]] struct Light { proj: mat4x4; pos: vec4; diff --git a/wgpu/examples/water/main.rs b/wgpu/examples/water/main.rs index dbc931cd1a..f2ccbe325d 100644 --- a/wgpu/examples/water/main.rs +++ b/wgpu/examples/water/main.rs @@ -5,7 +5,7 @@ mod point_gen; use bytemuck::{Pod, Zeroable}; use cgmath::Point3; -use std::{iter, mem}; +use std::{borrow::Cow, iter, mem}; use wgpu::util::DeviceExt; /// @@ -263,7 +263,7 @@ impl Example { impl framework::Example for Example { fn init( sc_desc: &wgpu::SwapChainDescriptor, - _adapter: &wgpu::Adapter, + adapter: &wgpu::Adapter, device: &wgpu::Device, queue: &wgpu::Queue, ) -> Self { @@ -486,14 +486,23 @@ impl framework::Example for Example { }); // Upload/compile them to GPU code. - let water_vs_module = - device.create_shader_module(&wgpu::include_spirv!("water_shader.vert.spv")); - let water_fs_module = - device.create_shader_module(&wgpu::include_spirv!("water_shader.frag.spv")); - let terrain_vs_module = - device.create_shader_module(&wgpu::include_spirv!("terrain_shader.vert.spv")); - let terrain_fs_module = - device.create_shader_module(&wgpu::include_spirv!("terrain_shader.frag.spv")); + let mut flags = wgpu::ShaderFlags::VALIDATION; + match adapter.get_info().backend { + wgpu::Backend::Metal | wgpu::Backend::Vulkan => { + flags |= wgpu::ShaderFlags::EXPERIMENTAL_TRANSLATION + } + _ => (), //TODO + } + let terrain_module = device.create_shader_module(&wgpu::ShaderModuleDescriptor { + label: Some("terrain"), + source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("terrain.wgsl"))), + flags, + }); + let water_module = device.create_shader_module(&wgpu::ShaderModuleDescriptor { + label: Some("water"), + source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("water.wgsl"))), + flags, + }); // Create the render pipelines. These describe how the data will flow through the GPU, and what // constraints and modifiers it will have. @@ -503,8 +512,8 @@ impl framework::Example for Example { layout: Some(&water_pipeline_layout), // Vertex shader and input buffers vertex: wgpu::VertexState { - module: &water_vs_module, - entry_point: "main", + module: &water_module, + entry_point: "vs_main", // Layout of our vertices. This should match the structs // which are uploaded to the GPU. This should also be // ensured by tagging on either a `#[repr(C)]` onto a @@ -518,8 +527,8 @@ impl framework::Example for Example { }, // Fragment shader and output targets fragment: Some(wgpu::FragmentState { - module: &water_fs_module, - entry_point: "main", + module: &water_module, + entry_point: "fs_main", // Describes how the colour will be interpolated // and assigned to the output attachment. targets: &[wgpu::ColorTargetState { @@ -572,8 +581,8 @@ impl framework::Example for Example { label: Some("terrain"), layout: Some(&terrain_pipeline_layout), vertex: wgpu::VertexState { - module: &terrain_vs_module, - entry_point: "main", + module: &terrain_module, + entry_point: "vs_main", buffers: &[wgpu::VertexBufferLayout { array_stride: terrain_vertex_size as wgpu::BufferAddress, step_mode: wgpu::InputStepMode::Vertex, @@ -581,8 +590,8 @@ impl framework::Example for Example { }], }, fragment: Some(wgpu::FragmentState { - module: &terrain_fs_module, - entry_point: "main", + module: &terrain_module, + entry_point: "fs_main", targets: &[sc_desc.format.into()], }), primitive: wgpu::PrimitiveState { diff --git a/wgpu/examples/water/terrain.wgsl b/wgpu/examples/water/terrain.wgsl new file mode 100644 index 0000000000..50f923610c --- /dev/null +++ b/wgpu/examples/water/terrain.wgsl @@ -0,0 +1,49 @@ +[[block]] +struct Uniforms { + projection_view: mat4x4; + clipping_plane: vec4; +}; + +[[group(0), binding(0)]] +var uniforms: Uniforms; + +const light: vec3 = vec3(150.0, 70.0, 0.0); +const light_colour: vec3 = vec3(1.0, 0.98, 0.82); +const ambient: f32 = 0.2; + +struct VertexOutput { + [[builtin(position)]] position: vec4; + [[location(0)]] colour: vec4; + // Comment this out if using user-clipping planes: + [[location(1)]] clip_dist: f32; +}; + +[[stage(vertex)]] +fn vs_main( + [[location(0)]] position: vec3, + [[location(1)]] normal: vec3, + [[location(2)]] colour: vec4, +) -> VertexOutput { + var out: VertexOutput; + out.position = uniforms.projection_view * vec4(position, 1.0); + + // https://www.desmos.com/calculator/nqgyaf8uvo + const normalized_light_direction = normalize(position - light); + const brightness_diffuse = clamp(dot(normalized_light_direction, normal), 0.2, 1.0); + + out.colour = vec4(max((brightness_diffuse + ambient) * light_colour * colour.rgb, vec3(0.0, 0.0, 0.0)), colour.a); + out.clip_dist = dot(vec4(position, 1.0), uniforms.clipping_plane); + return out; +} + +[[stage(fragment), early_depth_test]] +fn fs_main( + in: VertexOutput, +) -> [[location(0)]] vec4 { + // Comment this out if using user-clipping planes: + if(in.clip_dist < 0.0) { + discard; + } + + return vec4(in.colour.xyz, 1.0); +} diff --git a/wgpu/examples/water/terrain_shader.frag b/wgpu/examples/water/terrain_shader.frag deleted file mode 100644 index 895b179023..0000000000 --- a/wgpu/examples/water/terrain_shader.frag +++ /dev/null @@ -1,19 +0,0 @@ -#version 450 - -layout(early_fragment_tests) in; - -layout(location = 0) in vec4 v_Colour; -// Comment this out if using user-clipping planes: -layout(location = 1) in float v_ClipDist; - -layout(location = 0) out vec4 outColour; - -void main() { - // Comment this out if using user-clipping planes: - if(v_ClipDist < 0.0) { - discard; - } - - outColour = v_Colour; - outColour.a = 1.0; -} diff --git a/wgpu/examples/water/terrain_shader.frag.spv b/wgpu/examples/water/terrain_shader.frag.spv deleted file mode 100644 index aa54ce6d05..0000000000 Binary files a/wgpu/examples/water/terrain_shader.frag.spv and /dev/null differ diff --git a/wgpu/examples/water/terrain_shader.vert b/wgpu/examples/water/terrain_shader.vert deleted file mode 100644 index aa3d12a727..0000000000 --- a/wgpu/examples/water/terrain_shader.vert +++ /dev/null @@ -1,38 +0,0 @@ -#version 450 - -layout(set = 0, binding = 0) uniform Uniforms { - mat4x4 projection_view; - vec4 clipping_plane; -}; - -const vec3 light = vec3(150.0, 70.0, 0.0); -const vec3 light_colour = vec3(1.0, 250.0 / 255.0, 209.0 / 255.0); - -const float ambient = 0.2; - -layout(location = 0) in vec3 position; -layout(location = 1) in vec3 normal; -layout(location = 2) in vec4 colour; - -layout(location = 0) out vec4 v_Colour; -// Comment this out if using user-clipping planes: -layout(location = 1) out float v_ClipDist; - -void main() { - gl_Position = projection_view * vec4(position, 1.0); - - // https://www.desmos.com/calculator/nqgyaf8uvo - - vec3 normalized_light_direction = normalize(position - light); - - float brightness_diffuse = clamp(dot(normalized_light_direction, normal), 0.2, 1.0); - - v_Colour.rgb = max((brightness_diffuse + ambient) * light_colour * colour.rgb, 0.0); - v_Colour.a = colour.a; - - // Comment this out if using user-clipping planes: - v_ClipDist = dot(vec4(position, 1.0), clipping_plane); - - // Uncomment this if using user-clipping planes: - // gl_ClipDistance[0] = dot(vec4(position, 1.0), clipping_plane); -} diff --git a/wgpu/examples/water/terrain_shader.vert.spv b/wgpu/examples/water/terrain_shader.vert.spv deleted file mode 100644 index 587504e4fd..0000000000 Binary files a/wgpu/examples/water/terrain_shader.vert.spv and /dev/null differ diff --git a/wgpu/examples/water/water.wgsl b/wgpu/examples/water/water.wgsl new file mode 100644 index 0000000000..1e32908f95 --- /dev/null +++ b/wgpu/examples/water/water.wgsl @@ -0,0 +1,252 @@ +[[block]] +struct Uniforms { + view: mat4x4; + projection: mat4x4; + time_size_width: vec4; + viewport_height: f32; +}; +[[group(0), binding(0)]] var uniforms: Uniforms; + +const light_point: vec3 = vec3(150.0, 70.0, 0.0); +const light_colour: vec3 = vec3(1.0, 0.98, 0.82); +const one: vec4 = vec4(1.0, 1.0, 1.0, 1.0); + +const Y_SCL: f32 = 0.86602540378443864676372317075294; +const CURVE_BIAS: f32 = -0.1; +const INV_1_CURVE_BIAS: f32 = 1.11111111111; //1.0 / (1.0 + CURVE_BIAS); + +// +// The following code to calculate simplex 3D +// is from https://github.com/ashima/webgl-noise +// +// Simplex 3D Noise +// by Ian McEwan, Ashima Arts. +// +fn permute(x: vec4) -> vec4 { + var temp: vec4 = 289.0 * one; + return modf(((x*34.0) + one) * x, &temp); +} + +fn taylorInvSqrt(r: vec4) -> vec4 { + return 1.79284291400159 * one - 0.85373472095314 * r; +} + +fn snoise(v: vec3) -> f32 { + const C = vec2(1.0/6.0, 1.0/3.0); + const D = vec4(0.0, 0.5, 1.0, 2.0); + + // First corner + //TODO: use the splat operations when available + const vCy = dot(v, C.yyy); + var i: vec3 = floor(v + vec3(vCy, vCy, vCy)); + const iCx = dot(i, C.xxx); + const x0 = v - i + vec3(iCx, iCx, iCx); + + // Other corners + const g = step(x0.yzx, x0.xyz); + const l = (vec3(1.0, 1.0, 1.0) - g).zxy; + const i1 = min(g, l); + const i2 = max(g, l); + + // x0 = x0 - 0.0 + 0.0 * C.xxx; + // x1 = x0 - i1 + 1.0 * C.xxx; + // x2 = x0 - i2 + 2.0 * C.xxx; + // x3 = x0 - 1.0 + 3.0 * C.xxx; + const x1 = x0 - i1 + C.xxx; + const x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y + const x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y + + // Permutations + var temp: vec3 = 289.0 * one.xyz; + i = modf(i, &temp); + const p = permute( + permute( + permute(i.zzzz + vec4(0.0, i1.z, i2.z, 1.0)) + + i.yyyy + vec4(0.0, i1.y, i2.y, 1.0)) + + i.xxxx + vec4(0.0, i1.x, i2.x, 1.0)); + + // Gradients: 7x7 points over a square, mapped onto an octahedron. + // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) + const n_ = 0.142857142857;// 1.0/7.0 + const ns = n_ * D.wyz - D.xzx; + + const j = p - 49.0 * floor(p * ns.z * ns.z);// mod(p,7*7) + + const x_ = floor(j * ns.z); + const y_ = floor(j - 7.0 * x_);// mod(j,N) + + var x: vec4 = x_ *ns.x + ns.yyyy; + var y: vec4 = y_ *ns.x + ns.yyyy; + const h = one - abs(x) - abs(y); + + const b0 = vec4(x.xy, y.xy); + const b1 = vec4(x.zw, y.zw); + + //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - one; + //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - one; + const s0 = floor(b0)*2.0 + one; + const s1 = floor(b1)*2.0 + one; + const sh = -step(h, 0.0 * one); + + const a0 = b0.xzyw + s0.xzyw*sh.xxyy; + const a1 = b1.xzyw + s1.xzyw*sh.zzww; + + var p0: vec3 = vec3(a0.xy, h.x); + var p1: vec3 = vec3(a0.zw, h.y); + var p2: vec3 = vec3(a1.xy, h.z); + var p3: vec3 = vec3(a1.zw, h.w); + + //Normalise gradients + const norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); + p0 = p0 * norm.x; + p1 = p1 * norm.y; + p2 = p2 * norm.z; + p3 = p3 * norm.w; + + // Mix final noise value + var m: vec4 = max(0.6 * one - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0 * one); + m = m * m; + return 9.0 * dot(m*m, vec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3))); +} + +// End of 3D simplex code. + +fn apply_distortion(pos: vec3) -> vec3 { + var perlin_pos: vec3 = pos; + + //Do noise transformation to permit for smooth, + //continuous movement. + + //TODO: we should be able to name them `sin` and `cos`. + const sn = uniforms.time_size_width.x; + const cs = uniforms.time_size_width.y; + const size = uniforms.time_size_width.z; + + // Rotate 90 Z, Move Left Size / 2 + perlin_pos = vec3(perlin_pos.y - perlin_pos.x - size, perlin_pos.x, perlin_pos.z); + + const xcos = perlin_pos.x * cs; + const xsin = perlin_pos.x * sn; + const ycos = perlin_pos.y * cs; + const ysin = perlin_pos.y * sn; + const zcos = perlin_pos.z * cs; + const zsin = perlin_pos.z * sn; + + // Rotate Time Y + const perlin_pos_y = vec3(xcos + zsin, perlin_pos.y, -xsin + xcos); + + // Rotate Time Z + const perlin_pos_z = vec3(xcos - ysin, xsin + ycos, perlin_pos.x); + + // Rotate 90 Y + perlin_pos = vec3(perlin_pos.z - perlin_pos.x, perlin_pos.y, perlin_pos.x); + + // Rotate Time X + const perlin_pos_x = vec3(perlin_pos.x, ycos - zsin, ysin + zcos); + + // Sample at different places for x/y/z to get random-looking water. + return vec3( + //TODO: use splats + pos.x + snoise(perlin_pos_x + 2.0*one.xxx) * 0.4, + pos.y + snoise(perlin_pos_y - 2.0*one.xxx) * 1.8, + pos.z + snoise(perlin_pos_z) * 0.4 + ); +} + +// Multiply the input by the scale values. +fn make_position(original: vec2) -> vec4 { + const interpreted = vec3(original.x * 0.5, 0.0, original.y * Y_SCL); + return vec4(apply_distortion(interpreted), 1.0); +} + +// Create the normal, and apply the curve. Change the Curve Bias above. +fn make_normal(a: vec3, b: vec3, c: vec3) -> vec3 { + const norm = normalize(cross(b - c, a - c)); + const center = (a + b + c) * (1.0 / 3.0); //TODO: use splat + return (normalize(a - center) * CURVE_BIAS + norm) * INV_1_CURVE_BIAS; +} + +// Calculate the fresnel effect. +fn calc_fresnel(view: vec3, normal: vec3) -> f32 { + var refractive: f32 = abs(dot(view, normal)); + refractive = pow(refractive, 1.33333333333); + return refractive; +} + +// Calculate the specular lighting. +fn calc_specular(eye: vec3, normal: vec3, light: vec3) -> f32 { + const light_reflected = reflect(light, normal); + var specular: f32 = max(dot(eye, light_reflected), 0.0); + specular = pow(specular, 10.0); + return specular; +} + +struct VertexOutput { + [[builtin(position)]] position: vec4; + [[location(0)]] f_WaterScreenPos: vec2; + [[location(1)]] f_Fresnel: f32; + [[location(2)]] f_Light: vec3; +}; + +[[stage(vertex)]] +fn vs_main( + [[location(0)]] position: vec2, + [[location(1)]] offsets: vec4, +) -> VertexOutput { + const p_pos = vec2(position); + const b_pos = make_position(p_pos + vec2(offsets.xy)); + const c_pos = make_position(p_pos + vec2(offsets.zw)); + const a_pos = make_position(p_pos); + const original_pos = vec4(p_pos.x * 0.5, 0.0, p_pos.y * Y_SCL, 1.0); + + const vm = uniforms.view; + const transformed_pos = vm * a_pos; + //TODO: use vector splats for division + const water_pos = transformed_pos.xyz * (1.0 / transformed_pos.w); + const normal = make_normal((vm * a_pos).xyz, (vm * b_pos).xyz, (vm * c_pos).xyz); + const eye = normalize(-water_pos); + const transformed_light = vm * vec4(light_point, 1.0); + + var out: VertexOutput; + out.f_Light = light_colour * calc_specular(eye, normal, normalize(water_pos.xyz - (transformed_light.xyz * (1.0 / transformed_light.w)))); + out.f_Fresnel = calc_fresnel(eye, normal); + + const gridpos = uniforms.projection * vm * original_pos; + out.f_WaterScreenPos = (0.5 * gridpos.xy * (1.0 / gridpos.w)) + vec2(0.5, 0.5); + + out.position = uniforms.projection * transformed_pos; + return out; +} + + +const water_colour: vec3 = vec3(0.0, 0.46, 0.95); +const zNear: f32 = 10.0; +const zFar: f32 = 400.0; + +[[group(0), binding(1)]] var reflection: texture_2d; +[[group(0), binding(2)]] var terrain_depth_tex: texture_2d; +[[group(0), binding(3)]] var colour_sampler: sampler; + +fn to_linear_depth(depth: f32) -> f32 { + const z_n: f32 = 2.0 * depth - 1.0; + const z_e: f32 = 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)); + return z_e; +} + +[[stage(fragment)]] +fn fs_main(in: VertexOutput) -> [[location(0)]] vec4 { + const reflection_colour = textureSample(reflection, colour_sampler, in.f_WaterScreenPos.xy).xyz; + + const pixel_depth = to_linear_depth(in.position.z); + const normalized_coords = in.position.xy / vec2(uniforms.time_size_width.w, uniforms.viewport_height); + const terrain_depth = to_linear_depth(textureSample(terrain_depth_tex, colour_sampler, normalized_coords).r); + + const dist = terrain_depth - pixel_depth; + const clamped = pow(smoothStep(0.0, 1.5, dist), 4.8); + + const final_colour = in.f_Light + reflection_colour; + const t = smoothStep(1.0, 5.0, dist) * 0.2; //TODO: splat for mix()? + const depth_colour = mix(final_colour, water_colour, vec3(t, t, t)); + + return vec4(depth_colour, clamped * (1.0 - in.f_Fresnel)); +} diff --git a/wgpu/examples/water/water_shader.frag b/wgpu/examples/water/water_shader.frag deleted file mode 100644 index 0d704e33be..0000000000 --- a/wgpu/examples/water/water_shader.frag +++ /dev/null @@ -1,46 +0,0 @@ -#version 450 - -const vec3 water_colour = vec3(0.0, 117.0 / 255.0, 242.0 / 255.0); -const float zNear = 10.0; -const float zFar = 400.0; - -layout(set = 0, binding = 0) uniform Uniforms { - mat4x4 _view; - mat4x4 _projection; - vec4 time_size_width; - float viewport_height; -}; - -layout(set = 0, binding = 1) uniform texture2D reflection; -layout(set = 0, binding = 2) uniform texture2D terrain_depth_tex; -layout(set = 0, binding = 3) uniform sampler colour_sampler; - -layout(location = 0) in vec2 f_WaterScreenPos; -layout(location = 1) in float f_Fresnel; -layout(location = 2) in vec3 f_Light; - -layout(location = 0) out vec4 outColor; - -float to_linear_depth(float depth) { - float z_n = 2.0 * depth - 1.0; - float z_e = 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)); - return z_e; -} - -void main() { - vec3 reflection_colour = texture(sampler2D(reflection, colour_sampler), f_WaterScreenPos.xy).xyz; - - float pixel_depth = to_linear_depth(gl_FragCoord.z); - float terrain_depth = to_linear_depth(texture(sampler2D(terrain_depth_tex, colour_sampler), gl_FragCoord.xy / vec2(time_size_width.w, viewport_height)).r); - - float dist = terrain_depth - pixel_depth; - float clamped = pow(smoothstep(0.0, 1.5, dist), 4.8); - - outColor.a = clamped * (1.0 - f_Fresnel); - - vec3 final_colour = f_Light + reflection_colour; - - vec3 depth_colour = mix(final_colour, water_colour, smoothstep(1.0, 5.0, dist) * 0.2); - - outColor.xyz = depth_colour; -} diff --git a/wgpu/examples/water/water_shader.frag.spv b/wgpu/examples/water/water_shader.frag.spv deleted file mode 100644 index 8eb94cfa6e..0000000000 Binary files a/wgpu/examples/water/water_shader.frag.spv and /dev/null differ diff --git a/wgpu/examples/water/water_shader.vert b/wgpu/examples/water/water_shader.vert deleted file mode 100644 index b35251ef16..0000000000 --- a/wgpu/examples/water/water_shader.vert +++ /dev/null @@ -1,211 +0,0 @@ -#version 450 - -layout(set = 0, binding = 0) uniform Uniforms { - mat4x4 view; - mat4x4 projection; - vec4 time_size_width; - float _viewport_height; -}; - -const vec3 light_point = vec3(150.0, 70.0, 0.0); -const vec3 light_colour = vec3(1.0, 250.0 / 255.0, 209.0 / 255.0); - -const float Y_SCL = 0.86602540378443864676372317075294; -const float CURVE_BIAS = -0.1; -const float INV_1_CURVE_BIAS = 1.0 / (1.0 + CURVE_BIAS); - -layout(location = 0) in ivec2 position; -layout(location = 1) in ivec4 offsets; - -layout(location = 0) out vec2 f_WaterScreenPos; -layout(location = 1) out float f_Fresnel; -layout(location = 2) out vec3 f_Light; - -// -// The following code to calculate simplex 3D -// is from https://github.com/ashima/webgl-noise -// -// Simplex 3D Noise -// by Ian McEwan, Ashima Arts. -// -vec4 permute(vec4 x) { - return mod(((x*34.0)+1.0)*x, 289.0); -} - -vec4 taylorInvSqrt(vec4 r){ - return 1.79284291400159 - 0.85373472095314 * r; -} - -float snoise(vec3 v){ - const vec2 C = vec2(1.0/6.0, 1.0/3.0); - const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); - - // First corner - vec3 i = floor(v + dot(v, C.yyy)); - vec3 x0 = v - i + dot(i, C.xxx); - - // Other corners - vec3 g = step(x0.yzx, x0.xyz); - vec3 l = 1.0 - g; - vec3 i1 = min(g.xyz, l.zxy); - vec3 i2 = max(g.xyz, l.zxy); - - // x0 = x0 - 0.0 + 0.0 * C.xxx; - // x1 = x0 - i1 + 1.0 * C.xxx; - // x2 = x0 - i2 + 2.0 * C.xxx; - // x3 = x0 - 1.0 + 3.0 * C.xxx; - vec3 x1 = x0 - i1 + C.xxx; - vec3 x2 = x0 - i2 + C.yyy;// 2.0*C.x = 1/3 = C.y - vec3 x3 = x0 - D.yyy;// -1.0+3.0*C.x = -0.5 = -D.y - - // Permutations - i = mod(i, 289.0); - vec4 p = permute(permute(permute( - i.z + vec4(0.0, i1.z, i2.z, 1.0)) - + i.y + vec4(0.0, i1.y, i2.y, 1.0)) - + i.x + vec4(0.0, i1.x, i2.x, 1.0)); - - // Gradients: 7x7 points over a square, mapped onto an octahedron. - // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) - float n_ = 0.142857142857;// 1.0/7.0 - vec3 ns = n_ * D.wyz - D.xzx; - - vec4 j = p - 49.0 * floor(p * ns.z * ns.z);// mod(p,7*7) - - vec4 x_ = floor(j * ns.z); - vec4 y_ = floor(j - 7.0 * x_);// mod(j,N) - - vec4 x = x_ *ns.x + ns.yyyy; - vec4 y = y_ *ns.x + ns.yyyy; - vec4 h = 1.0 - abs(x) - abs(y); - - vec4 b0 = vec4(x.xy, y.xy); - vec4 b1 = vec4(x.zw, y.zw); - - //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; - //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; - vec4 s0 = floor(b0)*2.0 + 1.0; - vec4 s1 = floor(b1)*2.0 + 1.0; - vec4 sh = -step(h, vec4(0.0)); - - vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy; - vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww; - - vec3 p0 = vec3(a0.xy, h.x); - vec3 p1 = vec3(a0.zw, h.y); - vec3 p2 = vec3(a1.xy, h.z); - vec3 p3 = vec3(a1.zw, h.w); - - //Normalise gradients - vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); - p0 *= norm.x; - p1 *= norm.y; - p2 *= norm.z; - p3 *= norm.w; - - // Mix final noise value - vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0); - m = m * m; - return 9.0 * dot(m*m, vec4(dot(p0, x0), dot(p1, x1), - dot(p2, x2), dot(p3, x3))); -} - -// End of 3D simplex code. - -vec3 apply_distortion(vec3 pos) { - vec3 perlin_pos = pos; - - //Do noise transformation to permit for smooth, - //continuous movement. - - float sin = time_size_width.x; - float cos = time_size_width.y; - float size = time_size_width.z; - - // Rotate 90 Z - perlin_pos.xy = perlin_pos.yx; - perlin_pos.x = -perlin_pos.x; - // Move Left Size / 2 - perlin_pos.x -= size; - - float xcos = perlin_pos.x * cos; - float xsin = perlin_pos.x * sin; - float ycos = perlin_pos.y * cos; - float ysin = perlin_pos.y * sin; - float zcos = perlin_pos.z * cos; - float zsin = perlin_pos.z * sin; - - // Rotate Time Y - vec3 perlin_pos_y = vec3(xcos + zsin, perlin_pos.y, -xsin + xcos); - - // Rotate Time Z - vec3 perlin_pos_z = vec3(xcos - ysin, xsin + ycos, perlin_pos.x); - - // Rotate 90 Y - perlin_pos.xz = perlin_pos.zx; - perlin_pos.x = -perlin_pos.x; - - // Rotate Time X - vec3 perlin_pos_x = vec3(perlin_pos.x, ycos - zsin, ysin + zcos); - - // Sample at different places for x/y/z to get random-looking water. - return vec3(pos.x + snoise(perlin_pos_x + 2.0) * 0.4, pos.y + snoise(perlin_pos_y - 2.0) * 1.8, pos.z + snoise(perlin_pos_z) * 0.4); -} - -// Multiply the input by the scale values. -vec3 make_position(vec2 original) { - vec3 interpreted = vec3(original.x * 0.5, 0.0, original.y * Y_SCL); - return apply_distortion(interpreted); -} - -// Create the normal, and apply the curve. Change the Curve Bias above. -vec3 make_normal(vec3 a, vec3 b, vec3 c) { - vec3 norm = normalize(cross(b - c, a - c)); - vec3 center = (a + b + c) / 3.0; - return (normalize(a - center) * CURVE_BIAS + norm) * INV_1_CURVE_BIAS; -} - -// Calculate the fresnel effect. -float calc_fresnel(vec3 view, vec3 normal) { - float refractive = abs(dot(view, normal)); - refractive = pow(refractive, 1.33333333333); - return refractive; -} - -// Calculate the specular lighting. -float calc_specular(vec3 eye, vec3 normal, vec3 light) { - vec3 light_reflected = reflect(light, normal); - float specular = max(dot(eye, light_reflected), 0.0); - specular = pow(specular, 10.0); - return specular; -} - -void main() { - vec2 p_pos = position; - vec3 b_pos = make_position(p_pos + offsets.xy); - vec3 c_pos = make_position(p_pos + offsets.zw); - vec4 a_pos = vec4(make_position(p_pos), 1.0); - vec4 original_pos = vec4(p_pos.x * 0.5, 0.0, p_pos.y * Y_SCL, 1.0); - - vec4 water_pos = a_pos; - - mat4x4 vm = view; - - vec4 transformed_pos = vm * water_pos; - water_pos.xyz = transformed_pos.xyz / transformed_pos.w; - - vec3 normal = make_normal((vm * a_pos).xyz, (vm * vec4(b_pos, 1.0)).xyz, (vm * vec4(c_pos, 1.0)).xyz); - vec3 eye = normalize(-water_pos.xyz); - - vec4 transformed_light = vm * vec4(light_point, 1.0); - - f_Light = light_colour * calc_specular(eye, normal, normalize(water_pos.xyz - (transformed_light.xyz / transformed_light.w))); - f_Fresnel = calc_fresnel(eye, normal); - - vec4 projected_pos = projection * transformed_pos; - - gl_Position = projected_pos; - - vec4 gridpos = projection * vm * original_pos; - f_WaterScreenPos.xy = (0.5 * gridpos.xy / gridpos.w) + 0.5; -} diff --git a/wgpu/examples/water/water_shader.vert.spv b/wgpu/examples/water/water_shader.vert.spv deleted file mode 100644 index 688792a7c9..0000000000 Binary files a/wgpu/examples/water/water_shader.vert.spv and /dev/null differ