GetPixels

programming/c# 2020. 1. 1. 14:06
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class GetPixel : MonoBehaviour
{
    public RenderTexture rendTex;
    private Texture2D sourceTex;
 
    public GameObject prefab;
    public float offset = 1.2f;
    public float prefabScale = 5.0f;
 
    private int _width;
    private int _height;
 
    private Color[] pix;
    private List<GameObject> list;
    private List<Renderer> rendlist;
    private List<Transform> transformlist;
 
    private MaterialPropertyBlock properties; 
 
    void Start()
    { 
        sourceTex = GetRTPixels(rendTex);
        //소스 텍스트 크기 
        _width = sourceTex.width;
        _height = sourceTex.height;
        //픽셀 색깔 저장하기 
        pix = sourceTex.GetPixels(00, _width, _height);
        //리스트 생성  
        list = new List<GameObject>();
        rendlist = new List<Renderer>();
        transformlist = new List<Transform>();
        properties = new MaterialPropertyBlock();
 
        //픽셀 큐브 생성 
        for (int w = 0; w < _width; w++)
        {
            for (int h = 0; h < _height; h++)
            {
                GameObject obj = Instantiate(prefab, new Vector3(w * offset, 0, h * offset), Quaternion.identity) as GameObject;
                list.Add(obj);
                transformlist.Add(obj.transform);
                Renderer rend = obj.GetComponent<Renderer>();
                rendlist.Add(rend);
 
                obj.transform.SetParent(transform);
            }
        }
 
        transform.rotation = Quaternion.Euler(180-90-90); //보드 회전하기 
    }
 
    private void Update()
    {
        sourceTex = GetRTPixels(rendTex); //실시간으로 texture받아오기 
        pix = sourceTex.GetPixels(00, _width, _height); //pixel 받아오기 
 
        //픽셀 색상 적용 
        for (int i = 0; i < _width * _height; i++)
        {
            properties.SetColor("_Color", pix[i]);//gpuInstancing pixel Color값 받아오기 
            rendlist[i].SetPropertyBlock(properties); //gpuInstancing 사용 Color값 적용  
        }
 
        //pixel 애니메이션
        for (int i = 0; i < _width * _height; i++)
        {
            //화이트 제외 -> 사용하려면 아래 else로 묶어주기 
            //if(pix[i].r > .7f && pix[i].g > .7f && pix[i].b > .7f)
            //{
            //    transformlist[i].localScale = 
            //    new Vector3(1, Mathf.Lerp(list[i].transform.localScale.y, 0.1f, Time.deltaTime * 5.0f), 1);
            //}
 
            float color = pix[i].r + pix[i].g + pix[i].b;
 
            //색상 값 pingpong (균일)
            transformlist[i].localScale = 
            new Vector3(1, Mathf.PingPong(color * Time.time + .01f, color * prefabScale + 0.01f), 1);
 
            //색상 값 pingpong (비균일)
            //transformlist[i].localScale =
            //new Vector3(1, Mathf.PingPong(Time.time + .01f, color * prefabScale + 0.01f), 1);
 
            //속도 값 pingpong
            //transformlist[i].localScale = 
            //new Vector3(1, Mathf.PingPong(Time.time + color + 0.01f, prefabScale), 1);
 
            //색상 값 lerp - 색상 변형 영향 x
            //transformlist[i].localScale = 
            //new Vector3(1, Mathf.Lerp(list[i].transform.localScale.y, (color + 0.01f) * prefabScale, Time.deltaTime * 5.0f), 1);
        }
    }
 
    //renderTexture -> Texture2D로 전환 함수 
    static public Texture2D GetRTPixels(RenderTexture rt)
    {
        RenderTexture currentActiveRT = RenderTexture.active;
        RenderTexture.active = rt;
        Texture2D tex = new Texture2D(rt.width, rt.height);
        tex.ReadPixels(new Rect(00, tex.width, tex.height), 00);
        RenderTexture.active = currentActiveRT;
        return tex;
    }
 
}
cs


Posted by 도이(doi)
,

Enumerator란?

배열의 모든 요소를 반복하는 것처럼.
한 번에 collection에 있는 한 개의 아이템을 거치는 개념입니다. 
Enumerator를 사용하는 이유는 Coroutine이 이를 필요로 하기 때문입니다.


yield란?

yield라는 것은 반복자의 IEnumerator 객체에 값을 전달(yield)하거나,
반복의 종료를 알리기 위해 사용한다.

Coroutine은 어떻게 작동하는가?

coroutine을 사용하는 것은 iterator를 사용하는 것이다. 

https://m.blog.naver.com/PostView.nhn?blogId=dlwhdgur20&logNo=221016139917&proxyReferer=https%3A%2F%2Fwww.google.com%2F


Twist 

시작 축을 바꿔서 재미있게 돌아가도록 유도함. 
ex) y축을 기준으로 도는 도형에 start 함수에서 x축 변환을 줌 


Posted by 도이(doi)
,

static함수?

외부에서 접근 가능한 함수로 만들 때 사용함. 
using UnityEngine class처럼 다른 스크립트에서 접근해서 사용 가능함. 


Delegate ? 

