'Unity공부'에 해당되는 글 42건

  1. 2017.03.13 8강 씬 로드, 점수 처리 (마지막 스터디)
  2. 2017.03.13 Unity c# for designer - 7강 (점수, 장애물)
  3. 2017.01.23 Unity c# for designer - 6강(회전,충돌)
  4. 2016.12.02 Unity c# for designer - 5강 보충 수업
  5. 2016.11.28 Unity c# for designer - 5강 (미니게임 만들며 Script 배우기)
  6. 2016.11.28 Unity c# for designer 4강 / 클래스
  7. 2016.08.19 Unity c# for designer 3강 / 제어문
  8. 2016.08.01 Unity c# for designer 2강 / 연산자
  9. 2016.07.13 Unity c# for designer 1강 / 기본적인 프로그램
  10. 2015.07.21 7. Reflaction Shader(사내 교육용으로 작성한 PPT) 3
  11. 2015.07.06 6. Alpha Bland & Alpha Test(사내 교육용으로 작성한 PPT)
  12. 2015.07.06 5. texture Mask & Vertex Color Mask(사내 교육용으로 작성한 PPT)
  13. 2015.07.06 4. Normal Map & Emision & reflection(사내 교육용으로 작성한 PPT)
  14. 2015.07.06 3. Specular & Fake BDRF(사내 교육용으로 작성한 PPT)
  15. 2015.07.06 2 – Lambert Light & Half Lambert Light(사내 교육용으로 작성한 PPT)
  16. 2015.07.06 1 – Vertex Shader & Pixel Shader(사내 교육용으로 작성한 PPT)
  17. 2013.04.22 유니티 surface shader로 Unlit shader 만들기.
  18. 2012.12.12 셰이더 프로그래밍 입문-11(마지막단원) 1
  19. 2012.12.10 셰이더 프로그래밍 입문-10
  20. 2012.12.04 셰이더 프로그래밍 입문-9
  21. 2012.12.03 셰이더 프로그래밍 입문-8
  22. 2012.11.27 셰이더 프로그래밍 입문-7
  23. 2012.11.21 셰이더 프로그래밍 입문-6
  24. 2012.11.19 셰이더 프로그래밍 입문-5
  25. 2012.11.16 셰이더 프로그래밍 입문-4
  26. 2012.11.14 셰이더 프로그래밍 입문-3 2
  27. 2012.11.13 셰이더 프로그래밍 입문-2
  28. 2012.11.12 셰이더 프로그래밍 입문-1
  29. 2012.08.27 unity surface shader 공부 7 - surface shader custom Light 예제 따라하기
  30. 2012.08.24 unity surface shader 공부 6 - surface shader custom Light 예제 따라하기

씬 로드및 최종 점수처리를 간단히 해보고 길고 길었던 스터디를 마무리 합니다.

 

 




//카메라 -----------------------

using UnityEngine;
using System.Collections;

public class Cam : MonoBehaviour {

    public Transform Target;
    public Transform Camera;
    private Vector3 CamPos;
    public float CamX;
    public float CamY;
    public float CamSpeed;

    // Use this for initialization
    void Start () {
    
    }
    
    // Update is called once per frame
    void Update () {
        CamPos = new Vector3 (Target.position.x + CamX , CamY, Target.transform.position.z);
        Camera.transform.position = Vector3.Lerp (Camera.transform.position, CamPos, Time.smoothDeltaTime * CamSpeed);
    }
}

 

//캐릭터 -----------------------

using UnityEngine;
using System.Collections;

public class CharMove : MonoBehaviour {


    //public
    public GameObject Target;
    public float MovePower = 0.5f;
    public float MoveSpeed = 5.0f;
    public float RotationSpeed = 20.0f;
    public float ReturnPower = 0.5f;


    //private
    private float TargetPosition;
    private float TargetSetPosition;
    private Quaternion RotationQ;
    private bool OnForward;
    private bool OnLeft;
    private bool OnRight;
    private bool OnBack;
    private bool Moving;
    private bool StateForward;
    private bool StateLeft;
    private bool StateRight;
    private bool StateBack;


    //Collider Controller
    private string OnMoveVecter = "State";
    private string StayVecter = "State";

    //UI
    public GameObject ScoreLabel;
    private int num = 1;


    // Use this for initialization
    void Start () {
        ScoreLabel = GameObject.Find ("ScoreLabel");
    }
    
    // Update is called once per frame
    void Update () {

        //Debug.Log ("OnMoveVecter : "+OnMoveVecter);

        //forward move
        if(OnForward){
            Moving = true;
            Target.gameObject.transform.position += new Vector3(MovePower,0,0)*(Time.deltaTime * MoveSpeed);
            TargetPosition = Target.gameObject.transform.position.x;

            //Rotation
            RotationQ = Quaternion.Euler(0,0,0);
            Target.transform.rotation = Quaternion.Slerp(Target.transform.rotation, RotationQ , RotationSpeed * Time.deltaTime);

            if(TargetPosition >= TargetSetPosition){
                OnForward = false;
                Moving = false;
            }
        }


        // Left move
        if(OnLeft){
            Moving = true;
            Target.gameObject.transform.position += new Vector3(0,0,MovePower)*(Time.deltaTime * MoveSpeed);
            TargetPosition = Target.gameObject.transform.position.z;

            //Rotation
            RotationQ = Quaternion.Euler(0,-90.0f,0);
            Target.transform.rotation = Quaternion.Slerp(Target.transform.rotation, RotationQ , RotationSpeed * Time.deltaTime);

            if(TargetPosition >= TargetSetPosition){
                OnLeft = false;
                Moving = false;
            }

            Moving = false;
        }


        // Right move
        if(OnRight){
            Moving = true;
            Target.gameObject.transform.position -= new Vector3(0,0,MovePower)*(Time.deltaTime * MoveSpeed);
            TargetPosition = Target.gameObject.transform.position.z;

            //Rotation
            RotationQ = Quaternion.Euler(0,90.0f,0);
            Target.transform.rotation = Quaternion.Slerp(Target.transform.rotation, RotationQ , RotationSpeed * Time.deltaTime);

            if(TargetPosition <= TargetSetPosition){
                OnRight = false;
                Moving = false;
            }
        }


        // Back move
        if(OnBack){
            Moving = true;
            Target.gameObject.transform.position -= new Vector3(MovePower,0,0)*(Time.deltaTime * MoveSpeed);
            TargetPosition = Target.gameObject.transform.position.x;

            //Rotation
            RotationQ = Quaternion.Euler(0,180.0f,0);
            Target.transform.rotation = Quaternion.Slerp(Target.transform.rotation, RotationQ , RotationSpeed * Time.deltaTime);

            if(TargetPosition <= TargetSetPosition){
                OnBack = false;
                Moving = false;
            }
        }

    }


    //forward move btn
    public void CharForwardMove(){
        if (Moving == false & StateForward == false) {
            TargetSetPosition = Target.gameObject.transform.position.x + MovePower;
            OnForward = true;
            OnMoveVecter = "ForwardVecter";

            num = num + 1;
            ScoreLabel.GetComponent<UILabel>().text = num.ToString();
        }
    }

    // Left move btn
    public void CharLeftMove(){

        if(Moving == false & StateLeft == false){
            TargetSetPosition = Target.gameObject.transform.position.z + MovePower;
            OnLeft = true;
            OnMoveVecter = "LetfVecter";

        }
    
    }

    // Right move btn
    public void CharRightMove(){
        if (Moving == false & StateRight == false) {
            TargetSetPosition = Target.gameObject.transform.position.z - MovePower;
            OnRight = true;
            OnMoveVecter = "RightVecter";
        }
    }


    //forward move btn
    public void CharBackMove(){
        if (Moving == false & StateBack == false) {
            TargetSetPosition = Target.gameObject.transform.position.x - MovePower;
            OnBack = true;
            OnMoveVecter = "BackVecter";

            num = num - 1;
            ScoreLabel.GetComponent<UILabel>().text = num.ToString();
        }
    }



    //Trigger ON
    void OnTriggerEnter(Collider col){
        StayVecter = OnMoveVecter;
    }

    //collider
    void OnTriggerStay(Collider col){
        
        //Debug.Log ("TriggerStay : " + "Trigger Stay!!");
        if(StayVecter == "ForwardVecter"){
            StateForward = true;
        }else if(StayVecter == "LetfVecter"){
            StateLeft = true;
        }else if(StayVecter == "RightVecter"){
            StateRight = true;
        }else if(StayVecter == "BackVecter"){
            StateBack = true;
        }
    }

    void OnTriggerExit(Collider col){
        StateForward = false;
        StateLeft = false;
        StateRight = false;
        StateBack = false;
        OnMoveVecter = "State";
        StayVecter = "State";
    }



    /* collider Test
    void OnCollisionEnter(Collision col){
        Debug.Log ("OnCollisionEnter");
    }

    void OnCollisionExit(Collision col){
        Debug.Log ("OnCollisionExit");
    }

    void OnCollisionStay(Collision col){
        Debug.Log ("OnCollisionStay");
    }

    void OnTriggerEnter(Collider col){
        Debug.Log ("OnTriggerEnter");
    }

    void OnTriggerExit(Collider col){
        Debug.Log ("OnTriggerExit");
    }

    void OnTriggerStay(Collider col){
        Debug.Log ("OnTriggerStay");
    }
    */


}

 

 

//게임오버 UI -----------------------

using UnityEngine;
using System.Collections;

public class GameOverColl : MonoBehaviour {

    public GameObject GameOverLabal;

    // Use this for initialization
    void Start () {
        GameOverLabal = GameObject.Find ("GameOver_UI");
    }
    
    // Update is called once per frame
    void Update () {
    
    }

    void OnTriggerEnter(Collider col){
        if(col.gameObject.tag == "Player"){
            GameOverLabal.GetComponent<UIPanel> ().alpha = 1;
        }
    }
}

 

 

Posted by 프리랜서 디자이너

7강

- 점수 

- 장애물

- 게임오버

 

 

Posted by 프리랜서 디자이너

Unity c# for designer - 6강 (미니게임 만들며 Script 배우기)

 

학습내용

 
  • 과제풀이

  • 방향 버튼에 맞게 캐릭터 회전하기

  • 이동 완료시 까지 다른 버튼 작동안되게 처리하기

  • 충돌 처리





6-1강

6- 1강  코드  공유 드립니다.

