1 / 26

A Non-Photorealistic Fragment Shader in OpenGL 2.0

A Non-Photorealistic Fragment Shader in OpenGL 2.0. Bert Freudenberg Institut für Simulation und Graphik University of Magdeburg, Germany. Outline. OpenGL 2.0 proposal Vertex and fragment shaders Non-photorealistic shading Anti-aliasing in a shader Lighting Adding noise Conclusion.

lmelinda
Download Presentation

A Non-Photorealistic Fragment Shader in OpenGL 2.0

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. A Non-Photorealistic Fragment Shader in OpenGL 2.0 Bert Freudenberg Institut für Simulation und GraphikUniversity of Magdeburg, Germany

  2. Outline • OpenGL 2.0 proposal • Vertex and fragment shaders • Non-photorealistic shading • Anti-aliasing in a shader • Lighting • Adding noise • Conclusion

  3. OpenGL 2.0 Proposal • Shading Language • High-level language for • vertex shaders • fragment shaders • even more • Experimentally implemented as GL2 extension • available on 3Dlabs Wildcat VP

  4. Base for our shader • Scott F. Johnston’s “Mock Media” • From “Advanced RenderMan: Beyond the Companion” (SIGGRAPH ’98 Course #11) • RenderMan surface shader for woodprint-like appearance • Shading by lines of varying width

  5. Vertex Shader • Uses constant and per-vertex data to set up attributes varying across the primitive • Our shader: • one surface parameter • screen-space position

  6. Vertex Shader • varying float v; • void main(void) • { • v = gl_MultiTexCoord0.s; • gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; • }

  7. Fragment Shader • Gets interpolated varyingparameters • Similar to RenderMan surface shader • Evaluates some function to output color at a certain point in parameter space • Our shader: • output black or white to create lines

  8. Parameter • varying float v; • v = texcoord0.s; • Assigned in vertex shader • Interpolated value in fragment shader

  9. Sawtooth wave • sawtooth = fract( v * 16. );

  10. Triangle wave • triangle = abs(2. * sawtooth - 1.);

  11. Square wave • square = step(0.5, triangle); • Aliasing!

  12. Anti-aliasing • FSAA will not help • just raises resolution • Need to remove higher frequencies • manually • Step function has unlimited frequency • use smooth step instead

  13. Constant width smoothstep() • square =smoothstep(0.4, 0.6, triangle); • Buggy, hence: • edge0 = 0.4; edge1 = 0.6; • t = clamp((triangle - edge0) / (edge1 - edge0), 0., 1.); • square = t * t * (3. - 2. * t); • Aliasing + blurring

  14. Derivatives • dPdx(v), dPdy(v) • Derivative of parameter v in screen x and y

  15. Length of derivative • dp = length(vec2(dPdx, dPdy));

  16. Adaptive filter width • filterstep() • float edge = 0.5; • float w = 64. * dp; • float square = clamp((triangle + 0.5 * w - edge) / w, 0., 1.);

  17. Raising frequency • No more individual lines • Too dense in certain regions • Adjust frequency based on screen space density

  18. Partitioning by derivative • ilogdp = floor(log2(dp)); • No log2() yet • Texture as lookup table • vec3 tex0 = texture3(0, dp * 8.); • float logdp = (tex0.r - 0.5) * 256. + tex0.g;

  19. Adjusting frequency • exp2(floor(log2(dp))) * f; • frequency doubles in discrete steps • also works for distance!

  20. Tapering ends • linearly interpolate to double frequency • t = fract(log2(dp)); • triangle = abs((1. + t) * triangle - t);

  21. Lighting • Vertex Shader • pos = vec3(gl_ModelViewMatrix * gl_Vertex); • tnorm = normalize(gl_NormalMatrix * gl_Normal); • vec3 lightVec = normalize(LightPosition - pos); • lightIntensity = max(dot(lightVec, tnorm), 0.0);

  22. Lighting • Line width dependent on lighting • Adjust threshold by light intensity • square = step(lightIntensity, triangle);

  23. Noise • No noise() yet • 3D tilable noise tex = ( • F(x,y,z)*(t-x)*(t-y)*(t-z)+ • F(x-t,y,z)*(x)*(t-y)*(t-z)+ • F(x-t,y-t,z)*(x)*(y)*(t-z)+ • F(x,y-t,z)*(t-x)*(y)*(t-z)+ • F(x,y,z-t)*(t-x)*(t-y)*(z)+ • F(x-t,y,z-t)*(x)*(t-y)*(z)+ • F(x-t,y-t,z-t)*(x)*(y)*(z)+ • F(x,y-t,z-t)*(t-x)*(y)*(z)) • /(t*t*t);

  24. Noisy width • Bias threshold

  25. Noisy wiggles

  26. Conclusion • Learn about RenderMan shaders • Translate to OpenGL 2.0 • almost straight-forward • Anti-aliasing is an issue • use derivatives • Non-photorealistic Rendering is cool!

More Related