함수에 대한 참조. 델리게이트를 사용하면 함수를 변수처럼 사용할 수 있다. 
delegate를 사용하기 위해서는 delegate라고 선언하고 return값의 자료형과 파라미터를 입력해주어야 한다. 그 후에 함수를 변수처럼 가져와 사용가능함. 배열에 담아서 사용할 수도 있다. 


Enum?

열거형. list로 키워드를 선택할 수 있도록 함. 


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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Graph : MonoBehaviour
{
    public Transform pointPrefab;
    [Range(10100)] 
    public int resolution = 10//prefab의 개수
    [Range(0.1f, 5)]
    public float height = .5f;
    [Range(150)]
    public float length = 2f;
    [Range(0100)]
    public float rotationSpeed = 50f;
    [Range(.1f, 2f)]
    public float prefabScale = 1f;
    public GraphName function; //열거형(enum) 형태 
    private Transform[] points;
 
    private void Awake()
    {
        points = new Transform[resolution]; 
        for(int i=0; i < points.Length; i++)
        {
            Transform point = Instantiate(pointPrefab);
            point.SetParent(transform, false); 
            points[i] = point; 
        }
    }
 
    private void Update()
    {
        float step = length / resolution;
        Vector3 scale = Vector3.one * prefabScale;
        float t = Time.time;
        //delegate를 통한 함수의 배열 가져오기  
        GraphFuction[] functions = { 
            SineFunction, MultiSineFunction
        };
        //delegate 함수 중 하나 선택 
        GraphFuction f = functions[(int)function];
        for (int i=0; i<points.Length; i++)
        {
            //point wave animation
            Transform point = points[i];
            Vector3 position = point.localPosition; 
            position.x = (i + 0.5f) * step - (length / 2);
            position.y = f(position.x, t); 
            position.z = 0;
            point.localPosition = position; 
            point.localScale = scale;
        }
        //x축으로 회전 
        Quaternion rotation = transform.localRotation;
        rotation = Quaternion.Euler(t * rotationSpeed, 00);
        transform.localRotation = rotation;
    }
 
    public static float SineFunction(float x, float t)//static을 다른 스크립트에서 접근 가능  
    {
        return Mathf.Sin(Mathf.PI * (x + t));
    }
 
    public static float MultiSineFunction(float x, float t)
    {
        float y = Mathf.Sin(Mathf.PI * (x + t));
        y += Mathf.Sin(2f * Mathf.PI * (x + 0.5f * t))/2f;
        y *= 2f / 3f;
        return y;
    }
}
 
cs



1
2
3
4
using UnityEngine;
 
public delegate float GraphFuction(float x, float t);
 
cs


1
2
3
4
5
6
7
8
9
using UnityEngine;
 
public enum GraphName
{
    Sine,
    MultiSine
}
 
 
cs


Posted by 도이(doi)
,
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Graph : MonoBehaviour
{
    public Transform pointPrefab;
    [Range(10100)] 
    public int resolution = 10//prefab의 개수
    [Range(0.1f, 5)]
    public float height = .5f;
    [Range(150)]
    public float length = 2f;
    [Range(0100)]
    public float rotationSpeed = 50f;
    [Range(.1f, 2f)]
    public float prefabScale = 1f;
    Transform[] points;
 
    private void Awake()
    {
        points = new Transform[resolution]; //배열은 미리 크기를 지정해주어야 한다. 
        for(int i=0; i < points.Length; i++)
        {
            Transform point = Instantiate(pointPrefab);
            point.SetParent(transform, false); //생성자 하위 항목으로 prefab넣기 
            points[i] = point; //points배열에 생성한 point 넣기 
        }
    }
 
    private void Update()
    {
        float step = length / resolution;
        Vector3 scale = Vector3.one * prefabScale;
        for (int i=0; i<points.Length; i++)
        {
            //point wave animation
            Transform point = points[i];
            Vector3 position = point.localPosition; //local position을 변수값으로 가져옴 
            position.x = (i + 0.5f) * step - (length / 2);
            position.y = height * Mathf.Sin(Mathf.PI * (position.x + Time.time)); //x축으로 이동하는 sin파(애니메이션) 파이를 곱한 이유는 주기를 2로 변경하기 위해서  
            position.z = 0;
            point.localPosition = position; //localposition을 수정한 position으로 변경
            point.localScale = scale;
        }
        //x축으로 회전 
        Quaternion rotation = transform.localRotation;
        rotation = Quaternion.Euler(Time.time * rotationSpeed, 00);
        transform.localRotation = rotation;
    }
}
 
cs
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
32
33
34
35
36
37
38
39
Shader "Custom/ColoredPoint"
{
    Properties
    {
        _Glossiness ("Smoothness", Range(0,1)) = 1
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200
 
        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows
        #pragma target 3.0
 
        struct Input
        {
            float3 worldPos; //input값으로 worldPos 사용 
        };
 
        half _Glossiness;
        half _Metallic;
        
        UNITY_INSTANCING_BUFFER_START(Props)
        UNITY_INSTANCING_BUFFER_END(Props)
 
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            o.Albedo.rg = IN.worldPos.xy * 0.5 + 0.5; //worldPosition에 따라서 색상 가짐 
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = 0.5;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
 
cs


Posted by 도이(doi)
,