아래 코드는 정답이 아니니 심플하게 바꾸셔도 좋습니다.~^^

 

 

using UnityEngine;
using System.Collections;

public class studyCharMove : MonoBehaviour {


    //public
    public GameObject Target;
    public float MovePower = 0.0f;
    public float MoveSpeed = 0.0f;
    public float RotationSpeed = 0.0f;

    //private
    private float TargetPosition;
    private float TargetSetPosition;
    private Quaternion RotationQ;
    private bool OnForward;
    private bool OnLeft;
    private bool OnRight;
    private bool Moving;




    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

        //forward move
        if(OnForward){
            Moving = true;
            Target.gameObject.transform.position += new Vector3(MovePower,0,0)*(Time.deltaTime * MoveSpeed);
            TargetPosition = Target.gameObject.transform.position.x;

            //Rotation
            RotationQ = Quaternion.Euler(0,0,0);
            Target.transform.rotation = Quaternion.Slerp(Target.transform.rotation, RotationQ , RotationSpeed * Time.deltaTime);

            if(TargetPosition >= TargetSetPosition){
                OnForward = false;
                Moving = false;
            }

        }


        // Left move
        if(OnLeft){
            Moving = true;
            Target.gameObject.transform.position += new Vector3(0,0,MovePower)*(Time.deltaTime * MoveSpeed);
            TargetPosition = Target.gameObject.transform.position.z;

            //Rotation
            RotationQ = Quaternion.Euler(0,-90.0f,0);
            Target.transform.rotation = Quaternion.Slerp(Target.transform.rotation,RotationQ , RotationSpeed * Time.deltaTime);

            if(TargetPosition >= TargetSetPosition){
                OnLeft = false;
                Moving = false;
            }
        }

        // Right move
        if(OnRight){
            Moving = true;
            Target.gameObject.transform.position -= new Vector3(0,0,MovePower)*(Time.deltaTime * MoveSpeed);
            TargetPosition = Target.gameObject.transform.position.z;

            //Rotation
            RotationQ = Quaternion.Euler(0,90.0f,0);
            Target.transform.rotation = Quaternion.Slerp(Target.transform.rotation, RotationQ , RotationSpeed * Time.deltaTime);

            if(TargetPosition <= TargetSetPosition){
                OnRight = false;
                Moving = false;
            }
        }

    }


    //forward move btn
    public void CharForwardMove(){
        if(!Moving){
            TargetSetPosition = Target.gameObject.transform.position.x + MovePower;
            OnForward = true;
        }
    }

    // Left move btn
    public void CharLeftMove(){
        if(!Moving){
            TargetSetPosition = Target.gameObject.transform.position.z + MovePower;
            OnLeft = true;
        }
    }

    // Right move btn
    public void CharRightMove(){
        if (!Moving) {
            TargetSetPosition = Target.gameObject.transform.position.z - MovePower;
            OnRight = true;
        }
    }

} 




6-2강
using UnityEngine;
using System.Collections;

public class CharMove : MonoBehaviour {


    //public
    public GameObject Target;
    public float MovePower = 0.5f;
    public float MoveSpeed = 5.0f;
    public float RotationSpeed = 20.0f;
    public float ReturnPower = 0.5f;


    //private
    private float TargetPosition;
    private float TargetSetPosition;
    private Quaternion RotationQ;
    private bool OnForward;
    private bool OnLeft;
    private bool OnRight;
    private bool Moving;
    private bool StateForward;
    private bool StateLeft;
    private bool StateRight;


    //Collider Controller
    private string OnMoveVecter = "State";
    private string StayVecter = "State";




    // Use this for initialization
    void Start () {
        
    }
    
    // Update is called once per frame
    void Update () {

        Debug.Log ("OnMoveVecter : "+OnMoveVecter);

        //forward move
        if(OnForward){
            Moving = true;
            Target.gameObject.transform.position += new Vector3(MovePower,0,0)*(Time.deltaTime * MoveSpeed);
            TargetPosition = Target.gameObject.transform.position.x;

            //Rotation
            RotationQ = Quaternion.Euler(0,0,0);
            Target.transform.rotation = Quaternion.Slerp(Target.transform.rotation, RotationQ , RotationSpeed * Time.deltaTime);

            if(TargetPosition >= TargetSetPosition){
                OnForward = false;
                Moving = false;
            }

        }


        // Left move
        if(OnLeft){
            Moving = true;
            Target.gameObject.transform.position += new Vector3(0,0,MovePower)*(Time.deltaTime * MoveSpeed);
            TargetPosition = Target.gameObject.transform.position.z;

            //Rotation
            RotationQ = Quaternion.Euler(0,-90.0f,0);
            Target.transform.rotation = Quaternion.Slerp(Target.transform.rotation, RotationQ , RotationSpeed * Time.deltaTime);

            if(TargetPosition >= TargetSetPosition){
                OnLeft = false;
                Moving = false;
            }

            Moving = false;
        }

        // Right move
        if(OnRight){
            Moving = true;
            Target.gameObject.transform.position -= new Vector3(0,0,MovePower)*(Time.deltaTime * MoveSpeed);
            TargetPosition = Target.gameObject.transform.position.z;

            //Rotation
            RotationQ = Quaternion.Euler(0,90.0f,0);
            Target.transform.rotation = Quaternion.Slerp(Target.transform.rotation, RotationQ , RotationSpeed * Time.deltaTime);

            if(TargetPosition <= TargetSetPosition){
                OnRight = false;
                Moving = false;
            }
        }

    }


    //forward move btn
    public void CharForwardMove(){
        if (Moving == false & StateForward == false) {
            TargetSetPosition = Target.gameObject.transform.position.x + MovePower;
            OnForward = true;
            OnMoveVecter = "ForwardVecter";
        }
    }

    // Left move btn
    public void CharLeftMove(){

        if(Moving == false & StateLeft == false){
            TargetSetPosition = Target.gameObject.transform.position.z + MovePower;
            OnLeft = true;
            OnMoveVecter = "LetfVecter";

        }
    
    }

    // Right move btn
    public void CharRightMove(){
        if (Moving == false & StateRight == false) {
            TargetSetPosition = Target.gameObject.transform.position.z - MovePower;
            OnRight = true;
            OnMoveVecter = "RightVecter";
        }
    }





    //Trigger ON
    void OnTriggerEnter(Collider col){
        StayVecter = OnMoveVecter;
    }

    //collider
    void OnTriggerStay(Collider col){
        
        Debug.Log ("TriggerStay : " + "Trigger Stay!!");
        if(StayVecter == "ForwardVecter"){
            StateForward = true;
        }else if(StayVecter == "LetfVecter"){
            StateLeft = true;
        }else if(StayVecter == "RightVecter"){
            StateRight = true;
        }
    }

    void OnTriggerExit(Collider col){
        StateForward = false;
        StateLeft = false;
        StateRight = false;
        OnMoveVecter = "State";
        StayVecter = "State";
    }


} 




Posted by 프리랜서 디자이너

Unity c# for designer - 5강 보충 수업


scripting API

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


Gameobject

Find()

transform.position

transform.Rotate

transform.localScale

ngui Button




using UnityEngine;

using System.Collections;


public class findobj : MonoBehaviour {


public GameObject obj001;

public Transform obj002;

public GameObject obj003;

public float RotateSpeed = 1;


// Use this for initialization

void Start () {

obj001 = GameObject.Find("001");

obj002 = GameObject.Find ("002").transform;

obj003 = GameObject.Find("003");


Move001 ();

}

// Update is called once per frame

void Update () {

TranslateObj ();

RotateObj ();

}


public void Move001(){

obj001.transform.position = new Vector3 (0,0,0);

}


public void TranslateObj(){

obj002.transform.Translate (Vector3.forward * Time.deltaTime);

}


public void RotateObj(){

obj003.transform.Rotate (Vector3.right * Time.deltaTime * RotateSpeed);

}


public void ScaleObj(){

obj003.transform.localScale += new Vector3 (2,2,2);

}

}












Posted by 프리랜서 디자이너

Unity c# for designer - 5강 (미니게임 만들며 Script 배우기)



NGUI를 이용한 캐릭터 이동

원활한 수업을 위해 예제 리소스들을 미리 배치해 두었습니다.(무료어셋)


오늘은 캐릭터를 정해진 값 만큼 부드럽게 이동하는 코드와 캐릭터를 부드럽게

따라가는 스크립트를 작성하겠습니다.



캐릭터 이동 스크립트



using UnityEngine;

using System.Collections;


public class CharMove : MonoBehaviour {


public GameObject Target;

private bool OnForward = false;

private float TargetPosition;

private float TargetSetPosition;


public float MovePower = 50.0f;




// Use this for initialization

void Start () {


}

// Update is called once per frame

void Update () {

if(OnForward){

Target.gameObject.transform.position += new Vector3(MovePower,0,0)*Time.deltaTime;

TargetPosition = Target.gameObject.transform.position.x;


if(TargetPosition >= TargetSetPosition){

OnForward = false;

}


}

}



public void CharForwardMove(){

Debug.Log ("Forward!");

TargetSetPosition = Target.gameObject.transform.position.x + MovePower;

OnForward = true;

}


public void CharRightMove(){

Debug.Log ("Right!");

}


public void CharLeftMove(){

Debug.Log ("Left!");

}



}





부드럽게 따라가는 카메라 이동 스크립트



using UnityEngine;

using System.Collections;


public class Cam : MonoBehaviour {


public Transform Target;

public Transform Camera;

private Vector3 CamPos;

public float CamX;

public float CamY;

public float CamSpeed;


// Use this for initialization

void Start () {

}

// Update is called once per frame

void Update () {

CamPos = new Vector3 (Target.position.x + CamX , CamY, Target.transform.position.z);

Camera.transform.position = Vector3.Lerp (Camera.transform.position, CamPos, Time.smoothDeltaTime * CamSpeed);

}

}






플레이 영상




과제

외쪽이동, 오른쪽 이동코드를 작성해 오세요.~ (캐릭터 회전은 다음시간에 알려드립니다.)

Posted by 프리랜서 디자이너

Unity c# for designer 4강 / 클래스

C#이 보이는 그림책을 참고로 작성했습니다.

강의용 자료로 만들었기 때문에 구체적인 설명은 없습니다.



  • 객체지향?

  • 객체?

  • 클래스?

  • 인스턴스?

  • 메소드?

  • 필드?



