Single-Pass Multitexturing y (1,1) v (1,1) Blending 514780 2017 년가을학기 11/23/2017 단국대학교박경신 void SetMultitexturSquareData() { // 중간생략.. x glgenbuffers(4, &vbo[0]); u (-1,-1) (0,0) glbindbuffer(gl_array_buffer, vbo[0]); glbufferdata(gl_array_buffer, 4*sizeof(glm::vec3), &quadvertices[0], GL_STATIC_DRAW); glvertexattribpointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glenablevertexattribarray(0); glbindbuffer(gl_array_buffer, vbo[1]); glbufferdata(gl_array_buffer, 4*sizeof(glm::vec3), &quadnormals[0], GL_STATIC_DRAW); glvertexattribpointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0); glenablevertexattribarray(1); glbindbuffer(gl_array_buffer, vbo[2]); glbufferdata(gl_array_buffer, 4*sizeof(glm::vec2), &quadtexturecoords[0], GL_STATIC_DRAW) glvertexattribpointer(2, 2, GL_FLOAT, GL_FALSE, 0, 0); glenablevertexattribarray(2); glbindbuffer(gl_array_buffer, vbo[3]); glbufferdata(gl_array_buffer, 4*sizeof(glm::vec2), &quadtexturecoords[0], GL_STATIC_DRAW) glvertexattribpointer(3, 2, GL_FLOAT, GL_FALSE, 0, 0); glenablevertexattribarray(3); } Single-Pass Multitexturing Bind and enable two 2D multitextures to draw a quad Single-Pass Multitexturing GLSL fragment shader // stage 0 activate glactivetexture(gl_texture0); glbindtexture(gl_texture_2d, texture0); // stage 1 activate glactivetexture(gl_texture1); glbindtexture(gl_texture_2d, texture1); // draw multitexture square drawsquare(); // texture disabled glbindtexture(gl_texture_2d, 0); uniform sampler2d gtexturesampler1, gtexturesampler2; uniform int gmodulate; // Material properties if (gmodulate == 1) MaterialDiffuseColor = texture2d(gtexturesampler1, TexCoordPass0).rgba * texture2d(gtexturesampler2, TexCoordPass1).rgba; else MaterialDiffuseColor = texture2d(gtexturesampler1, TexCoordPass0).rgba + texture2d(gtexturesampler2, TexCoordPass1).rgba; vec4 MaterialAmbientColor = gmaterialambientcolor * MaterialDiffuseColor; vec4 MaterialSpecularColor = gmaterialspecularcolor;
Multipass Multitexturing 같은물체를다른모드를사용하여여러번렌더링하는것 예를들어, 라이트맵 (lightmap) 효과를위해물체를정상적으로그리고난후블렌딩함수를사용하여같은물체를다시한번그려줌 // first pass 일반텍스쳐를사용하여정상적으로그림 glactivetexture(gl_texture0); glbindtexture(gl_texture_2d, textureid1); drawsquare(); // second pass 라이트맵텍스쳐와원래텍스쳐를블랜딩함 gldepthfunc(gl_lequal); // accept co-planar fragments glenable(gl_blend); glblendfunc(gl_one, GL_ONE); // Add Blending glactivetexture(gl_texture0); glbindtexture(gl_texture_2d, textureid2); drawsquare(); gldepthfunc(gl_less); gldisable(gl_blend); Alpha Channel Alpha Channel Model Porter & Duff s Compositing Digital Images, SIGGRAPH 84 RGBA alpha는 4번째색으로불투명도 (opacity of color) 조절에사용함 불투명도 (opacity) 는얼마나많은빛이면을관통하는가의척도임 투명도 (transparency) 는 1 alpha로주어짐 Alpha=1.0 완전히불투명 Alpha=0.5 - 반투명 Alpha=0.0 완전히투명 Blending 프레임버퍼의색과물체의색을합성함 일반적인블렌딩공식 R = SourceFactor * R s + DestinationFactor * R d G = SourceFactor * G s + DestinationFactor * G d B = SourceFactor * B s + DestinationFactor * B d Source color (R s, G s, B s ) 는물체의색 Destination color (R d, G d, B d ) 는프레임버퍼에있는색 SourceFactor, DestinationFactor는 glblendfunc() 함수로지정함 glblendfunc() 함수에서쓰이는블렌딩공식 알파블렌딩의경우 glblendfunc(gl_src_alpha, GL_ONE_MINUS_SRC_ALPHA); GLSL 알파블렌딩 Gvec4 result = vec4(gl_fragcolor.a) * gl_fragcolor + vec4(1.0 - gl_fragcolor.a) * pixel_color; Blending 알파블렌딩 물체의색을투명하게나타나게함 Alpha blending = A s * C s + (1 - A s ) * C d // alpha blending - alpha에의해그리고자하는물체의투명도결정 glblendfunc(gl_src_alpha, GL_ONE_MINUS_SRC_ALPHA); R = A s * R s + (1 - A s ) * R d G = A s * G s + (1 - A s ) * G d B = A s * B s + (1 - A s ) * B d 대상색상값 C d = vec4(0.5, 1, 1, 1) A = A s * A s + (1 - A s ) * A d 소스색상값 C s = vec4(1, 0, 1, 0.3) // 즉, 소스 alpha = 0.3 R = 0.3 * R s + 0.7 * R d G = 0.3 * G s + 0.7 * G d B = 0.3 * B s + 0.7 * B d A = 0.3 * A s + 0.7 * A d R = 0.3*1 + 0.7*0.5 = 0.65 G = 0.3*0 + 0.7*1 = 0.7 B = 0.3*1 + 0.7*1 = 1 A = 0.3*0.3 + 0.7*1 = 0.79
Blending Functions Factor name GL_ZERO GL_ONE GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA GL_DST_ALPHA GL_ONE_MINUS_DST_ALPHA GL_CONSTANT_ALPHA GL_ONE_MINUS_CONSTANT_ALPHA GL_SRC_COLOR GL_ONE_MINUS_SRC_COLOR GL_DST_COLOR GL_ONE_MINUS_DST_COLOR GL_CONSTANT_COLOR GL_ONE_MINUS_CONSTANT_COLOR Computed Factor vec4(0.0) vec4(1.0) vec4(gl_fragcolor.a) vec4(1.0 gl_fragcolor.a) pixel_color.a vec4(1.0 pixel_color.a) vec4(color.a) vec4(1.0 color.a) gl_fragcolor vec4(1.0) - gl_fragcolor pixel_color vec4(1.0) - pixel_color color vec4(1.0) color OpenGL Blending 블렌딩활성화 glenable(gl_blend) 블렌딩함수정의 glblendfunc(gl_src_alpha, GL_ONE_MINUS_SRC_ALPHA) [0, 1] 영역의알파값추가 RGBA vec4(1, 0, 0, 0.5) // transparency 50% red 혹은알파가있는 RGBA 텍스쳐이미지를사용함 Smooth-shaded Alpha Time-Varying Alpha R,G,B 색들과마찬가지로응용프로그램에서각각의픽셀에대한Alpha 값을제어할수있음 만약알파값이각정점에다르게지정되어있으면, 알파값도보간되어나타남 그래서부드러운면 (soft edge) 을형성할수있음 시간의경과에따라알파값을변하게주어 fade-in 또는 fade-out 효과를줄수있음
Texture Alpha RGBA 4 채널텍스쳐이미지를사용하여보다복잡한형체를간단한기하객체를사용하여구성할수있음 Chroma Keying 영화나비디오프로덕션에서많이사용 크로마키잉의단적인예로, 기상캐스터의 TV 날씨방송에서실시간액터 (live actor) 의이미지와그래픽적인날씨정보의합성을들수있음 배경색을찾아서그값을알파값으로지정하여사용함 Blending & Drawing Order 블렌딩은현재그리고자하는물체와이전에그려진물체의그림그리는순서 (drawing order) 가중요함 블렌딩함수의 source color( 현재그리고자하는물체의색 ) 와 destination color ( 이미그려진프레임버퍼의색 ) 로작용함 만약투명한물체와불투명한물체를같이그리고자한다면, 불투명부터먼저그린후에투명한것을그릴것 Depth-buffering이블렌딩전에실행되도록함 Blending & Drawing Order 만약여러개의투명한물체를같이그리고자한다면, 전향순서 (back-to-front order) 로그릴것 이순서는카메라의위치에의해서달라질수있음 여러개의투명한물체를같이그릴때, 서로를가리는현상 (occlusion) 을막기위해서 depth mask 를비활성화함 gldepthmask(gl_false) 를통하여깊이버퍼를 read-only 로만듬 구를먼저그린후입방체를그릴것
Backface Culling 투명한물체를그릴때는후면추리기 (backface culling) 를활성화할것 투명한물체는일반적으로후면이보이게됨 glenable(gl_cull_face) 는물체의후면 (backface) 를그리는것을막아줌 4 CCW 3 Filtering 블렌딩은전체장면의색을필터링하는효과에사용될수있음 전체화면의크기를가진사각형을그리고블렌딩함수를적용함 // 전체장면을어둡게함 glblendfunc(gl_zero, GL_SRC_ALPHA) 1 2 Front face 4 3 CW gldisable(gl_cull_face) glenable(gl_cull_face) 1 2 Back face Filtering // 전체장면에원하는색 ( 즉, 보라색 ) 으로만듬 glblendfunc(gl_zero, GL_SRC_COLOR); glcolor4f(1.0, 0.0, 0.5, 1.0); // 전체장면의색을보색 (inverted color) 으로바꿈 glblendfunc(gl_one_minus_dst_color, GL_ZERO); glcolor4f(1.0, 1.0, 1.0, 1.0) Fog 연무효과 (fog effect) 깊이에의존적인색으로블렌딩함으로써물체와관측자사이의부분적인반투명공간의느낌을생성함 Fog를컴퓨터그래픽스에서구현하려면관측점에서멀리있는물체를작고희미하게보이도록표현함 OpenGL에서 Fog를지원하는데, 연무효과를적용하는시점은좌표변화, 광원설정, 텍스쳐매핑등의그리기과정에서제일마지막에수행함
Fog 연무블렌딩함수 finalcolor = FogFactor * fragmentcolor + (1 FogFactor) * fogcolor 연무함수 void glfogifv(glenum pname, TYPE param) 연무계수 (fog factor) Exponential Gaussian Linear (depth cueing) OpenGL Fog OpenGL 에서연무효과는연무색과단편 (fragment) 의색이합성되는것임. 합성의정도는렌더링될단편과관측자와의거리함수로계산됨. GLfloat fcolor[4] = {1.0, 1.0, 1.0, 1.0}: glenable(gl_fog); glfogi(gl_fog_mode, GL_LINEAR); glfogf(gl_fog_start, 5.0); glfogf(gl_fog_end, 40.0); glfogfv(gl_fog, fcolor); OpenGL Fog Mode 연무계수 (fog factor) Linear glfogi(gl_fog_mode, GL_LINEAR); GL_FOG_START, GL_FOG_END Exponential glfogi(gl_fog_mode, GL_EXP); GL_FOG_DENSITY Gaussian glfogi(gl_fog_mode, GL_EXP2); GL_FOG_DENSITY GLfloat fcolor[4] = {1.0, 1.0, 1.0, 1.0}: glenable(gl_fog); glfogi(gl_fog_mode, GL_EXP); glfogf(gl_fog_density, 0.5); glfogfv(gl_fog, fcolor); OpenGL Fog Mode struct FogParameters { vec4 vfogcolor; // Fog color float fstart; float fend; // This is only for linear fog float fdensity; // For exp and exp2 equation int iequation; // 0 = linear, 1 = exp, 2 = exp2 }; float getfogfactor(fogparameters params, float ffogcoord) { float fresult = 0.0; if(params.iequation == 0) fresult = (params.fend-ffogcoord)/(params.fend-params.fstart); else if(params.iequation == 1) fresult = exp(-params.fdensity*ffogcoord); else if(params.iequation == 2) fresult = exp(-pow(params.fdensity*ffogcoord, 2.0)); fresult = 1.0-clamp(fResult, 0.0, 1.0); return fresult; }