http://game-icons.net/


jsp 관련 문서를 작성하는데 word에서는 자꾸만 'j네' 또는 'J네'로 변경이 된다.


[파일] - [옵션]을 선택한다.



[언어 교정] - [자동 고침 옵션]을 선택한다.



입력 창과 결과 창에 값을 입력하면 된다.


http://Render-Crowd-Of-Animated-Characters-master


애니메이션을 가진 캐릭터의 Mesh를 이용하여 해당 애니메이션에 맞는 Anim Map을 생성해준다.


이를 이용하면 Shader에서 Mesh의 각 Vertex 부분을 이동시킨 것과 같은 모양으로 렌더링을 해준다.


실제로 Mesh의 모양을 변형하는 것이 아니다.


gpu instancing을 사용하여 draw call을 줄여준다고 한다.


써보면 되게 매력적이다.


http://orcacode.tistory.com/entry/Unity-Android-Bluetooth-플러그인과-원리


남는 학점 채우려고 했던 과목이었지만 재밌었다.


아이디어도 중요하지만 섬세함이 많이 필요한 것이 디자인이라는 생각이 많이 들었다.


지금보면 어딘가 부족해보이는 부분은 내가 섬세함이 부족했기 때문이라는 생각이 든다.



주제 : 홍보물 제작


캡콤, SEED9, CJ >> 마계촌 온라인 포스터의 밑부분을 활용한 것 같다. 지금은 망했다.


주변에 둥실둥실 떠다니는 아이콘과 부처 뒤의 나무가 조금 아쉽다


색감 보정에 대한 강의 후에 만든 과제였을 것이다.



주제 : 전자제품 홍보


예전부터 나는 엑스페리아 시리즈가 좋았다. 


아이폰은 4부터 5S까지의 각진 디자인이 좋았고 엑스페리아는 언제나 각진 디자인이라 좋았다.


XZ2가 곡면 디자인을 넣었으니 성능 안좋고 디자인도 못생긴 폰이 되어버렸다.



과제 주제 : 브랜드의 크리스마스 이미지 만들기


안드로이드 마스코트는 다양한 이미지가 있어서 사용하기 좋다.



주제 : 스마트폰 특정 브랜드의 위젯, 인터페이스 및 잠금화면 제작.


iOS는 해볼 수 없는 커스텀 인터페이스다. 이래서 안드로이드가 좋다.


안드로이드의 Smart Launcher를 대학교 입학할 때 구매한 이후로 지금까지 사용하고 있다.


https://play.google.com/store/apps/details?id=ginlemon.flowerpro


간략하면서 보기 좋은 UI가 매력적이다.


PSP의 XMB도 폰으로 쓰기에 괜찮다고 생각한다. 


옆으로 넘기고 위아래로 넘기고.. 나중에 만들어보고 싶다. 



주제 : 모바일 게임 및 UI 디자인


이런 디자인의 게임이면 망할 것이다..



주제 : 캐릭터를 활용한 포스터


반창고 부분은 이름이 들어간 부분이다.


지금보니 되게 성의없어 보인다.



주제 : 캐릭터와 패스를 활용한 디자인


왜 햄토리 였을까?



주제 : 픽셀아트와 손글씨를 이용한 포스터 디자인


SHURE SRH840을 막 샀을 때라 헤드폰에 관심이 좀 있었던 것 같다.




지금보니 뒤로 갈수록 점점 성의없어 보인다.

'호랑이 담배피던 시절에' 카테고리의 다른 글

포트폴리오(취업 이전)  (0) 2021.06.10
2017.02.18.  (0) 2019.02.18
2011.04.04.  (0) 2018.03.26
[Prezi] CG를 꿈꾸다  (0) 2018.03.26

참고 : https://forum.unity.com/threads/shadow-catcher-or-matte-shadow-shader.414418/


홀로렌즈는 MR 컨텐츠를 즐기기 위한 장비이다.