A


using UnityEngine;

using System.Collections;


public class method_01{


   void Start () {


   }

   public int Add(int a){

      return a;

   }

   public string Add(string z, string w) {

      return z + w;

   }


}






B


using UnityEngine;

using System.Collections;


public class method_02 : MonoBehaviour {


   // Use this for initialization

   void Start () {


method_01 myclass = new method_01 ();


       myclass.Add(10);

Debug.Log (myclass.Add(10));


myclass.Add("methodA", "methodB");

Debug.Log (myclass.Add("methodA", "methodB"));

   }


}








과제

복습~

Posted by 프리랜서 디자이너

Unity c# for designer 3강 / 제어문

C#이 보이는 그림책을 참고로 작성했습니다.

강의용 자료로 만들었기 때문에 구체적인 설명은 없습니다.



오늘은 다양한 조건문을 배우고 유니티 API를 이용해

오브젝트를 간단히 움직여 보겠습니다.

NGUI도 간단히 사용해 보겠습니다.




유니티 스크립트를 시작하는데 꼭 필요한 자료 입니다.

즐찾 하세요.~ ^^


Unity 스크립트 자습서

http://unity3d.com/kr/learn/tutorials/topics/scripting




Unity Script API

https://docs.unity3d.com/ScriptReference/30_search.html?q=Translate




1. if 문을 이용한 오브젝트 이동과 UI Label

using UnityEngine;

using System.Collections;


public class if001 : MonoBehaviour {


public bool go;

public UILabel uiText;

public float speed;


void Start () {

}

void Update () {

if (go == true) {

this.gameObject.transform.Translate (Vector3.right * Time.deltaTime * speed);

uiText.GetComponent<UILabel>().text = "right!";

} else {

this.gameObject.transform.Translate (Vector3.left * Time.deltaTime * speed);

uiText.GetComponent<UILabel>().text = "left!";

}

}

}





2. for문을 이용한 연산과 UI Label



using UnityEngine;

using System.Collections;


public class for001 : MonoBehaviour {


public UILabel uiText;

public int count;


void Start () {

for(int i = 0; i <= count; i++){

Debug.Log ("i = "+i);

Debug.Log ("count = "+count);


if(i == 10){

uiText.GetComponent<UILabel> ().text = "finish!!";

}

}

}

void Update () {

}

}






3. foreach문을 이용한 UI Label 문자 바꾸기



using UnityEngine;

using System.Collections;


public class foreach001 : MonoBehaviour {


public UILabel[] TT = new UILabel[3];

public string text = "Oh!!";



// Use this for initialization

void Start () {


TT [0] = GameObject.Find ("Label_1").GetComponent<UILabel>();

TT [1] = GameObject.Find ("Label_2").GetComponent<UILabel>();

TT [2] = GameObject.Find ("Label_3").GetComponent<UILabel>();


foreach( UILabel result in TT){

result.text = text;

}

}

// Update is called once per frame

void Update () {

}

}






4. while문을 이용한 UI Label 문자 바꾸기



using UnityEngine;

using System.Collections;


public class while001 : MonoBehaviour {


public int count;

public int whileCount;

public UILabel uiText;


void Start () {


while(whileCount < count){

Debug.Log (whileCount);

whileCount++;

}


uiText.GetComponent<UILabel> ().text = whileCount.ToString ();

}

void Update () {

}

}





5. switch문으로 오브젝트 제어하기


using UnityEngine;

using System.Collections;


public class swirch001 : MonoBehaviour {


public Move moveState;


public GameObject obj;

public float speed;

public UILabel uiText;


public enum Move {

go, stop

}


// Use this for initialization

void Start () {

}

// Update is called once per frame

void Update () {


switch(moveState){

case Move.go:

obj.transform.Translate (Vector3.right * Time.deltaTime * speed);

uiText.GetComponent<UILabel>().text = "GO!";

break;

case Move.stop:

Debug.Log ("STOP!");


break;

}


}

}









과제

이번 과제는 복습입니다.

복습 복습 복습~



Posted by 프리랜서 디자이너

Unity c# for designer 2강 / 연산자

C#이 보이는 그림책을 참고로 작성했습니다.

강의용 자료로 만들었기 때문에 구체적인 설명은 없습니다.


1. 산술 연산자


연산자

기능

사용법

+

덧셈

a = b + c

-

뺄셈

a = b - c

*

곱셈

a = b * c

/

나눗셈

a = b  / c

%

나머지

a = b % c

=

대입

a = b

++

증가

변수의 값을 증가 시킴

--

감소

변수의 값을 감소 시킴



using UnityEngine;

using System.Collections;


public class calculation : MonoBehaviour {


public float b = 10f;

public float c = 20f;


// Use this for initialization

void Start () {

float d = b + c;

float e = b - c;

float f = b * c;

float g = b % c;

float h = b;

float i = ++b;

float j = --c;


Debug.Log (d);

Debug.Log (e);

Debug.Log (f);

Debug.Log (g);

Debug.Log (h);

Debug.Log (i);

Debug.Log (j);


}

// Update is called once per frame

void Update () {

}

}








2. 비교 연산자


연산자

사용법

의미

==

a == b

a와 b는 같다

<

a < b

a는 b보다 작다

>

a > b

a는 b보다 크다

<=

a <= b

a는 b보다 작거나 같다

>=

a >= b

a는 b보다 크거나 같다

!=

a != b

a와 b는 같지 않다.





3. 논리형




using UnityEngine;

using System.Collections;


public class tnb : MonoBehaviour {



public int a = 10;

public int b = 20;

public bool c;

public bool d;

public bool e;


// Use this for initialization

void Start () {

c = a < b;

d = a > b;

e = a == b;

Debug.Log (c);

Debug.Log (d);

Debug.Log (e);

}

// Update is called once per frame

void Update () {

}

}



조건 연산자


using UnityEngine;

using System.Collections;


public class tnb2 : MonoBehaviour {


public string right;

public string wrong;

private bool value;

private string answer;



// Use this for initialization

void Start () {

value = true;

answer = value ? right : wrong;

Debug.Log (answer);


value = false;

answer = value ? right : wrong;

Debug.Log (answer);

}

// Update is called once per frame

void Update () {

}

}









4. 논리 연산자


연산자

사용법

의미

&, &&

(a >= 10) && (a <50)

a는 10 이상이고 50 미만이면 참

|, ||

(a == 1) || (a == 100)

a는 1 또는 100이면 참

!

!(a == 100)

a는 100과 같다면 거짓




using UnityEngine;

using System.Collections;


public class tnb3 : MonoBehaviour {


public int a = 3;

public int b = 4;

bool x;

bool y;


// Use this for initialization

void Start () {

x = (a < 0);

y = (b > 0);


Debug.Log ((a == 3) & (b == 3));

Debug.Log (x | y);

Debug.Log (!(a == b));


}

// Update is called once per frame

void Update () {

}

}








5. 연산 우선 순위

간단한 문자 출력을 해보며 간단히 구조를 살펴봅니다.



6. 형 변환


using UnityEngine;

using System.Collections;


public class tnb4 : MonoBehaviour {


// Use this for initialization

void Start () {


Debug.Log ("3 / 2 = " + 3 / 2);

Debug.Log ("3 / 2 = " + 3 / 2);


Debug.Log ("3 / 2 = " + (float) 3/2);

Debug.Log ("3 / 2 = " + 3 / (float)2);


Debug.Log ("1.2 + 1.3 = " + (int)1.2f * (int)1.3f);

}

// Update is called once per frame

void Update () {

}

}






8. 과제

코드로 옮겨 보세요.


과제

using UnityEngine;

using System.Collections;


public class homework02 : MonoBehaviour {




열거형 calc_A ,calc_B 를 선언합니다.


public 정수형 value_A,value_B 를 선언합니다.

public 문자열 talkA,talkB를 선언합니다.


논리형(bool)talkValue,answer_01,answer_02,answer_04,answer_05을 선언합니다.

문자열 answer_03을 선언합니다.


정수형 a,b,c,d를 선언합니다.





void Start () {


스타트 함수에서 아와 같이 연산식을 각각대입합니다.

value_A * value_B = a

value_B % value_A = b

++value_B = c

value_B = d


각각에 변수에 아래의 식을 코드로 옮기세요.

answer_01 = a는b보다 작거나 같다.

answer_02 = a와b는 같지않다.

answer_03 = talkA와 talkB의 조건연산식 (힌트 talkValue? XXX : XXX )

answer_04 = a는b보다 크다 || c와d는 같다

answer_05 = (calcuEnum==CalcuEnum.calc_A) && (a는b보다 크다);

talkValue = talkValue는 참 입니다.


answer_01,answer_02,answer_03,answer_04,answer_05의 디버그 로그를 찍으세요.


}



void Update () {

}


}








잠깐!!!

실행전 인스펙터에 value_A는 10을 value_B는 20을 대입합니다.

인스펙터에 talkA는 Oh!를 talkB는 Ah!대입합니다.

그리고는 열거형 calc_A를 선택합니다.

실행~!



결과





Posted by 프리랜서 디자이너

Unity c# for designer 1강 / 기본적인 프로그램

C#이 보이는 그림책을 참고로 작성했습니다.

강의용 자료로 만들었기 때문에 구체적인 설명은 없습니다.


 

1. Hello world

간단한 문자 출력을 해보며 간단히 구조를 살펴봅니다.



 

1) helloWorld c# 스크립트를 하나 생성합니다.



 

2) 더블 클릭 해서 모노 창이 띄웁니다.



 

3) 이제 첫 스크립트를 작성할 준비가 끝났습니다.

이제 아래와 같이 작성해보세요.


 

void Update () {


Debug.Log ("Hellor World");

}




 

4) 작성한 후 스크립트를 끌어다 카메라에 넣고 플레이 해보세요.

콘솔 창에 Hello World 가 계속해서 출력되는 것을 확인 할 수 있습니다.


 

첫 스크립트 작성을 축하 합니다.!

짝짝짝~ ㅎㅎ





 

2. 프로그램의 기본 구조

유니티 C#의 기본 구조는 아래와 같습니다.

각각의 세부 설명은 이후 차차 설명하겠습니다.


 





 

3. 유니티 C# 기본 함수

출처 : http://dlgnlfus.tistory.com/64


 

void Awake(){

}


