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

PVRTC : IOS에서 주로 사용됩니다.(PowerVR Texture Compression)

 

유니티에서 기본 압축 포멧으로 PVRTC1이 사용됩니다.

정밀도로 2pp(2비트) 와 4pp(4비트) 두개의 타입으로 존재합니다.

기본적으로 아무것도 안하면, 유니티에서는 RGB PVRTC 4 bits로 저장됩니다.

 

초기버전은 PVRTC1 와 최근(?) PVRTC2가 존재합니다.

PVRTC2가 더 업그레이드된 버전이겠지요?

하지만, 유니티는 PVRTC1만 지원합니다.

 

알파테스쳐가 있든 없든 압축이 됩니다.

텍스쳐를 변조처리할때 선형보간을 수행하여 픽셀 블럭화 현상이 완화되지만, 대신 번짐 현상이 발생하여

만화풍의 스프라이트나 아이콘은 번짐현상이 발생합니다.

이럴때는 해상도를 512에서 1024로 바꾼는 방법을 선택하는것이 현명할것입니다.

아니면 압축을 안하는 방법을 써야겠습니다.

 

 

ETC: 안드로이드에서 주로 사용됩니다.(Ericsson Texture Compression)

 

기본적으로 아무것도 안하면, 유니티에서는 RGB CompressedETC 4 bits로 저장됩니다.

 

ETC1 과 업그레이드 버전 ETC2가 존재합니다.

ETC2는 OpenGL ES 3.0이상에서만 지원됩니다.

갤럭시 S3이하는 OpenGL ES 2.0으로 구동됩니다.

하지만, 그렇다고 OpenGL ES 2.0에서 ETC2가 구동이 안되는것은 아니고, 메모리를 더 잡아먹고 느려질뿐입니다.

프로젝트에 따라 선택하는게 현명한 선택일겁니다.

아주아주아주아주 범용은 ETC1, 구형폰따위는 하면 ETC2로..

ETC1은 알파 채널을 지원하지 않습니다만, 4비트로 저장하면 지원됩니다.(뭔개소리인가 싶지만, 알아서 텍스쳐를 하나 더 생성한다고 생각하면 되고, 결국 메모리를 더 잡지만 안되는건 아님이라고 생각하면 될듯합니다?)

 

ASTC: (Adaptive Scalabe Texture Compression)

 

ETC아 PVRTC와 다르게 더 많은 블록 크기를 사용합니다.

(12x12 block까지 사용되고, ETC와 PVRTC 4x4 block까지)

 

OpenGL ES 3.2이상이거나 OpenGL ES 3.1+AEP(Android Extesion Pack)에서만 지원됩니다.

그래서 고사양? 폰에서 추천한다고 합니다.

 

 

개인적으로는 가장 좋은 방법은 빌드할때 가장 높은것을 선택해보고, 최저사양으로 테스트하면서, 점차 낮춰가는게 좋은 방법이 아닐까 싶습니다.

잘모르겠으면...기본으로 합시다.^^;

 

 

출처: 유니티 그래픽스 최적화 스타트업

 

 

 

 

 

 

 

 

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

Terrain Bake시 주의할점  (0) 2020.12.16
Reflection Probe의 반사..  (0) 2020.12.14
Unity Mask  (0) 2020.12.11
볼때마다 잊어버리는 조명설정..  (0) 2020.11.18
유니티 빌드옵션 Compression Method  (0) 2020.11.11

Unity의 기본셰이더를 보면 Mask texture를 넣는 부분이 있습니다.

Mask 기본은 연두색으로 이루어진 경우가 많은데 이유는 RGBA채널별로 각각 다른 텍스쳐를 넣어서 텍스쳐 한장으로 효율적인 텍스쳐관리를 위해서 제작됩니다.

일반적으로 메탈이나 AO는 흑백외에는 컬러를 사용하지 않기 때문에 텍스쳐 한장으로 만드는것이 여러가지 유리합니다.

 

R- metal관련 맵을 넣는 부분입니다.
G- AO관련 맵을 넣는 부분입니다.
B- 마스크맵입니다.(구멍뚫는 용도?)
A-smoothness맵을 넣는 부분입니다.(블랙이면 반응이 없어요.)

 

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

