Particle Systems with Compute & Geometry Shader. Institute of Computer Graphics and Algorithms Vienna University of Technology

Similar documents
Geometry Shaders. And how to use them

COMP371 COMPUTER GRAPHICS

OpenGL Compute Shaders

A Review of OpenGL Compute Shaders

Shaders. Introduction. OpenGL Grows via Extensions. OpenGL Extensions. OpenGL 2.0 Added Shaders. Shaders Enable Many New Effects

Shaders. Slide credit to Prof. Zwicker

CSE 167: Introduction to Computer Graphics Lecture #7: GLSL. Jürgen P. Schulze, Ph.D. University of California, San Diego Spring Quarter 2016

CPSC 436D Video Game Programming

Compute Shaders. Christian Hafner. Institute of Computer Graphics and Algorithms Vienna University of Technology

Programming with OpenGL Shaders I. Adapted From: Ed Angel Professor of Emeritus of Computer Science University of New Mexico

CS475/CS675 - Computer Graphics. OpenGL Drawing

Comp 410/510 Computer Graphics Spring Programming with OpenGL Part 2: First Program

Programming with OpenGL Shaders I. Adapted From: Ed Angel Professor of Emeritus of Computer Science University of New Mexico

Get the most out of the new OpenGL ES 3.1 API. Hans-Kristian Arntzen Software Engineer

CSE 167. Discussion 03 ft. Glynn 10/16/2017

Information Coding / Computer Graphics, ISY, LiTH. Compute shaders!! The future of GPU computing or a late rip-off of Direct Compute?

OpenGL Compute Shaders

OUTLINE. Implementing Texturing What Can Go Wrong and How to Fix It Mipmapping Filtering Perspective Correction

Comp 410/510 Computer Graphics Spring Programming with OpenGL Part 3: Shaders

OpenGL pipeline Evolution and OpenGL Shading Language (GLSL) Part 2/3 Vertex and Fragment Shaders

CS 432 Interactive Computer Graphics

OPENGL RENDERING PIPELINE

GLSL Introduction. Fu-Chung Huang. Thanks for materials from many other people

Lecture 11 Shaders and WebGL. October 8, 2015

Starting out with OpenGL ES 3.0. Jon Kirkham, Senior Software Engineer, ARM

Tutorial 1: Your First Triangle!

WebGL and GLSL Basics. CS559 Fall 2015 Lecture 10 October 6, 2015

Programming with OpenGL Part 3: Shaders. Ed Angel Professor of Emeritus of Computer Science University of New Mexico

Building Models. Prof. George Wolberg Dept. of Computer Science City College of New York

Building Models. CS 537 Interactive Computer Graphics Prof. David E. Breen Department of Computer Science

Tutorial 04. Harshavardhan Kode. September 14, 2015

Programming shaders & GPUs Christian Miller CS Fall 2011

Blis: Better Language for Image Stuff Project Proposal Programming Languages and Translators, Spring 2017

Shadows. Prof. George Wolberg Dept. of Computer Science City College of New York

12.2 Programmable Graphics Hardware

OpenGL Shading Language Hints/Kinks

Graphics Programming. Computer Graphics, VT 2016 Lecture 2, Chapter 2. Fredrik Nysjö Centre for Image analysis Uppsala University

GPU Programming EE Final Examination

Real-time Graphics 9. GPGPU

CS195V Week 3. GLSL Programming

Comp 410/510 Computer Graphics Spring Programming with OpenGL Part 4: Three Dimensions

Tutorial 12: Real-Time Lighting B

C P S C 314 S H A D E R S, O P E N G L, & J S RENDERING PIPELINE. Mikhail Bessmeltsev

WebGL and GLSL Basics. CS559 Fall 2016 Lecture 14 October

Information Coding / Computer Graphics, ISY, LiTH GLSL. OpenGL Shading Language. Language with syntax similar to C

How to use tessellation to add geometric detail to your scenes. How to use geometry shaders to process whole primitives and create geometry on the fly

Programmable GPUs. Real Time Graphics 11/13/2013. Nalu 2004 (NVIDIA Corporation) GeForce 6. Virtua Fighter 1995 (SEGA Corporation) NV1