-스크립트가 실행될 때 한 번만 호출되는 함수이다.

-주로 게임의 상태 값 또는 변수의 초기화에 사용한다.

-start 함수가 호출되기 전에 먼저 호출된다.

-스크립트가 비 활성화돼 있어도 실행된다.

/*코루틴 사용 불가*/

void Start () {

}


-Update 함수가 호출되기 전에 한번만 호출된다.

-스크립트가 활성화돼 있어야 실행된다.

-다른 스크립트의 모든 Awake가 모두 실행된 이후에 실행된다.

void Update () {

}


-프레임마다 호출되는 함수로 주로 게임의 핵심 로직을 작성한다.

-스크립트가 활성화돼 있어야 실행된다.

-코루틴 사용 불가

void LateUpdate (){

}

-모든 Update 함수가 호출되고 나서 한 번 씩 호출된다.

-순차적으로 실행해야 하는 로직에 사용한다.

-카메라 이동 로직에 주로 사용하는 함수다.

-스크립트가 활성화돼 있어야 실행된다.

void FixedUpdate (){

}


-주로 물리 엔진을 사용하는 경우에 일정 시간 간격으로 힘을 가할 때 사용하는 함수다.

-스크립트가 활성화돼 있어야 실행된다.

void OnEnable (){

}


-게임 오브젝트 또는 스크립트가 활성화됐을 때 호출된다.

-이벤트 연결 시 사용한다.

-코루틴 사용 불가

void OnDisable (){

}


-게임오브젝트 또는 스크립트가 비활성화됐을 때 호출된다.

-이벤트 연결을 종료할 때 사용한다.

-코루틴 사용 불가

void OnGUI (){


}


-레거시 GUI 관련 함수를 사용할 때 사용한다.






 

3. 변수

이번엔 여러가지 변수를 선언해 보겠습니다.

따라해보세요.~


 

using UnityEngine;

using System.Collections;


public class unityVariable : MonoBehaviour {


public int a = 1;

public float b = 1.5f;

private decimal c = 1.96666666666666666666666666m;

public string d = "디자이너를 위한 C# 기초";

public string e = "Good";

public string f = "Designer";

private string g = "good designer";

private string h = "GOOD DESIGNER";


System.Text.StringBuilder sb = new System.Text.StringBuilder();



// Use this for initialization

void Start () {

Debug.Log (a);

Debug.Log (b);

Debug.Log (c.ToString());

Debug.Log (d);

Debug.Log (e+f);

Debug.Log (g.ToUpper());

Debug.Log (h.ToLower());

Debug.Log (g[0]);


//StringBuilder

sb.Append("one ");

sb.Append("two ");

sb.Append("three");

Debug.Log (sb.ToString());


}

// Update is called once per frame

void Update () {

}

}






 

아래와 같은 결과가 나오면 성공~




 

4. 배열

간단히 배열을 만들어 보겠습니다.

따라해 보세요.


 

using UnityEngine;

using System.Collections;


public class unityArray : MonoBehaviour {


public int[] aArray = new int[5];

private int[] bArray = new int[] { 6, 7, 8, 9, 10 };



// Use this for initialization

void Start () {


aArray [0] = 1;

aArray [1] = 2;

aArray [2] = 3;

aArray [3] = 4;

aArray [4] = 5;

Debug.Log (aArray[0]);

Debug.Log (aArray[1]);

Debug.Log (aArray[2]);

Debug.Log (aArray[3]);

Debug.Log (aArray[4]);


Debug.Log (bArray[0]);

Debug.Log (bArray[1]);

Debug.Log (bArray[2]);

Debug.Log (bArray[3]);

Debug.Log (bArray[4]);

}

// Update is called once per frame

void Update () {

}

}





 

결과는 아래와 같습니다.


 

다 차원 배열은 책을 참고하세요.!!




 

5. 열거형

이번에도 역시 열거형 작성을 따라해 보세요.



 

using UnityEngine;

using System.Collections;


public class unityEnum : MonoBehaviour {


public Animal animal;


public enum Animal {

mouse, cat, bird

};



// Use this for initialization

void Start () {


}

// Update is called once per frame

void Update () {


Debug.Log (animal);


}

}





 

인스펙터에 항목을 변경하면 변경된 값이 찍히면 성공!!





 

6. unity script reference


 

유니티에서 제공하는 유니티 스크립트 자료 입니다.

스크립트를 짜다 보면 참고할 때가 옵니다.~

http://docs.unity3d.com/kr/current/Manual/CreatingAndUsingScripts.html


 




 

7. 과제

복습하고 결과 화면을 스샷을 찍어 글을 올려 주세요.


 

Posted by 프리랜서 디자이너

 

 

 

 

 

 

 

 

 

0123

 

Posted by 프리랜서 디자이너

 

01234567891011

 

Posted by 프리랜서 디자이너

 

012345

 

Posted by 프리랜서 디자이너

 

0123456789

 

Posted by 프리랜서 디자이너

 

012345678910

 

Posted by 프리랜서 디자이너

 

01234

 

Posted by 프리랜서 디자이너

 

01234567891011121314

 

Posted by 프리랜서 디자이너

유니티 surface shader로 Unlit shader 만들기.

 

회사에서 Unlit 물 셰이더가 필요해서 버텍스 프랴그먼트로 짜려다 너무 귀찮아서 구글 뒤져보니... 커스텀 라이팅으로 unlit을 만들더군요...  저장!!

 

 

CGPROGRAM
 #pragma surface surf NoLighting 

.

.

중략

.

.

 fixed4 LightingNoLighting(SurfaceOutput s, fixed3 lightDir, fixed atten){
         fixed4 c;
         c.rgb = s.Albedo;
         c.a = s.Alpha;
         return c;   
         }

 

기억해두자~

Posted by 프리랜서 디자이너

외곽선 찾기와 양각효과

 

외곽선찾기

대에충 픽셀의 병도 대비를 이용해 외곽선을 찾는다 인데.....

과정이 뭔소린지 이해가 안된다... 걍 일딴 따라하기 정도로 끝을 내야지.. 잘 모르겠넹....

지난번 세피아 효과에서 세피아 패스만 삭제하고, 변수 추가만 있고 나버진 전부 같다....

흑백 패스에서 픽셀셰이더 코드반 변경.............

 

 

흑백효과  픽셀셰이더 코드

 

struct PS_INPUT{
   float2 mUV : TEXCOORD0;
};


float3x3 Kx = {-1,0,1,
               -2,0,2,
               -1,0,1};
              
              
float3x3 Ky = {1,2,1,
               0,0,0,
             -1,-2,-1};

              
sampler2D SceneSampler;

float2 gPixelOffset;

float4 ps_main(PS_INPUT Input) : COLOR{
  
   float Lx = 0;
   float Ly = 0;
  
   for( int y = -1; y<=1; ++y ){
      for( int x = -1; x <=1; ++x ){
         float2 offset = float2(x,y) * gPixelOffset;
         float3 tex = tex2D(SceneSampler, Input.mUV + offset).rgb;
         float luminance = dot(tex, float3(0.3,0.59,0.11));
        
         Lx += luminance * Kx[y+1][x+1];
         Ly += luminance * Ky[y+1][x+1];
      }
   }
  
   float L = sqrt((Lx*Lx) + (Ly*Ly));
   return float4(L.xxx,1);
}

 

 

결과

 

 

 

 

 

 

 

 

양각효과

위에 패스를 복사해 패스 추가후 수정....이것역시 왹곽선 찻기로 나온 것을 포토샵의 양각효과처럼 표현한것임....

조금은 이해가지만 잘 몰겠심 ㅜㅜ 헐;;

 

 

양각효과 픽셀셰이더 코드

 

struct PS_INPUT{
   float2 mUV : TEXCOORD0;
};


float3x3 K =  {-2,-1,0,
               -1,0,1,
               0,1,2 };
              
              
              
              
sampler2D SceneSampler;

float2 gPixelOffset;

float4 ps_main(PS_INPUT Input) : COLOR{
  
   float res = 0;
  
   for( int y = -1; y<=1; ++y ){
      for( int x = -1; x <=1; ++x ){
         float2 offset = float2(x,y) * gPixelOffset;
         float3 tex = tex2D(SceneSampler, Input.mUV + offset).rgb;
         float luminance = dot(tex, float3(0.3,0.59,0.11));
        
         res += luminance * K[y+1][x+1];
      }
   }
  
   res += 0.5f;
   return float4(res.xxx,1);
}


 

 

 

 

결과

 


 

 

 

셰이더 입문 도 이걸로 끝났다...... 물론 다 이해 한것은 아니지만 이다음으로 공부할 이론과 자주 사용하는 함수를 정리하면서 익히자..... 역시 디자이너는 꺼꾸로 배워야 편한듯 ㅎ;; 공부는 힘들어~

 

 

 

 

 

셰이더 프로그래밍 입문 끝!!!

 

 

 

 

 

 

 

 

 

 

Posted by 프리랜서 디자이너

영상처리 기법 흑백/세피아 사진 만들기

 

정점 셰이더

 

struct VS_INPUT{
   float4 mPosition : POSITION;
   float2 mUV : TEXCOORD0;
};

struct VS_OUTPUT{
   float4 mPosition : POSITION;
   float2 mUV : TEXCOORD0;
};

VS_OUTPUT vs_main (VS_INPUT Input){
   VS_OUTPUT Output;
  
   Output.mPosition = Input.mPosition;
   Output.mUV = Input.mUV;
  
   return Output;
}

 

//처음부터 투영좌표에 메쉬가 생성되어있기 때문에 정점좌표와 uv만 입출력한다.

//책 참고~

 

픽셀 셰이더

 

struct PS_INPUT{
   float2 mUV : TEXCOORD0;
};

sampler2D SceneSampler;

float4 ps_main(PS_INPUT Input) : COLOR{
   float4 tex = tex2D(SceneSampler, Input.mUV);
   return tex;
}

//랜더첵스쳐된  SceneSampler 텍스쳐를 입혀준다.

 

 

 

흑백 만들기 /픽셀 셰이더

 

struct PS_INPUT{
   float2 mUV : TEXCOORD0;
};

sampler2D SceneSampler;

