Push parameters into shaders

This commit is contained in:
hodasemi 2020-11-24 16:38:29 +01:00
parent 6abc793708
commit 8f86376e99
5 changed files with 129 additions and 22 deletions

View file

@ -1,9 +1,15 @@
#version 450 #version 450
layout (location = 0) in vec2 in_uv;
layout (location = 0) out vec4 color; layout (location = 0) out vec4 color;
const int MAX_ITER = 1000; layout (set = 0, binding = 0) uniform Parameters {
const float SIZE = 0.01; int max_iter;
float size;
float time;
float factor;
} parameters;
float hue_to_rgb(float p, float q, float t) { float hue_to_rgb(float p, float q, float t) {
if (t < 0.0) { if (t < 0.0) {
@ -57,7 +63,7 @@ void mandelbrot_iter(float px, float py, out float ox, out int iter) {
float yy = 0.0; float yy = 0.0;
float xy = 0.0; float xy = 0.0;
for (int i = 0; i < MAX_ITER; i++) { for (int i = 0; i < parameters.max_iter; i++) {
xx = x * x; xx = x * x;
yy = y * y; yy = y * y;
xy = x * y; xy = x * y;
@ -74,14 +80,14 @@ void mandelbrot_iter(float px, float py, out float ox, out int iter) {
} }
ox = xx + yy; ox = xx + yy;
iter = MAX_ITER; iter = parameters.max_iter;
} }
vec3 paint(float nx, float ny) { vec3 paint(float nx, float ny) {
float r; float r;
int n; int n;
mandelbrot_iter(SIZE * nx, SIZE * ny, r, n); mandelbrot_iter(parameters.size * nx, parameters.size * ny, r, n);
if (r > 4.0) { if (r > 4.0) {
return hsl_to_rgb(float(n) / 800.0 * r, 1.0, 0.5); return hsl_to_rgb(float(n) / 800.0 * r, 1.0, 0.5);
@ -90,6 +96,43 @@ vec3 paint(float nx, float ny) {
} }
} }
// void main() {
// color = vec4(paint(gl_FragCoord.x, gl_FragCoord.y), 1.0);
// }
void main() { void main() {
color = vec4(paint(gl_FragCoord.x, gl_FragCoord.y), 1.0); vec2 tc = vec2(in_uv.x) * parameters.time * parameters.factor;
float x0 = (tc.x * 3 - 2);
float y0 = (tc.y * 2 - 1);
float x = 0;
float y = 0;
int iteration = 0;
while ((x * x + y * y <= 4) && (iteration < parameters.max_iter))
{
float xtemp = x * x - y * y + x0;
y = 2 * x * y + y0;
x = xtemp;
iteration += 1;
}
if (iteration == parameters.max_iter)
{
// Hier wird der Farbwert für das Innere der Mandelbrotmenge gesetzt
color = vec4(0, 0, 0, 1);
}
else
{
// Hier kann eine beliebige Farbwahl stattfinden(z.B. mit einer Farbtabelle).
// als Index verwendet man die Variable "iteration", die einen Wert zwischen 1 und parameters.max_iter hat.
x = sin(float(iteration));
color = vec4(x, x, x, 1);
}
} }

Binary file not shown.

View file

@ -2,13 +2,29 @@ use std::{mem, sync::Arc};
use context::{prelude::*, ContextObject}; use context::{prelude::*, ContextObject};
#[derive(Debug, Clone)]
struct ShaderInfo {
max_iter: i32,
size: f32,
time: f32,
factor: f32,
}
#[derive(Clone)]
struct Vertex {
position: [f32; 2],
uv: [f32; 2],
}
pub struct Fractal { pub struct Fractal {
context: Arc<Context>, context: Arc<Context>,
descriptor_set: Arc<DescriptorSet>, descriptor_set: Arc<DescriptorSet>,
pipeline: Arc<Pipeline>, pipeline: Arc<Pipeline>,
render_target: RenderTarget, render_target: RenderTarget,
vertex_buffer: Arc<Buffer<[f32; 2]>>,
vertex_buffer: Arc<Buffer<Vertex>>,
descriptor_buffer: Arc<Buffer<ShaderInfo>>,
} }
impl Fractal { impl Fractal {
@ -55,14 +71,22 @@ impl Fractal {
vec![VkVertexInputBindingDescription { vec![VkVertexInputBindingDescription {
binding: 0, binding: 0,
inputRate: VK_VERTEX_INPUT_RATE_VERTEX, inputRate: VK_VERTEX_INPUT_RATE_VERTEX,
stride: mem::size_of::<[f32; 2]>() as u32, stride: mem::size_of::<Vertex>() as u32,
}],
vec![VkVertexInputAttributeDescription {
location: 0,
binding: 0,
format: VK_FORMAT_R32G32_SFLOAT,
offset: 0,
}], }],
vec![
VkVertexInputAttributeDescription {
location: 0,
binding: 0,
format: VK_FORMAT_R32G32_SFLOAT,
offset: 0,
},
VkVertexInputAttributeDescription {
location: 1,
binding: 0,
format: VK_FORMAT_R32G32_SFLOAT,
offset: 8,
},
],
) )
.set_fragment_shader(ShaderModule::from_slice( .set_fragment_shader(ShaderModule::from_slice(
context.device().clone(), context.device().clone(),
@ -99,17 +123,48 @@ impl Fractal {
let vertex_buffer = Buffer::builder() let vertex_buffer = Buffer::builder()
.set_data(&[ .set_data(&[
[-1.0, -1.0], Vertex {
[1.0, -1.0], position: [-1.0, -1.0],
[1.0, 1.0], uv: [0.0, 0.0],
[1.0, 1.0], },
[-1.0, 1.0], Vertex {
[-1.0, -1.0], position: [1.0, -1.0],
uv: [1.0, 0.0],
},
Vertex {
position: [1.0, 1.0],
uv: [1.0, 1.0],
},
Vertex {
position: [1.0, 1.0],
uv: [1.0, 1.0],
},
Vertex {
position: [-1.0, 1.0],
uv: [0.0, 1.0],
},
Vertex {
position: [-1.0, -1.0],
uv: [0.0, 0.0],
},
]) ])
.set_memory_usage(MemoryUsage::CpuOnly) .set_memory_usage(MemoryUsage::CpuOnly)
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) .set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
.build(context.device().clone())?; .build(context.device().clone())?;
let shader_info = Buffer::builder()
.set_data(&[ShaderInfo {
max_iter: 1000,
size: 0.001,
time: 0.0,
factor: 1.0,
}])
.set_memory_usage(MemoryUsage::CpuOnly)
.set_usage(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
.build(context.device().clone())?;
descriptor_set.update(&[DescriptorWrite::uniform_buffers(0, &[&shader_info])])?;
Ok(Arc::new(Self { Ok(Arc::new(Self {
context: context.clone(), context: context.clone(),
@ -117,6 +172,7 @@ impl Fractal {
pipeline, pipeline,
render_target, render_target,
vertex_buffer, vertex_buffer,
descriptor_buffer: shader_info,
})) }))
} }
} }
@ -127,6 +183,10 @@ impl ContextObject for Fractal {
} }
fn update(&self) -> VerboseResult<()> { fn update(&self) -> VerboseResult<()> {
let mut mapping = self.descriptor_buffer.map_complete()?;
mapping[0].time = self.context.time().as_secs_f32();
Ok(()) Ok(())
} }

View file

@ -1,7 +1,11 @@
#version 450 #version 450
layout (location = 0) in vec2 position; layout (location = 0) in vec2 in_position;
layout (location = 1) in vec2 in_uv;
layout (location = 0) out vec2 out_uv;
void main() { void main() {
gl_Position = vec4(position, 0.0, 1.0); gl_Position = vec4(in_position, 0.0, 1.0);
out_uv = in_uv;
} }

Binary file not shown.