현실 공간에 가상의 오브젝트를 띄우는데, 그림자가 보이지 않는다면 이질감을 주게 된다.


위의 참고 글을 보면 다음과 같은 소스 코드가 있다.



Shader "Unlit/VertColorWithShadow"
{
    Properties
    {
        _MainColor("Main Color", COLOR) = (0,0,0,1)
        _ShadowColor("Shadow Color", COLOR) = (1,0,0,1)
    }
 
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100
 
        Pass
        {
            Tags {"LightMode" = "ForwardBase"}
 
            CGPROGRAM
            #pragma multi_compile_fwdbase
            #pragma vertex vert
            #pragma fragment frag
 
            #include "UnityCG.cginc"
            #include "AutoLight.cginc"
 
            float4 _MainColor;
            float4 _ShadowColor;
 
            struct appdata
            {
                float4 vertex : POSITION;
            };
 
            struct v2f
            {
                float4 pos : SV_POSITION;
                float4 mainColor : COLOR;
                LIGHTING_COORDS(1,2)
            };
         
            v2f vert (appdata v)
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                o.mainColor = _MainColor;
 
                TRANSFER_VERTEX_TO_FRAGMENT(o);
 
                return o;
            }
         
            fixed4 frag (v2f i) : SV_Target
            {
                fixed atten = 1.0 - LIGHT_ATTENUATION(i);
                fixed3 shadowColor = atten * _ShadowColor.rgb;
                fixed4 finalColor = i.mainColor + fixed4(shadowColor, 1.0);
 
                return finalColor;
            }
            ENDCG
        }
 
        // Pass to render object as a shadow caster
        Pass
        {
            Name "ShadowCaster"
            Tags { "LightMode" = "ShadowCaster" }
     
            ZWrite On ZTest LEqual Cull Off
 
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_shadowcaster
            #include "UnityCG.cginc"
 
            struct v2f {
                V2F_SHADOW_CASTER;
            };
 
            v2f vert( appdata_base v )
            {
                v2f o;
                TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
                return o;
            }
 
            float4 frag( v2f i ) : SV_Target
            {
                return float4(1.0, 1.0, 1.0, 1.0);
            }
            ENDCG
        }
    }
}

위의 Shader 코드를 Unity에서 작성한다.


Material을 새로 만들고 Shader를 집어넣는다.


Shadow Color를 적절하게 조절해준다.


Spatial Mapping Manager의 Surface Material에 위의 Material을 넣어준다.


그러면 홀로렌즈로 볼 때는 그림자가 정상적으로 나오는 것을 볼 수 있다.


하지만 디바이스 포탈을 통해 캡처나 녹화를 하면 다음과 같이 나온다.



공간이 어둡게 된 부분은 Spatial Mapping이 된 부분이고 밝은 부분은 Mapping이 되지 않은 부분이다.


홀로렌즈 시연을 할 때, 디바이스 포탈이나 스펙데이터 뷰를 사용한 녹화가 필요한데 이런 현상이 일어나면 곤란하다.


위의 코드 일부를 수정하면 간단하게 해결된다.

            fixed4 frag (v2f i) : SV_Target
            {
                fixed atten = 1.0 - LIGHT_ATTENUATION(i);
		if(atten > 0)
		{
 	               fixed3 shadowColor = atten * _ShadowColor.rgb;
        	       fixed4 finalColor = i.mainColor + fixed4(shadowColor, 1.0);
 
 	               return finalColor;
		}
		else
			return float4(0, 0, 0, 0);
            }





그림자 색감을 좀 더 부드럽고 퍼지는 느낌을 주고 싶지만 아직은 홀로렌즈의 성능이 낮아서 불가능하다.



Spatial Mapping에 있는 기능 때문인건지 InputManager의 기능인 것인지는 모르겠지만


OnInputClicked가 실행되면 Spatial Mapping의 Material이 켜지거나 꺼진다.