float4 ps_main(PS_INPUT Input) : COLOR{
   float4 tex = tex2D(SceneSampler, Input.mUV);
//   tex.rgb = (tex.r + tex.g + tex.b ) /3;
//   tex.rgb = tex.r * 0.3 + tex.g * 0.59 + tex.g * 0.11;
   tex.rgb = dot(tex.rgb, float3(0.3,0.59,0.11));
   return tex;
}

//흑백으로만들어주는 공식에따라 구현

//dot 공식으로 변경하면 더 빠르다고 함.

 

 

 

 

 

 

 

 

 

세피아 만들기/픽셀 셰이더

 

struct PS_INPUT{
   float2 mUV : TEXCOORD0;
};

sampler2D SceneSampler;

float4 ps_main(PS_INPUT Input) : COLOR{
   float4 tex = tex2D(SceneSampler, Input.mUV);
  
     float4 sepia;
 //  sepia.a = tex.a;
 //  sepia.r = tex.r * 0.393f + tex.g * 0.769f + tex.b * 0.189f;
 //  sepia.g = tex.g * 0.349f + tex.g * 0.686f + tex.b * 0.168f;
 //  sepia.b = tex.b * 0.272f + tex.g * 0.534f + tex.b * 0.131f;
  
   sepia.a = tex.a;
   sepia.r = dot(tex.rgb, float3(0.393f,0.769f,0.189f));
   sepia.g = dot(tex.rgb, float3(0.349f,0.686f,0.168f));
   sepia.b = dot(tex.rbb, float3(0.272f,0.534f,0.131f));
  
   return sepia;
}

//마이크로소프트(?)가 권한 세피아 색만들기 공식으로 구현

//dot공식으로 변경해주면 더 빠르다고함.

 

 

 

 

...다음은...외곽선 찾기와 양각효과.....면 이책도 끝이군.... 그다음엔 자주 사용하는 공삭들 정리해놔야겠네....이론이 부족하니 깊이가 없어;;

 

 

 

 

Posted by 프리랜서 디자이너

그림자 기법을 평정한 그림자매핑

 

 

-요약 이론-

그림자 생성단계

1. 랜더링 결과 (빛을 가로막은 첫번째 물체의 깊이)를 저장할 랜더 타깃을 정해준다.

2. 카메라를 광원 위치에 두고 물체들을 그린다.

3. 픽셀 셰이더에서 빛으로부터 현재 픽셀까지의 깊이를 반환한다.

 

그림자 적용단계

1. 랜더링 결과(일반 장면랜더링)를 화면(백버퍼)에 저장한다.

2. 카메라를 눈 위치에 두고 물체를 그린다.

3. 빛으로부터 현재 픽셀까지의 깊이를 그림자맵에 담겨있는 결과와 비교한다. 현재 깊이가 그림자맵의 깊이보다 크면 그림자를 씌운다.

 

 

 

 

 

그림자만들기위한 정점 셰이더

 

struct VS_INPUT {
   float4 mPosition : POSITION;
};

struct VS_OUTPUT{
   float4 mPosition : POSITION;
   float4 mClipPosition : TEXCOORD1;
};

 

float4x4 gWorldMatrix;
float4x4 gLightViewMatrix;
float4x4 gLightProjectionMatrix;

float4 gWorldLightPosition;

 

 

VS_OUTPUT vs_main(VS_INPUT Input){
   VS_OUTPUT Output;
  
   float4x4 lightViewMatrix = gLightViewMatrix;
  
   float3 dirZ = -normalize(gWorldLightPosition.xyz);
   float3 up = float3(0,1,0);
   float3 dirX = cross(up, dirZ);
   float3 dirY = cross(dirZ, dirX);
  
   lightViewMatrix = float4x4(
      float4(dirX, -dot(gWorldLightPosition.xyz, dirX)),
      float4(dirY, -dot(gWorldLightPosition.xyz, dirY)),
      float4(dirZ, -dot(gWorldLightPosition.xyz, dirZ)),
      float4(0, 0, 0, 1));
   lightViewMatrix = transpose(lightViewMatrix);
  
   Output.mPosition = mul(Input.mPosition, gWorldMatrix);
   Output.mPosition = mul(Output.mPosition, lightViewMatrix);
   Output.mPosition = mul(Output.mPosition, gLightProjectionMatrix);
  
   Output.mClipPosition = Output.mPosition;
  
   return Output;

  
}
//gLightViewMatrix  = 대입할 시멘틱이 없어서 정점 셰이더에서 구현했다고함.

 

 

 

 

 

그림자만들기위한 픽셀 셰이더

 

struct PS_INPUT{
   float4 mClipPosition : TEXCOORD1;
};

 

 

float4 ps_main(PS_INPUT Input) : COLOR
{
  
   float Depth = Input.mClipPosition.z / Input.mClipPosition.w;
   return float4(Depth.xxx,1);
  
}

float4x4 gWorldMatrix;
float4x4 gLightViewMatrix;
float4x4 gLightProjectionMatrix;

float4 gWorldLightPosition;
//동차좌표에 있는 값을 화면상의 좌표값으로 사용하려면 w 값을 1로 바꿔 줘야한다.

 

 

 

 

 

 

 

 

 

그림자 입히기 위한 셰이더-원환체

 

정점 셰이더 코드

 


struct VS_INPUT{
   float4 mPosition : POSITION;
   float3 mNormal : NORMAL;
};

struct VS_OUTPUT{
   float4 mPosition : POSITION;
   float4 mClipPosition : TEXCOORD1;
   float mDiffuse : TEXCOORD2;
};

float4x4 gWorldMatrix;
float4x4 gLightProjectionMatrix;
float4x4 gLightViewMatrix;

float4 gWorldLightPosition;

float4x4 gViewProjectionMatrix;

 

VS_OUTPUT vs_main( VS_INPUT Input )
{
   VS_OUTPUT Output;
 
   float4x4 lightViewMatrix = gLightViewMatrix;

   float3 dirZ = -normalize(gWorldLightPosition.xyz);
   float3 up = float3(0,1,0);
   float3 dirX = cross(up, dirZ);
   float3 dirY = cross(dirZ, dirX);
  
   lightViewMatrix = float4x4(
      float4(dirX, -dot(gWorldLightPosition.xyz, dirX)),
      float4(dirY, -dot(gWorldLightPosition.xyz, dirY)),
      float4(dirZ, -dot(gWorldLightPosition.xyz, dirZ)),
      float4(0, 0, 0, 1));
   lightViewMatrix = transpose(lightViewMatrix);

 

 

   float4 worldPosition = mul(Input.mPosition, gWorldMatrix);
   Output.mPosition = mul(worldPosition, gViewProjectionMatrix);

   Output.mClipPosition = mul(worldPosition, lightViewMatrix);
   Output.mClipPosition = mul(Output.mClipPosition, gLightProjectionMatrix);
  
   float3 lightDir = normalize(worldPosition.xyz - gWorldLightPosition.xyz);
   float3 worldNormal = normalize(mul(Input.mNormal, (float3x3)gWorldMatrix));
   Output.mDiffuse = dot(-lightDir, worldNormal);
  
   return Output;
  
}

 

 

 

픽셀 셰이더 코드

 

sampler2D ShadowSampler;
float4 gObjectColor;

struct PS_INPUT{
   float4 mClipPosition : TEXCOORD1;
   float mDiffuse : TEXCOORD2;
};

float4 ps_main(PS_INPUT Input):COLOR
{
   float3 rgb = saturate(Input.mDiffuse ) * gObjectColor;
   float currentDepth = Input.mClipPosition.z / Input.mClipPosition.w;
  
   float2 uv = Input.mClipPosition.xy /Input.mClipPosition.w;
   uv.y = -uv.y;
   uv = uv * 0.5 +0.5;
  
   float shadowDepth = tex2D(ShadowSampler, uv).r;
  
   if(currentDepth > shadowDepth + 0.0000125f){
      rgb *= 0.5f;
   }
  
   return float4(rgb,1.0f);
}

 

 

 

 

 

 

 

 

 

 

다음은...영상처리 기법.. 거의다 했구먼....입문편도.....

 

 

Posted by 프리랜서 디자이너

UV 애니메이션과 울렁효과

 

정점 셰이더

 

struct VS_INPUT{
   float4 mPosition : POSITION;
   float3 mNormal : NORMAL;
   float2 mUV : TEXCOORD0;
};

 

struct VS_OUTPUT{
   float4 mPosition : POSITION;
   float2 mUV: TEXCOORD0;
   float3 mDiffuse : TEXCOORD1;
   float3 mViewDir : TEXCOORD2;
   float3 mReflection : TEXCOORD3;
};

float gWaveHeight;
float gSpeed;
float gWaveFrequency;
float gUVSpeed;

//uv에니메이션과 울렁 효과를 위한 float 타입의 변수 4개 추가

 

float4x4 gWorldMatrix;
float4x4 gViewMatrix;
float4x4 gProjectionMatrix;
float gTime;

float4 gWorldLightingPosition;
float4 gWorldCameraPosition;


VS_OUTPUT vs_main (VS_INPUT Input){
   VS_OUTPUT Output;
   
   float3 cosTimeX = gWaveHeight * cos(gTime * gSpeed + Input.mUV.x * gWaveFrequency);
   float3 cosTimeY = gWaveHeight * cos(gTime * gSpeed + Input.mUV.y * gWaveFrequency);
   Input.mPosition.xy += cosTimeY + cosTimeX;
    //cos(): 함수를 이용해 uv와 버텍스 애니메이션 구현

    //cosTime  을 하나 더 추가해 y축도 추가로 구현.

   
   Output.mPosition = mul(Input.mPosition, gWorldMatrix);
  
   float3 lightDir = Output.mPosition.xyz - gWorldLightingPosition;
   lightDir = normalize(lightDir);
   
   float3 viewDir = normalize(Output.mPosition.xyz - gWorldCameraPosition.xyz);
   Output.mViewDir = viewDir;
   
   Output.mPosition = mul(Output.mPosition, gViewMatrix);
   Output.mPosition = mul(Output.mPosition, gProjectionMatrix);
  
   float3 worldNormal = mul(Input.mNormal,(float3x3)gWorldMatrix);
   worldNormal = normalize(worldNormal);

   
   Output.mDiffuse = dot(-lightDir, worldNormal);
   Output.mReflection = reflect(lightDir,worldNormal);
  
   Output.mUV = Input.mUV + float2(gTime*gUVSpeed, 0);
  
   return Output;
}

 

 

 

 

 

픽셀 셰이더

 