Reflection Probe의 반사..  (0) 2020.12.14
플렛폼별 Texutre 설정  (0) 2020.12.11
볼때마다 잊어버리는 조명설정..  (0) 2020.11.18
유니티 빌드옵션 Compression Method  (0) 2020.11.11
Memory Profiler  (0) 2020.11.10

컬렉션

ArrayList

ArrayList arrayL = new ArrayList();
void Start(){
	arrayL.Add(1); //추가하기
	arrayL.Add(3);
    	arrayL.Add("list");
    	arrayL.Add("fun");
    
    	arrayL.Remove(list); //list를 지움.
        arrayL.RemoveAt(2); // 3번째 add된것을 지움.
        arrayL.RemoveRange(0,2) // 0-2까지 범위를 지움.
        arrayL[0] = "tt";//0번 인덱스를 바꾸는것.
    
    print(arrayLsit.Count);
    
    for(int i =0; 1 <arrayL.Count; i++)
    {
    	print(arrayL[i];
    }
    
}

List =  정수형, 문자형등 형식을 정해서 넣어서 사용하므로 ArrayList보다 성능이 더 좋다고 할수 있다.

 

HashTable =  특정키값을 정해서 리스트를 만드는 기능이다. [만수(특정값 , 10000)]

Dictionary =  HashTable과 유사하고 List처럼 정해진 형식을 사용한다.

 

Queue = 순서대로 값을 넣고 순서대로 값을 빼내서 없앨때 사용된다.

    Queue<int> qqu = new Queue<int>();

    void Start()
    {
        qqu.Enqueue(1);
        qqu.Enqueue(3);
        qqu.Enqueue(5);

        if (qqu.Count != 0)// 아무것도 없을때 에러가 나지 않게 if를 넣어준다.
            print(qqu.Dequeue());
        if (qqu.Count != 0)
            print(qqu.Dequeue());
        if (qqu.Count != 0) 
            print(qqu.Dequeue());
    }

 

Stack= 순서대로 값을 넣고 반대순서대로 값을 없앨때 사용된다.(젠가는 위로 쌓아서 위에서 부터 제거한다.)

    Stack<int> SST = new Stack<int>();

    void Start()
    {
        SST.Push(1);
        SST.Push(7);
        SST.Push(3);


        print(SST.Pop());
        print(SST.Pop());
        print(SST.Pop());

    }

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

물체를 회전하고 상하 반복움직임.  (0) 2020.12.11
텍스쳐 애니메이션 타일셋  (0) 2020.12.11
텍스쳐를 자동으로 설정해봅시다.  (0) 2020.12.06
유니티의 Object 이해  (0) 2020.12.06
Scene 재시작  (0) 2020.11.21

뷰포트 그대로 렌더링한다기 보다는 유사하게 렌더링한다는게 맞을거 같습니다.

 

 

아래는 화면 캡쳐입니다.

이 개념을 이해하는데 많은 시간이 소요되었네요.

 

우선 개념을 잡아보자면, 벡터는 방향과 길이를 말하는것이고, 스칼라는 양을 나타냅니다.

 

A가 0cm에서 5cm로 간다고 생각하면 이것은 벡터입니다.

B가 4cm에서 9cm로 간다면 이것도 벡터입니다.

그리고 A와 B는 둘다 같은 벡터입니다.

A, B 둘다 같은 벡터입니다.

벡터는 사실 시작점이 어디인지는 중요하지 않습니다. 거리와 방향만 중요할 뿐입니다.

하지만 C가 0cm에서 -5cm로 간다면 이건 A와 B랑은 다릅니다. 이유는 C의 방향은 반대이기 때문입니다.

A = B C

어찌되었건 A,B,C 모두 벡터입니다.

서로 다른 벡터입니다.

 

스칼라는 양인데,

A의 크기가 5cm라면 A=5cm 입니다.

A도 시작위치는 중요하지 않습니다. A의 방향도 중요하지 않습니다. 다만, A=5cm 입니다.

그래서 스칼라는 마이너스라는 개념이 없습니다. 오로지 크기 또는 거리 또는 양 만을 나타내기 때문입니다.

 

그래서 vector는 +, - 가 존재하고, scalar는 +만 존재합니다.

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

SpecularShader  (0) 2020.12.19
diffuseShader  (0) 2020.12.15
좌표공간 변환  (0) 2020.12.12
내적(dot)  (0) 2020.12.12
UnlitShader  (0) 2020.12.11
using UnityEngine;
using UnityEditor;



public class TexturePostProcessor : AssetPostprocessor

{

	void OnPostprocessTexture(Texture2D texture)

	{

		TextureImporter importer = assetImporter as TextureImporter;

		importer.textureType = TextureImporterType.Default;

		importer.anisoLevel = 1;

		importer.filterMode = FilterMode.Bilinear;

		importer.mipmapEnabled = false; // 밉맵설정

		importer.maxTextureSize = 1024; // 텍스쳐 사이즈 설정
		
		var textureImporter = assetImporter as TextureImporter;
		textureImporter.SetPlatformTextureSettings(new TextureImporterPlatformSettings
		{
			overridden = true,//탭킨다.
			name = "Standalone",//PC설정
			maxTextureSize=1024,//사이즈설정
			format = TextureImporterFormat.DXT1Crunched //포멧설정
        });


	}

	}

}

