차례대로 Standard, CustomLambert, HalfLambert

 

1. Standard

 

Shader "Custom/lambert"
{
    Properties
    {
        _MainTex("Main Texture", 2D) = "white"{}
        _NormalMap("NormalMap", 2D) = "bump" {}
        _Color("Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        CGPROGRAM
        #pragma surface surf Standard
        #pragma target 3.0
        sampler2D _MainTex;
        sampler2D _NormalMap;     
        float4 _Color;
        struct Input
        {
            float4 color : COLOR;
            float2 uv_MainTex;
            float2 uv_NormalMap;
        };

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            
            float4 c = tex2D(_MainTex, IN.uv_MainTex);
            float4 d = tex2D(_NormalMap, IN.uv_NormalMap);
            o.Normal = UnpackNormal (d);
            o.Albedo = c.rgb * _Color;
            o.Alpha = c.a;
        }
        // 빛을 만든다
       
        ENDCG
    }
    FallBack "Diffuse"
}

 

2. CustomLambert

Shader "Custom/customLambert"
{
    Properties
    {
        _MainTex("Main Texture", 2D) = "white"{}
        _NormalMap("NormalMap", 2D) = "bump" {}
        _Color("Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        CGPROGRAM
        #pragma surface surf _MyLambert
        #pragma target 3.0
        sampler2D _MainTex;
        sampler2D _NormalMap;     
        float4 _Color;
        struct Input
        {
            float4 color : COLOR;
            float2 uv_MainTex;
            float2 uv_NormalMap;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            float4 c = tex2D(_MainTex, IN.uv_MainTex);
            float4 d = tex2D(_NormalMap, IN.uv_NormalMap);
            o.Normal = UnpackNormal (d);
            o.Albedo = c.rgb * _Color;
            o.Alpha = c.a;
        }
        // 빛을 만든다
        float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
        {
            float4 final;
            float ndot1 = dot(s.Normal, lightDir);
            final.rgb = ndot1 * s.Albedo.rgb;
            final.a = s.Alpha;
            return final;
            }
        ENDCG
    }
    FallBack "Diffuse"
}

 

2-2. CustomLambert

Shader "Custom/customLambert"
{
    Properties
    {
        _NormalMap("Normal Map",2D) = "bump"{}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        CGPROGRAM
        #pragma surface surf _MyLambert noambient;
        #pragma target 3.0
        sampler2D _NormalMap;     
        struct Input
        {
            float4 color : COLOR;
            float2 uv_NormalMap;
        };
        void surf (Input IN, inout SurfaceOutput o)
        {
            float4 c = tex2D(_NormalMap, IN.uv_NormalMap);
            o.Normal = UnpackNormal (c);
            o.Albedo = 1;
            
        }

        float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
        {
            float4 final;
            //return float4(1,0,0,1);
            //노멀벡터와 조명벡터를 내적해라
            float ndot1 = dot(s.Normal, lightDir);
            final = saturate(ndot1);
            return final;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 

3. HalfLambert

Shader "Custom/customLambert2"
{
    Properties
    {
        _MainTex("Main Texture", 2D) = "white"{}
        _NormalMap("NormalMap", 2D) = "bump" {}
        _Color("Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        CGPROGRAM
        #pragma surface surf _MyLambert
        #pragma target 3.0
        sampler2D _MainTex;
        sampler2D _NormalMap;     
        float4 _Color;
        struct Input
        {
            float4 color : COLOR;
            float2 uv_MainTex;
            float2 uv_NormalMap;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            float4 c = tex2D(_MainTex, IN.uv_MainTex);
            float4 d = tex2D(_NormalMap, IN.uv_NormalMap);
            o.Normal = UnpackNormal (d);
            o.Albedo = c.rgb * _Color;
            o.Alpha = c.a;
        }
        // 빛을 만든다
        float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
        {
            float4 final;
            float ndot1 = dot(s.Normal, lightDir)* 0.5 + 0.5;
            final = pow(ndot1, 3);
            final.rgb = ndot1 * s.Albedo.rgb * _LightColor0.rgb * atten;
            final.a = s.Alpha;
            return final;
            }
        ENDCG
    }
    FallBack "Diffuse"
}

 


 

CustomLambert의 기본형

 

1. #pragma surface surf _MyLambert

2. void surf (Input IN, inout SurfaceOutput o)

3. float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
 {
  ;
     return float4(1, 0, 0 , 1);

 }

 

우선 이 3가지로 스탠다드를 바꿔주고 메서드를 만들어준다.

이때 매개변수는 변경하거나 수정할 수 없으며 주어진 대로 사용해야 한다.

 

 

float3 lightDir
조명 방향의 벡터
단, 조명을 편하게 사용하기 위해 뒤집혀지고 길이가 1인 단위 벡터 상태

 

float atten(uation) - 감쇠
그림자를 받거나 거리가 멀어지면 점점 조명이 흐려지는 라이트의 거리별 현상

 

dot : 노멀 벡터와 라이트 벡터를 내적 연산해주는 함수

우리는 o.Normal에 값을 넣지 않았지만 s.Normal의 값을 가져올 수 있다.

 

lightDir

lightDir은 vertex에서 바라보는 조명의 방향을 뒤집은 조명 벡터이므로 두 벡터를 단순히 내적하면 cos값이 나온다.

 

나중에 ambient light 또는 추가라이트를 비출 때 이 음수는 문제를 일으킬수 있는데

이(0아래는 전부 0으로 잘라주는)를 해결해주는 함수 saturate, max가 있다.

saturate
max

이 함수들을 사용하면 빨간선처럼 0보다 작은수는 0으로 지정해준다.

 


 

HalfLambert

 

* 0.5 + 0.5는 마법의 숫자이다.

이 공식은 -1 ~ 1까지의 숫자를 0에서 1까지의 범위로 만들어준다.

그 결과 cos라인을 끌어 올려주어 부드러운 결과 값이 나온다.

 

조명의 색상 or 감쇠를 이용할 수 있다.

ex) final.rgb = ndotl * s.Albedo * _LightColor0.rgb * atten;

 

https://docs.unity3d.com/kr/2021.3/Manual/SL-UnityShaderVariables.html

 

빌트인 셰이더 변수 - Unity 매뉴얼

Unity의 빌트인 포함 파일에는 셰이더에 대한 전역 변수(예: 현재 오브젝트의 변환 매트릭스, 광원 파라미터, 현재 시간 등)가 포함되어 있습니다. 이러한 셰이더 프로그램에서 이러한 전역 변수

docs.unity3d.com

 

이에 따라 조명의 색깔을 변경하고 거리에 따른 그림자를 조절할 수 있다.

https://docs.unity3d.com/kr/530/Manual/StandardShaderMaterialParameterAlbedoColor.html

 

알베도 컬러 및 투명도 - Unity 매뉴얼

Albedo 파라미터는 표면의 베이스 컬러를 제어합니다.

docs.unity3d.com

 

Shader "Custom/fire"
{
    Properties
    {
        _MainTex ("Main Texture", 2D) = "white"{}
        _MainTex2 ("Main Texture2", 2D) = "white"{}
        _Speed("Speed", Range(0,10.0)) = 1
        _BrightNess("BrightNess", Range(0,1)) = 1
        _Color("Color",Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent"}

        CGPROGRAM
        #pragma surface surf Standard alpha:fade
        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _MainTex2;
        float _Speed;
        float _BrightNess;
        float _Color;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_MainTex2;
           
        };

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            //데이터 
            float2 d_uv = IN.uv_MainTex2;
            d_uv.y -= _Time.y;
           
            float4 d = tex2D(_MainTex2, d_uv * _Speed);

            //d.rgb
            //d.r => 0 

            //체크 
            float2 c_uv = IN.uv_MainTex;
            float4 c = tex2D(_MainTex, c_uv + d); 

            //체크를 보여주고 있음 
            o.Emission = c.rgb * _BrightNess;
            o.Alpha = c.a ;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 

 


 

 

 

Shader "Custom/vertexcolor"
{
    Properties
    {
        _MainTex("Main Texture", 2D) = "white"{}
        _MainTex2("Main Texture2", 2D) = "white"{}
        _MainTex3("Main Texture3", 2D) = "white"{}
        _MainTex4("Main Texture4", 2D) = "white"{}
        
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
     

        CGPROGRAM
      
        #pragma surface surf Standard fullforwardshadows

        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _MainTex2;
        sampler2D _MainTex3;
        sampler2D _MainTex4;


        
        struct Input
        {
            float4 color : COLOR;
            float2 uv_MainTex;
            float2 uv_MainTex2;
            float2 uv_MainTex3;
            float2 uv_MainTex4;


        };

       

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
           float4 c =tex2D(_MainTex, IN.uv_MainTex);
           //o.Emission = c.rgb + IN.color.rgb;

           IN.uv_MainTex2 -= _Time.y * 0.2;
           //float2 d_uv2 = IN.uv_MainTex2;
            //d_uv2.y -= _Time.y;
            float4 d = tex2D(_MainTex2,IN.uv_MainTex2);
           o.Emission = lerp(c.r, d.rgb, IN.color.r ); // 보이지 않는 곳을 0 보이는 곳을 1이라고 생각
           

           float4 e = tex2D(_MainTex3, IN.uv_MainTex3);
           o.Emission = lerp(o.Emission, e.rgb, IN.color.g);

           float4 f = tex2D(_MainTex4, IN.uv_MainTex4);
           o.Emission = lerp(o.Emission, f.rgb, IN.color.b);
           
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 


 

Shader "Custom/rock"
{
    Properties
    {
        _MainTex ("Main Texture", 2D) = "white"{}
        _MainTex2 ("Main Texture2", 2D) = "white"{}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        CGPROGRAM
        #pragma surface surf Standard
        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _MainTex2;

        struct Input
        {
            float4 color : COLOR; //버텍스 컬러 
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            //이끼 
            float4 d = tex2D(_MainTex2, IN.uv_MainTex);
            //돌맹이 
            float4 c = tex2D(_MainTex, IN.uv_MainTex);
            
            //이끼를 버텍스 컬러 R 부분에 출력하자 
            o.Albedo = lerp(c.rgb, d.rgb, IN.color.r);
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 


https://docs.unity3d.com/kr/530/Manual/StandardShaderMaterialParameterMetallic.html

https://docs.unity3d.com/kr/2022.1/Manual/StandardShaderMaterialParameterSmoothness.html

https://docs.unity3d.com/Manual/StandardShaderMaterialParameterNormalMap.html

 

Unity - Manual: Normal map (Bump mapping)

Normal map (Bump mapping) Normal maps are a type of Bump Map. They are a special kind of texture that allow you to add surface detail such as bumps, grooves, and scratches to a model which catch the light as if they are represented by real geometry. Unity

docs.unity3d.com

 

평활도 - Unity 매뉴얼

평활도(Smoothness) 개념은 스페큘러 워크플로우와 메탈릭 워크플로우 모두에 적용되며 매우 비슷한 방식으로 작동합니다. 디폴트로 메탈릭 또는 스페큘러 텍스처 맵이 할당되지 않았다면 슬라이

docs.unity3d.com

 

메탈릭모드: 메탈릭 파라미터 - Unity 매뉴얼

Metallic 워크플로에서 작업하는 경우(스페큘러 워크플로와 달리) 표면의 반사도 및 광원 반응이 메탈릭 레벨과 평활도 레벨에 따라 바뀝니다.

docs.unity3d.com

 

Shader "Custom/Metallic"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
        _NormalMap ("NormalMap", 2D) = "bump"{}
        _NormalStength("Normal Stength", Range(0.1, 2)) = 0
        _Occlusion("Occlusion", 2D) = "white"{}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        CGPROGRAM
        #pragma surface surf Standard
        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _NormalMap;
        sampler2D _Occlusion;
        float _NormalStength;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_NormalMap;
        };

        half _Glossiness;
        half _Metallic;

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;

            float4 n = tex2D(_NormalMap, IN.uv_NormalMap);
            float3 normal = UnpackNormal(n);
            fixed4 occlusion = tex2D(_Occlusion, IN.uv_MainTex);

            o.Occlusion = occlusion;
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;

            o.Normal = float3(normal.x * _NormalStength , normal.y * _NormalStength , normal.z);

            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 

 

 

Shader "Custom/rockGolem2"
{
    Properties
    {
        _MainTex("MainTex",2D) = "white" {}
        _MainTex2("Left Hand",2D) = "white" {}
        _MainTex3("Right Hand",2D) = "white" {}
        _NormalMap ("NormalMap", 2D) = "bump"{}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
        _Occlusion ("Occlusion", 2D) = "white"{}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
       
        CGPROGRAM
        #pragma surface surf Standard
        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _MainTex2;
        sampler2D _MainTex3;
        sampler2D _NormalMap;
        half _Glossiness;
        half _Metallic;
        sampler2D _Occlusion;



        struct Input
        {
            float2 uv_MainTex;
            float2 uv_MainTex2;
            float2 uv_MainTex3;
            float4 color : COLOR;
            float2 uv_NormalMap;
        };
    
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            //fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
            //o.Albedo = IN.color.rgb;
            //o.Alpha = c.a;
            IN.uv_MainTex2.y += _Time.y * 0.2;
            IN.uv_MainTex3.y += _Time.y * 0.2;
            fixed4 body = tex2D (_MainTex, IN.uv_MainTex);
            fixed4 lHand = tex2D (_MainTex2, IN.uv_MainTex2);
            fixed4 rHand = tex2D (_MainTex3, IN.uv_MainTex3);


            //float2 d_uv2 = IN.uv_MainTex2;
            //d_uv2.y -= _Time.y;




            //o.Albedo = lerp(0, body, IN.color.r);
            o.Albedo = lerp(body, lHand, IN.color.r);
            o.Albedo = lerp(o.Albedo, rHand, IN.color.b);

            float4 n = tex2D(_NormalMap, IN.uv_NormalMap);
            float3 normal = UnpackNormal(n);
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Normal = normal;
            o.Occlusion = tex2D(_Occlusion, IN.uv_MainTex);


        }
        ENDCG
    }
    FallBack "Diffuse"
}

하이어라키에 Sphere 구체 추가

ㅏ이어

폴더를 만든 후 Materials와 Shaders를 추가해준다

그 후

NewSurfaceShader를 New Material로 드래그해서 Assign

그 후

New Material을 Sphere에 드래그해서 Assign

코드 안에 내용들을 지워주는데 Input에 아무것도 없으면 오류가 난다.

이런식으로 프로티에 작성해주면 인스펙터에 생성이된다.

드래그한 코드

즉 o오브젝트에 Albedo를 float3(red, green, blue)를 할당하는데 red에만 1을 선언한 상태와 결과

 

Emission으로 바구면 평면으로 볼 수 있다.

 

Emission에 컬러속성을 할당 한후 값을 넣어주면

인스펙터에서 컬러창으로 색을 변경할 수 있다.

r g b에 각각 red blue green 변수를 선언후 할당한후

pow를 사용 pow(x,y) => x를 y 제곱

Red, Greed, Blue를 각각 이동하여 색을 변경할 수 있다.

BrightDarkness 변수 선언후 + 를 사용해서

Emission값을 flat(r,g,b)와 함께 사용

 

Texture 2D속성을 사용

float4 c = tex2D(_MainTex, IN.uv_MainTex);

그 후 만들어진 텍스쳐 필드에 텍스쳐 할당

https://docs.unity3d.com/Manual/SL-SurfaceShaders.html

 

Unity - Manual: Writing Surface Shaders

Surface Shaders and rendering paths Writing Surface Shaders In the Built-in Render PipelineA series of operations that take the contents of a Scene, and displays them on a screen. Unity lets you choose from pre-built render pipelines, or write your own. Mo

docs.unity3d.com

 

+ Recent posts