a non-photorealistic fragment shader in opengl 2.0

26
A Non-Photorealistic Fragment Shader in OpenGL 2.0 Bert Freudenberg Bert Freudenberg Institut für Simulation und Graphik Institut für Simulation und Graphik University of Magdeburg, Germany University of Magdeburg, Germany

Upload: titus

Post on 19-Jan-2016

43 views

Category:

Documents


0 download

DESCRIPTION

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. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

A Non-Photorealistic Fragment Shader in OpenGL 2.0

A Non-Photorealistic Fragment Shader in OpenGL 2.0

Bert FreudenbergBert Freudenberg

Institut für Simulation und GraphikInstitut für Simulation und GraphikUniversity of Magdeburg, GermanyUniversity of Magdeburg, Germany

Page 2: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

OutlineOutline• OpenGL 2.0 proposal OpenGL 2.0 proposal

• Vertex and fragment shadersVertex and fragment shaders

• Non-photorealistic shadingNon-photorealistic shading

• Anti-aliasing in a shaderAnti-aliasing in a shader

• LightingLighting

• Adding noiseAdding noise

• ConclusionConclusion

Page 3: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

OpenGL 2.0 ProposalOpenGL 2.0 Proposal

Shading LanguageShading Language•High-level language for

•vertex shaders

•fragment shaders

•even more

•Experimentally implemented as GL2 extension

•available on 3Dlabs Wildcat VP

Page 4: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

Base for our shaderBase for our shaderScott F. Johnston’s “Mock Media”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

Page 5: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

Vertex ShaderVertex Shader

• Uses constant and per-vertex data to set up Uses constant and per-vertex data to set up attributes attributes varyingvarying across the primitive across the primitive

• Our shader:Our shader:•one surface parameter

•screen-space position

Page 6: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

Vertex ShaderVertex Shadervarying float v; void main(void){ v = gl_MultiTexCoord0.s; gl_Position = gl_ModelViewProjectionMatrix *

gl_Vertex;}

Page 7: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

Fragment ShaderFragment Shader

• Gets interpolated Gets interpolated varyingvarying parametersparameters

• Similar to RenderMan surface shaderSimilar to RenderMan surface shader

• Evaluates some function to output Evaluates some function to output colorcolor at a at a certain point in parameter spacecertain point in parameter space

• Our shader: Our shader: •output black or white to create lines

Page 8: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

Parameter Parameter varying float v;varying float v;

v = texcoord0.s;v = texcoord0.s;

• Assigned in vertex Assigned in vertex shadershader

• Interpolated value in Interpolated value in fragment shaderfragment shader

Page 9: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

Sawtooth waveSawtooth wavesawtooth = sawtooth =

fract( v * 16. );fract( v * 16. );

Page 10: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

Triangle waveTriangle wavetriangle = triangle =

abs(2. * sawtooth - abs(2. * sawtooth - 1.);1.);

Page 11: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

Square waveSquare wavesquare = square =

step(0.5, triangle);step(0.5, triangle);

• Aliasing!Aliasing!

Page 12: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

Anti-aliasingAnti-aliasing

• FSAA will not helpFSAA will not help• just raises resolution

• Need to remove higher frequenciesNeed to remove higher frequencies•manually

• Step function has unlimited frequencyStep function has unlimited frequency•use smooth step instead

Page 13: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

Constant width smoothstep()Constant width smoothstep()

square =square =smoothstep(0.4, 0.6, smoothstep(0.4, 0.6, triangle);triangle);

• Buggy, hence:Buggy, hence:edge0 = 0.4; edge1 = 0.6;t = clamp((triangle -

edge0) / (edge1 - edge0), 0., 1.);

square = t * t * (3. - 2. * t);

• Aliasing + blurringAliasing + blurring

Page 14: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

DerivativesDerivatives• dPdx(v), dPdy(v)dPdx(v), dPdy(v)

• Derivative of Derivative of parameter v in screen parameter v in screen x and yx and y

Page 15: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

Length of derivativeLength of derivativedp = length(vec2(dPdx, dp = length(vec2(dPdx,

dPdy));dPdy));

Page 16: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

Adaptive filter widthAdaptive filter widthfilterstep()filterstep()

float edge = 0.5;float edge = 0.5;

float w = 64. * dp;float w = 64. * dp;

float square = float square = clamp((triangle + 0.5 clamp((triangle + 0.5 * w - edge) / w, 0., 1.);* w - edge) / w, 0., 1.);

Page 17: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

Raising frequencyRaising frequency

• No more individual No more individual lineslines

• Too dense in certain Too dense in certain regionsregions

• Adjust frequency Adjust frequency based on screen based on screen space densityspace density

Page 18: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

Partitioning by derivativePartitioning by derivativeilogdp = floor(log2(dp));ilogdp = floor(log2(dp));

• No log2() yetNo log2() yet• Texture as lookup tableTexture as lookup table

vec3 tex0 = texture3(0, dp * 8.);

float logdp = (tex0.r - 0.5) * 256. + tex0.g;

Page 19: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

Adjusting frequencyAdjusting frequencyexp2(floor(log2(dp))) * exp2(floor(log2(dp))) *

f;f;

• frequency doubles in frequency doubles in discrete stepsdiscrete steps

• also works for also works for distance!distance!

Page 20: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

Tapering endsTapering ends• linearly interpolate to linearly interpolate to

double frequencydouble frequency

t = fract(log2(dp));triangle = abs((1. + t) *

triangle - t);

Page 21: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

LightingLightingVertex ShaderVertex 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);

Page 22: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

LightingLighting• Line width Line width

dependent on dependent on lightinglighting

• Adjust threshold by Adjust threshold by light intensitylight intensity

square = step(lightIntensity, triangle);

Page 23: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

NoiseNoise• No noise() yetNo noise() yet

3D tilable noise tex = 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);

Page 24: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

Noisy widthNoisy width• Bias thresholdBias threshold

Page 25: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

Noisy wigglesNoisy wiggles

Page 26: A Non-Photorealistic  Fragment Shader  in OpenGL 2.0

Bert Freudenberg, University of Magdeburg

ConclusionConclusion

• Learn about RenderMan shadersLearn about RenderMan shaders

• Translate to OpenGL 2.0 Translate to OpenGL 2.0 •almost straight-forward

• Anti-aliasing is an issueAnti-aliasing is an issue•use derivatives

• Non-photorealistic Rendering is cool!Non-photorealistic Rendering is cool!