Shader "ryoo/DiffuseShader1"
{
    Properties
    {
        _DiffuseTex ("Texture", 2D) = "white" {}
        _Color("Color",Color) = (1,0,0,1)
        _Ambient("Ambient",Range(0,1)) = 0.25
    }
    SubShader
    {
        Tags { "LightMode"="ForwardBase" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"
            #include "UnityLightingCommon.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                float4 worldNormal : TEXCOORD1;
            };

            sampler2D _DiffuseTex;
            float4 _DiffuseTex_ST;
            fixed4 _Color;
            float _Ambient;
            

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _DiffuseTex);
                float3 worldNormal = UnityObjectToWorldNormal(v.normal);
                //o. worldNormal = worldNormal;
                
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float3 normalDirection = normalize(i.worldNormal);
                
                float4 tex = tex2D(_DiffuseTex, i.uv);
                
                float nl = max(_Ambient, dot(normalDirection, _WorldSpaceLightPos0.xyz));
                float4 diffuseTerm = nl * _Color * tex *_LightColor0;
                
                return diffuseTerm;
            }
            ENDCG
        }
    }
}

참고서적: 유니티 물리 기반 셰이더 개발 

'Unity > Code base Shader' 카테고리의 다른 글

Specular 다 광원지원  (0) 2020.12.21
SpecularShader  (0) 2020.12.19
좌표공간 변환  (0) 2020.12.12
내적(dot)  (0) 2020.12.12
UnlitShader  (0) 2020.12.11

자주 헛갈려서 그림으로 정리해봤습니다.

'Unity > C#' 카테고리의 다른 글

재미로 만들어보는 유니티(콘솔) 로또  (0) 2020.12.29
유리가 깨지는 연출  (0) 2020.12.15
물체를 회전하고 상하 반복움직임.  (0) 2020.12.11
텍스쳐 애니메이션 타일셋  (0) 2020.12.11
C# 기초 기억창고2  (0) 2020.12.11

Reflection Probe를 이용해서 거울 효과를 만들어보려고했는데, 인터넷에 있는 영상을 따라서 물체에 중심을 두고 시도하였습니다.

하지만, 이상하게 물체들이 반사가 되긴하지만 엄청나게 크고 이상한 위치에 있었습니다.

이리저리 테스트를 하다가 알게되었네요.

카메라의 위치와 Reflection Probe와 관계가 있습니다.

Reflection Probe는 카메라 포지션의 Y값의 반대가 되어야 정위치에 온다는걸 알았네요.

물체자체가 리플렉션을 갖을때는 그자신이 움직이기에 상관이없지만 이렇게 카메라의 시점에서 보면 다른게 당연하겠네요.

 

 

 

 

'Unity > ETC' 카테고리의 다른 글

Post process 간략 설명  (0) 2020.12.18
Terrain Bake시 주의할점  (0) 2020.12.16
플렛폼별 Texutre 설정  (0) 2020.12.11
Unity Mask  (0) 2020.12.11
볼때마다 잊어버리는 조명설정..  (0) 2020.11.18

float3 UnityObjectToWorldDir(in float3 dir) 객체 공간의 방향을 취해 월드 공간에서의 방향 값으로 변환해준다.

 

float3 UnityObjectToWorldNormal(in float3 norm) 객체 공간이 노멀을 취해 월드 공간에서의 노멀 값으로 변환해준다.

빛을 계산하는데 유용하다.

 

float3 UnityWorldSpaceViewDir(in float3 worldPos) 월드 공간에서의 정점 위치를 취해 월드 공간에서의 뷰의 방향을 반환한다. 빛을 계산하는데 유용하다.

 

float3 UnityWorldSpaceLightDir(in float3 worldPos) 월드 공간에서의 정점 위치를 취해 공간에서의 빛의 방향을 반환한다. 빛을 계산하는데 유용하다.

 

unity_ObjectToWorld 객체 공간에서 월드공간으로 변환하는 행렬

unity_WorldToObject 위의 행열의 역행렬, 월드공간에서 객체 공간으로 변환하는 행렬

샘플) float4 vertexWorld = mul(unity_ObjectToWorld, v.vertex);

 

 

unity_WorldToCamer 월드 공간에서 카메라 공간으로 변환한다.

unity_CameraToWorld 위행열의 역행렬, 카메라 공간에서 월드 공간으로 변환한다.

float3 UnityViewToClipPos(in float3 pos) 뷰 공간에서 절단 공간으로 위치를 변환한다.

 

float4 UnityWorldToClipPos(in float pos) 위치를 월드 공간에서 절단 공간으로 변환

float4 UnityViewToClipPos(in float pos) 위치를 뷰 공간에서 절단 공간으로 변환

