일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 포인터
- C# delegate
- C++
- c#
- Python
- c언어
- docker
- c# 추상 클래스
- c# winform
- gitlab
- jupyter lab
- Data Structure
- Algorithm
- c# 윈폼
- 플러터
- jupyter
- dart 언어
- github
- vim
- Flutter
- 유니티
- Unity
- 도커
- 깃
- C언어 포인터
- HTML
- 다트 언어
- git
- 구조체
- Houdini
- Today
- Total
목록전체 글 (507)
nomad-programmer
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/djusiL/btrVAMfcx1Z/deS50lnFURexKiIC9FfU2K/img.png)
바탕화면 설정 시에 '16비트(트루컬러)'라는 용어를 접해봤을 것이다. 16비트 컬러의 의미는 점 하나를 표시하는데 16비트를 사용한다는 뜻이다. 즉, 16비트가 표현할 수 있는 상태의 수 만큼이나 다양한 색상을 표현할 수 있다는 의미이다. 컴퓨터 상에서 색상을 표현할 때는 보통 빛의 3요소인 빨강(Red), 초록(Green), 파랑(Blue), 즉 RGB를 기본 원소로 사용한다. 이 R, G, B 각각의 밝기에 따라서 여러 가지 색깔이 만들어지는 것이다. 16비트 컬러의 경우에는 이 R, G, B 각각의 밝기가 16비트 안에 모두 포함되어야 한다. 그래서 R, G, B가 보통 5비트, 6비트, 5비트씩 할당된다 (각각 5비트씩 할당하고 1비트는 쓰지 않는 경우도 있다). 그래서 R과 B는 2의5승 단계..
#include #include using namespace std; int main() { char c = 1; short int si = 2; int i = 4; cout
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/kESkM/btrVzYzX0ko/nrgPbXKAQNbVmKgWRYKNPk/img.png)
나는 무엇인가를 학습할 때, 무작정 하기보다는 시간 별로 기록하면서 학습을 진행한다. 이렇게 하였을 때 장점으로는 잉여 시간을 확실하게 줄일 수 있다. 30분동안의 나의 행동을 점수로 매겨 해당 점수를 준 이유와 보완할 것을 기록한다. 그런데... 5점을 주는 경우가 별로 없다... 아주 간혹 있다... 아주 간혹. 이렇게 내가 무엇을 했는지 기록하여 본다면, 내가 학습할 대상에 더욱 집중하게 된다. 그리고 1시간 단위가 아닌 30분 단위로 한 이유는 조금 더 세세하게 기록하기 위함도 있고 1시간 동안 오직 한 가지 학습에 집중할 수가 없기 때문이다. 인간이 집중할 수 있는 시간은 15분이라고 알고 있다. 따라서 15분 단위로 기록하면 더욱 좋다. 하지만 나는 30분 단위로 하였다. 칸 수가 너무 많아져..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/dZgHyh/btrUuHGnleg/WvHn3UIXT6dyunKLknz930/img.png)
다른 오브젝트에 잇는 스크립트의 변수를 변경하거나 함수를 호출하는 방법을 알아보자. GetComponent 함수를 사용하는 방법과 Singleton 기법을 사용하는 방법이 있다. 2개의 오브젝트 obj1, boj2를 만들고 obj1에는 TextScript1.cs 스크립트를 컴포넌트로 추가하고 obj2에는 TextScript2.cs 스크립트를 컴포넌트로 추가할 것이다. 그리고 TextScript1.cs 스크립트 안에서 obj2의 컴포넌트인 TextScript2.cs 스크립트의 변수를 변경하고 함수를 호출하겠다. GetComponent 함수 사용하기 TextScript1 스크립트를 드래그하여 Hierarchy 뷰에 있는 obj1 오브젝트에 놓는다. 마찬가지로 TextScript2 스크립트를 드래그하여 Hie..
유니티 관련 자세한 설명은 역시 유니티 공식 문서를 보는 것이 최고. https://docs.unity3d.com/kr/530/Manual/ExecutionOrder.html 이벤트 함수 실행 순서(Execution Order of Event Functions) - Unity 매뉴얼 Unity 이벤트 함수는 사전에 정해진 순서대로 실행됩니다. 실행 순서는 다음과 같습니다. docs.unity3d.com 간략하게 설명하자면... 게임이 시작될 때, 초기화해야 하는 것들을 이곳에 넣으면 된다. Start() 함수와의 차이점은 게임이 실행될 때, 단 한번 실행되는 것은 두 함수 모두 같은데 Awake() 함수가 Start() 함수보다 한박자 빠르다.
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/zeFAO/btrvMH42ckr/0UvDNc6OlBsUJiSH5W5my0/img.png)
일반적인 메쉬 오브젝트라면 3D 프로그램에서 UV를 다시 펴서 import 하는 것으로 늘어난 텍스처를 해결할 수 있다. 하지만 예를 들어 게임에서 실시간으로 높은 지형이 튀어 올라오는 기능을 가지고 있다고 생각해보자. 혹은 눈발을 헤치고 지나가면서, 실시간으로 눈이 파이는 효과를 만들어야 한다고 생각해 보자. 그렇다면 미리 옆면에 대응되는 UV를 만들어 놓을 수가 없다. 그러면서도 옆면에는 세로로 주욱 늘어나지 않은, 제대로 된 텍스처가 입혀지도록 만들고 싶다고 생각해보자. UV가 따로 필요 없으면서 어디라도 텍스쳐가 늘어나지 않고 제대로 입혀지는 기능이 Triplanar이다. 이 기술의 핵심은 World Position을 UV로 사용하는 것이다. Shader "Custom/Triplanar" { Pr..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/b2YSU3/btrvS7Oa8Bz/C3L6krR3lV71A4jyVTE1nk/img.png)
굴절 효과를 적절하게 사용하면 아주 멋진 효과를 낼 수 있다. 유리나 물에도 응용할 수 있다. 일반적으로 이 효과를 만들 때 프레그먼트 셰이더를 사용한다만 서피스 셰이더로도 만들 수 있다. Shader "Custom/Refraction" { Properties { _MainTex ("Albedo (RGB)", 2D) = "white" {} _RefStrength("Refraction Strength", Range(0, 0.1)) = 0.05 } SubShader { Tags { "RenderType"="Transparent" "Queue"="Transparent"} zwrite off GrabPass{} CGPROGRAM #pragma surface surf nolight noambient alpha:f..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/qdxfx/btrtRXG2WNj/0WbJFqzttVWBiUJbD7FwwK/img.png)
Matcap이란 Material Capture의 준말로, Ramp Texture와 비슷하게 이미지로 조명을 대신하는 방식 중 하나이다. Matcap은 라이트의 영향을 최소화해야 하는 모바일 게임에서 최적화를 위해 자주 사용되는 '가짜' 라이팅 방식이며, ViewDir을 기반으로 하므로 카메라를 회전하지 않는 상황에서 좋은 효과를 볼 수 있는 기능이다. 이 방식을 사용하면 라이트를 '전혀 사용하지 않고'도 조명을 받은 것 같은 효과를 낼 수 있다. Shader "Custom/matcap" { Properties { _MainTex ("Albedo (RGB)", 2D) = "white" {} _Matcap ("Matcap", 2D) = "white" {} } SubShader { Tags { "RenderT..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/tKVqI/btrshy3O4ic/o2VoCokwuWqYEkfqlkriE1/img.gif)
게임에서 몬스터가 죽을 때, 마치 타들어 가면서 재가 되는 느낌으로 사라지는 장면을 볼 수 있다. 타 들어가면서 흩날리는 재는 파티클로 처리하더라도, 실제 타들어 가는 셰이더를 만들어보자. 타들어 가며 사라져야 하므로, 알파가 적용되어야 한다. 알파 블랜딩이 가동되도록 만들고, 노이즈 텍스처를 받아서 알파로 사용할 수 있도록 해야 한다. Shader "Custom/Alpha2Pass" { Properties { _MainTex ("Albedo (RGB)", 2D) = "white" {} _NoiseTex ("NoiseTes", 2D) = "white" {} _Cut("Alpha Cut", Range(0, 1)) = 0 [HDR]_OutColor ("OutColor", Color) = (1,1,1,1) _..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/cJ4ZeE/btrseQqlccd/tkmoySKUHP4OTZC6i8heAK/img.png)
알파 블랜딩을 사용하면 반대쪽 팔이 안으로 들어오고, 앞뒤 판정이 이상해지면서 좋지 않은 결과를 얻는다. 이것을 해결하는 방법 중 하나는 2Pass를 이용하는 것이다. 원리는 간단하다. 첫 번째 패스는 z 버퍼에는 그리되 화면에는 그리지 않는 것이다. 즉, z 버퍼에만 그리는 패스를 만든다. 이 코드는 모든 variants를 최소한으로 줄이고, 최대한 계산을 줄여서 만든 셰이더이다. ColorMask 0 명령은 화면에 이 셰이더의 결과물을 보이지 않도록 만든다. 아예 투명으로 만들어도 된다만, fog 등 예상치 못한 외부의 결과물에 대한 대비책이다. 그리고 두 번째 패스에서 z 버퍼를 쓰지 않고 그린다. 평범한 반투명이다. 그러면 이미 존재하던 z 버퍼에 가려진 부분은 그려지지 않게 될테니 깨끗한 반투명..
Shader "Custom/AlphaBlend" { Properties { _MainTex ("Albedo (RGB)", 2D) = "white" {} } SubShader { Tags { "RenderType"="Transparent" "Queue"="Transparent" } zwrite off blend SrcAlpha OneMinusSrcAlpha LOD 200 CGPROGRAM #pragma surface surf Lambert keepalpha #pragma target 3.0 sampler2D _MainTex; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { fixed4 c = tex2D (_..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/0MnxQ/btrr2T2nyTc/LHFRXUFUleOrEzucHd2gN0/img.png)
기본적으로 게임의 오브젝트들을 그리는 순서는 정해져 있지 않고, 오브젝트가 그려질 때마다 z 버퍼를 참고로 앞뒤 판정을 한 후 그려질 픽셀과 안 그려질 픽셀을 결정한다. 게임이 시작되면 매 프레임마다 배경이나 캐릭터, 이펙트, UI들이 모두 그려지는 과정을 거치게 된다. 모든 것이 매 프레이마다 특정한 경로(Pipeline)를 따라서 재계산되고 화면에 그려지면서 한 프레임의 화면이 완성되는 것이다. 그렇다면 무엇인 가장 먼저 그려질까? 원론적으로 말하자면, 그리는 순서는 상당히 제멋대로라서 예측하기가 어렵다. 물론 특정한 명령이나 그룹핑에 따라 그리는 순서가 조정될 수 있지만, 기본적으로는 '계산이 끝난 것이 먼저 그려진다' 라는 원칙으로 그려지고 있으니 어떤 것이 먼저 그려질지 알 수 가 없는 것이다...