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
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
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
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
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
Bert Freudenberg, University of Magdeburg
Vertex ShaderVertex Shadervarying float v; void main(void){ v = gl_MultiTexCoord0.s; gl_Position = gl_ModelViewProjectionMatrix *
gl_Vertex;}
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
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
Bert Freudenberg, University of Magdeburg
Sawtooth waveSawtooth wavesawtooth = sawtooth =
fract( v * 16. );fract( v * 16. );
Bert Freudenberg, University of Magdeburg
Triangle waveTriangle wavetriangle = triangle =
abs(2. * sawtooth - abs(2. * sawtooth - 1.);1.);
Bert Freudenberg, University of Magdeburg
Square waveSquare wavesquare = square =
step(0.5, triangle);step(0.5, triangle);
• Aliasing!Aliasing!
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
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
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
Bert Freudenberg, University of Magdeburg
Length of derivativeLength of derivativedp = length(vec2(dPdx, dp = length(vec2(dPdx,
dPdy));dPdy));
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.);
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
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;
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!
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);
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);
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);
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);
Bert Freudenberg, University of Magdeburg
Noisy widthNoisy width• Bias thresholdBias threshold
Bert Freudenberg, University of Magdeburg
Noisy wigglesNoisy wiggles
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!
Top Related