참고: 두나미스 테크니컬 아트 & 애니메이터 (Tech Art / Anim)

도움주신분들: 핑속님,성국님.

 

 

https://docs.unity3d.com/ScriptReference/TextureFormat.html

 

Unity - Scripting API: TextureFormat

Success! Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable. Close

docs.unity3d.com

 

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

텍스쳐 애니메이션 타일셋  (0) 2020.12.11
C# 기초 기억창고2  (0) 2020.12.11
유니티의 Object 이해  (0) 2020.12.06
Scene 재시작  (0) 2020.11.21
캐릭터 랜덤 모션  (0) 2020.11.02

- 스크립트 안에서 gameObject는 '나자신=해당Object 자신'이고 GameObject는 '다른 Object' 이다?

- 유니티에서 대문자로 시작되는 것들은 Class로 생각하면...

- 같은이름인데 소문자의 경우 클래스의 인스턴스라고 생각하면..

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

C# 기초 기억창고2  (0) 2020.12.11
텍스쳐를 자동으로 설정해봅시다.  (0) 2020.12.06
Scene 재시작  (0) 2020.11.21
캐릭터 랜덤 모션  (0) 2020.11.02
EditorWindow  (0) 2020.10.30
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class restart : MonoBehaviour
{
    void Update()
    {
        if (Input.GetKey(KeyCode.Space))
        {
            SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
        }
    }
}

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

텍스쳐를 자동으로 설정해봅시다.  (0) 2020.12.06
유니티의 Object 이해  (0) 2020.12.06
캐릭터 랜덤 모션  (0) 2020.11.02
EditorWindow  (0) 2020.10.30
간단한 애니메이션 스크립트  (0) 2020.09.08

앞뒤로 물체가 반복 이동하게 된다.
좀더 쉬운 방법

 

깃발처럼 물결이 친다.
유사하지만 다른방법

learn.unity.com/tutorial/visual-effects-shadergraph-2019-3?uv=2019.1&projectId=5d0a4b59edbc2a001fe52445#5efcff47edbc2a004d2e7c6b

 

Visual Effects: Shadergraph (+2019.3) - Recorded Learn Live Session - Unity Learn

Watch the recording of the Learn Live virtual session where a Unity Certified Instructor led learners through a series of mini-challenges to make a flag wave utilizing the Time, Sine and UV nodes to give the flag a wave effect. Throughout the session you w

learn.unity.com

 

'Unity > Shader Graph & Amplify' 카테고리의 다른 글

갈라짐 연출하기  (0) 2021.03.18
Shader graph 팁  (0) 2020.12.19
Amplify Shader 주요 기능  (0) 2020.11.04
툰 쉐이더 Amplify shader set  (0) 2020.11.02
Shader graph-input03  (0) 2020.07.12

 

이놈에 기억력이란...

 

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

플렛폼별 Texutre 설정  (0) 2020.12.11
Unity Mask  (0) 2020.12.11
유니티 빌드옵션 Compression Method  (0) 2020.11.11
Memory Profiler  (0) 2020.11.10
코딩을 도와주는 비쥬얼스크립트  (0) 2020.11.10

이 방법은 제가 작업하면서 우연히 알아낸 방법입니다. (어딘가 있을거 같긴하지만, 본적이 없으므로...)