sampler2D DiffuseSampler;
sampler2D SpecularSampler;

float3 gLightColor;

 

 

struct PS_INPUT{
   float2 mUV : TEXCOORD0;
   float3 mDiffuse : TEXCOORD1;
   float3 mViewDir : TEXCOORD2;
   float3 mReflection : TEXCOORD3;
};

float4 ps_main(PS_INPUT Input):COLOR{

   float4 albedo = tex2D( DiffuseSampler, Input.mUV );
   float3 diffuse = gLightColor*albedo.rgb*saturate(Input.mDiffuse);
  
   float3 reflection = normalize(Input.mReflection);
   float3 viewDir = normalize(Input.mViewDir);
   float3 spacular = 0;
  
   if( diffuse.x > 0){
      spacular = saturate(dot(reflection,-viewDir));
      spacular = pow(spacular, 20.0f);
     
      float4 specularIntensity = tex2D( SpecularSampler, Input.mUV);
      spacular *= specularIntensity.rgb * gLightColor;
   }
   
   float3 ambient = float3(0.1f, 0.1f, 0.1f) * albedo;

   return float4(ambient + diffuse + spacular,1);
}

 

 

 

 

 

 

*HLSL*

cos() : 코사인 함수

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Posted by 프리랜서 디자이너

입방체 텍스쳐면 있다면

코드 2줄만으로도 만들 수 있는 환경맵핑

 

 

정점 셰이더

 

float4x4 gWorldMatrix;
float4x4 gWorldViewProjectionMatrix;

float4 gWorldLightPosition;
float4 gWorldCameraPosition;

struct VS_INPUT
{
   float4 mPosition : POSITION;
   float3 mNormal: NORMAL;
   float3 mTangent: TANGENT;
   float3 mBinormal: BINORMAL;
   float2 mUV: TEXCOORD0;
};

struct VS_OUTPUT
{
   float4 mPosition : POSITION;
   float2 mUV: TEXCOORD0;
   float3 mLightDir : TEXCOORD1;
   float3 mViewDir: TEXCOORD2;
   float3 T : TEXCOORD3;
   float3 B : TEXCOORD4;
   float3 N : TEXCOORD5;
};

VS_OUTPUT vs_main( VS_INPUT Input )
{
   VS_OUTPUT Output;

   Output.mPosition = mul( Input.mPosition, gWorldViewProjectionMatrix );
   Output.mUV = Input.mUV;

   float4 worldPosition = mul( Input.mPosition, gWorldMatrix );
   float3 lightDir = worldPosition.xyz - gWorldLightPosition.xyz;
   Output.mLightDir = normalize(lightDir);
  
   float3 viewDir = normalize(worldPosition.xyz - gWorldCameraPosition.xyz);
   Output.mViewDir = viewDir;
  
   float3 worldNormal = mul( Input.mNormal, (float3x3)gWorldMatrix );
   Output.N = normalize(worldNormal);
  
   float3 worldTangent = mul(Input.mTangent, (float3x3)gWorldMatrix );
   Output.T = normalize(worldTangent);
  
   float3 worldBinormal = mul(Input.mBinormal, (float3x3)gWorldMatrix );
   Output.B = normalize(worldBinormal);
  
   return Output;
}

 

 

픽셸 셰이더

 

struct PS_INPUT
{
   float2 mUV : TEXCOORD0;
   float3 mLightDir : TEXCOORD1;
   float3 mViewDir: TEXCOORD2;
   float3 T : TEXCOORD3;
   float3 B : TEXCOORD4;
   float3 N : TEXCOORD5;
};

sampler2D DiffuseSampler;
sampler2D SpecularSampler;
sampler2D NormalSampler;
samplerCUBE EnvironmentSampler;

float3 gLightColor;

float4 ps_main(PS_INPUT Input) : COLOR
{
   float3 tangentNormal = tex2D(NormalSampler, Input.mUV).xyz;
   tangentNormal = normalize(tangentNormal * 2 - 1)*float3(0,0,1);
//노멀값이 너무 쎄서 float3 값을 곱해줘서 환경맵핑이 잘보이게만들어 준다.

   
   float3x3 TBN = float3x3(normalize(Input.T), normalize(Input.B), normalize(Input.N));
   TBN = transpose(TBN);
   float3 worldNormal = mul(TBN, tangentNormal);
  
   float4 albedo = tex2D(DiffuseSampler, Input.mUV);
   float3 lightDir = normalize(Input.mLightDir);
   float3 diffuse = saturate(dot(worldNormal, -lightDir));
   diffuse = gLightColor * albedo.rgb * diffuse;
  
   float3 viewDir = normalize(Input.mViewDir);

//환경맵에도 카메라벡터를 사용하기위해 if문 밖으로 빼주었다.


   float3 specular = 0;
  
   if ( diffuse.x > 0 )
   {
      float3 reflection = reflect(lightDir, worldNormal);

      specular = saturate(dot(reflection, -viewDir ));
      specular = pow(specular, 20.0f);
     
      float4 specularIntensity  = tex2D(SpecularSampler, Input.mUV);
      specular *= specularIntensity.rgb * gLightColor;
     
   }

 

   float3 viewReflect = reflect(viewDir, worldNormal);

//reflect()함수를 사용해 반사벡터를 구한다.


   float3 environment = texCUBE(EnvironmentSampler, viewReflect).rgb;
//   texCUBE()함수를 이용해 환경맵을 구현한다.


   float3 ambient = float3(0.1f, 0.1f, 0.1f) * albedo;
  
   return float4(ambient + diffuse + specular+environment * 0.5f, 1);

//return에 환경맵을 더해주고 강도를 조절을 위해 *0.5f를 해준다.
}

 

 

#HLSL#

texCUBE() : 입방체 텍스쳐를 샘플링하는 함수

reflect() : 카메라의 반사 벡터를 구하는 함수

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Posted by 프리랜서 디자이너

폴리곤 수를 늘리지 않고도

디테일을 추가할 수 있는 법선 맵핑

 

-이론-

각 픽셀의 법선 정보를 담고있는 텍스쳐를 법선맵(normal map)이라고 한다.

 

법선

법선백터의 경우 -1~0~1 의 값을 가진다 하지만 텍스쳐는 0~1의 값을 갖는다  그때문에 법선벡터의 값을 수식으로 0~1을 가진것 처럼 만들어 준다. 그렇게 해주면 법선 벡터의 0이 텍스쳐에서는 0.5가 되게 만들어 준다.

법선맵 RGB = XYZ x 0.5 + 0.5 

 

법선맵을 법선백터로 바꾸는 공식

법선벡터 XYZ = 법선맵 RGB x 2 - 1  

 

법선공간

법선벡터는 각 표면을 기준으로 벡터의 방향이 결정된다

법선백터를 접선공간, 혹은 표면공간이라고 한다.

 

시멘틱

uv의 u나 v의 축을 접선이라고 부른다.

외적 계산으로 또 하나의 축을 구한다.이것을 종 법선이라고 한다.

법선맵,접선,종법선의 정보를 이미 모델이나 텍스쳐가 자지고있기 때문에 시멘틱을 사용하는 것만으로 이점보들을 구할 수 있다.

 

 

-HLSL함수-

TANGENT : 정점에서 접선정보를 불어올때 사용하는 시멘틱.

BINORMAL : 정점에서 종법선정보를 불러올때 사용하는 시멘틱.

transpos() : 전치 행렬을 구하는 HLSL함수.

 

 

 

 

-실습-

 

정점 셰이더

 

struct VS_INPUT{
   float4 mPosition : POSITION;
   float3 mNormal : NORMAL;
   float2 mUV : TEXCOORD0;
   float3 mTangent: TANGENT;
   float3 mBinormal:BINORMAL;
};

//탄젠트와 바이노멀 시멘틱 구조체 선언

 

 

 

struct VS_OUTPUT{
   float4 mPosition : POSITION;
   float2 mUV: TEXCOORD0;
   float3 mLightDir : TEXCOORD1;
   float3 mViewDir: TEXCOORD2;
   float3 T : TEXCOORD3;
   float3 B : TEXCOORD4;
   float3 N : TEXCOORD5;
};

 

 

float4x4 gWorldMatrix;
float4x4 gWorldViewProjectionMatrix;

float4 gWorldLightPosition;
float4 gWorldCameraPosition;


VS_OUTPUT vs_main (VS_INPUT Input){
   VS_OUTPUT Output;
  
   Output.mPosition = mul(Input.mPosition, gWorldMatrix);
   Output.mUV = Input.mUV;
  
   float4 worldPosition = mul(Input.mPosition, gWorldViewProjectionMatrix);
   float3 lightDir = worldPosition.xyz - gWorldLightPosition.xyz;
   Output.mLightDir = normalize(lightDir);
  
  
  
   float3 viewDir = normalize(Output.mPosition.xyz - gWorldCameraPosition.xyz);
   Output.mViewDir = viewDir;
  
   
   
   float3 worldNormal = mul(Input.mNormal,(float3x3)gWorldMatrix);
   Output.N = normalize(worldNormal);
   //노멀 눨드 구하기


   float3 worldTangent = mul(Input.mNormal, (float3x3)gWorldMatrix);
   Output.T = normalize(worldTangent);
    //탄젠트 월드 구하기  


   float3 worldBinormal = mul(Input.mBinormal, (float3x3)gWorldMatrix);
   Output.B = normalize(worldBinormal);
   //바이노멀 월드 구하기


   return Output;
}

 

 

 

픽셀 셰이더

 

sampler2D DiffuseSampler;
sampler2D SpecularSampler;
sampler2D NormalSampler;

//노멀텍스쳐 샘플러

float3 gLightColor;

엠비언트 컬러

 

 

struct PS_INPUT{
   float2 mUV : TEXCOORD0;
   float3 mLightDIr : TEXCOORD1;
   float3 mViewDir : TEXCOORD2;
   float3 T : TEXCOORD3;
   float3 B : TEXCOORD4;
   float3 N : TEXCOORD5;
};

 