이를 해결하는 다양한 방법이 있겟지만 다음과 같은 방법을 이용하여 해결하였다.



SpatialMappingManager의 해당 부분을 drawVisualMeshes = value; 부분을 주석처리 하면 된다.


내부를 건드려서 좋은 방법은 아닌 것 같지만 일단 다음과 같이 진행하였다.

http://goodjoon.tistory.com/262


크라우드 펀딩 + 블록체인..


이번에 기획서로 쓰고자 했던 내용인데 너무나도 비슷한 글이 하나 발견되었다.


블록체인을 이용하여 무엇을 할 수 있을까? 하는 고민으로 다양한걸 생각해보지만


너무나 많은 종류의 코인이 등장해서 찾기가 너무 힘들다.


Circle Hough Transform : https://en.wikipedia.org/wiki/Circle_Hough_Transform


컴퓨터비전이라는 과목에 대한 과제이다.


Circle Tough Transform을 이용하여 원을 그리면 된다.


반지름을 알지 못하는 원에 대한 Circle Hough Transform의 간략한 코드는 위키 사이트를 참고한다.


OpenCV에 이미 Circle Hough Transform을 알아서 해주는 기능이 있지만 이를 이용하지 않는 과제이다.







예제로 받은 코드는 다음과 같다.


다만, 조금 이상한 부분이 존재한다.


해당 과목을 진행하시는 교수님은 MATLAB을 주로 사용하는 것으로 안다.


그래서 동적 배열이 적용되는 이미지 배열 기능을 넣지 않았나 싶다.


먼저 이에 해당 하는 부분을 수정하도록 한다. 주어진 과제만 수정하고자 한다면 딱히 의미는 없다.




int *vote = new int[width*height*rad_max];



이미지에서 화면 밖으로 벗어나지 않는 원을 찾고자 한다면


반지름의 최대값은 특정 값으로 제한된다.



const int rad_max = min(width, height) / 2;



그렇다면 배열 초기화에 대한 코드는 다음과 같이 바뀐다.



	for (int i = 0; i < width; ++i)
	{
		for (int j = 0; j < height; ++j)
		{
			for (int k = 0; k < rad_max; ++k)
			{
				vote[i*(height*rad_max) + j * (rad_max)+k] = 0;
			}
		}
	}


예제 코드에서는 캐니 알고리즘이 contours에 미리 적용되어져 있다.


이를 활용하여 Circle Hough Transform에 대한 voting을 구현한다.


Wiki에 나와있는 기본 공식을 참고하여 작성하면 다음과 같다.



	for (int i = 0; i < width; ++i)
	{
		for (int j = 0; j < height; ++j)
		{
			if (contours.at<uchar>(j, i) == 0)
				continue;
			for (int k = rad_min; k < rad_max; ++k)
			{
				for (int t = 0; t < thetha; t++)
				{
					int a = i - k * cos(t * PI / 180);
					int b = j - k * sin(t * PI / 180);
					if (a >= 0 && a <width && b >= 0 && b<height)
						vote[a*(height*rad_max) + b * rad_max + k] += 1;
				}
			}
		}
	}


그리는 부분은 주석을 참고하여 작성하면 된다.



	for (int i = 0; i < width; i++)
	{
		for (int j = 0; j < height; j++)
		{
			for (int k = rad_min; k < rad_max; k++)
			{
				if (vote[i*(height *rad_max) + j * rad_max + k] > threshold)
				{
					Point center(i, j);
					circle(image, center, k, Scalar(255, 0, 0), 1);
				}
			}
		}
	}


여기까지 해주면 기본은 완성이다.


다만 처음할 때 불편했던 점이 있었는데, Threshold를 임의로 찾아야 한다는 점이 불편했다.


정확한 Threshold를 찾는 법에 대해서는 아직 모르겠고, 좀 더 쉽게 Threshold 범위를 유추하는 법을 찾고자 한다.



