일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
29 | 30 | 31 |
- c# 윈폼
- 도커
- 포인터
- 유니티
- 깃
- docker
- HTML
- gitlab
- 플러터
- c언어
- dart 언어
- c# winform
- github
- C++
- jupyter lab
- c#
- Unity
- 구조체
- 다트 언어
- c# 추상 클래스
- Flutter
- Houdini
- Algorithm
- jupyter
- vim
- C# delegate
- C언어 포인터
- git
- Python
- Data Structure
- Today
- Total
목록CG/Unity (16)
nomad-programmer
다른 오브젝트에 잇는 스크립트의 변수를 변경하거나 함수를 호출하는 방법을 알아보자. 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() 함수보다 한박자 빠르다.
일반적인 메쉬 오브젝트라면 3D 프로그램에서 UV를 다시 펴서 import 하는 것으로 늘어난 텍스처를 해결할 수 있다. 하지만 예를 들어 게임에서 실시간으로 높은 지형이 튀어 올라오는 기능을 가지고 있다고 생각해보자. 혹은 눈발을 헤치고 지나가면서, 실시간으로 눈이 파이는 효과를 만들어야 한다고 생각해 보자. 그렇다면 미리 옆면에 대응되는 UV를 만들어 놓을 수가 없다. 그러면서도 옆면에는 세로로 주욱 늘어나지 않은, 제대로 된 텍스처가 입혀지도록 만들고 싶다고 생각해보자. UV가 따로 필요 없으면서 어디라도 텍스쳐가 늘어나지 않고 제대로 입혀지는 기능이 Triplanar이다. 이 기술의 핵심은 World Position을 UV로 사용하는 것이다. Shader "Custom/Triplanar" { Pr..
굴절 효과를 적절하게 사용하면 아주 멋진 효과를 낼 수 있다. 유리나 물에도 응용할 수 있다. 일반적으로 이 효과를 만들 때 프레그먼트 셰이더를 사용한다만 서피스 셰이더로도 만들 수 있다. 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..
Matcap이란 Material Capture의 준말로, Ramp Texture와 비슷하게 이미지로 조명을 대신하는 방식 중 하나이다. Matcap은 라이트의 영향을 최소화해야 하는 모바일 게임에서 최적화를 위해 자주 사용되는 '가짜' 라이팅 방식이며, ViewDir을 기반으로 하므로 카메라를 회전하지 않는 상황에서 좋은 효과를 볼 수 있는 기능이다. 이 방식을 사용하면 라이트를 '전혀 사용하지 않고'도 조명을 받은 것 같은 효과를 낼 수 있다. Shader "Custom/matcap" { Properties { _MainTex ("Albedo (RGB)", 2D) = "white" {} _Matcap ("Matcap", 2D) = "white" {} } SubShader { Tags { "RenderT..
게임에서 몬스터가 죽을 때, 마치 타들어 가면서 재가 되는 느낌으로 사라지는 장면을 볼 수 있다. 타 들어가면서 흩날리는 재는 파티클로 처리하더라도, 실제 타들어 가는 셰이더를 만들어보자. 타들어 가며 사라져야 하므로, 알파가 적용되어야 한다. 알파 블랜딩이 가동되도록 만들고, 노이즈 텍스처를 받아서 알파로 사용할 수 있도록 해야 한다. 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) _..
알파 블랜딩을 사용하면 반대쪽 팔이 안으로 들어오고, 앞뒤 판정이 이상해지면서 좋지 않은 결과를 얻는다. 이것을 해결하는 방법 중 하나는 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 (_..
기본적으로 게임의 오브젝트들을 그리는 순서는 정해져 있지 않고, 오브젝트가 그려질 때마다 z 버퍼를 참고로 앞뒤 판정을 한 후 그려질 픽셀과 안 그려질 픽셀을 결정한다. 게임이 시작되면 매 프레임마다 배경이나 캐릭터, 이펙트, UI들이 모두 그려지는 과정을 거치게 된다. 모든 것이 매 프레이마다 특정한 경로(Pipeline)를 따라서 재계산되고 화면에 그려지면서 한 프레임의 화면이 완성되는 것이다. 그렇다면 무엇인 가장 먼저 그려질까? 원론적으로 말하자면, 그리는 순서는 상당히 제멋대로라서 예측하기가 어렵다. 물론 특정한 명령이나 그룹핑에 따라 그리는 순서가 조정될 수 있지만, 기본적으로는 '계산이 끝난 것이 먼저 그려진다' 라는 원칙으로 그려지고 있으니 어떤 것이 먼저 그려질지 알 수 가 없는 것이다...
Shader "Custom/Reflection" { Properties { _MainTex ("Albedo (RGB)", 2D) = "white" {} _Cube ("Cubemap", Cube) = ""{} } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Lambert noambient #pragma target 3.0 sampler2D _MainTex; samplerCUBE _Cube; struct Input { float2 uv_MainTex; float3 worldRefl; }; void surf (Input IN, inout SurfaceOutput o) { fixed4 c = tex2D (_Ma..
Warped Diffuse 기법은 가볍고도 응용이 편리해서 지금도 많이 사용되는 기법이다. 이 기법의 핵심 구현 기법은 빛 계산으로 쓰는 공식인 노멀과 라이트 벡터의 내적을 UV로 이용한다는 것이다. Shader "Custom/NewSurfaceShader" { Properties { _MainTex ("Albedo (RGB)", 2D) = "white" {} _RampTex ("RampTex", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Warp noambient #pragma target 3.0 sampler2D _MainTex; sampler2D _RampTex;..
Shader "Custom/NewSurfaceShader" { Properties { _MainTex ("Albedo (RGB)", 2D) = "white" {} _BumpMap ("NormalMap", 2D) = "bump" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Toon Lambert #pragma target 3.0 sampler2D _MainTex; sampler2D _BumpMap; struct Input { float2 uv_MainTex; float2 uv_BumpMap; }; void surf (Input IN, inout SurfaceOutput o) { fixed4 c =..
CGPROGRAM #pragma suface surf Lambert vertex:vert void vert(inout appdata_full v){ // y축으로 1m 만큼 이동 v.vertex.y += 1; } vertex:vert로 버텍스 셰이더가 vert라는 함수 이름으로 시작된다는 것을 #pragma에서 알려주고, void로 시작하는 vert이름의 함수를 만든다. appdata_full이 보인다. 이것은 surf 함수에서 사용했떤 SurfaceOutputStandard처럼, UnityCG.cginc 파일 안에 미리 선언되어 있는 특정한 구조체이다. 이 구조체는 버텍스가 가지고 있는 정보를 구조체로 만든 것이며, 이 구조체를 메뉴얼에서 찾아보면 다음과 같이 설명하고 있다. appdata_base: ..
Shader "Custom/NewSurfaceShader" { Properties { _MainTex ("Albedo (RGB)", 2D) = "white" {} _BumpMap ("Bump Map", 2D) = "bump" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Test #pragma target 3.0 sampler2D _MainTex; sampler2D _BumpMap; struct Input { float2 uv_MainTex; float2 uv_BumpMap; }; void surf (Input IN, inout SurfaceOutput o) { fixed4 c = tex2D (_..
라이팅을 커스터마이징하게 만들 수 있다. #pragma surface surf Test noambient 라이팅 이름을 Test로 지정하였다. 이름은 마음대로 지어도 상관 없다. 대신 이름에 적합한 라이팅 함수를 추가해주어야 한다. float4 LightingTest(SurfaceOutput s, float3 lightDir, float atten) { return float4(1, 0, 0, 1); } 이 함수는 무엇을 하든지 붉은 결과물을 출력하는 기능을 가진 함수이다. 또한 이어서 나오는 이름에 주의해야 한다. 저자가 설정한 커스텀 라이트 이름은 "Test" 였다. 그래서 앞에 "Lighting" 이란 이름을 추가해야 라이트 함수로 받아들인다. Lighting + (커스텀 라이트 이름) 따라서, 커..
유니티 셰이더는 ShaderLab이라고 불리는 자체 스크립트 언어를 이용하고 있다. 스크립트는 일반적인 코딩과 약간 다른 방식으로 작성되며 문법도 약간 다르다. 굳이 이렇게 스크립트로 제작된 이유는 유니티의 특성과 사용자의 편의성 때문이다. 유니티는 멀티 플랫폼 제작이 자동으로 지원되는 엔진이다. 즉, 모바일이나 pc, 콘솔기기에 따라 제작되는 셰이더가 달라야 한다. 또한 셰이더는 글미자가 있을 때와 없을 때, 라이트맵이 있을 때와 없을 때 등 여러 가지 경우의 수에 따라 제작방법이 다르다. 다양한 경우의 수를 사용자가 제각각 작성하고 관리한다면 상당한 무리가 따를 수밖에 없다. 그래서 만들어진 유니티 내부의 셰이더 스크립트가 ShderLab이다. 이 스크립트를 사용하면 다양한 경우의 셰이더 분기를 자동..