float4 ps_main(PS_INPUT Input):COLOR{

   float3 tangentNormal = tex2D( NormalSampler, Input.mUV).xyz;
   tangentNormal = normalize(tangentNormal * 2 - 1);
//탄젠트노멀을 0~1까지로 바꿔주는 수식  


   float3x3 TBN = float3x3(normalize(Input.T), normalize(Input.B),normalize(Input.N));
   TBN = transpose(TBN);
//전치 행열  


   float3 worldNormal = mul(TBN, tangentNormal);
  
   float3 lightDir = normalize(Input.mLightDIr);
   float3 diffuse = saturate(dot(worldNormal, -lightDir));
  
   float4 albedo = tex2D(DiffuseSampler, Input.mUV);
   diffuse = gLightColor * albedo.rgb * diffuse;
  
   float3 specular = 0;
      if(diffuse.x>0){
         float3 reflection = reflect(lightDir, worldNormal);
         float3 viewDir = normalize(Input.mViewDir);
        
         specular = saturate(dot(reflection, -viewDir));
         specular = pow(specular, 20.0f);
        
         float4 specularIntendity = tex2D(SpecularSampler, Input.mUV);
         specular *= specularIntendity.rgb * gLightColor;
      }
  
   float3 ambient = float3(0.1f,0.1f,0.1f) * albedo;
  
   return float4(ambient + diffuse * specular,1);

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Posted by 프리랜서 디자이너

-만화 같은 명암을 입히는 툰 셰이더-

 

 

희안하게 주석 넣으면 오류난다....혹 이거 보시는 분들은 랜더몽키에 주석 빼시길....

 

 

 

정점 셰이더


struct VS_INPUT{
   float4 mPosition : POSITION;
   float3 mNormal : NORMAL;
};

struct VS_OUTPUT{
   float4 mPosition : POSITION;
   float3 mDiffuse : TEXCOORD1;
};


float4x4 gWorldViewProjectionMatrix;
//뷰,월드,프로젝션을 미리 구해 합쳐놓은 변수.
float4x4 gInvWorldMatrix;
//라이트 구하기 위한 역행열 변수.
float4 gWorldLightPosition;
//라이트 포지션.


VS_OUTPUT vs_main(VS_INPUT Input){

   VS_OUTPUT Output;
  
   Output.mPosition = mul(Input.mPosition, gWorldViewProjectionMatrix);
   //미리 구해놓은 행열을 가지고 포지션을 구한다.


   float3 objectLightPosition = mul(gWorldLightPosition,gInvWorldMatrix);

//라이트 포지션과 역행열을 이용해 라이트 포지션 구하기.


   float3 LightDir = normalize(Input.mPosition.xyz - objectLightPosition);
//   버텍스 포지션과 라이트 포지션으로 라이트 구현하기.


   Output.mDiffuse = dot(-LightDir, normalize(Input.mNormal));
//구현한 라이트와 노멀을 닷 공식으로 디퓨즈 구현.   
   return (Output);
}

 

 

 

 

픽셸셰이더

 

float3 gSurfaceColor;

//엠비언트 컬러쯤으로 보면된다....

 

struct PS_INPUT{
   float3 mDiffuse : TEXCOORD1;
};

 

float4 ps_main(PS_INPUT Input):COLOR{
   float3 diffuse = saturate(Input.mDiffuse);

//세튜레이트로 1를 넘는값은자른다.
   diffuse = ceil(diffuse * 5)/5.0f;
   //디퓨즈*5/5.0 한 값을 무조건 오림 함수로
   return float4(gSurfaceColor * diffuse.xyz,1);

//엠비언트 컬러에 디퓨즈를 곱해 반환.
}

 

**HLSL함수**

ceil():무조건 올림 함수

 

 

 

 

 

 

 

 

 

 

 

 

 

Posted by 프리랜서 디자이너

물체에 색을 입히는 디퓨즈/스페큘러맵핑

 

뭐야 왜 주석넣으면 에러나는거지??

지난 기본라이팅 파일을 복사해 이름만 바꿔서 필요한 부분만 추가해서 하고있다......

 

 

 

 

 

정점 셰이더

 

struct VS_INPUT{
   float4 mPosition : POSITION;
   float3 mNormal : NORMAL;
   float2 mUV : TEXCOORD0;
};

//Diffuse 를 위해 UV TEXCOORD0 를 추가해준다.

 

 

 

struct VS_OUTPUT{
   float4 mPosition : POSITION;
   float2 mUV: TEXCOORD0;
   float3 mDiffuse : TEXCOORD1;
   float3 mViewDir : TEXCOORD2;
   float3 mReflection : TEXCOORD3;
};

//Diffuse 를 위해 UV TEXCOORD0 를 추가해준다.

 

float4x4 gWorldMatrix;
float4x4 gViewMatrix;
float4x4 gProjectionMatrix;

float4 gWorldLightingPosition;
float4 gWorldCameraPosition;


VS_OUTPUT vs_main (VS_INPUT Input){
   VS_OUTPUT Output;
  
   Output.mPosition = mul(Input.mPosition, gWorldMatrix);
  
   float3 lightDir = Output.mPosition.xyz - gWorldLightingPosition;
   //월드노멀에 라이팅 구하기
   lightDir = normalize(lightDir);
   //정규화.
  
   float3 viewDir = normalize(Output.mPosition.xyz - gWorldCameraPosition.xyz);
   Output.mViewDir = viewDir;
   //정반사광 구하기.
  
   Output.mPosition = mul(Output.mPosition, gViewMatrix);
   Output.mPosition = mul(Output.mPosition, gProjectionMatrix);
  
   float3 worldNormal = mul(Input.mNormal,(float3x3)gWorldMatrix);
   //월드노멀 구하기.
   worldNormal = normalize(worldNormal);
   //정규화.
  
   Output.mDiffuse = dot(-lightDir, worldNormal);
   Output.mReflection = reflect(lightDir,worldNormal);
  
   Output.mUV = Input.mUV;
   //OutPut에 uv를 전달해 준다.


   return Output;
}

 

 

 

 

 

픽셀 셰이더

 

sampler2D DiffuseSampler;
sampler2D SpecularSampler;

float3 gLightColor;

//텍스쳐 참조 추가, 라이트 컬러 추가

 

struct PS_INPUT{
   float2 mUV : TEXCOORD0;
   float3 mDiffuse : TEXCOORD1;
   float3 mViewDir : TEXCOORD2;
   float3 mReflection : TEXCOORD3;
};

//uv TEXCOORD 받기

 

float4 ps_main(PS_INPUT Input):COLOR{

   float4 albedo = tex2D( DiffuseSampler, Input.mUV );
   float3 diffuse = gLightColor*albedo.rgb*saturate(Input.mDiffuse);
   //tex2D함수 디퓨즈 텍스쳐 적용

  //diffuse에 텍스쳐와 라이트 컬러 적용


   float3 reflection = normalize(Input.mReflection);
   float3 viewDir = normalize(Input.mViewDir);
   float3 spacular = 0;
  
   if( diffuse.x > 0){
      spacular = saturate(dot(reflection,-viewDir));
      spacular = pow(spacular, 20.0f);
     
      float4 specularIntensity = tex2D( SpecularSampler, Input.mUV);
      spacular *= specularIntensity.rgb * gLightColor;

  //tex2D 함수로 스펙큘러 텍스쳐추가및 라이트컬러 적용
   }
   //diffuse.x값이 0보다 크면  스펙큘러 구현.
  
   float3 ambient = float3(0.1f, 0.1f, 0.1f) * albedo;

  //엠비언트에 알베도 적용

   return float4(ambient + diffuse + spacular,1);
}

 

 

 

 

 

 

 

 

 

 

 

 

 

Posted by 프리랜서 디자이너

기본적인 조명 셰이더

 

 

정점셰이더

 

struct VS_INPUT{
   float4 mPosition : POSITION;
   float3 mNormal : NORMAL;
};

 

 

struct VS_OUTPUT{
   float4 mPosition : POSITION;
   float3 mDiffuse : TEXCOORD1;
   float3 mViewDir : TEXCOORD2;
   float3 mReflection : TEXCOORD3;
};

 

 

float4x4 gWorldMatrix;
float4x4 gViewMatrix;
float4x4 gProjectionMatrix;

float4 gWorldLightingPosition;
float4 gWorldCameraPosition;

 


VS_OUTPUT vs_main (VS_INPUT Input){
   VS_OUTPUT Output;
  
   Output.mPosition = mul(Input.mPosition, gWorldMatrix);
  
   float3 lightDir = Output.mPosition.xyz - gWorldLightingPosition;
   //월드노멀에 라이팅 구하기
   lightDir = normalize(lightDir);
   //정규화.
  
   float3 viewDir = normalize(Output.mPosition.xyz - gWorldCameraPosition.xyz);
   Output.mViewDir = viewDir;
   //정반사광 구하기.
  
   Output.mPosition = mul(Output.mPosition, gViewMatrix);
   Output.mPosition = mul(Output.mPosition, gProjectionMatrix);
  
   float3 worldNormal = mul(Input.mNormal,(float3x3)gWorldMatrix);
   //월드노멀 구하기.
   worldNormal = normalize(worldNormal);
   //정규화.
  
   Output.mDiffuse = dot(-lightDir, worldNormal);
   Output.mReflection = reflect(lightDir,worldNormal);
  
   return Output;
}

 

 

픽셀 셰이더

 

struct PS_INPUT{
   float3 mDiffuse : TEXCOORD1;
   float3 mViewDir : TEXCOORD2;
   float3 mReflection : TEXCOORD3;
};

 

float4 ps_main(PS_INPUT Input):COLOR{
   float3 diffuse = saturate(Input.mDiffuse);
  
   float3 reflection = normalize(Input.mReflection);
   float3 viewDir = normalize(Input.mViewDir);
   float3 spacular = 0;
  
   if( diffuse.x > 0){
      spacular = saturate(dot(reflection,-viewDir));
      spacular = pow(spacular, 20.0f);
   }
   //diffuse.x값이 0보다 크면  스펙큘러 구현.
  
   float3 ambient = float3(0.1f, 0.1f, 0.1f);

//엠비언트추가

   return float4(ambient+diffuse+spacular,1);
}

 

 

 

 

**HLSL함수**

normalize() :정규화 함수

saturate() : 0~1을 넘는 값을 잘라 냄

reflect() : 벡터반사 함수

pow() : 거듭제곱 함수

dot() : 내적 함수

 

 

 

 

 

 

 

 

 

 

 

 

 

Posted by 프리랜서 디자이너

텍스쳐 맵핑

(기본에작업된 크드를 재활용하자.... 왜냐면 귀찮으니깐....쩝....)

 

 

 

 

1. 정점 셰이더

 

struct VS_INPUT{
   float4 mPosition : POSITION;
   float2 mTexCoord : TEXCOORD0;

//인풋 구조체에 uv 추가
};

 

struct VS_OUTPUT{
   float4 mPosition : POSITION;
   float2 mTexCoord : TEXCOORD0;

//아웃풋 구조채에 uv추가
};

 

 

float4x4 gWorldMatrix;
float4x4 gViewMatrix;
float4x4 gProjectionMatrix;

 

 

VS_OUTPUT vs_main(VS_INPUT Input){
   VS_OUTPUT Output;
   Output.mPosition = mul( Input.mPosition, gWorldMatrix );
   Output.mPosition = mul( Output.mPosition, gViewMatrix );
   Output.mPosition = mul( Output.mPosition, gProjectionMatrix );
  
   Output.mTexCoord = Input.mTexCoord;
   //인풋uv받아서 아웃풋에 전달한다.
   return Output;
}

 

 

 

 

2. 픽셀 셰이더

 


sampler2D DiffuseSampler;

//2D 텍스쳐 선언

 

struct PS_INPUT{
   float2 mTexCoord : TEXCOORD;
};

//정점셰이더의 uv 인풋

 

float4 ps_main(PS_INPUT Input) : COLOR{
   float4 albedo = tex2D(DiffuseSampler, Input.mTexCoord);

//albedo라는 변수에 tex2D함수로 텍스쳐와 uv를 담는다.


   return albedo.rgba;

//albedo의rgba속성을 출력한다.
}

 

 

 

**팁**

HLSL내장 함수

tex2D(DiffuseSampler, Input.mTexCoord);

함수이름(텍스쳐, Input.uv);

이 함수로 쉽게 구현할수있다.

 

 

 

 

 

 

 

다음은 기본적인 조명 셰이더.....복습이라 조금 지겹지만 좋다..이걸로 더 제대로 셰이더를 알게 될테니...

 

 

 

 

Posted by 프리랜서 디자이너

셰이더 프로그래밍 입문-1

 

오늘부터 짬짬히 hlsl 셰이더 공부를 시작한다. 이미 예전에 포프님의 블로그를 통해 일부 공부했었지만.. 책이 나왔으니 다시 제대로 공부해보장.....물론 내 나름의 정리이니까 이포스팅을 보는 다른분들은 도움이 안될거임..ㅎㅎ;;

"같이 공부하실분은 책을 사거나 블로그로 가보세요~"

교재는 "셰이더 프로그램밍 입문"........

 

 

 

1. 공부 준비하기

별다른 준비는 필요업고 걍 AMD사의 랜더몽키를 설치하면된다.....

 

 

 

 

 

2.진짜 쉬운 빨강 셰이더

 

 

1)정점셰이더 코드

 