int threshold = -1;
float threshold_persent = 0.8f;
int real_threshold = 0;


먼저 변수를 몇개 추가했다.


theshold 초기값을 -1로 한 이유는 아래의 변수들을 이용하기 위함이다.


threshold_persent는 최대 vote값에서 몇 % 아래를 threshold로 잡을 것인지 정하기 위한 변수이다.


real_threshold는 %를 통해 일정 범위를 유추했따면 좀 더 세세한 변수를 찾아내기 위한 변수이다.



	for (int i = 0; i < width; ++i)
	{
		for (int j = 0; j < height; ++j)
		{
			for (int k = rad_min; k < rad_max; ++k)
			{
				if (vote[i*(height*rad_max) + j * (rad_max)+k] > threshold)
				{
					threshold = vote[i*(height*rad_max) + j * (rad_max)+k];
				}
			}
		}
	}
	//포괄적인 수정값
	int maxvote = threshold;
	threshold *= threshold_persent;
	//세부적인 수정값
	if (real_threshold != 0)
		threshold = real_threshold;


먼저 최대 vote 값을 찾아낸 후, 여기서 일정 % 아래값을 theshold로 잡는다.


real_threshold 값을 설정했다면 해당 값을 threshold로 잡는다.


real_theshold 값을 정했다면 위의 반복문을 수행하지 않아도 되나, maxvote 값을 확인하기 위하여 유지하였다.



	printf("max vote : %d ", maxvote);
	if (real_threshold == 0)
		printf("range : %.1f%% ", (1-threshold_persent)*100);
	printf("threshold : %d\n", threshold);




처음 20%의 범위를 통해 207에서 전체 원이 다 보인다는 것을 확인했고, 수치를 조금씩 올려본 결과 212가 가장 적절한 threshold임을 알아냈다.


원에서 살짝 어긋나보이는 것은 voting을 할 때의 a, b의 계산된 값이 int로 들어오는 것으로 인한 한계라고 예상된다.


threshold를 쉽게 찾아내고 싶었지만 아직 정확한 방법을 찾지 못했기에 다음과 같이 진행하였다.





첫 과제였기에 조건(Circle Hough Transform)에 대한 내용보다는 그 외 코드 수정 및 부가 기능에 대한 내용만 많이 작성되어져 있다.




t * PI / 180 이 아니라 PI*(t/180)은 왜 안되냐는 질문이 있었다.


int / int 일 때 값은 무조건 int이다.


PI * t를 먼저 계산하면 double이 되고 double / int를 하면 double이다.




a, b에 넣을 때는 다시 int가 된다. 이 때 a, b는 자동으로 floor 값을(내림값)을 받는다.


a, b에 집어넣기 전에 계산된 값을 round 함수를 이용하여 반올림을 하면 좀 더 정확하지 않겠냐는 의견이 있었다.


맞는 것 같아서 테스트를 해봤다.


threshold 값을 모든 원이 보일 수 있는 최대값으로 설정하였으나 선이 두꺼워졌고


원 안쪽으로 살짝 들어간 선이 몇개 있어서 사용하지 않았다.


이미지가 작아서 그런지는 모르겠지만 조금 고민해볼 문제라고 생각한다.




코딩하는 것보다 블로그에 글 올리는게 더 어렵다.


< > 기호 두개 때문에 자꾸 코드가 이상하게 들어간다.


highlight.js를 사용하지 않고 그냥 이미지로 붙여넣을지 고민중이다.


서로 충돌하는 오브젝트 중에 하나는 무조건 Rigidbody가 있어야 한다.


두 오브젝트가 모두 Rigidbody가 있더라도 둘 다 isKinematic이 켜져 있으면 안된다.


그러면 문제없이 작동하는 것을 확인할 수 있다.


별 내용은 없는데 가끔 까먹게 되서 글로 작성한다.

http://eestrella.tistory.com/22

+ Recent posts