일반적으로 인터넷에 있는 Render to texture 방식을 이용하면 뭔가 음영이 명확하게 텍스쳐에 안뽑히곤합니다.

도타 가이드(support.steampowered.com/kb/8700-SJKN-4322/dota-2-character-texture-guide)를 보고 해도...

그렇게 만족스러운 텍스쳐가 뽑아지지 않았었습니다.(약간 흐릿하다고 할까요?)

그러던중, 섭스턴스 페인터를 사용하다보니, World space normal이라는 노멀을 알게되면서 작업 방식에 큰 변화가 왔었습니다.

그래서, 아래 내용을 공유해봅니다.

 

1. 하이폴과 로우폴리곤 물체가 있습니다.

2. 섭스턴스 페인터에서 베이킹을 합니다.

3. 베이킹된 결과물을 텍스쳐로 뽑아냅니다.

   이때 중요한것은!!! 바로 World space normal을 뽑아야 한다는 것입니다.

4. 결과를 보듯이 자연스럽게 위에서 아래로 빛을 받은 형태의 그림자가 명확하게 생성되는것을 볼수 있습니다.

   R은 좌에서 우로 방향으로 빛이 들어온것이고, G는 위에서 아래로 빛방향이 , B는 정면에서 빛이 들어온것입니다.

  이것을 적절히 잘 섞으면 뚜렷한 음영을 뽑아낼수 있습니다.

아래는 일반 노멀입니다.

5.  오른쪽의 음영이 뚜렷하고 자연스럽게 텍스쳐링 된것을 알수가 있습니다.

 

이것만 봐서는 잘 모를수 있지만 캐릭터를 뽑아보면 꽤 이쁘게 뽑힌것을 확인할수 있습니다.

옵션선택은 Default / LZ4 / LZ4HC 이렇게 3가지가 존재한다.

2019.2까지는 Default로 선택되어있었는데,

 

Default(ZIP) : 기본값

LZ4 : 빌드 속도 빠름. 개발빌드 때 적합함.

LZ4HC : 빌드는 느린데, 로딩이 빨라짐. 최종빌드에 적합함.

 

출처: mentum.tistory.com/366

 

 

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

Unity Mask  (0) 2020.12.11
볼때마다 잊어버리는 조명설정..  (0) 2020.11.18
Memory Profiler  (0) 2020.11.10
코딩을 도와주는 비쥬얼스크립트  (0) 2020.11.10
복사 오브젝트와 Attach 오브젝트의 포퍼먼스 차이  (0) 2020.09.29

Unode입니다.

플레이메이커를 사용하면서 매번 느끼는것은 도데체 내가 짠 로직이 코드로는 어떻게 되는가 라는것이었습니다.

볼트는 사용하려했지만... 코딩에 가깝다는데...그래도 코드를 볼수 없다는게... 그다지 매력적이지 않았습니다.

그냥 플레이메이커에 비해 코딩에 가깝다는것이지..어차피 코드는 아니니깐..

코드를 모르는 상태로 짠다는게 약간 불안함도 있고.. 그러던중 볼트와 플레이메이커에 대해서 싸우던 해외개발자들중에

한사람이 글이 들어왔습니다. "unode를 사용해라... 그럼 코드에 대해서 알게될것이다."

그래서 다운받았습니다... 디스코드에서 개발자가 질문에 대답도 잘해주고 앞으로 기대되는 스크립트입니다.

(사실 가장 큰 이유는...코딩이 힘들어요..ㅠㅠ 별것도 아닌것에 맨날 오타나고...오류나고..ㅜㅜ)

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

유니티 빌드옵션 Compression Method  (0) 2020.11.11
Memory Profiler  (0) 2020.11.10
복사 오브젝트와 Attach 오브젝트의 포퍼먼스 차이  (0) 2020.09.29
유니티 패키지에 대한 정보는  (0) 2020.09.08
dynamic bone test  (0) 2020.08.21
Shader "Custom/fake_reflection"
{
	Properties
	{
	_MainTex("Albedo (RGB)", 2D) = "white" {}
	_NormalMap("NormalMap", 2D) = "bump" {}
	_reflect("reflect", Range(-1,1)) = 0.9
	_CubeMap("CubeMap", cube) = "" {}
	}
		SubShader
	{
		Tags{ "RenderType" = "Opaque" }

		CGPROGRAM
#pragma surface surf Lambert 
#pragma target 3.0

		sampler2D _MainTex, _NormalMap;
		samplerCUBE _CubeMap;
		float _reflect;

	struct Input
	{
		float2 uv_MainTex, uv_NormalMap;
		float3 worldRefl;
		INTERNAL_DATA
	};

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

		o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_NormalMap));

		o.Albedo = c.rgb;
		o.Emission = texCUBE(_CubeMap, WorldReflectionVector(IN, o.Normal))*_reflect;

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

