사용자 도구

사이트 도구


language:shader:unity:shaderlab-basic

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

language:shader:unity:shaderlab-basic [2014/05/15 18:46] – 만듦 kieunslanguage:shader:unity:shaderlab-basic [2024/04/23 22:45] (현재) – 바깥 편집 127.0.0.1
줄 1: 줄 1:
  
 +[[http://jinhomang.tistory.com/entry/%EC%9C%A0%EB%8B%88%ED%8B%B0-%EC%85%B0%EC%9D%B4%EB%8D%94%EC%9D%98-%EA%B8%B0%EC%B4%88-1|유니티셰이더의기초 1~6]]까지 따라하면서 정리한 것
 +
 +====== ShaderLab : 기본형식 ======
 +
 +  * Unity의 셰이더 작성용 ShaderLab 스크립트 언어.
 +
 +기본 형식
 +
 +<code>
 +Shader "BasicShader" {
 +  SubShader {
 +    // Shaderlab code
 +  }
 +}
 +</code>
 +
 +===== SubShader =====
 +
 +  * 한개의 Shader에 스크립트에, 여러개의 SubShader 작성.
 +  * 유니티 디바이스에 맞는 스크립트를 선택 사용.
 +
 +개념상 (그럴걸이라고 믿고 가는) 지원 되는 디바이스 대응
 +
 +<code>
 +Shader "BasicShader" {
 +  SubShader {
 +    // 매우 좋은 스펙 디바이스
 +  }
 +  SubShader {
 +    // 좋은 스펙 디바이스
 +  }
 +  SubShader {
 +    // 낮은 스펙 디바이스
 +  }
 +}
 +</code>
 +
 +===== Fallback =====
 +
 +<code>
 +Shader "BasicShader" {
 +  SubShader {
 +    // Shaderlab code
 +  }
 +  Fallback "Diffuse"
 +}
 +</code>
 +
 +  * 여러 SubShader조차 실패 하는 경우, **Fallback**에 정의된 쉐이더를 사용.
 +
 +===== Pass =====
 +
 +  * SubShader 내부에 정의(추가)
 +  * 오브젝트의 렌더링 단위.
 +  * SubShader 안의 Pass 수만큼 오브젝트에 셰이더 작업을 처리
 +  * 위의 것부터 순서대로 처리
 +
 +<code>
 +Shader "BasicShader" {
 +  SubShader {
 +    // Shaderlab code
 +    Pass {  }
 +    Pass {  }
 +  }
 +  Fallback "Diffuse"
 +}
 +</code>
 +
 +====== ShaderLab 키워드 ======
 +
 +===== 색 입히기 =====
 +
 +^ 오브젝트를 퍼렇게 칠한다 ^^
 +| <code>
 +Shader "Study/SolidBlue"
 +{
 +  SubShader {
 +    Pass {
 +      Color (0,0,1,1)
 +    }
 +  } 
 +}
 +</code> | {{:language:shader:solidblue_t1.png|}} |
 +
 +  * 오브젝트를 퍼렇게 칠한다.
 +  * 색상 정보만 있기 때문에, 색만 칠한다.
 +  * **Color** 키워드는 색상을 부여하는구나,라고 이해하고.
 +
 +===== 재질과 조명추가 =====
 +
 +키워드
 +  * Material 
 +    * Diffuse, Ambient
 +  * Lighting
 +
 +==== 매트리얼 설정 ====
 +
 +셰이더의 목적은 **재질과 라이팅**에 반응되도록 하는 것이므로, 
 +  * 매트리얼과 조명 모델을 추가한다.
 +
 +SubShader 의 Pass 내부에 **Material** 키워드로 조명 방식을 추가한다.
 +
 +<code>
 +Material {
 +  Diffuse (0,0,1,1)
 +  Ambient (0,0,1,1)
 +}
 +</code>
 +
 +==== 라이팅추가 ====
 +
 +재질이 표시되려면 조명을 (재질은 조명을 받은 반응이므로) 추가하는데,
 +  * 여기에서는 **고정파이프라인**을 사용하므로
 +  * 조명에 대한 전반 처리는 GPU에 미리 정의된 것을 사용
 +  * **Lighting** 키워드를 조명을 사용한다는 것을 명시
 +
 +<code>
 +Lighting On
 +</code>
 +
 +==== 매트리얼, 조명 추가된 셰이더 ====
 +
 +**Material**, **Lighting** 키워드가 **Pass** 블럭 내부에 있다.
 +
 +^ 조명과 함께 퍼렇게 칠한다. ^^
 +| <code>
 +Shader "Study/VertexLitBlue"
 +{
 +  SubShader {
 +    Pass {
 +      Material {
 +        Diffuse (0,0,1,1)
 +        Ambient (0,0,1,1)
 +      }
 +      Lighting On
 +    }
 +  } 
 +}
 +</code> | {{:language:shader:vertexlitblue_t1.png|}} |
 +
 +
 +====== Fixed Function Shader ======
 +
 +  * VertexShader, PixelShader 이전에 사용되던 그래픽 파이프 라인.
 +  * 기능이 정해져 있어서, 단순 설정만으로도 동작된다.
 +  * Per-Vertex Lighting 만 사용.
 +  * 프로그래밍이 들어가지 않는다.(진짜?)
 +
 +클래식한 기능이지만, 셰이더 이전의 쓰던 기능은 다 되므로 은근히 막강. 
 +  * 활용은 개인기에 따라..
 +
 +참고 : [[https://docs.unity3d.com/Documentation/Manual/ShaderTut1.html|Shaders: ShaderLab & Fixed Function shaders]]
 +
 +
 +====== 프로퍼티 ======
 +
 +  변수다,생각.
 +
 +  * 매트리얼의 Diffuse, Ambient에 적용할 색상을 "색상프로퍼티"로 받아 온다.
 +
 +<code>
 +Material {
 +  Diffuse (0,0,1,1)
 +  Ambient (0,0,1,1)
 +}
 +</code>
 +
 +위의 예제에서는 매트리얼에 값을 고정 값으로 설정 했는데, 
 +**Properties** 키워드와 구문 블럭 내부에, 변수 역할의 프로퍼티를 추가할 수 있다. \\ 
 +(유니티 인스펙터에 노출되는 그것들)
 +
 +Diffuse와 Ambient에 대한 프로퍼티를 추가. 다른 색상을 지정하도록 코드를 변경.
 +
 +^ 재질 색상을 프로퍼티로 받아들인다. ^^
 +| <code>
 +Shader "Study/VertexLitBlue2"
 +{
 +  Properties {
 +    _DiffuseColor ("DiffuseColor", COLOR) = (0,0,1,1)
 +    _AmbientColor ("AmbientColor", COLOR) = (0,0,1,1)
 +  }
 +  SubShader {
 +    Pass {
 +      Material {
 +        Diffuse [_DiffuseColor]
 +        Ambient [_AmbientColor]
 +      }
 +      Lighting On
 +    }
 +  } 
 +}
 +</code> | {{:language:shader:studyvertexblue2_1.png|}} |
 +| ::: | {{:language:shader:studyvertexblue2_2.png|}} |
 +
 +  * Properties : SubShader 바깥쪽에 적는다.
 +  * [[https://docs.unity3d.com/Documentation/Components/SL-Properties.html|Unity3D Properties 레퍼런스 링크]]
 +  
 +  * **매트리얼의 값을 %%[,]%%로 둘러서 사용했다.**
 +
 +<code>
 +_DiffuseColor ("DiffuseColor", COLOR) = (0,0,1,1)
 +</code>
 +
 +  * _DiffuseColor : 셰이더에서 사용할 변수 이름
 +  * "DiffuseColor" : 인스펙터에서 보여질 이름
 +  * COLOR : 이 프로퍼티의 타입
 +  * (0,0,1,1) : 기본 값. 값을 변경하지 않는 경우 사용할 값.
 +
 +===== 사용 가능한 타입 =====
 +
 +  * name ("display name", **Range (min, max)**) = number \\ : Defines a float property, represented as a slider from min to max in the inspector.
 +  * name ("display name", **Color**) = (number,number,number,number) \\ : Defines a color property.
 +  * name ("display name", **2D**) = "name" { options } \\ : 2D texture 정의 프로퍼티
 +  * name ("display name", **Rect**) = "name" { options } \\ : Defines a rectangle (non power of 2) texture property.
 +  * name ("display name", **Cube**) = "name" { options } \\ : Defines a cubemap texture property.
 +  * name ("display name", **Float**) = number \\ : Defines a float property.
 +  * name ("display name", **Vector**) = (number,number,number,number) \\ : Defines a four component vector property.
 +
 +
 +===== SetTexutre =====
 +
 +==== SetTexutre: 텍스쳐 프로퍼티 ====
 +
 +**2D** 프로퍼티로 텍스쳐를 설정해서 오브젝트에 입힐 수 있다.
 +
 +  * 텍스쳐 프로퍼티 설정
 +  * 텍스쳐를 오브젝트 적용하는 스크립트
 +
 +^ 텍스쳐를 입힌다. ^^
 +| <code>
 +Shader "Study/VertexLitTex"
 +{
 +    Properties {
 +        _DiffuseColor ("DiffuseColor", COLOR) = (0,0,1,1)
 +        _AmbientColor ("AmbientColor", COLOR) = (0,0,1,1)
 +        _MainTex ("MainTex", 2D) = "white"
 +    }
 +    SubShader {
 +        Pass {
 +            Material {
 +                Diffuse [_DiffuseColor]
 +                Ambient [_AmbientColor]
 +            }
 +
 +            Lighting On
 +
 +            SetTexture [_MainTex] 
 +        }
 +    } 
 +}</code> | 최초의 화면 \\ {{:language:shader:study_vertexlit_tex_1.png|}} |
 +| ::: | 텍스쳐를 등록한 후의 결과 \\ {{:language:shader:study_vertexlit_tex_2.png|}} |
 +
 +  * **SetTexture** : 키워드로 텍스쳐를 지정한다.
 +
 +위의 결과는, 텍스쳐를 오브젝트에 적용되었지만 라이팅 연산이 반영되지 않았다.
 +
 +==== SetTexutre: 라이팅 연산 추가 ====
 +
 +SetTexture 구문을 확장해서 ( %%{, }%%를 추가한다 ) 텍스쳐 연산 방법을 추가한다.
 +
 +<code>
 +SetTexture [_MainTex] { Combine texture * primary } 
 +</code>
 +
 +  * Combine : 텍스쳐에 다른 값과 연산( 곱)한다.
 +    * texture : Combine에 사용되는 키워드. 텍스쳐를 뜻함
 +    * primary : Combine 키워드가 호출되지 전까지의 계산 결과물.
 +  * [[https://docs.unity3d.com/Documentation/Components/SL-SetTexture.html|Combine에 대한 온라인 도움말]]
 +
 +| <code>
 +Shader "Study/VertexLitTex2"
 +{
 +    Properties {
 +        _DiffuseColor ("DiffuseColor", COLOR) = (0,0,1,1)
 +        _AmbientColor ("AmbientColor", COLOR) = (0,0,1,1)
 +        _MainTex ("MainTex", 2D) = "white"
 +    }
 +    SubShader {
 +        Pass {
 +            Material {
 +                Diffuse [_DiffuseColor]
 +                Ambient [_AmbientColor]
 +            }
 +            Lighting On
 +            SetTexture [_MainTex] {
 +                Combine texture * primary
 +            }
 +        }
 +    } 
 +}
 +</code> | {{:language:shader:study_vertexlit_tex2_combinemul.png|}} |
 +
 +텍스쳐 색상(texture)과 이전 라이팅 계산 결과(primary)를 곱해서 화면에 표시한다.
 +
 +
 +==== Combine ====
 +
 +[[https://docs.unity3d.com/Documentation/Components/SL-SetTexture.html|Combine에 대한 온라인 도움말]]
 +
 +  * 3개까지의 src1~src3 까지 사용가능한 듯
 +  * 가능한 연산
 +    * 곱/합/빼기
 +
 +Combine의 조합 방식
 +
 +| combine <src1> * <src2>            | 곱한다. 결과는 다소 어두워진다. 하지만 색상 결합의 기본은 곱이므로 이걸 사용한다. |
 +| :::                                | (0.2 * 0.2 = 0.04) 색상이 점점 0(검정)에 가까워지므로.                            |
 +| :::                                | 하지만 1(white)로 곱하면 원래 색상이 나오므로.                                    |
 +| combine <src1> + <src2>            | 더한다. 밝아진다. \\ 점점 1에 가까워지니까.                                       |
 +| combine <src1> - <src2>            | 빼는데.. 이건 좀 미묘.                                                            |
 +| combine <src1> +- <src2>           | src1을 src2에 더한 다음, 0.5를 뺀다. (signed add?)                                |
 +| combine <src1> lerp(<src2>) <src3> | src2의 알파값으로 src1(=1)과 src3(=0)사이의 보간 값을 사용한다.                   |
 +| :::                                | 숫자 범위가 (1~0)임의 주의                                                        |
 +| combine <src1> * <src2> + <src3>   | src1.rgba * src2.a + src3 . 이건 뭘까..                                           |
 +| combine <src1> * <src2> +- <src3>  | src1.rgba * src2.a + src3 - 0.5                                                   |
 +| combine <src1> * <src2> - <src3>   | src1(전체) * src2(알파값) - src3(전체)                                            |
 +
 +src 프로퍼티는 아래 키워드로 변경 가능
 +
 +  * Texture : **%%SetTexture [<텍스쳐 이름>]%%**에서 지정한 텍스쳐. (SetTexture 구문에서 텍스쳐를 제어하려면 가리키는 키워드가 필요하잖아.)
 +  * Primary : 정점 색상을 사용한 라이팅 계산 결과. **Material**에 지정한 조명 모델에 대한 계산 결과.
 +  * Previous : 바로 직전까지 계산한 텍스쳐 연산 결과.
 +  * Constant : Constant is the color specified in ConstantColor
 +
 +combine <연산> %%<보정용 키워드>%%
 +
 +  * **double**, **quad** : combine 결과를 x2 또는 x4 <code>
 +SetTexture [_MainTex] { Combine texture * primary DOUBLE }</code>
 +  * **src** 프로퍼티에는 **one -** 옵션을 붙여서 반대값을 사용하게 할 수 있다.
 +  * **src** : **src alpha**, **alpha**키워드를 붙어서 알파만 사용하게 할 수 있다.
 +
 +| src1 * src2 | src1 + src2 | src1 - src2 |
 +| {{:language:shader:study_vertexlit_tex2_combinemul.png?200|}} | {{:language:shader:study_vertexlit_tex2_combineadd.png?200|}}  | {{:language:shader:study_vertexlit_tex2_combineminus.png?200|}} |
 +
 +=== 색상과 알파분리 ===
 +
 +<code>
 +combine src1 src2, color(alpha)
 +</code>
 +
 +"," 로 색상과 알파 부분을 분리.
 +
 +  - "src1 src2"에서는 원래 그대로 적용
 +  - color(alpha)에서는 (1)번 연산에서 적용된 결과에 알파값을 적용
 +
 +=== 그외 ===
 +
 +  * ConstantColor color \\:Defines a constant color that can be used in the combine command.
 +  * matrix [MatrixPropertyName] \\: Transforms texture coordinates used in this command with the given matrix.
 +
 +
 +==== SetTexutre: 두장의 텍스쳐 ====
 +
 +  combine lerp 활용
 +
 +텍스쳐만 표시되도록 재질 설정을 삭제하고 텍스쳐만 받는 셰이더 작성
 +
 +| <code>
 +Shader "Study/TwoTexture"
 +{
 +  Properties {
 +    _MainTex ("MainTex", 2D) = "white"
 +    _SubTex ("SubTex", 2D) = "white"
 +  }
 +  SubShader {
 +    Pass {
 +      SetTexture [_MainTex] 
 +      
 +      SetTexture [_SubTex] { Combine texture * previous }
 +    }
 +  } 
 +}
 +</code> | {{:language:shader:study_two_tex_1.png|}} \\ {{:language:shader:study_two_tex_2.png|}} |
 +
 +  * primary 삭제 : primary를 넣으면, 연산된 라이팅 결과가 없기 때문에 검게 처리된다.
 +  * _MainTex 지정 후, \\ 바로 _SubTex로 **previous**로 "곱"연산.
 +  * 결과는 두장의 이미지가 겹쳐 보인다.
 +
 +두번째 텍스쳐는 알파값이 있는 투명한 이미지인데, 투명 처리를 하지 않아서 그림이 깨져보인다.
 +
 +**combine lerp()**로 알파를 반영 해본다.
 +
 +<code>
 +// texture의 알파값으로 src1, src2의 비율을 조정한다. 알파가 1(not 투명) _SubTex값을 사용, 0에 가까워질수록 previous를 사용
 +SetTexture [_SubTex] {
 +  Combine texture lerp(texture) previous
 +}
 +</code>
 +
 +셰이더 수정
 +| <code>
 +Shader "Study/TwoTexture"
 +{
 +    Properties {
 +        _MainTex ("MainTex", 2D) = "white"
 +        _SubTex ("SubTex", 2D) = "white"
 +    }
 +    SubShader {
 +        Pass {
 +            SetTexture [_MainTex] 
 +
 +            SetTexture [_SubTex] {
 +                Combine texture lerp(texture) previous
 +            }
 +        }
 +    } 
 +}
 +</code> | {{:language:shader:study_two_tex_3.png|}} |
 +
 +
 +
 +===== Blend =====
 +
 +반투명 효과 같은, "색상섞은 후 효과"를 얻으려면 **Blend** 로 조합 방법을 적는다.
 +
 +  * [[https://docs.unity3d.com/Documentation/Components/SL-Blend.html|Unity3d Blending]]
 +
 +기본 포맷
 +<code>
 +Blend <SrcFactor> <DstFactor>
 +</code>
 +
 +  (새로 찍을 색상 값) SrcFactor * (기존 배경의 색상) DstColor
 +
 +색상을 섞겠다는 뜻인데, SrcFactor와 DstFactor에는 블렌딩에 사용될 색상 속성(Blend Factor)을 지정해야 한다.
 +
 +<code>
 +Blend SrcAlpha OneMinusSrcAlpha
 +</code>
 +
 +원래 문서의 설명(이 명료해서)
 +
 +<note>이 경우에 만약 오브젝트의 알파값이 0.6 이라고 한다면, SrcAlpha = 0.6 이고 OneMinusSrcAlpha = 0.4 이므로 오브젝트 색상과 배경 색상은 60% 대 40% 비율로 섞여서 결국 오브젝트가 반투명하게 보이는 효과를 나타내는 것입니다.</note>
 +
 +  * Factor라는 것에 유의해야 하는데,
 +  * OneMinusAlpha는 원본 색상에서의 (1-Alpha)값을 배경색에 대한 알파값으로 적용하라는 뜻.
 +
 +0~1 사이의 색상이나 알파 값을 어디에서 가져올 것이냐에 대한 **선택 구문**
 +
 +**잡...**
 +
 +| <code>
 +Blend SrcAlpha DstAlpha
 +</code> | 이 경우, 둘다 0.6이면 어떻게 될려나. 최대값은 1이니까 |
 +
 +==== 구문의 위치 ====
 +
 +SubShader, Pass의 안쪽에 위치. 
 +
 +==== 오브젝트를 반투명하게 표시 ====
 +
 +텍스쳐 두장만 표시하는 셰이더에, **Blend를 넣어 봅니다.**
 +
 +| <code>
 +Shader "Study/TransObject"
 +{
 +  Properties {
 +    _MainTex ("MainTex", 2D) = "white" {}
 +    _SubTex ("SubTex", 2D) = "white" {}
 +  }
 +  SubShader {
 +    Pass {
 +  
 +Blend SrcAlpha OneMinusSrcAlpha
 +
 +      SetTexture [_MainTex] 
 +      SetTexture [_SubTex] { Combine texture lerp(texture) previous }
 +    }
 +  } 
 +}
 +</code> | {{:language:shader:study_transobject_1.png|}} |
 +
 +Blend만 넣어서는 결과가 나오지 않음.
 +
 +어느 정도의 알파값을 SrcAlpha로 지정할 것인지 정할 수 있는 코드를 넣어야 하는데,
 +색상값을 입력 받아 \\ 이 색상의 알파값을 최종 알파값으로 사용하도록 코드를 추가.
 +
 +| <code>
 +Shader "Study/TransObject"
 +{
 +  Properties {
 +
 +_Alpha ("AlphaColor", COLOR) = (0,0,0,1)
 +
 +    _MainTex ("MainTex", 2D) = "white" {}
 +    _SubTex ("SubTex", 2D) = "white" {}
 +  }
 +  SubShader {
 +    Pass {
 +  
 +Blend SrcAlpha OneMinusSrcAlpha
 +
 +      SetTexture [_MainTex] 
 +      SetTexture [_SubTex] { 
 +
 +ConstantColor[_Alpha]  
 +Combine texture lerp(texture) previous, constant
 +
 +      }
 +    }
 +  } 
 +}
 +</code> | {{:language:shader:study_transobject_2.png|}} |
 +| ::: | {{:language:shader:study_transobject_3.png|}} |
 +
 +  * _Alpha라는 컬러 값을 받는 프로퍼티 추가
 +  * SubShader > Pass > 두번째 SetTexutre 에, **ConstantColor** 키워드로 색상 숫자값을 선언하고,
 +  * combine에서 텍스쳐 연산 이후에 
 +  * 얼마나 알파 값을 적용할 것인지 _Alpha를 사용하도록 코드 추가
 +
 +렌더링 큐를 설정하지 않는데도 앞뒤 제대로 나오니.. 쩝인데.
 +혹시 모르니,
 +
 +오브젝트의 앞 뒤로 반투명하게 나와야 할게 제대로 나오지 않는다면 렌더링 큐 설정이 필요하다는 뜻.
 +
 +
 +Shader "Study/TransObject"
 +{
 +  Properties {
 +    _Alpha ("AlphaColor", COLOR) = (0,0,0,1)
 +    _MainTex ("MainTex", 2D) = "white" {}
 +    _SubTex ("SubTex", 2D) = "white" {}
 +  }
 +  SubShader {
 +    
 +Tags { "Queue" = "Transparent"
 +    
 +    Pass {
 +      Blend SrcAlpha OneMinusSrcAlpha
 +      SetTexture [_MainTex] 
 +      SetTexture [_SubTex] { 
 +        ConstantColor[_Alpha]  
 +        Combine texture lerp(texture) previous, constant
 +      }
 +    }
 +  } 
 +}
 +</code>
 +
 +렌더링 큐를 Transparent로 설정해서, Transparent 에 해당되는 녀석들이 그려질때 같이 그려지도록 설정한다.
 +
 +==== 렌더링 큐 ====
 +
 +오브젝트가 렌더링 되는 순서를 정할 수 있는데, 5단계가 기본이다.
 +
 +^ 키워드             ^ 숫자인덱스 ^ 설명                                                                             ^
 +| Background         | 1000       | 가장 먼저 그린다. 다른 것들에 가린다는 뜻                                        |
 +| Geometry \\ 기본값 | 2000       | 대부분 여기에 해당됨. 반투명 오브젝트 위주                                       |
 +| AlphaTest          | 2450       | 반투명한 Geometry? 가 뭐지? 나무? 알파 테스트를 필요 있는 것.                    |
 +| Transparent         | 3000       | 투명한 (유리, 파티클) 오브젝트는 여기로 와야 함. 이게 거의 많이 쓰일 것 같은데.. |
 +| Overlay            | 4000       | 가장 나중에 그리는데, 언제든 보이는 가장 앞에 있는 (렌즈플레어 같은) 오브젝트    |
 +
 +렌더링 큐는 **Tag** 키워드로 입력하는데,
 +  * SubShader에 위치할 수도 있고,
 +  * Pass 구문 안에도 넣을 수 있다.
 +
 +<code>
 +Tags = { "Queue" = "Transparent" }
 +</code>
 +
 +또한 기본 키워드에 숫자를 더하거나 빼서 렌더링 순서를 임의 설정할 수 있다.
 +
 +<code>
 +Tags = { "Queue" = "Geometry+1" }
 +</code>
 +
 +
 +
 +
 +
 +====== 색상 ======
 +
 +셰이더에서도 색상값은 (0~1) 사이의 값을 사용.
 +  * 순서 : RGBA
 +  * Color( 1, 1, 1, 1 ) : Color ( <R>, <G>, <B>, <A> )
 +
 +===== 색상 연산 =====
 +
 +범위 값이, 0~1 사이 값인 것만 주의 하면 연산할때 도움이 된다.
 +  * 곱
 +    * 큰수와 작은수를 곱하면 색상값이 더 작아지는데 조심. ( 0.1 * 0.01, 작아지지잖아 )
 +    * Pow 함수를 사용할때는 요 주의
 +  * 합
 +    * 곱보다는 숫자 변화가 적지만 
 +    * 더한다는건 더 흰색에 가까워진다는 뜻이므로