float4 UnityObjectToClipPos(in float pos) 정점 위치를 객체 공간에서 절단 공간으로 변환

 

 

밝기를 계산하는 방법

float brightness = cos(angle_of_incidence) // 입사각으로 구하는 밝기
float brightness = dot(normal,lightDir) // 노멀 벡터와 빛의 방향 벡터로 계산한 밝기
float3 pixelColor = brightness*lightColor*surfaceColor // 입사각으로 구하는 밝기

 

 

'Unity > Code base Shader' 카테고리의 다른 글

SpecularShader  (0) 2020.12.19
diffuseShader  (0) 2020.12.15
내적(dot)  (0) 2020.12.12
UnlitShader  (0) 2020.12.11
벡터(Vector)와 스칼라(Scalar)  (0) 2020.12.10

내적은 두 벡터의 각 성분끼리의 곱이라고 합니다.(스칼라곱이라고도 한다.)

 

빨간부분이 하나의 점이 되는데 점은 영어로 dot이고 그리고 이것은 내적인겁니다.

 

내적은 게임에서 복잡한 cosθ식을 좀더 가벼운 연산으로 바꿔서 사용하는 용도로 사용한다고 합니다.

 

길이가 1인 벡터는 단위벡터(unit vector)라고 하고 단윈벡터를 만드는 과정을 정규화(normalize)라고 합니다.

'Unity > Code base Shader' 카테고리의 다른 글

SpecularShader  (0) 2020.12.19
diffuseShader  (0) 2020.12.15
좌표공간 변환  (0) 2020.12.12
UnlitShader  (0) 2020.12.11
벡터(Vector)와 스칼라(Scalar)  (0) 2020.12.10

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
public class AnimateTiledTexture : MonoBehaviour
{
    public int _columns = 2;                        // The number of columns of the texture
    public int _rows = 2;                           // The number of rows of the texture
    public Vector2 _scale = new Vector3(1f, 1f);    // Scale the texture. This must be a non-zero number. negative scale flips the image
    public Vector2 _offset = Vector2.zero;          // You can use this if you do not want the texture centered. (These are very small numbers .001)
    public Vector2 _buffer = Vector2.zero;          // You can use this to buffer frames to hide unwanted grid lines or artifacts
    public float _framesPerSecond = 10f;            // Frames per second that you want to texture to play at
    public bool _playOnce = false;                  // Enable this if you want the animation to only play one time
    public bool _disableUponCompletion = false;     // Enable this if you want the texture to disable the renderer when it is finished playing
    public bool _enableEvents = false;              // Enable this if you want to register an event that fires when the animation is finished playing
    public bool _playOnEnable = true;               // The animation will play when the object is enabled
    public bool _newMaterialInstance = false;       // Set this to true if you want to create a new material instance
 
    private int _index = 0;                         // Keeps track of the current frame 
    private Vector2 _textureSize = Vector2.zero;    // Keeps track of the texture scale 
    private Material _materialInstance = null;      // Material instance of the material we create (if needed)
    private bool _hasMaterialInstance = false;      // A flag so we know if we have a material instance we need to clean up (better than a null check i think)
    private bool _isPlaying = false;                // A flag to determine if the animation is currently playing
 
 
    public delegate void VoidEvent();               // The Event delegate
    private List<VoidEvent> _voidEventCallbackList; // A list of functions we need to call if events are enabled
 
    // Use this function to register your callback function with this script
    public void RegisterCallback(VoidEvent cbFunction)
    {
        // If events are enabled, add the callback function to the event list
        if (_enableEvents)
            _voidEventCallbackList.Add(cbFunction);
        else
            Debug.LogWarning("AnimateTiledTexture: You are attempting to register a callback but the events of this object are not enabled!");
    }
 
    // Use this function to unregister a callback function with this script
    public void UnRegisterCallback(VoidEvent cbFunction)
    {
        // If events are enabled, unregister the callback function from the event list
        if (_enableEvents)
            _voidEventCallbackList.Remove(cbFunction);
        else
            Debug.LogWarning("AnimateTiledTexture: You are attempting to un-register a callback but the events of this object are not enabled!");
    }
 
    public void Play()
    {
        // If the animation is playing, stop it
        if (_isPlaying)
        {
            StopCoroutine("updateTiling");
            _isPlaying = false;
        }
        // Make sure the renderer is enabled
        GetComponent<Renderer>().enabled = true;
 
        //Because of the way textures calculate the y value, we need to start at the max y value
        _index = _columns;
 
        // Start the update tiling coroutine
        StartCoroutine(updateTiling());
    }
 