큐브맵이 있어야 작동한다.

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

적을 나타내는 아웃라인  (0) 2020.12.19
가벼운 툰 셰이더  (0) 2020.12.16
기본적인 일반텍스쳐+노멀+아웃라인 적용 쉐이더  (0) 2020.10.06
Alpha  (0) 2020.05.24
RampTexture  (0) 2020.05.21
macroScript TestUvw
category:"RHY"
buttontext:"TestUvw"
toolTip:"TestUvw v1.0"

(
try(destroyDialog TestUvw)catch()
rollout TestUvw  " <TestUvw> " width:162 height:300

(
button bt1 "    UVW190   "
button bt2 "   UVW200   "

	on bt1 pressed do 
		(
		modPanel.addModToSelection (Uvwmap ()) ui:on
		$.modifiers[#UVW_Map].length = 190
		$.modifiers[#UVW_Map].width = 190
		$.modifiers[#UVW_Map].axis = 1
			)
			
	on bt2 pressed do 
		(
		modPanel.addModToSelection (Uvwmap ()) ui:on
		$.modifiers[#UVW_Map].length = 200
		$.modifiers[#UVW_Map].width = 200
		$.modifiers[#UVW_Map].axis = 1
			)	
		)
	createdialog TestUvw

)

스크립트라기보다는 매크로입니다. (개인적으로 꼭 필요한 기능인데...왜 이런게 없는지..)

물체를 정면으로 펼쳐주는겁뉘다.

 

 

 

 

Clamp와 Saturate는 비슷한 기능이나 숫자를 넣고 안넣고의 차이가 있습니다.

Clamp는 노멀이나 컬러가 곱해지거나 더해질때 특정 값( min, max 주로 0과 1)을 넣어서 넘어가지 않게 설정하는것입니다.

즉, 1+1= 2가 되는것을 1로 제한하는것입니다. 숫자가 낮아지거나 밝아지면 점점 검은색이나 힌색으로 변하는것을 방지한다고 생각하면 됩니다.

 

 

UV좌표를 참조하여 타일링이나 U나 V좌표를 가지고 조작이 가능합니다.

 

 

3D상에 좌표 XYZ를 가져와서 오브젝트의 형태와 관계없이 월드좌표로 조작이 되도록 합니다.

위에서 아래로 오브젝트를 나누거나, 좌우에서 우로 오브젝트를 나누는것이 가능합니다.

 

 

Scale은 텍스쳐를 곱할때 사용된다. 일종에 multiply 기능이라고 생각하면되는데 약간은 다릅니다.

Negate는 Scale를 뒤집을수 있다.(one minus랑 비슷한거 같습니다.)

 

Sign의 기능은 노멀값(컬러?)을 중간값없이 -1,0,1로 끊어주는 기능입니다.

 

 

세기능의 차이점 입니다.(상자 위치는 0,0,0입니다.Abs만 약간 치우쳤군요.)

Sign은 -1,0,1로 나뉘어서 출력되는 것 입니다.( 그이하나 이상이 안된다고 생각하면됩니다.)

Relay는 -1에서 1 사이에서 출력되는 것 입니다.( 그이하나 이상이 안된다고 생각하면됩니다.)

Abs는 0 에서 1 사이가 출력되는 것 입니다.( 그이하나 이상이 안된다고 생각하면됩니다.)

 

'Unity > Shader Graph & Amplify' 카테고리의 다른 글

Shader graph 팁  (0) 2020.12.19
sign값을 이용한 포지션 이동  (0) 2020.11.18
툰 쉐이더 Amplify shader set  (0) 2020.11.02
Shader graph-input03  (0) 2020.07.12
Shader graph-input02  (0) 2020.06.29