Today s Agenda. Shaders fundamentals. Programming with shader-based OpenGL

Programmable Graphics Hardware

EDAF80 Introduction to Computer Graphics. Seminar 3. Shaders. Michael Doggett. Slides by Carl Johan Gribel,

GLSL Introduction. Fu-Chung Huang. Thanks for materials from many other people

3d Programming I. Dr Anton Gerdelan

Overview. By end of the week:

Shaders (some slides taken from David M. course)

2D graphics with WebGL

Fog example. Fog is atmospheric effect. Better realism, helps determine distances

Applying Textures. Lecture 27. Robb T. Koether. Hampden-Sydney College. Fri, Nov 3, 2017

CS770/870 Spring 2017 Open GL Shader Language GLSL

CS770/870 Spring 2017 Open GL Shader Language GLSL

EECS 487: Interactive Computer Graphics

CGT520 Lighting. Lighting. T-vertices. Normal vector. Color of an object can be specified 1) Explicitly as a color buffer

CS452/552; EE465/505. Image Processing Frame Buffer Objects

GPU Programming EE Final Examination

GLSL Overview: Creating a Program

Real-time Graphics 9. GPGPU

Computação Gráfica. Computer Graphics Engenharia Informática (11569) 3º ano, 2º semestre. Chap. 4 Windows and Viewports

Point-Based rendering on GPU hardware. Advanced Computer Graphics 2008

Programming with OpenGL Part 5: More GLSL. Ed Angel Professor Emeritus of Computer Science University of New Mexico

Shader Programming 1. Examples. Vertex displacement mapping. Daniel Wesslén 1. Post-processing, animated procedural textures

Understanding M3G 2.0 and its Effect on Producing Exceptional 3D Java-Based Graphics. Sean Ellis Consultant Graphics Engineer ARM, Maidenhead

Lecture 5 Vertex and Fragment Shaders-1. CITS3003 Graphics & Animation

Copyright Khronos Group 2012 Page 1. Teaching GL. Dave Shreiner Director, Graphics and GPU Computing, ARM 1 December 2012

CS195V Week 6. Image Samplers and Atomic Operations

The OpenGL Shading Language

GLSL Geometry Shaders

The Graphics Pipeline

Computer Graphics CS 543 Lecture 4 (Part 2) Building 3D Models (Part 2)

Information Coding / Computer Graphics, ISY, LiTH. OpenGL! ! where it fits!! what it contains!! how you work with it 11(40)

Cg 2.0. Mark Kilgard

SUMMARY. CS380: Introduction to Computer Graphics Texture Mapping Chapter 15. Min H. Kim KAIST School of Computing 18/05/03.

OpenGL BOF Siggraph 2011

From system point of view, a graphics application handles the user input, changes the internal state, called the virtual world by modeling or

CS 450: COMPUTER GRAPHICS REVIEW: STATE, ATTRIBUTES, AND OBJECTS SPRING 2015 DR. MICHAEL J. REALE

WebGL: Hands On. DevCon5 NYC Kenneth Russell Software Engineer, Google, Inc. Chair, WebGL Working Group

CS4621/5621 Fall Basics of OpenGL/GLSL Textures Basics

The Projection Matrix

The Graphics Pipeline

Drawing with OpenGL. Chapter 3. Chapter Objectives

CSE 4431/ M Advanced Topics in 3D Computer Graphics. TA: Margarita Vinnikov

The Graphics Pipeline and OpenGL III: OpenGL Shading Language (GLSL 1.10)!

Shader Programs. Lecture 30 Subsections 2.8.2, Robb T. Koether. Hampden-Sydney College. Wed, Nov 16, 2011

Information Coding / Computer Graphics, ISY, LiTH GLSL. OpenGL Shading Language. Language with syntax similar to C

Today s Agenda. Basic design of a graphics system. Introduction to OpenGL

CSE 167: Introduction to Computer Graphics Lecture #13: GLSL. Jürgen P. Schulze, Ph.D. University of California, San Diego Fall Quarter 2015

Efficient and Scalable Shading for Many Lights

A Tessellated Parametric Triangular Bézier Patch

Introduction to Shaders.

OpenGL Performances and Flexibility. Visual Computing Laboratory ISTI CNR, Italy

