Skip to content
Snippets Groups Projects
Select Git revision
  • main
1 result

cg-tutorial

  • Color Blending

    컴퓨터 그래픽스 기말 프로젝트 소프트웨어학과 201820721 이성학(Seonghak Lee)

    1. 주제선정 과정

    평소에 취미로 그림을 그리면서 레이어에 Blend Mode기능을 종종 사용하곤 했습니다. 컴퓨터 그래픽스 강의중 Color Blending이란 그래픽 처리 기법을 배우게 되었는데, 이것이 그림을 그릴때 쓰던 Blend mode와 같은 기법이라는 것을 알게 되었습니다. 관련 내용을 찾아보니 Three.js에서도 Color Blending을 기본적으로 지원하고 있어 기말 프로젝트로 Color Blending의 예제를 만들어보면 재밌을 것 같아서 주제로 선정하게 되었습니다.

    1.1. Color Blending?

    컴퓨터 그래픽스에서의 Color Blending은 겹쳐진 두 색을 섞어 새로운 색을 만드는 방법입니다. 여기서 섞을 두 색상은 Source, Destination으로 부릅니다. Source는 그리고자 하는 색, Destination은 배경색을 의미합니다. 두 색상 모두 [R,G,B,A] 총 4개의 채널로 이루어져 있고, 각각의 채널은 0~1의 float으로 표현됩니다. 예를들어 [1,0,0,1]은 완전 불투명한 빨강색을 나타내게 됩니다. Color Blending함수는 이 Blending Equation에 따라 Source와 Destination의 연산을 수행해 새로운 색상을 만듭니다.

    1.2. Blending Equation

    기본적인 Blending Equation은 다음과 같습니다.

    AddEquation : Blend(Source, Destination) = (Source * 상수1) + (Destination * 상수2)
    SubtractEquation : Blend(Source, Destination) = (Source * 상수1) - (Destination * 상수2)
    ReverseSubtractEquation : Blend(Source, Destination) = (Destination * 상수2) - (Source * 상수1)
    MinEquation : Blend(Source, Destination) = Min((Source * 상수1), (Destination * 상수2))
    MaxEquation : Blend(Source, Destination) = Max((Source * 상수1), (Destination * 상수2))

    source와 destination에 각각 특정한 상수를 곱하고, 그 값들을 Equation 규칙에 따라 연산해줍니다. 곱할수 있는 상수들은 다음과 같습니다.

    Zero : 0
    One : 1
    SrcColor : Source의 Color값
    OneMinusSrcColor : 1-(Source의 Color값)
    SrcAlpha : Source의 Alpha값
    OneMinusSrcAlpha : 1-(Source의 Alpha값)
    DstAlpha : Destination의 Alpha값
    OneMinusDstAlpha : 1-(Destination의 Alpha값)
    SrcColor : Source의 Color값
    OneMinusDstColor : 1-(Destination의 Color값)

    1.3. Blending Example

    자주 쓰이는 몇가지 Color Blending들을 소개해보겠습니다.

    1.3.1. Normal Blending

    Blend(Source, Destination) = (Source * Srcalpha) + (Destination * OneMinusSrcAlpha)

    three.js에서 material을 만들면 기본적으로 적용되어있는 Blending입니다. 그릴 대상에 Alpha값을 곱해주고, 배경에는 1-(Source의 Alpha값)을 곱해줍니다. 그 다음, 그 두 색상을 더합니다.

    1.3.2. Add Blending

    Blend(Source, Destination) = (Source * One) + (Destination * One)

    Add blending은 빛 표현을 할 때 자주 쓰이는 방식입니다. 단순히 Source와 Destination의 색을 더하는 방법으로, 가산 혼합과 같은 결과가 나오게 됩니다.

    1.3.3. Multiply Blending

    Blend(Source, Destination) = (Source * Zero) + (Destination * SrcColor)

    Multiply Blending은 어둠이나 그림자 표현을 할 때 자주 쓰이는 방식입니다. 첫번째 항으 0이 되고 Destination과 Source의 곱만이 남게 됩니다. Destination과 Source의 색은 0과 1사이의 값으로 표현되므로, 색이 겹치면 겹칠수록 값이 낮아져서 어둡게 보이게 됩니다.

    2. 개발과정

    2.1. Camera

    '두 물체가 겹쳐지는 상황'을 잘 보여야 하기 때문에, 물체들끼리 정투영시키는 OrthographicCamera를 사용하기로 했습니다.

    
        const camera = new THREE.OrthographicCamera( -100, 100, 100, -100, 1, 1000 );
        camera.position.z = 100; 
        camera.lookAt(1,0,0); 

    2.2. Scene

    Add, Multiply Blending에서 물체들을 잘 구별하기 위해 background color로 바꿨습니다. LambertMaterial, PhongMaterial의 명암 표현을 위해 AmbientLight, PointLight를 추가했습니다. Color Blending의 구현이 주 목적이므로, light를 조작하는 패널은 구현하지 않았습니다.

    
        const scene = new THREE.Scene();
        scene.background=new THREE.Color(0x777777);
        const renderer = new THREE.WebGLRenderer({canvas}); 
    
        const light = new THREE.AmbientLight( 0x505050 );
        const pointLight = new THREE.PointLight(0xffffff, 1.0, 1000, 1); 
        pointLight.position.set (-100,200,150); 
        scene.add(light , pointLight);

    2.3. SphereGeometry

    OrthographicCamera는 BoxGeometry를 사용할 때 다른 면이 잘 보이지 않기 때문에 SphereGeometry를 사용하여 명암이 잘 나타나도록 했습니다. 또한 Color Blending은 두가지 색상으로 연산하기 때문에, 여러개의 SphereGeometry를 겹쳐지도록 구성하였습니다. 겹쳐있다가 겹치지 않게 이동하는 Animation을 반복하여 색이 겹칠때와 겹치지 않을때의 결과를 모두 확인 가능하도록 했습니다.

    
        const geometry = new THREE.SphereGeometry(30, 20, 20);
        const material1 = new THREE.MeshPhongMaterial( { 
    	    color: colorarr[0], shininess : 90.0 });
        const material2 = new THREE.MeshPhongMaterial( { 
    	    color: colorarr[1], shininess : 90.0 });
        const material3 = new THREE.MeshPhongMaterial( { 
    	    color: colorarr[2], shininess : 90.0 });
        const sphere1 = new THREE.Mesh( geometry, material1 );
        const sphere2 = new THREE.Mesh( geometry, material2 );
        const sphere3 = new THREE.Mesh( geometry, material3 );
    
        var rot = 0.0; 
        var rad=18;
        const animate = function () {
    	    requestAnimationFrame( animate );
    	    if(rotate==true)
    	    {
    	        rot += 0.025;
    	    }
    	    sphere1.position.x = (Math.cos(rot+(-90 * Math.PI/180))*rad);
            sphere1.position.y = rad+(Math.sin(rot+(-90 * Math.PI/180))*rad);
            sphere2.position.x = rad*Math.cos(210 * Math.PI/180)+(Math.cos(rot+(30 * Math.PI/180))*rad);
            sphere2.position.y = rad*Math.sin(210 * Math.PI/180)+(Math.sin(rot+(30 * Math.PI/180))*rad);
            sphere3.position.x = rad*Math.cos(-30 * Math.PI/180)+(Math.cos(rot+(150 * Math.PI/180))*rad);
            sphere3.position.y = rad*Math.sin(-30 * Math.PI/180)+(Math.sin(rot+(150 * Math.PI/180))*rad);
    
    	    renderer.render( scene, camera );
        };

    2.4. Blending

    Blending은 material.blending으로 바꿀 수 있습니다. three.js에는 기본적으로 제공하는 Blending은 다음과 같습니다. THREE.NoBlending THREE.NormalBlending THREE.AdditiveBlending THREE.SubtractiveBlending THREE.MultiplyBlending THREE.CustomBlending 이중 THREE.CustomBlending을 사용하여 Source와 Destination의 곱해주는 상수를 직접 선택 가능하도록 하였습니다.

    
    	sphere1.material.blending = THREE.CustomBlending;
    	sphere2.material.blending = THREE.CustomBlending;
    	sphere3.material.blending = THREE.CustomBlending;

    2.5. Transparent

    Transparent가 false이고, 먼저 생성된 Material가 다른 것보다 더 앞에 놓여져 있을때, 뒷쪽의 배경에 대한 연산을 아예 수행하지 않습니다. 따라서 Blending이 제대로 되지 않을 수 있습니다. 따라서 원활한 Blending을 위해 opacity를 변경하지 않더라도 Transparent는 true로 설정해야 합니다.

    
    	sphere1.material.transparent = true;
    	sphere2.material.transparent = true;
    	sphere3.material.transparent = true;

    2.6. Control Panel

    기본적인 구현이 완성되었으면, index.html에서 canvas 오른쪽에 여러가지 Control Panel을 추가하여 여러 값들을을 조절할수 있도록 구성하여 예제를 완성하였습니다. 콘츄럴 빼날

    3. 느낀점

    이번 기말프로젝트에서 Color Blending을 이용하여 다양한 그래픽 효과를 구현해보았습니다. 게임이나 디지털 영상 매체에서 보이는 파티클 효과나 어두운 효과들을 Color Blending을 활용하면 쉽게 구현할 수 있다는 것을 알게 되었습니다. 저는 게임 개발 쪽으로 진로를 희망하고 있는데, 이번 컴퓨터 그래픽스에서 배운 내용들과 기말 프로젝트를 진행하면서 스스로 공부한 내용들을 활용하면 단순히 Unity Engine이나 Unreal Engine에서 제공하는 툴의 기능만 활용하여 게임을 제작하는 것이 아니라 그 바탕이 되는 그래픽스 기술을 더 잘 이해하여 좋은 게임을 만들 수 있겠다는 생각을 하게 되었습니다.

    4. Reference

    https://threejs.org/docs/index.html?q=mate#api/en/constants/Materials

    https://threejs.org/docs/index.html?q=mate#api/en/constants/CustomBlendingEquations

    https://threejs.org/examples/?q=material#webgl_materials_blending_custom

    https://cglearn.codelight.eu/pub/computer-graphics/blending

    5. License

    This project is released under MIT license