FOG; COMPOSITING 1
OUTLINE • Fog • Compositing • Blending • Transparency • Clipping • 3D Textures • Noise 2
FOG • Atmospheric haze Provides more realism in a scene • • Also provides more sense of scene depth Simple (and effective) approach is to blend fog color with pixel color dependent on depth • • Can be done in the fragment shader
FRAGMENT SHADER #version 430 in vec3 vertEyeSpacePos; in vec2 tc; out vec4 fragColor; uniform mat4 mv_matrix; uniform mat4 proj_matrix; layout (binding=0) uniform sampler2D t; // for texture layout (binding=1) uniform sampler2D h; // for height map void main(void) { vec4 fogColor = vec4(0.7, 0.8, 0.9, 1.0); // bluish gray float fogStart = 0.2; float fogEnd = 0.8; // the distance from the camera to the vertex in eye space is simply the length of a // vector to that vertex, because the camera is at (0,0,0) in eye space. float dist = length(vertEyeSpacePos.xyz); float fogFactor = clamp(((fogEnd-dist)/(fogEnd-fogStart)), 0.0, 1.0); fragColor = mix(fogColor,(texture(t,tc)),fogFactor); }
FOG RESULT
COMPOSITING
COMPOSITING • Pixel operations use the z-buffer Until now, we only used this to determine which fragments were visible or not • • Depth buffer – hidden surface removal But we can do more than this • • First, color vectors (vec4) have the alpha component alpha = 1, totally opaque • • alpha = 0, totally transparent Second, we can use glBlendEquation() and glBlendFunc() to specify how to treat • overlapping pixels This has to be done in the Java/JOGL code – this step is not programmable •
COMPOSITING • How it works: Source and destination pixels are multiplied by the source and destination factors • specified to glBlendFunc(src, dest) The operation specified in glBlendEquation is used to combine the source and • destination pixels Also use glEnable(GL_BLEND) OR glDisable(GL_BLEND) • Tables for these constants are in the next slides • • Default are GL_ONE for source, GL_ZERO for destination • Default operation is GL_BLEND
GLBLENDFUNC() PARAMETERS
GLBLENDEQUATION() PARAMETERS Constant Operation GL_FUNC_ADD result = source + destination GL_FUNC_SUBTRACT result = source – destination GL_FUNC_REVERSE_SUBTRACT result = destination – source GL_MIN result = min(source, destination) GL_MAX result = max(source, destination)
TRANSPARENCY • Picture on left has alpha = 1 in pyramid Picture on right has alpha = 0.8 in pyramid • Sufficient for flat transparent objects, but maybe not for 3D objects •
TRANSPARENCY • Just disabling back face culling doesn’t have the effect we really want Artifacts occur based on the order of rendering • • One simple approach is to render non- transparent objects first, but that doesn’t fix this particular situation • In this case, a two pass approach in rendering first front faces and then back faces works Need to flip normal vectors for lighting to appear correct on back faces •
USER DEFINED CLIPPING PLANES • You may want to slice an object at some point (who wouldn’t?) Can define a clipping plane with the equation: • • ax + by + cz + d = 0 (a, b, c) is the normal to the plan • • d defines its distance from the origin Can use the “built - in” GLSL variable gl_clip_distance[ ] in the vertex shader • • e.g.: gl_clip_distance[0] = dot(clip_plane.xyz, vertPos) + clip_plane.w … assuming you have defined clip_plane to hold your (a, b, c, d) values •
THE RESULT • Making macaroni from a torus… Not ideal – inside faces are not drawn •
RESULT OF A TWO PASS PROCESS • Now back faces are shown as well As before, winding order needs to be reversed, and normals need to be flipped so • that lighting works correctly
3D TEXTURES • Unlike 2D textures, these are usually generated procedurally Can conceptualize this as an object being carved out of a 3D block of material •
CODE TO GENERATE STRIPE void generate3Dpattern() { for (int x=0; x<texHeight; x++) { for (int y=0; y<texWidth; y++) { for (int z=0; z<texDepth; z++) { if ((y/10)%2 == 0) tex3Dpattern[x][y][z] = 0.0; else tex3Dpattern[x][y][z] = 1.0; } } } }
CAN APPLY THIS TO ANY OBJECT
CODE TO GENERATE CHECKERBOARD
CHECKERBOARD DRAGON
NOISE • Many natural materials can be modeled with various noise patterns Construct your 3D pattern with random numbers • • You can then fill an array with the noise and a function to create different patterns
NOISE • Same “granite” cube as before, but with different levels of resolution
SMOOTHED NOISY PATTERNS • Again, same “granite” pattern with smoothed noise – based on texel distance from each other, shown at different resolutions
TURBULENCE • Combining smoothed levels to create a more random looking “turbulent” pattern
MARBLE PATTERN • Start with stripe pattern – this starts out diagonal Sine function produce the blurry edges • • Add varying level of noise to perturb the stripes Can include lighting to make it look realistic •
“MARBLE” STANFORD DRAGON
“WOOD” 3D TEXTURE • Start with striped texture, but arranged in rings Can both perturb the stripes, as with marble, and “rotate” the texel coordinates a bit for • more enhancement
“WOOD” DOLPHIN
“CLOUDS” • Use the turbulence map from the cube we looked at previously Change the color • • Stretch it to fit the half sphere Voila – looks like clouds •
MODIFIED TURBULENCE • By adding a logistic / sigmoid function to the texture, can get clouds with more distinct boundaries
DRIFTING CLOUDS – AND SLIGHT CHANGE • Make the z variable of the texture change gradually over time
SPECIAL EFFECTS • Dissolve effect Command in the GLSL language – discard • void main(void) { float noise = texture(s,originalPosition/2.0+.5).x; if (noise > t) { fragColor = texture(e,tc); } else { discard; } }
SUMMARY • Fog • Compositing • Blending • Transparency • Clipping • 3D Textures • Noise 33
Recommend
More recommend