    public void ChangeMaterial(Material newMaterial, bool newInstance = false)
    {
        if (newInstance)
        {
            // First check our material instance, if we already have a material instance
            // and we want to create a new one, we need to clean up the old one
            if (_hasMaterialInstance)
                Object.Destroy(GetComponent<Renderer>().sharedMaterial);
 
            // create the new material
            _materialInstance = new Material(newMaterial);
 
            // Assign it to the renderer
            GetComponent<Renderer>().sharedMaterial = _materialInstance;
 
            // Set the flag
            _hasMaterialInstance = true;
        }
        else // if we dont have create a new instance, just assign the texture
            GetComponent<Renderer>().sharedMaterial = newMaterial;        
 
        // We need to recalc the texture size (since different material = possible different texture)
        CalcTextureSize();
 
        // Assign the new texture size
        GetComponent<Renderer>().sharedMaterial.SetTextureScale("_MainTex", _textureSize);
    }
 
    private void Awake()
    {
        // Allocate memory for the events, if needed
        if (_enableEvents)
            _voidEventCallbackList = new List<VoidEvent>();
 
        //Create the material instance, if needed. else, just use this function to recalc the texture size
        ChangeMaterial(GetComponent<Renderer>().sharedMaterial, _newMaterialInstance);
    }
 
    private void OnDestroy()
    {
        // If we wanted new material instances, we need to destroy the material
        if (_hasMaterialInstance)
        {
            Object.Destroy(GetComponent<Renderer>().sharedMaterial);
            _hasMaterialInstance = false;
        }
    }
 
    // Handles all event triggers to callback functions
    private void HandleCallbacks(List<VoidEvent> cbList)
    {
        // For now simply loop through them all and call yet.
        for (int i = 0; i < cbList.Count; ++i)
            cbList[i]();
    }
 
    private void OnEnable()
    {
 
       CalcTextureSize();
 
        if (_playOnEnable)
            Play();
    }
 
    private void CalcTextureSize()
    {
        //set the tile size of the texture (in UV units), based on the rows and columns
        _textureSize = new Vector2(1f / _columns, 1f / _rows);
 
        // Add in the scale
        _textureSize.x = _textureSize.x / _scale.x;
        _textureSize.y = _textureSize.y / _scale.y;
 
        // Buffer some of the image out (removes gridlines and stufF)
        _textureSize -= _buffer;
    }
 
    // The main update function of this script
    private IEnumerator updateTiling()
    {
        _isPlaying = true;
 
        // This is the max number of frames
        int checkAgainst = (_rows * _columns);
 
        while (true)
        {
            // If we are at the last frame, we need to either loop or break out of the loop
            if (_index >= checkAgainst)
            {
                _index = 0;  // Reset the index
 
                // If we only want to play the texture one time
                if (_playOnce)
                {
                    if (checkAgainst == _columns)
                    {
                        // We are done with the coroutine. Fire the event, if needed
                        if(_enableEvents)
                            HandleCallbacks(_voidEventCallbackList);
 
                        if (_disableUponCompletion)
                            gameObject.GetComponent<Renderer>().enabled = false;
 
                        // turn off the isplaying flag
                        _isPlaying = false;
 
                        // Break out of the loop, we are finished
                        yield break;
                    }
                    else
                        checkAgainst = _columns;    // We need to loop through one more row
                }
 
            }
 
            // Apply the offset in order to move to the next frame
            ApplyOffset();
 
            //Increment the index
            _index++;
 
            // Wait a time before we move to the next frame. Note, this gives unexpected results on mobile devices
            yield return new WaitForSeconds(1f / _framesPerSecond);
        }        
    }
 
    private void ApplyOffset()
    {
        //split into x and y indexes. calculate the new offsets
        Vector2 offset = new Vector2((float)_index / _columns - (_index / _columns), //x index
                                      1 - ((_index / _columns) / (float)_rows));    //y index
 
        // Reset the y offset, if needed
        if (offset.y == 1)
            offset.y = 0.0f;
 
        // If we have scaled the texture, we need to reposition the texture to the center of the object
        offset.x += ((1f / _columns) - _textureSize.x) / 2.0f;
        offset.y += ((1f / _rows) - _textureSize.y) / 2.0f;
 
        // Add an additional offset if the user does not want the texture centered
        offset.x += _offset.x;
        offset.y += _offset.y;
 
        // Update the material
        GetComponent<Renderer>().sharedMaterial.SetTextureOffset("_MainTex", offset);
    }
}

관중용으로 썼었는데, 어디서 구했는지 기억이 안나네요. 너무 오래전이라..

'Unity > C#' 카테고리의 다른 글