struct VS_INPUT{
   float4 mPosition : POSITION;
};

//구조체에는 ; 붙는다

 

struct VS_OUTPUT{
   float4 mPosition : POSITION;
};

//구조체에는 ; 붙는다

 

float4x4 gWorldMatrix;

//월드행열
float4x4 gViewMatrix;

//뷰 행열
float4x4 gProjectionMatrix;

//투영행열

 

VS_OUTPUT vs_main(VS_INPUT Input){
  
   VS_OUTPUT Output;
  
   Output.mPosition = mul( Input.mPosition, gWorldMatrix );

//정점의 월드공간 연산
   Output.mPosition = mul( Output.mPosition, gViewMatrix );

//월드 공간을 뷰공간으로 연산
   Output.mPosition = mul( Output.mPosition, gProjectionMatrix );

//뷰 공간을 투영공간으로 연산
   
   return Output;
}

 

 

**팁**

정점 셰이더 함수의 의미

VS_OUTPUT vs_main(VS_INPUT Input)

함수의 이름은 vs_main 이다.

함수의 인수는 VS_INPUT 데이터형의 input 이다.

함수의 반환값은 VS_OUTPUT 데이터형이다.

 

 

2)픽셀셰이더 코드

 

float4 ps_main() : COLOR{
   return float4 (1.0f,0.0f,0.0f,1.0f);
}

//반한되는 r,g,b,a의 값

 

 

**팁**

픽셀셰이더 함수의 의미

float4 ps_main() : COLOR

함수의이름은 ps_main 이다.

매계변수를 받지 않는다.

반환형은 float4 이다.

반환값을 백 버퍼의 컬러값으로 처리한다.

.

.

.

.

.

.

 

 

 

올만에 다시하니 오타가 또 나오네...예전에 처음 할때보다는 99% 좋아지긴 했지만 짱난다.....

다음은 텍스쳐 맵핑....

 

 

Posted by 프리랜서 디자이너

내장 BlinnPhong Shader를 커스텀 라이트 로 표현

 

커스텀 버텍스 스펙큘러 라이트......알파에 스펙뮬러를 적용 안한 라이트라 버텍스로 스펙쿨러가 적용되고있다....

예제는 여기 까지지만 노멀과 림, 리플렉션 등등을 넣으려면 이 커스텀 라이트는 기본 모델일뿐 적용할곳을 몇군데 바꿔야 하는 라이트가 되겠네....역시 예제는 예제일뿐... 실제 적용은 다른 얘기지....

 

다음 공부는 거의 모든 기능이 들어간 서피스 라이트 하나 구현해보고 플레그먼크 셰이더로 넘어가 보자.....

 

 

Shader "DY/surf_Specular" {
 Properties{
  _MainTex("Texture",2D)="white"{}
 }
 
 SubShader{
  Tags{"RenderType"="Opaque"}
  CGPROGRAM
  #pragma surface surf SimpleSpecular
  
  half4 LightingSimpleSpecular (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten){

   half3 h = normalize (lightDir + viewDir);

 //스펙큘러를 위한 하프노말.

 

   half diff = max(0, dot(s.Normal, lightDir));

//디뷰즈 라이트를 위한 닷..max함수로 음수로 못돌아가게 한것 같다.
   
   float nh = max(0,dot(s.Normal,h));

//하프노멀에 노멀을 닷 해 스펙큘러를 구했다 역시나 max함수 사용.
   
   float spec = pow(nh, 48.0);

//pow함수를 이용해 스펙큘러 구현.
   
   half4 c;
   c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * spec) * (atten * 2);

//모든 라이트가 버텍스라이트로 들어가 있다.

 

   c.a = s.Alpha;

//여기서 알파는 별달리 의미가 없다


   return c;
  }
  
  struct Input{
   float2 uv_MainTex;
  };
  
  sampler2D _MainTex;
  
  void surf (Input IN, inout SurfaceOutput o){
   o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
  }
  
  ENDCG
 }
 Fallback"Diffuse"
}

 

 

 

 

 

 

 

 

 

 

Posted by 프리랜서 디자이너

surface shader Custom Light 예제 따라하기~

 

 

 

==================================================================================================================

심플 램버트 라이트.....내장 램버트 라이트를 따라한 커스텀 라이트

 

Shader "DY/surf_Diffuse" {
 Properties{
  _MainTex("Diffuse",2D)="white"{}
 }
 SubShader{
  Tags {"RanderType"="Opaque"}
  
  CGPROGRAM
  #pragma surface surf SimpleLambert
  
  half4 LightingSimpleLambert(SurfaceOutput s, half3 lightDir, half atten){
   half NdotL = dot(s.Normal, lightDir);
   half4 c;
   c.rgb = s.Albedo * _LightColor0.rgb *(NdotL * atten *2);
   c.a = s.Alpha;
   return c;
  }
  //커스텀 램버트 라이트

 


  struct Input{
   float2 uv_MainTex;
  };
  
  sampler2D _MainTex;
  
  void surf (Input IN, inout SurfaceOutput o){
   o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
  }
  
  ENDCG
 }
 Fallback"Diffuse"
}

 

 

 

 

==================================================================================================================

 

하프 램버트 라이트.....밸브의 하프 램버트를 구현한 커스텀 라이트

 

Shader "DY/surf_wraf" {
 Properties{
  _MainTex("Diffuse",2D)="white"{}
 }
 SubShader{
  Tags {"RanderType"="Opaque"}
  
  CGPROGRAM
  #pragma surface surf WrafLambert
  
  half4 LightingWrafLambert(SurfaceOutput s, half3 lightDir, half atten){
   half NdotL = dot(s.Normal, lightDir);
   half diff = NdotL*0.5+0.5;
   half4 c;
   c.rgb = s.Albedo * _LightColor0.rgb *(diff * atten *2);
   c.a = s.Alpha;
   return c;
  }
  //커스텀 하프램버트 라이트

  //half diff = NdotL*0.5+0.5;

 


  struct Input{
   float2 uv_MainTex;
  };
  
  sampler2D _MainTex;
  
  void surf (Input IN, inout SurfaceOutput o){
   o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
  }
  
  ENDCG
 }
 Fallback"Diffuse"
}

 

 

 

 

 

==================================================================================================================

 

컬러 텍스쳐를 활용한 커스텀 툰 라이팅.........텍스쳐 메모리 때문에 아마 사용할 일은 없을듯 

 

Shader "DY/Toon Ramp" {
 Properties{
  _MainTex("Diffuse",2D)="white"{}
  _Ramp("shading Ramp",2D)="gray"{}
 }
 SubShader{
  Tags {"RanderType"="Opaque"}
  
  CGPROGRAM
  #pragma surface surf Ramp
  
  sampler2D _Ramp;
  
  half4 LightingRamp(SurfaceOutput s, half3 lightDir, half atten){
   half NdotL = dot(s.Normal, lightDir);
   half diff = NdotL*0.5+0.5;
   half3 ramp = tex2D(_Ramp, float2(diff)).rgb;
   half4 c;
   c.rgb = s.Albedo * _LightColor0.rgb *ramp*(atten *2);
   c.a = s.Alpha;
   return c;
  }

//툰 램프 커스텀 라이트
//half3 ramp = tex2D(_Ramp, float2(diff)).rgb;

 

  struct Input{
   float2 uv_MainTex;
  };
  
  sampler2D _MainTex;
  
  void surf (Input IN, inout SurfaceOutput o){
   o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
  }
  
  ENDCG
 }
 Fallback"Diffuse"
}

 

 

 

 

=======================================================================================================================

 

 

 

 

 

 

 

 

 

 

 

 

 

Posted by 프리랜서 디자이너