How to Work on Next Gen Effects Now: Bridging DX10 and DX9. Guennadi Riguer ATI Technologies

Tutorial 3: Texture Mapping

Transcription:

Particle Systems with Compute & Geometry Shader Institute of Computer Graphics and Algorithms Vienna University of Technology

Motivation https://www.youtube.com/watch?v=spwbwtu9xyk 24.11.2016 RTR 2016 Spelitz 1

Overview Particle with properties Position Velocity Type,... Compute shader for physics Apply forces Update properties Geometry shader to create a quad Create a billboard / sprite Fragment shader to render 24.11.2016 RTR 2016 Spelitz 2

Frame Conditions Upper limit of particles (maximum amount) One or more particle emitters Particle count is variable Each particle can spawn new particles Particles can die Because of this flexibility we need (*) One array of particles from the previous frame One array of particles from the current frame One atomic counter to keep track of the number (*) If we would not use two arrays we would need an indication which particles are alive or dead plus memory management 24.11.2016 RTR 2016 Spelitz 3

Data Structure Think about particle properties vec4: Position (x,y,z,ttl) vec4: Velocity and time-to-live (vx,vy,vz,<unused>) C++ 2 x 2 SSBOs for position and velocity Geometry Shader layout(std430, binding = 0) buffer Pos1 { vec4 Position_In[]; ; layout(std430, binding = 1) buffer Vel1 { vec4 Velocity_In[]; ; layout(std430, binding = 2) buffer Pos2 { vec4 Position_Out[]; ; layout(std430, binding = 3) buffer Vel2 { vec4 Velocity_Out[]; ; 24.11.2016 RTR 2016 Spelitz 4

Setup SSBO We create 2 x 2 SSBOs Incoming position & velocity buffers Outgoing position & velocity buffers // i = [0,1] glgenbuffers(1, &ssbo_pos[i]); glbindbuffer(gl_shader_storage_buffer, ssbo_pos[i]); glbufferdata(gl_shader_storage_buffer, MAX_PARTICLES * sizeof(glm::vec4), NULL, GL_DYNAMIC_DRAW); 24.11.2016 RTR 2016 Spelitz 5

Setup Atomic Counter glgenbuffers(1, &atomiccounter); glbindbuffer(gl_atomic_counter_buffer, atomic_counter); glbufferdata(gl_atomic_counter_buffer, sizeof(gluint), NULL, GL_DYNAMIC_DRAW); GLuint value = 0; glbuffersubdata(gl_atomic_counter_buffer, 0, sizeof(gluint), &value); glbindbuffer(gl_atomic_counter_buffer, 0); // Because of a performance warning when reading the atomic counter, we // create a buffer to move-to and read-from instead. glgenbuffers(1, &temp_buffer); glbindbuffer(gl_copy_write_buffer, temp_buffer); glbufferdata(gl_copy_write_buffer, sizeof(gluint), NULL, GL_DYNAMIC_READ); glbindbuffer(gl_copy_write_buffer, 0); 24.11.2016 RTR 2016 Spelitz 6

Setup VAO For rendering we connect each of our position SSBOs to a vertex array object GLuint vaos[2]; // one VAO for each SSBO const GLuint position_layout = 0; glgenvertexarrays(2, vaos); glbindvertexarray(vaos[i]); glbindbuffer(gl_array_buffer, ssbo_pos[i]); glenablevertexattribarray(position_layout); glvertexattribpointer(position_layout, 4, GL_FLOAT, GL_FALSE, 0, 0); Vertex shader: layout (location = 0) in vec4 Position; 24.11.2016 RTR 2016 Spelitz 7

Setup Initial Data We need initial particle emitters const int TTL = 10000; // time-to-live in seconds std::vector<glm::vec4> positions; std::vector<glm::vec4> velocities; positions.push_back(glm::vec4(0, 0, 0, TTL)); positions.push_back(glm::vec4(2, 0, 1, TTL)); velocities.push_back(glm::vec4(0, 0, 0, 0)); // no velocity velocities.push_back(glm::vec4(0, 0, 0, 0)); particle_count = positions.size(); // copy the data to the SSBO: glbindbuffer(gl_shader_storage_buffer, ssbo_pos[0]); glbuffersubdata(gl_shader_storage_buffer, 0, particle_count * sizeof(positions[0]), &positions[0]); // do the same for velocities 24.11.2016 RTR 2016 Spelitz 8

Compute Shader (1) #version 430 // choose a sufficient work group size: layout (local_size_x = 16, local_size_y = 16, local_size_y = 1) in; [...] // our buffers as defined before // current particle count (atomic counter) layout (binding = 4, offset = 0) uniform atomic_uint Count; uniform uint LastCount; uniform uint MaximumCount; uniform float DeltaT; const vec3 GRAVITY = vec3(0, -9.81f, 0); void main() { [...] 24.11.2016 RTR 2016 Spelitz 9

Compute Shader (2) void main() { // unique one-dimensional index: uint idx = gl_globalinvocationid.x + gl_globalinvocationid.y * gl_numworkgroups.x * gl_workgroupsize.x; if(idx >= LastCount) return; vec3 forces = GRAVITY; forces += vec3(-5.5f, 0, 0); // add wind or other forces vec3 velocity = Velocity_In[idx].xyz + DeltaT * forces; vec3 pos = Position_In[idx].xyz + DeltaT * velocity; float TTL = Position_In[idx].w - DeltaT; if (TTL > 0) { // particle s still alive addparticletooutputlist(pos, velocity, TTL); see next slide 24.11.2016 RTR 2016 Spelitz 10

Compute Shader (3) void addparticletooutputlist(vec3 pos, vec3 vel, float TTL) { // increment the atomic counter and use its previous value: uint nr = atomiccounterincrement(count); if (nr >= MaximumCount) { // we are out of memory atomiccounterdecrement(count); return; Position_Out[nr] = vec4(pos, TTL); Velocity_Out[nr] = vec4(vel, 0); 24.11.2016 RTR 2016 Spelitz 11

Vertex Shader #version 420 pretty straight forward layout (location = 0) in vec4 Position; uniform mat4 ModelViewMatrix; out vdata { float TTL1; // additional vertex data goes here vertex; void main() { gl_position = ModelViewMatrix * vec4(position.xyz, 1.0f); vertex.ttl1 = Position.w; 24.11.2016 RTR 2016 Spelitz 12

Geometry Shader #version 330 layout (points) in; // points in layout (triangle_strip, max_vertices = 4) out; // quads out uniform mat4 ProjectionMatrix; in vdata { float TTL1; vertex[]; // from vertex shader out vec2 TexCoord0; flat out float TTL0; // flat: no interpolation between vertices void main (void) { const vec2 size = vec2(5, 5); vec4 P = gl_in[0].gl_position; // position in view-space vec2 va = P.xy + vec2(-0.5, -0.5) * size; // bottom-left corner gl_position = ProjectionMatrix * vec4(va, P.zw); TexCoord0 = vec2(0.0, 0.0); TTL0 = vertex[0].ttl1; EmitVertex(); [...] // repeat accordingly for other corners EndPrimitive(); See: http://www.geeks3d.com/20140815/particle-billboarding-with-the-geometry-shader-glsl/ 24.11.2016 RTR 2016 Spelitz 13

Fragment Shader in vec2 TexCoord0; flat in float TTL0; out vec4 FragColor; Note: Do whatever you need here. Read from texture or generate procedurally vec3 pow3(vec3 v, float p) { return pow(abs(v), vec3(p)); vec3 glowsphere(vec3 color, vec2 p, float radius, float glow) { // Inspired by https://www.shadertoy.com/view/4lfxrf float term = 1./length(p)/5.; return pow3(color * term * 0.5, glow) * radius; void main() { vec3 basecolor = vec3(0.588, 1.0, 0.588) * clamp(ttl0, 0.0, 1.0); vec3 color = glowsphere(basecolor, TexCoord0 * 2-1, 5, 3.25); float lum = dot(color, vec3(0.299, 0.587, 0.114)); FragColor = vec4(color, lum); // use luminance as alpha 24.11.2016 RTR 2016 Spelitz 14

Bringing Everything Together 1. Run the compute shader Use one set of buffers (position, velocity) as input Use the other set as output Switch buffers in the next frame (ping/pong) 2. Run the rendering Use the computed positions as input Points are converted to quads Use textures or procedural code for display 24.11.2016 RTR 2016 Spelitz 15

Starting the Compute Shader (1) void calculate(double deltatime) { gluseprogram(computeshader); // set all uniforms, like deltatime, current particle count,... gluniform..(...); // set SSBO and atomic counters... glbindbufferbase(gl_shader_storage_buffer, 0, ssbo_pos[index]); index =!index; // ping-pong between buffers Compute Shader: layout (local_size_x = 16, local_size_y = 16, local_size_y = 1) in; // Execute compute shader with a 16 x 16 work group size GLuint groups = (particle_count / (16 * 16)) + 1; gldispatchcompute(groups, 1, 1); [...] // Read back results, like new particle count... (next slide) 24.11.2016 RTR 2016 Spelitz 16

Starting the Compute Shader (2) void calculate(double deltatime) { [...] // Read atomic counter through a temporary buffer glbindbuffer(gl_atomic_counter_buffer, atomic_counter); glbindbuffer(gl_copy_write_buffer, temp_buffer); // from atomic counter to temp buffer: glcopybuffersubdata(gl_atomic_counter_buffer, GL_COPY_WRITE_BUFFER, 0, 0, sizeof(gluint)); GLuint *countervalue = (GLuint*)glMapBufferRange(GL_COPY_WRITE_BUFFER, 0, sizeof(gluint), GL_MAP_READ_BIT GL_MAP_WRITE_BIT); particle_count = countervalue[0]; countervalue[0] = 0; // reset atomic counter in temp buffer glunmapbuffer(gl_copy_write_buffer); // stop writing to temp buffer // copy temp buffer to atomic counter: glcopybuffersubdata(gl_copy_write_buffer, GL_ATOMIC_COUNTER_BUFFER, 0, 0, sizeof(gluint)); // memory barrier, to make sure everything from the compute shader is written glmemorybarrier(gl_vertex_attrib_array_barrier_bit); 24.11.2016 RTR 2016 Spelitz 17

Starting the Rendering void draw() { enableblendmode(); gluseprogram(renderprogram); // program with VS -> GS -> FS // set uniforms (matrices,...) as usual glbindvertexarray(vaos[index]); // bind VAO gldrawarrays(gl_points, 0, particlecount); glbindvertexarray(0); gluseprogram(0); disableblendmode(); 24.11.2016 RTR 2016 Spelitz 18

Blending Many blending possibilites http://www.andersriggelsen.dk/glblendfunc.php void enableblendmode() { glenable(gl_blend); // activate blending gldepthmask(gl_false); // disable writing to depth buffer glblendfunc(gl_src_color, GL_SRC_COLOR); glblendequation(gl_max); void disableblendmode() { gldisable(gl_blend); gldepthmask(gl_true); 24.11.2016 RTR 2016 Spelitz 19

Dynamic Spawning of Particles Spawning X particles per second Problem: FPS are not constant High framerate -> Spawn only ½ or ¼ of a particle?? Solution: Accumulate count over multiple frames double particles_to_spawn = 0; void calculate(double deltatime) { const double spawnratepersecond = 2; particles_to_spawn += spawnratepersecond * deltatime; GLuint spawncount = 0; if (particles_to_spawn > 0) { spawncount += (GLuint) particles_to_spawn; particles_to_spawn -= spawncount; // set spawncount as uniform in compute shader 24.11.2016 RTR 2016 Spelitz 20

Have fun! Look at the accompanied source code for more information References are at the end of the presentation Disclaimer: This approach was tested on NVidia cards It may or may not work on AMD, Intel, etc. 24.11.2016 RTR 2016 Spelitz 21

References http://www.tomshannon3d.com/2014/07/blueprintfirewor ks.html http://www.gamedev.net/page/resources/_/creative/visual -arts/make-a-particle-explosion-effect-r2701 http://www.lighthouse3d.com/tutorials/opengl-atomiccounters/ http://www.geeks3d.com/20140815/particle-billboardingwith-the-geometry-shader-glsl/ 24.11.2016 RTR 2016 Spelitz 22