Sin, Cos, Tan  (0) 2020.12.15
물체를 회전하고 상하 반복움직임.  (0) 2020.12.11
C# 기초 기억창고2  (0) 2020.12.11
텍스쳐를 자동으로 설정해봅시다.  (0) 2020.12.06
유니티의 Object 이해  (0) 2020.12.06
Shader "Unlit/SimpleUnlitTexturedShader"
{
    Properties
    {
        // we have removed support for texture tiling/offset,
        // so make them not be displayed in material inspector
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100
        
        Pass
        {
            CGPROGRAM
            // use "vert" function as the vertex shader(정점쉐이더)
            #pragma vertex vert
            // use "frag" function as the pixel (fragment) shader(픽셀/프레그먼트 쉐이더)
            #pragma fragment frag

            #include "UnityCG.cginc" // 셰이더 컴파일을 하는데 포함시키고자하는 라이브러리에 지정

            //버텍스 쉐이더를 넣는곳- 정점 데이터를 appdata 구조를 통해 수집하고 이는 정점 함수로 전달한다.
            struct appdata
            {
                float4 vertex : POSITION; // 버텍스 위치
                float2 uv : TEXCOORD0; // 텍스쳐 좌표
            };

            // 버텍스 쉐이더를 내보내는곳.- 정점함수는 v2f(vertex to fragment) 데이터 구조 멤버들의 내용을 채우고 이를 프래그먼트 함수의 인자로 전달한다.
            struct v2f
            {
                float2 uv : TEXCOORD0; // 텍스쳐 좌표
                float4 vertex : SV_POSITION; // 클립공간위치
            };

            // 샘플링 할 텍스처- 변수선언
            sampler2D _MainTex;

            // vertex shader
            v2f vert (appdata v)
            {
                v2f o;
                // 위치를 클립 공간으로 변환
                // (모델 * 뷰 * 투영 행렬로 곱하기)
                o.vertex = UnityObjectToClipPos(v.vertex);// UnityObjectToClipPos-정점 좌표 공간에서 레스터라이저가 사용하는 좌표 공간으로 변환
                
                // 텍스처 좌표를 전달하기
                o.uv = v.uv;
                return o;
            }
            
            // 픽셀 쉐이더-낮은 정밀도를 반환합니다 ( "fixed4"타입)
            // color ("SV_Target" semantic) 하나의 프레그먼트 색상 출력을 의미함.
            fixed4 frag (v2f i) : SV_Target
            {
                // 샘플 텍스처,반환
                fixed4 col = tex2D(_MainTex, i.uv);
                return col;
            }
            ENDCG
        }
    }
}

버텍스 셰이더(Vertex Shader) 는 3D 모델의 각 버텍스에서 실행되는 프로그램입니다. 많은 경우 버텍스 셰이더는 특별히 흥미로운 동작을 하지는 않습니다. 여기서는 버텍스 위치를 오브젝트 공간에서 이른바 “클립 공간”으로 변환하기만 합니다. GPU가 오브젝트를 화면에 래스터화하기 위해 클립 공간을 사용합니다. 프래그먼트 셰이더에서 텍스처를 샘플링하기 위해 필요로 합니다.

프래그먼트 셰이더(Fragment Shader)는 오브젝트가 화면에서 차지하고 있는 모든 픽셀마다 실행되는 프로그램이며 보통 각 픽셀의 컬러를 계산하고 출력하기 위해 사용됩니다. 화면에는 보통 수백만 개의 픽셀이 있으며 프래그먼트 셰이더는 이 모든 픽셀에 대해 실행됩니다! 프래그먼트 셰이더를 최적화하는 것은 전반적인 게임 성능에 있어 매우 중요한 부분입니다.

 

docs.unity3d.com/kr/current/Manual/SL-VertexFragmentShaderExamples.html

 

버텍스 및 프래그먼트 셰이더 예제 - Unity 매뉴얼

이 페이지에서는 버텍스 및 프래그먼트 프로그램 예제를 다룹니다. 셰이더에 대한 기본 안내는 셰이더 튜토리얼을 참조하십시오: 1부 및 2부. 표준 머리티얼 셰이더를 작성하는 쉬운 방법을 살

docs.unity3d.com

unity3d.com/get-unity/download/archive

 

Get Unity - Download Archive - Unity

Unity is the ultimate game development platform. Use Unity to build high-quality 3D and 2D games, deploy them across mobile, desktop, VR/AR, consoles or the Web, and connect with loyal and enthusiastic players and customers.

unity3d.com

유니티오리지날 쉐이더 다운로드

 

'Unity > Code base Shader' 카테고리의 다른 글

SpecularShader  (0) 2020.12.19
diffuseShader  (0) 2020.12.15
좌표공간 변환  (0) 2020.12.12
내적(dot)  (0) 2020.12.12
벡터(Vector)와 스칼라(Scalar)  (0) 2020.12.10