'Work'에 해당되는 글 183건

  1. 2013.06.21 iTween Path collider 충돌시 멈추기
  2. 2013.06.21 ITween Example Tutorial
  3. 2013.06.20 유니티 라이트 프로브 셰이더 예제
  4. 2013.05.09 TD CameraControl C#
  5. 2013.05.07 유니티 C# 공부 모음
  6. 2013.04.22 유니티 surface shader로 Unlit shader 만들기.
  7. 2012.12.12 셰이더 프로그래밍 입문-11(마지막단원) 1
  8. 2012.12.10 셰이더 프로그래밍 입문-10
  9. 2012.12.04 셰이더 프로그래밍 입문-9
  10. 2012.12.03 셰이더 프로그래밍 입문-8
  11. 2012.11.27 셰이더 프로그래밍 입문-7
  12. 2012.11.21 셰이더 프로그래밍 입문-6
  13. 2012.11.19 셰이더 프로그래밍 입문-5
  14. 2012.11.16 셰이더 프로그래밍 입문-4
  15. 2012.11.14 셰이더 프로그래밍 입문-3 2
  16. 2012.11.13 셰이더 프로그래밍 입문-2
  17. 2012.11.12 셰이더 프로그래밍 입문-1
  18. 2012.08.27 unity surface shader 공부 7 - surface shader custom Light 예제 따라하기
  19. 2012.08.24 unity surface shader 공부 6 - surface shader custom Light 예제 따라하기
  20. 2012.08.24 Custom Lighting models in Surface Shaders
  21. 2012.08.21 unity surface shader 공부 5 - surface shader 예제 따라하기
  22. 2012.08.20 unity surface shader 공부 4 - surface shader 예제 따라하기
  23. 2012.08.17 unity surface shader 공부 3 - surface shader 예제 따라하기
  24. 2012.07.27 unity surface shader 공부 2 - surface shader 예제 따라하기
  25. 2012.07.26 unity surface shader 공부 1 - surface shader 예제 따라하기
  26. 2012.07.26 SurfaceShaderLighting
  27. 2012.07.26 SurfaceShaders
  28. 2012.07.23 unity fixed shader 로 짜는 shader 공부 6- 염색셰이더 1
  29. 2012.07.20 한방에 모아보는 레퍼런스 1
  30. 2012.07.20 unity fixed shader 로 짜는 shader 공부 5 - 유니티 라이트맵 모바일 셰이더 분석?
TA/Unity2013. 6. 21. 10:03

iTween Path collider충돌시 멈추기

 

using UnityEngine;
using System.Collections;

public class test : MonoBehaviour {


 
 void Start () {
 iTween.MoveTo(gameObject, iTween.Hash("path", iTweenPath.GetPath("New Path 3"), "time",5,"easetype",iTween.EaseType.linear));
 }
 
 void stop(){
  iTween.Stop(gameObject);
 }
 
 void OnTriggerEnter(Collider col)
 {
  stop();
 }
}

Posted by 프리랜서 디자이너
TA/Unity2013. 6. 21. 07:41

ITween Example Tutorial

 

http://hatoru.tistory.com/157

 

< 유니티 에셋 1 : ITween Example Tutorial > 

*공식 ITween Example : http://itween.pixelplacement.com/examples.php

Animating 2D(GUITextures)

-GUITextures를 이용한 2D 애니메이션를 ITween으로 구현한다.



1. 패키지를 Import 한다.
[ Assets - Import Package - Custom Package... ]



2. GUITexture의 구성

 -PresentationScreen : 빈 오브젝트 (스크립트를 여기에 Add한다)
   -iTweenLogo
   -PresentsText
   -whiteDiagonalGradient : ( 자식 오브젝트는 모두 GUITexture이다)

* PresentationScreen 활성화

* TitleScreen 비활성화

 

3. GUITexture 만들기
Create Other - GUI Texture를 이용해서 만든다

4. GUITexture 좌표
 
 각 GUITexture의 Inspector의 Pixel Insert 좌표를 화면에 보여질 위치에 설정한다. 
  - 화면 밖에서 화면 안으로 들어 오는 효과 일 경우 이 좌표는 목적지가 된다. (IN : MoveFrom()함수 사용)
  - 화면 안에서 확면 밖으로 나가는 경우 이 좌표는 시작점이 된다.  (OUT : MoveTo()함수 사용)

5. iTween의 함수 사용 법

  iTween.MoveFrom(gameObject,iTween.Hash("x",-0.4,"time",0.6,"delay",1.2));
     --
x축 -0.4에서 부터 게임오브젝트에 설정되 좌표까지
      --속도(time)는 0.6
     --이동후 1.2의 시간 만큼 애니메이션 시간을 흘려보낸다(delay)

< iTween의 해쉬 String >

Property Name Type Purpose
name string an individual name useful for stopping iTweens by name
audiosource AudioSource for which AudioSource to use
volume float or double for the target level of volume
pitch float or double for the target pitch
time float or double

for the time in seconds the animation will take to complete
애니메이션이 완료되는 시간이며 속도를 설정한다.

delay float or double for the time in seconds the animation will wait before beginning
애니메이션 시작 전 대기 시간을 설정 한다.
easetype EaseType or string for the shape of the easing curve applied to the animation
애니메이션에 적용할  완곡 곡선 설정
looptype LoopType or string for the type of loop to apply once the animation has completed
onstart string for the name of a function to launch at the beginning of the animation
onstarttarget GameObject for a reference to the GameObject that holds the "onstart" method
onstartparams Object for arguments to be sent to the "onstart" method
onupdate string for the name of a function to launch on every step of the animation
onupdatetarget GameObject for a reference to the GameObject that holds the "onupdate" method
onupdateparams Object for arguments to be sent to the "onupdate" method
oncomplete string

for the name of a function to launch at the end of the animation
애니메이션이 끝났을때 지정된 함수를 수행한다.

oncompletetarget GameObject

for a reference to the GameObject that holds the "oncomplete" method
"oncomplete"를 hold하고 있는 게임오브젝트 참조

oncompleteparams Object for arguments to be sent to the "oncomplete" method
ignoretimescale boolean setting this to true will allow the animation to continue independent of the current time which is helpful for animating menus after a game has been paused by setting Time.timeScale=0

예)
 void SwitchToTitleScreen()
{
    gameObject.SetActiveRecursively(false);  //현재 오브젝트를 비활성화 시킨다.
    titleScreen.SetActiveRecursively(true);     //다음 오브젝트를 활성화 시킨다.
}
==> 애니메이션이 끝나고 Swtich() 함수를 부르기 위한 hash String을 사용한다. 
        "oncomplete"

iTween.FadeTo(whiteDiagonalGradient,iTween.Hash("alpha",0,"time",.6,"delay",2.8,"easetype","easeincubic"
                    ,"oncomplete","SwitchToTitleScreen","oncompletetarget",gameObject));

< iTween 함수 >

구분

함수 

설명 

 Scale

scaleTo()
scaleFrom() 

 

Punches 

 punchPosition()
punchRotation()

 

Shake 

shake() 

 

Stab 

 stab()

 

Audio 

 audioTo()

 

Rotate 

roateTo()
rotateFrom()
rotateBy() 

 

Fade 

fadeTo()
fadeFrom() 

 

color 

colorTo() 
colorFrom()

 

Movement 

moveTo()
moveFrom()
moveToBezier() 

 


< iTween easing type >
링크 : http://www.robertpenner.com/easing/



6. coroutin을 이용한 활성화/비활성화
IEnumerator SwitchToPresentationScreen()
{
   yield return new WaitForSeconds(2);                   //2초간 대기한다.
    gameObject.SetActiveRecursively(false);            //현재 오브젝트 비활성화
    presentationScreen.SetActiveRecursively(true);  //활성화

}

void Update()
{
    if(Input.GetMouseButtonDown(0))  //coroutine 이 실행될 조건
    {
        StartCoroutine(SwitchToPresentationScreen());   
    }
}

'TA > Unity' 카테고리의 다른 글

SDK....빌드셋팅 한방 Xamarin...  (0) 2013.07.23
iTween Path collider 충돌시 멈추기  (0) 2013.06.21
유니티 라이트 프로브 셰이더 예제  (0) 2013.06.20
TD CameraControl C#  (0) 2013.05.09
유니티 C# 공부 모음  (0) 2013.05.07
Posted by 프리랜서 디자이너
TA/Unity2013. 6. 20. 10:59

유니티 라이트 프로브 셰이더 예제

 

 

 

 

플레그먼트

 

Shader "Probes" {
Properties {
_MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
_SHLightingScale("LightProbe influence scale",float) = 1
}

SubShader {
Tags { "RenderType"="Opaque" "LightMode"="ForwardBase"}
LOD 100

CGINCLUDE
#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;

float _SHLightingScale;

struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
fixed3 spec : TEXCOORD1;
fixed3 SHLighting: TEXCOORD2;
};


v2f vert (appdata_full v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord;
float3 worldNormal = mul((float3x3)_Object2World, v.normal);
float3 shl = ShadeSH9(float4(worldNormal,1));
o.SHLighting = shl * _SHLightingScale;

return o;
}
ENDCG

Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
fixed4 frag (v2f i) : COLOR
{
fixed4 c = tex2D (_MainTex, i.uv);

c.rgb *= i.SHLighting;

return c;
}
ENDCG 
}
}
}

 

 

 

서피스

 

Shader "Custom/ModifyLightProbes" {

 

Properties {  _Color ("Main Color", Color) = (1,1,1,1)      

         _MainTex ("Base (RGB)", 2D) = "white" {} 

  _Amount ("SH scale", Float) = 1   

}   

 

SubShader {  

      Tags { "RenderType"="Opaque" }       

LOD 200               

CGPROGRAM       

#pragma surface surf Lambert noambient vertex:vert       

#pragma debug        

 

sampler2D _MainTex;       

fixed4 _Color;       

float _Amount;        

 

struct Input {  

float2 uv_MainTex;           

float3 shLight;       

 };               

 

 

void vert (inout appdata_full v, out Input o) {

            // evaluate SH light           

float3 worldN = mul ((float3x3)_Object2World, SCALED_NORMAL);           

o.shLight = ShadeSH9 (float4 (worldN, 1.0));       

}        

 

 

 

void surf (Input IN, inout SurfaceOutput o) {           

half4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;           

     o.Albedo = c.rgb;           

o.Alpha = c.a;                       

 

// modify the SH lighting anyway you want,           

// here's just simple scaling           

float3 shLight = _Amount * IN.shLight;       

                

// emission is just added to the final color,           

     // so SH light needs to be multiplied by albedo           

o.Emission = o.Albedo * shLight; 

     

}       

ENDCG   

 }   

FallBack "Diffuse"

}

 

 

 

'TA > Unity' 카테고리의 다른 글

iTween Path collider 충돌시 멈추기  (0) 2013.06.21
ITween Example Tutorial  (0) 2013.06.21
TD CameraControl C#  (0) 2013.05.09
유니티 C# 공부 모음  (0) 2013.05.07
Texture Matrix in Fixed Function  (0) 2012.07.18
Posted by 프리랜서 디자이너
TA/Unity2013. 5. 9. 07:53

TD 예제 스크립트 카메라 컨트롤러

 

using UnityEngine;
using System.Collections;

 

#pragma warning disable 0168 // variable declared but not used.
#pragma warning disable 0219 // variable assigned but not used.
#pragma warning disable 0414 // private field assigned but not used.

 

public class CameraControl : MonoBehaviour {

 //public enum _Platform{Hybird, Mouse&Keyboard, Touch} 키보드와 터치 모두 가능....
 //public _Platform platform;

 

 public float panSpeed=5;
 public float zoomSpeed=5;
 
 private float initialMousePosX;
 private float initialMousePosY;
 
 private float initialRotX;
 private float initialRotY;
 
 
 public float minPosX=-10;
 public float maxPosX=10;
 
 public float minPosZ=-10;
 public float maxPosZ=10;
 
 public float minRadius=8;
 public float maxRadius=30;
 
 public float minRotateAngle=10;
 public float maxRotateAngle=89;

 //calculated deltaTime based on timeScale so camera movement speed always remain constant
 private float deltaT;
 
 private Transform cam;
 private Transform thisT;

 void Awake(){
  thisT=transform;
  
  cam=Camera.main.transform;
 }
 
 // Use this for initialization
 void Start () {
  minRotateAngle=Mathf.Max(10, minRotateAngle);
  maxRotateAngle=Mathf.Min(89, maxRotateAngle);
  
  minRadius=Mathf.Max(1, minRadius);
 }
 
 // Update is called once per frame
 void Update () {
  
  if(Time.timeScale==1) deltaT=Time.deltaTime;
  else deltaT=Time.deltaTime/Time.timeScale;
  
  
  #if UNITY_EDITOR || (!UNITY_IPHONE && !UNITY_ANDROID)
  
  //mouse and keyboard
  if(Input.GetMouseButtonDown(1)){
   initialMousePosX=Input.mousePosition.x;
   initialMousePosY=Input.mousePosition.y;
   initialRotX=thisT.eulerAngles.y;
   initialRotY=thisT.eulerAngles.x;
  }

  if(Input.GetMouseButton(1)){
   float deltaX=Input.mousePosition.x-initialMousePosX;
   float deltaRotX=(.1f*(initialRotX/Screen.width));
   float rotX=deltaX+deltaRotX;
   
   float deltaY=initialMousePosY-Input.mousePosition.y;
   float deltaRotY=-(.1f*(initialRotY/Screen.height));
   float rotY=deltaY+deltaRotY;
   float y=rotY+initialRotY;
   
   //limit the rotation
   if(y>maxRotateAngle){
    initialRotY-=(rotY+initialRotY)-maxRotateAngle;
    y=maxRotateAngle;
   }
   else if(y<minRotateAngle){
    initialRotY+=minRotateAngle-(rotY+initialRotY);
    y=minRotateAngle;
   }
   
   thisT.rotation=Quaternion.Euler(y, rotX+initialRotX, 0);
  }
  
  
  Quaternion direction=Quaternion.Euler(0, thisT.eulerAngles.y, 0);
  
  if(Input.GetButton("Horizontal")) {
   Vector3 dir=transform.InverseTransformDirection(direction*Vector3.right);
   thisT.Translate (dir * panSpeed * deltaT * Input.GetAxisRaw("Horizontal"));
  }

  if(Input.GetButton("Vertical")) {
   Vector3 dir=transform.InverseTransformDirection(direction*Vector3.forward);
   thisT.Translate (dir * panSpeed * deltaT * Input.GetAxisRaw("Vertical"));
  }
  
  //cam.Translate(Vector3.forward*zoomSpeed*Input.GetAxis("Mouse ScrollWheel"));
  
  if(Input.GetAxis("Mouse ScrollWheel")<0){
   if(Vector3.Distance(cam.position, thisT.position)<maxRadius){
    cam.Translate(Vector3.forward*zoomSpeed*Input.GetAxis("Mouse ScrollWheel"));
   }
  }
  else if(Input.GetAxis("Mouse ScrollWheel")>0){
   if(Vector3.Distance(cam.position, thisT.position)>minRadius){
    cam.Translate(Vector3.forward*zoomSpeed*Input.GetAxis("Mouse ScrollWheel"));
   }
  }
  
  //thisT.Translate(cam.forward*zoomSpeed*Input.GetAxis("Mouse ScrollWheel"), Space.World);
  
  #endif
  
  float x=Mathf.Clamp(thisT.position.x, minPosX, maxPosX);
  float z=Mathf.Clamp(thisT.position.z, minPosZ, maxPosZ);
  //float y=Mathf.Clamp(thisT.position.y, verticalLimitBottom, verticalLimitTop);
  
  thisT.position=new Vector3(x, thisT.position.y, z);
  
 }
 
 
 public bool showGizmo=true;
 void OnDrawGizmos(){
  if(showGizmo){
   Vector3 p1=new Vector3(minPosX, transform.position.y, maxPosZ);
   Vector3 p2=new Vector3(maxPosX, transform.position.y, maxPosZ);
   Vector3 p3=new Vector3(maxPosX, transform.position.y, minPosZ);
   Vector3 p4=new Vector3(minPosX, transform.position.y, minPosZ);
   
   Gizmos.color=Color.green;
   Gizmos.DrawLine(p1, p2);
   Gizmos.DrawLine(p2, p3);
   Gizmos.DrawLine(p3, p4);
   Gizmos.DrawLine(p4, p1);
  }
 }
 
}

'TA > Unity' 카테고리의 다른 글

ITween Example Tutorial  (0) 2013.06.21
유니티 라이트 프로브 셰이더 예제  (0) 2013.06.20
유니티 C# 공부 모음  (0) 2013.05.07
Texture Matrix in Fixed Function  (0) 2012.07.18
HLSL 함수  (0) 2012.07.10
Posted by 프리랜서 디자이너
TA/Unity2013. 5. 7. 08:42

유니티 C# 공부 모음 01

 

 

오브젝트 배열 잡기

.

.Public class ex: MonoBehaviour {

//클레스

 

private int currentWaypoint = 0;

//배열갯수 인스펙터에서 조절 가능하게 전역변수로....

 

GameObject AAA;

GameObject BBB;

//변수 설정

 

void Start () {

 

       AAA= GameObject.Find("AAA_01");

BBB= GameObject.Find("AAA_01");

//게임오브젝트 담기

 

waypoints[0] = AAA.transform;

waypoints[1] = BBB.transform;

//배열지정하기

}//스타트

.

.

void Update () {

activeWaypoint = waypoints[currentWaypoint];

//activeWaypoint 변수에 배열 넘겨 저장 시키기.

}//업데이트

.

.

}//클레스

 

 

 

 

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

 

OnTriggerEnter 예제

void OnTriggerEnter(Collider col)
 {
  
      Debug.Log("collider Trigger!");
      if(col.gameObject.tag == "waypoint")
      {
           currentWaypoint++;
           Debug.Log("current no = " +currentWaypoint);
      }
  
      if(state == 0)
      {
           if(currentWaypoint != 9){
           wark();
           }else{
                Destroy(this.gameObject);
           }
      }
 }

 

// OnTriggerEnter(Collider col) 트리거 충돌시 자동 호출된다. 단 유닛에 리지드바디가 추가되어있어야함.

 

 

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

 

 

 

오브젝트 카메라 바라보게 만들기.

using UnityEngine;
using System.Collections;

 

public class LookAtCamera : MonoBehaviour {
 
 public Camera cameraToLookAt;

//전역변수로 카메라 타입의 변수 생성

 


 void Start () {
  cameraToLookAt = Camera.main;

변수에 카메라담기 초기화...작업
 }
 



 void Update () {
  Vector3 v = cameraToLookAt.transform.position - transform.position;

//카메라 위치 구하기


  v.x = v.z = 0.0f;

//x와z축 0.0f로 만들기


  transform.LookAt(cameraToLookAt.transform.position - v);

//카메라를 y축을 중심으로 바라보게 만들기.
 }
}

 

 

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

 

 

인스턴스 만들고 오브젝트 발사하기

 

public Rigidbody FireBall;

public float FireBallSpeed = 1.0f;

.

.

.

Rigidbody playerAttak = (Rigidbody)Instantiate(FireBall,transform.position,transform.rotation);
playerAttak.velocity = transform.TransformDirection(new Vector3(0,0,FireBallSpeed));

 

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

 

오브젝트간 거리 구하기

 

float Distance = Vector3.Distance(obj1.transform.position, obj2.transform.position);

Distance 함수를 사용해 거리를 구한다.

 

 

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

 

 

A오브젝트가 B오브젝트를 바라보게 만들기

 

transform.rotation = Quaternion.Slerp(Creep.transform.rotation, Quaternion.LookRotation(Target.transform.position - Creep.transform.position), 1);

 

Quaternion함수를 (축) 같은 축으로 만들기

Slerp 함수는 보간기능

LookRotation() 은 특정 오브젝트를 바라보개 만든다,

 

 

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

 

오브젝트에 시간을 곱해 좌표이동시키기

transform.Translate(Vector3.forward * Time.smoothDeltaTime * MoveSpeed);

 

// Translate(Vector3)

 

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'TA > Unity' 카테고리의 다른 글

유니티 라이트 프로브 셰이더 예제  (0) 2013.06.20
TD CameraControl C#  (0) 2013.05.09
Texture Matrix in Fixed Function  (0) 2012.07.18
HLSL 함수  (0) 2012.07.10
Blending modes..참고 자료  (0) 2012.06.08
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 프리랜서 디자이너

Custom Lighting models in Surface Shaders

Surface Shaders를 쓸 때, 사용자는 표면(albedo color, normal, ...)의 속성을 설명하고 있고 조명 상호 작용이 조명 모델(Lighting Model).

내장된 조명 모델이 Lambert (diffuse 조명)이고 BlinnPhong (반사적인 조명) 입니다.

 

때때로 사용자는 사용자 정의 조명 모델을 사용하기를 원할지도 모르고 표면 쉐이더에서 저것을 하는 것이 가능합니다.

조명 모델이 어떤 규칙을 매치하는Cg/HLSL 함수 두 개보다 더 많지 않습니다. 내장된 LambertBlinnPhong 모델은 Unity 안의 Lighting.cginc 파일에서 정의됩니다(Windows에서 {unity install path}/Data/CGIncludes/Lighting.cginc, Mac에서 /Applications/Unity/Unity.app/Contents/CGIncludes/Lighting.cginc).

Lighting Model declaration

조명 모델은 Lighting으로 시작하는 이름을 가지는 일반 함수 2개 입니다. 그들은 사용자의 쉐이더 파일 또는included 파일 중 하나에서 어디서나 선언될 수 있습니다. 함수는 이것과 같습니다:

  1. half4 LightingName (SurfaceOutput s, half3 lightDir, half atten);이것은 뷰 디렉션에 의존하지 않는 포워드 렌더링 경로에서 사용됩니다 (예. diffuse).
  2. half4 LightingName (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten);이것은 뷰 디렉션에 의존하는 조명 모델을 위한 포워드 렌더링 경로에서 사용됩니다.
  3. half4 LightingName_PrePass (SurfaceOutput s, half4 light);이것은 deferred 조명 경로에서 사용됩니다.

사용자가 모든 함수를 선언할 필요가 없다는 것을 참고하세요.

조명 모델은 뷰 디렉션을 사용하거나 또는 하지 않는다는 것입니다.

 

 

 

유사하게 조명 모델이 deferred 조명에서 작동하지 않는다면 사용자는 _PrePass 함수를 선언하지 않고 그것을 사용하는 모든 쉐이더가 포워드 렌더링만으로 컴파일할 것입니다.

 

 

 

 

디렉셔널 라이트맵 디코딩은 어떤 상황들에서는 조명이 포워드와 지연 조명에서처럼 비슷한 방식으로 사용자화(customizing) 될 필요가 있습니다.

 

당신의 라이트 모델이 보는 방향에 의존적인지 아닌지에 따라 아래의 함수 중 하나를 사용하세요.

두개의 함수 다 포워드라이팅과 지연라이팅 렌더링 경로를 자동으로 처리합니다.

  1. half4 LightingName_DirLightmap (SurfaceOutput s, fixed4 color, fixed4 scale, bool surfFuncWritesNormal);이것은 보는 방향 의존적이지 않은 라이트 모델들에 사용됩니다 (e.g. diffuse).

이것은 종속 방향을 볼 수 없습니다 빛이 모델에 사용됩니다(e.g. diffuse).

  1. half4 LightingName_DirLightmap (SurfaceOutput s, fixed4 color, fixed4 scale, half3 viewDir, bool surfFuncWritesNormal, out half3 specColor);이것은 보는 방향 의존적인 라이트 모델들에 사용됩니다.

 

 

 

 

 

 

'TA > Unity Shader 레퍼런스' 카테고리의 다른 글

SurfaceShaderLighting  (0) 2012.07.26
SurfaceShaders  (0) 2012.07.26
한방에 모아보는 레퍼런스  (1) 2012.07.20
Pass  (0) 2012.07.19
Category  (0) 2012.07.18
Posted by 프리랜서 디자이너

 

TintFinalColor 셰이더.........

 

예제파일이 내 유니티 버전과 마지 않는건지 표면지시자가 없다고 나온다...그래서 걍 내식 대로? 고쳐서 넣었다..... 뭐하러 그리 어려게 작성 한걸까???

 

마찬가지로 버텍스에 포그 컬러 넣는 셰이더도 같은 이유로 작성이 안된다.. 패스...귀찮아 내일 부터는 서피스 라이팅이다~

 

 

Shader "DY/TintFinalColor" {
 Properties{
  _MainTex("Texture",2D)="white"{}
  _ColorTint("Tint",Color)=(1.0,1.0,1.0,1.0)
 }
 SubShader{
  Tags{"RenderType"="Opaque"}
  
  CGPROGRAM
  #pragma surface surf Lambert
  
  struct Input{
   float2 uv_MainTex;
  };
  
  fixed4 _ColorTint;
  sampler2D _MainTex;
  
  void surf (Input IN, inout SurfaceOutput o){
   o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb*_ColorTint;
  }

//디퓨즈에 컬러속성을 곱해서 색을 입혀준다..방식은 멀티 플라이라고 보면됨.


  ENDCG
 }
 Fallback"Diffuse"
}

 

 

 

 

 

 

 

 

 

Posted by 프리랜서 디자이너

Normal Extrusion 추가....노멀값을 조절 해 메쉬를 뿔리는 셰이더??? 뿔린 메쉬를 뒤집어 툰셰이딩에 응용한다고도 한다....

 

 

Shader "DY/NormalExtrusion" {
 Properties{
  _MainTex("texture",2D)="white"{}
//  _Amount("Extrusion Amount",Range(-1,1))=0.0
  _Amount("Extrusion Amount",float)=0.0
 }

//슬라이드 조절바가 불편해서 수치 입력으로 바꿨다....


 SubShader{


  Tags{"RanderType"="Opaque"}
  CGPROGRAM
  #pragma surface surf Lambert vertex:vert
  
  struct Input{
   float2 uv_MainTex;
  };
  
  float _Amount;


  void vert (inout appdata_full v){
   v.vertex.xyz +=v.normal * _Amount;
  }

// cg구문에 옵션에 해당하는 구문

//cg에 정의 되있는 Apptata를 활용해 메쉬가 뿔어나 보이게 만들었다...
  
  sampler2D _MainTex;
  
  void surf (Input IN, inout SurfaceOutput o){
   o.Albedo = tex2D(_MainTex,IN.uv_MainTex).rgb;
  }
  ENDCG
 }
 FallBack"Diffuse"
}

 

 

 

 

 

 

 

Custom Vertex Color 추가 ..... 로컬좌표 버텍스에 노멀 컬러를 입혔다...... 어디다 쓰지 ???

 

 

Shader "DY/CustomVertex" {
 properties{
  _MainTex("Texture",2D)="white"{}
 }
 SubShader{
  Tags{"RenderType"="Opaque"}
  
  CGPROGRAM
  #pragma surface surf Lambert vertex:vert
  
  struct Input{
   float2 uv_MainTex;
   float3 customColor;
  };
  
  void vert (inout appdata_full v, out Input o){
   o.customColor = abs(v.normal);
  }

// cg구문에 옵션에 해당하는 구문

//cg에 정의 되있는 Apptata를 활용해 버텍스에 컬러를 입혔다...

//ui쪽엔 버텍스에 컬러 접근해 컬러 바꾸던데... 그런데서나 쓸수 있으려나?
  
  sampler2D _MainTex;
  
  void surf (Input IN, inout SurfaceOutput o){
   o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
   o.Albedo *= IN.customColor;
  }
  
  ENDCG
 }
 FallBack"Diffuse"
}

 

 

 

 

 

 

 

 

 

 

Posted by 프리랜서 디자이너

Cubemap Reflection 넣기......

 

이번 예제파일을 살짝 변경했다 좀더 쎄게~ 강하게~찐하게~ ㅋㅋ

 

worldRefl 라는 내장 함수를 사용해 간단히 구현한다.... 정말 번거롭지 않게 만들어 놓은 서피스 셰이더....

 

 

Shader "DY/WordRef1"{

 

 Properties{

  _MainTex("Texture",2D) = "white"{}

  _Cube("CubeMap",CUBE) = ""{}

 }

 

 SubShader{

  Tags{"RenderType"="Opaque"}

  CGPROGRAM

  #pragma surface surf Lambert

  

  struct Input{

   float2 uv_MainTex;

   float3 worldRefl;

  };

  //worldRef1 내장 함수 선언 reflect 내장함수와 같은 의미 인듯 하다...

 

  sampler2D _MainTex;

  samplerCUBE _Cube;

  float3 texcol;

  //심심해서 조금 바꿔보려고 변수하나 추가했다

 

  void surf(Input IN, inout SurfaceOutput o){

   texcol = tex2D(_MainTex,IN.uv_MainTex).rgb;

   texcol*=texcol;

//텍스쳐 끼리 곱해 멀티플라이 효과를 준당

 

   o.Albedo = texcol;

   o.Emission = texCUBE(_Cube,IN.worldRefl).rgb;

  }

//Emission 에 큐브를 적용한다 이 Emission을 넣으면 전체적으로 밝아지게됨 빛나보이게하려고 그런거 같다....

 

 

  ENDCG

 }

 Fallback"Diffuse"

}

 

 

 

 

 

Cubemap Reflection 에 Normal Map 추가 하기.....

 

이유는 잘 모르겟으나...(뒤져봐야겠지..)INTERNAL_DATA 는 입력 구조체가 필요하고, 픽셀당 반사벡터에 필요한 내장 함수인 WorldReflectionVector(,) 를 넣어야한다~

 

 

Shader "DY/WordRef1_bump" {

 Properties{
  _MainTex("Texture",2D) = "white"{}
  _Cube("CubeMap",CUBE) = ""{}
  _BumpMap ("Bumpmap", 2D) = "bump" {}
 }
 
 SubShader{
  Tags{"RenderType"="Opaque"}
  CGPROGRAM
  #pragma surface surf Lambert
  
  struct Input{
   float2 uv_MainTex;
   float3 worldRefl;
   float2 uv_BumpMap;
   INTERNAL_DATA

  };
  // INTERNAL_DATA 구조체 추가~ 뭐하는 넘일까...

 


  sampler2D _MainTex;
  samplerCUBE _Cube;
  sampler2D _BumpMap;
  float3 texcol;
  
  void surf(Input IN, inout SurfaceOutput o){
   texcol = tex2D(_MainTex,IN.uv_MainTex).rgb;
   texcol*=texcol;
   o.Albedo = texcol;
   o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
   o.Emission = texCUBE (_Cube, WorldReflectionVector (IN, o.Normal)).rgb;

  }

//Emission에 WorldReflectionVector 내장 함수를 넣었다....

//이건 픽셀당 반사 백터를 구하기 위한이란다 그러니까 노멀이 들어가서 필요하게된 변수 라는거지


  ENDCG
 }
 Fallback"Diffuse"
}

 

 

 

 

 

 

 

Slices via World Space Position 구현하기....

 

딱히 쓸일이 있을진 모르겠다.....

clip() Cg/HLSL 함수를 사용해서 구현하고 월드 좌표는 내장 함수인 worldPos 변수를 사용한다......

 

Shader"DY/Slices"{

 Properties{

  _MainTex("Texture",2D)="white"{}

  _BumpMap("BumpMap",2D)="Bump"{}

 }

 

 SubShader{

 

  Tags{"RenderType"="Opaque"}

  

  Cull Off

  //메쉬의 뒷면을 살려라!!~~ 라는것

 

  CGPROGRAM

  #pragma surface surf Lambert

  

  struct Input{

   float2 uv_MainTex;

   float2 uv_BumpMap;

   float3 worldPos;

  };

  

  sampler2D _MainTex;

  sampler2D _BumpMap;

  

  void surf (Input IN, inout SurfaceOutput o){

   clip (frac((IN.worldPos.y+IN.worldPos.z*0.1)*5)-0.5);

//함수와 월드 좌표를 이용해 메쉬를 잘라진 것처럼 랜더링 걸어  버린다.

 

   o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;

   o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));

  }

 

  ENDCG

 }

 Fallback"Diffuse"

}

 

 

 

 

 

 

 

 

 

 

Posted by 프리랜서 디자이너

4. Rim Lighting 추가....

 

Shader"DY/surf_ex_004"{

 Properties{

 _MainTex("Texture",2D)="white"{}

 _BumpMap("Bump Map",2D)="bump"{}

 _RimColor("Rim Color",Color)=(0.5,0.5,0.5,0.5)

 _RimPower("Rim Power",Range(0.5,8.0))=3.0

 }

//프로퍼티에 림컬러와 림파워 추가

 

 

 SubShader{

 Tags{"RanderType"="Opaque"}

 

 CGPROGRAM

 #pragma surface surf Lambert

 

 

  struct Input{

   float2 uv_MainTex;

   float2 uv_BumpMap;

   float3 viewDir;

  };

  //인풋에 뷰다이렉션 추가

  

  sampler2D _MainTex;

  sampler2D _BumpMap;

  float4 _RimColor;

  float _RimPower;

//아웃풋에 림컬러와 파워를 전달하기위해 변수 선언

 

  void surf(Input IN, inout SurfaceOutput o){

   o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;

   o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));

   half rim = 1.0 - saturate(dot(normalize(IN.viewDir), o.Normal));

//정규화한 뷰다이렉션과 노멀의 내적을 구하고 1을 넘지한게 세추레이트 함수를 적용 후 뒤집는다.

//림과 림파와를 파워 함수를 적용하고 림컬러와 합성한다.

   o.Emission = _RimColor.rgb*pow(rim,_RimPower);

  }

 ENDCG

 }

 Fallback"Diffuse"

}

 

 

 

5.Detail Texture 추가.....

 

Shader"DY/surf_005"{

 

Properties {
      _MainTex ("Texture", 2D) = "white" {}
      _BumpMap ("Bumpmap", 2D) = "bump" {}
      _Detail ("Detail", 2D) = "gray" {}
    }


    SubShader {
      Tags { "RenderType" = "Opaque" }


      CGPROGRAM
      #pragma surface surf Lambert


      struct Input {
          float2 uv_MainTex;
          float2 uv_BumpMap;
          float2 uv_Detail;
      };


      sampler2D _MainTex;
      sampler2D _BumpMap;
      sampler2D _Detail;


      void surf (Input IN, inout SurfaceOutput o) {
          o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
          o.Albedo *= tex2D (_Detail, IN.uv_Detail).rgb * 2;

          //Albedo를 추가 해 텍스쳐를 멀티플라이형식으로 합성한다. 
          o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
      }


      ENDCG
    }
    Fallback "Diffuse"
  }

 

 

 


 

 

6. DetailMap screen space...변경 적용

 

Shader"DY/surf_ex_006"{

 

Properties {

      _MainTex ("Texture", 2D) = "white" {}

      _Detail ("Detail", 2D) = "gray" {}

    }

 

    SubShader {

      Tags { "RenderType" = "Opaque" }

 

      CGPROGRAM

      #pragma surface surf Lambert

 

      struct Input {

          float2 uv_MainTex;

          float4 screenPos;

      };

 

      sampler2D _MainTex;

      sampler2D _Detail;

 

      void surf (Input IN, inout SurfaceOutput o) {

          o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;

          float2 screenUV = IN.screenPos.xy / IN.screenPos.w;

          screenUV *= float2(8,6);

    //float2에 스크린XY좌표와 W스케일 받아오기

   //각각 성분에 8,6 을 곱한값이 screenUV 이다.

          o.Albedo *= tex2D (_Detail, screenUV).rgb * 2;

      }

      ENDCG

    }

    Fallback "Diffuse"

  }

 

 

 

 

Posted by 프리랜서 디자이너

서피스 셰이더 공부 시작.....예전에 문서 다 읽어 봤지만 마치 처음 읽어 보는 것 같은 이 이상한 기분..;;;;

 

이번은 서피스 셰이더 예제 따라하기~

 

1. 램버트 라이트 에 색상만 출력하는 초 간단 셰이더

 

Shader "DY/surf_ex_001" {
 SubShader{
  Tags{"RenderType"="Opaque"}
  
  CGPROGRAM
  #pragma surface surf Lambert

//기본으로 지정되있는 램버트 라이트 사용
  
   struct Input {
    float4 color : COLOR;
   };

//인풋은 달랑 색상만 받는다


   void surf (Input IN, inout SurfaceOutput o){
    o.Albedo = 0.5;
   }

//Albedo는 색상(Diffuse) 정하는 구문이고 0.5 는 컬러값 (회색)을 준다.
  ENDCG
  }
  //SubShader
}
//Shader

 

 

 

 

 

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

 

 

2. 텍스쳐 추가...디퓨즈 셰이더

 

Shader "DY/surf_ex_002" {
 Properties{
  _MainTex("Texture",2D)="White"{}
 }
 SubShader{
  Tags{"RanderType"="Opaque"}
  CGPROGRAM
  #pragma surface surf Lambert
  
  struct Input{
   float2 uv_MainTex;
  };
  //인풋에 메인 텍스쳐의 uv정보를 받아온다.


  sampler2D _MainTex;
  //2D텍스쳐를 사용하기 위한 참조.


  void surf(Input IN, inout SurfaceOutput o){
   o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
  }

//디퓨즈에 해당하는Albedo에 메인 텍스쳐와 인풋의 uv정보를 적용.
  
  ENDCG
 }
 Fallback "Diffuse"

//그래픽카드가 안맞거나 오류가 생기면 디뷰즈 셰이더로 대체.
}

 

 

 

 

 

 

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

 

 

3. 범프맵 추가 ......(사칙연산이 되는구나......좋다! 서피스!!)

 

Shader "DY/surf_ex_003" {
 Properties{
  _MainTex("Texture",2D)="white"{}
  _BumpMap("Bumpmap",2D)="bump"{}
 }
 SubShader{
  Tags{"RanderType"="Opaque"}
  
  CGPROGRAM
  #pragma surface surf Lambert
  
  struct Input{
   float2 uv_MainTex;
   float2 uv_BumpMap;
  };
  //인풋에 범프맵 uv추가.


  sampler2D _MainTex;
  sampler2D _BumpMap;

//범프맵도 2D텍스쳐니까 참조 추가.
  
  void surf(Input IN, inout SurfaceOutput o){
   o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
   o.Normal = UnpackNormal (tex2D(_BumpMap, IN.uv_BumpMap));
  }

//유니티의 노말압축을 풀어주고(UnpackNormal) 범프맵과 uv정보 적용


  ENDCG
 }
 Fallback"Diffuse"
}


 

 

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

 

 

Posted by 프리랜서 디자이너

Custom Lighting models in Surface Shaders

Surface Shaders를 쓸 때, 사용자는 표면(albedo color, normal, ...)의 속성을 설명하고 있고 조명 상호 작용이 조명 모델(Lighting Model). 내장된 조명 모델이 Lambert (diffuse 조명)이고 BlinnPhong (반사적인 조명) 입니다.

때때로 사용자는 사용자 정의 조명 모델을 사용하기를 원할지도 모르고 표면 쉐이더에서 저것을 하는 것이 가능합니다. 조명 모델이 어떤 규칙을 매치하는Cg/HLSL 함수 두 개보다 더 많지 않습니다. 내장된 LambertBlinnPhong 모델은 Unity 안의 Lighting.cginc 파일에서 정의됩니다(Windows에서 {unity install path}/Data/CGIncludes/Lighting.cginc, Mac에서 /Applications/Unity/Unity.app/Contents/CGIncludes/Lighting.cginc).

Lighting Model declaration

조명 모델은 Lighting으로 시작하는 이름을 가지는 일반 함수 2개 입니다. 그들은 사용자의 쉐이더 파일 또는included 파일 중 하나에서 어디서나 선언될 수 있습니다. 함수는 이것과 같습니다:

  1. half4 LightingName (SurfaceOutput s, half3 lightDir, half atten);이것은 뷰 디렉션에 의존하지 않는 포워드 렌더링 경로에서 사용됩니다 (예. diffuse).
  2. half4 LightingName (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten);이것은 뷰 디렉션에 의존하는 조명 모델을 위한 포워드 렌더링 경로에서 사용됩니다.
  3. half4 LightingName_PrePass (SurfaceOutput s, half4 light);이것은 deferred 조명 경로에서 사용됩니다.

사용자가 모든 함수를 선언할 필요가 없다는 것을 참고하세요. 조명 모델은 뷰 디렉션을 사용하거나 또는 하지 않는다는 것입니다. 유사하게 조명 모델이 deferred 조명에서 작동하지 않는다면 사용자는 _PrePass 함수를 선언하지 않고 그것을 사용하는 모든 쉐이더가 포워드 렌더링만으로 컴파일할 것입니다.

디렉셔널 라이트맵 디코딩은 어떤 상황들에서는 조명이 포워드와 지연 조명에서처럼 비슷한 방식으로 사용자화(customizing) 될 필요가 있습니다. 당신의 라이트 모델이 보는 방향에 의존적인지 아닌지에 따라 아래의 함수 중 하나를 사용하세요. 두개의 함수 다 포워드라이팅과 지연라이팅 렌더링 경로를 자동으로 처리합니다.

  1. half4 LightingName_DirLightmap (SurfaceOutput s, fixed4 color, fixed4 scale, bool surfFuncWritesNormal);이것은 보는 방향 의존적이지 않은 라이트 모델들에 사용됩니다 (e.g. diffuse).

This is used for light models that are not view direction dependent (e.g. diffuse).

  1. half4 LightingName_DirLightmap (SurfaceOutput s, fixed4 color, fixed4 scale, half3 viewDir, bool surfFuncWritesNormal, out half3 specColor);이것은 보는 방향 의존적인 라이트 모델들에 사용됩니다.

예제 Examples

Surface Shader Lighting Examples

 

'TA > Unity Shader 레퍼런스' 카테고리의 다른 글

Custom Lighting models in Surface Shaders  (0) 2012.08.24
SurfaceShaders  (0) 2012.07.26
한방에 모아보는 레퍼런스  (1) 2012.07.20
Pass  (0) 2012.07.19
Category  (0) 2012.07.18
Posted by 프리랜서 디자이너

Writing Surface Shaders

조명과 상호작용하는 쉐이더를 쓰는 것은 복잡합니다. 다른 조명 타입과 그림자 옵션, 렌더링 경로 (포워드 그리고 지연 렌더링)이 있고 쉐이더는 모든 복잡성을 다뤄야만 합니다.

Unity에서 Surface Shaders는 낮은 레벨의 vertex/pixel shader programs을 사용하는 것 보다 조명 쉐이더를 쓰는 것을 더욱 쉽게 만드는 코드 생성 방법입니다. 표면 쉐이더에 연관된 사용자 정의 언어, 마술 또는 닌자가 없다는 것을 참고하세요; 그것은 단지 손으로 쓰여져야하는 모든 반복적인 코드를 생성합니다. 사용자는 여전히Cg / HLSL로 쉐이더 코드를 씁니다.

예를 위해서 Surface Shader ExamplesSurface Shader Custom Lighting Examples를 살펴보시기 바랍니다.

How it works

사용자는 사용자가 입력값으로 필요로 하는 어떠한UVs 또는 데이터를 취하는 "surface function"을 정의하고 결과 구조 SurfaceOutput를 채웁니다. SurfaceOutput은 기본적으로 표면의 속성을 설명합니다 (그것은albedo 색상, normal, 발산, 반사 등). 사용자는Cg / HLSL로 이 코드를 씁니다.

표면 쉐이더 컴파일러는 그 때 어떤 입력값이 필요되어 지는지, 무슨 결과가 채워지는 지 등을 알아내고 포워드 그리고 지연 렌더링을 처리하기 위해 패스들을 렌더링할 뿐만 아니라 실제 vertex&pixel shaders를 생성합니다.

표면 쉐이더의 기본적인 결과 구조는 이것입니다:

struct SurfaceOutput {
    half3 Albedo;
    half3 Normal;
    half3 Emission;
    half Specular;
    half Gloss;
    half Alpha;
};

Samples

Surface Shader ExamplesSurface Shader Custom Lighting Examples 페이지를 살펴보시기 바랍니다.

Surface Shader compile directives

표면 쉐이더는 다른 쉐이더들 처럼 CGPROGRAM..ENDCG 블록 사이에 놓여집니다. 차이는 이것입니다:

  • 그것은 SubShader 안이 아닌 Pass 블록안에 놓여져야만 합니다. 표면 쉐이더는 다수의 패스들로 스스로 컴파일 할 것입니다.

그것은 그것이 표면 쉐이더라는 것을 알리기 위해 #pragma surface 지시어를 사용합니다:

    #pragma surface surfaceFunction lightModel [optionalparams]

Required parameters:

  • surfaceFunction - 어떤Cg 함수가 표면 쉐이더 코드를 가지는지 입니다. 함수는 void surf (Input IN, inout SurfaceOutput o)의 형태를 가져야 합니다. 거기서 입력값은 사용자가 정의한 구조입니다. 입력값은 어떠한 텍스쳐 좌표라도 포함해야 하고 표면 함수에 의해 필요되는 여분의 자동 변수들도 포함해야 합니다
  • lightModel - 사용하는 조명 모델. 내장된 것들은 Lambert (diffuse) 와 BlinnPhong (specular) 입니다. 사용자 자신의 것을 쓰는 방법을 위해서는 Custom Lighting Models 페이지를 참고하시기 바랍니다.

Optional parameters:

  • alpha - 알파 블렌딩 모드. 반투명 쉐이더를 위해서 이것을 사용합니다.
  • alphatest:VariableName - 알파 테스팅 모드. 투명하고 컷아웃 쉐이더를 위해서 이것을 사용합니다. 컷오프 값은VariableName과 함께 소수점 변수안에 있습니다.
  • vertex:VertexFunction - 사용자 정의 꼭지점 변형 함수. 예를 위해서Tree Bark를 살펴보세요.
  • exclude_path:prepass or exclude_path:forward - 주어진 렌더링 경로를 위해서 패스를 생성하지 마십시오.
  • dualforward - dual lightmaps 렌더링 경로에서 [[RenderTech-ForwardRendering | forward을 사용합니다.
  • fullforwardshadows - Forward 렌더링 경로에서 모든 그림자 타입을 지원합니다.
  • decal:add - 첨가하는 데칼 쉐이더 (예. terrain AddPass).
  • decal:blend - 반투명 데칼 쉐이더
  • softvegetation - 오직Soft Vegetation이 활성화될 때 표면 쉐이더가 그려지도록 만듭니다.
  • noambient - 주변의 조명이나 또는 주변의 고조파 조명도 적용하지 않습니다.
  • novertexlights - 포워드 렌더링에서 주변의 고조파 조명이나 또는 정점 조명도 적용하지 않습니다.
  • nolightmap - Lightmap 이 쉐이더에서 지원을 비활성화 합니다 (쉐이더를 더 작게 만듭니다).* noforwardadd - Forward 렌더링 첨가적인 패스를 비활성화 합니다. 이것은 vertex/SH당 계산되는 모든 다른 조명과 함께 쉐이더가 하나의 완전한 방향성있는 조명을 지원하도록 만듭니다. 쉐이도를 역시 더 작게 만듭니다.
  • approxview - 그것을 필요로하는 쉐이더를 위해서 픽셀당 대신에 정점당 일반화된 뷰 디렉션을 계산합니다. 이것은 더 빠르나 뷰 디렉션은 카메라가 표면에 가까울 때 완전히 옳은 것은 아닙니다.
  • halfasview - 뷰 디렉션 대신에 조명 함수로 절반 방향 벡터를 패스합니다. 절반 방향은 정점당 계산될 것이고 일반화될 것입니다. 이것은 더 빠르나 완전히 옳지는 않습니다.

또한 사용자는CGPROGRAM 블록 안에서 #pragma debug쓸 수 있고 그 후에 표면 컴파일러는 생성된 코드의 많은 코멘트들을 나눌 것입니다. 사용자는 쉐이더 인스펙터에서Open Compiled Shader을 사용하는 것을 볼 수 있습니다.

Surface Shader input structure

입력 구조 Input은 일반적으로 쉐이더에 의해 필요되어지는 어떠한 텍스쳐 좌표라도 가집니다. 텍스쳐 좌표는 텍스쳐 이름 다음에 "uv"라고 이름지어져야만 합니다.

 

입력 구조에 끼워 넣을 수 있는 추가적인 값들:

  • float3 viewDir - 뷰 디렉션을 포함할 것이고Parallax 효과를 위해서는rim 조명등이 포함될 것입니다.
  • float4 with COLOR semantic - 보간되는 정점당 색상을 포함할 것입니다.
  • float4 screenPos - w 반사 효과를 위해서 스크린 공간 위치를 포함할 것입니다. 예를 들어Dark Unity에서 WetStreet 쉐이더에 의해 사용됩니다.
  • float3 worldPos - 세계 공간 위치를 포함할 것입니다.
  • float3 worldRefl - 표면 쉐이더가o.Normal로 쓰여지지 않는다면 세계 반사 벡터를 포함할 것입니다. 예를 들어Reflect-Diffuse를 살펴보시기 바랍니다.
  • float3 worldNormal - 표면 쉐이더가o.Normal로 쓰여지지 않는다면 세계 normal 벡터를 포함할 것입니다.
  • float3 worldRefl; INTERNAL_DATA - 표면 쉐이더가o.Normal로 쓰여진다면 세계 반사 벡터를 포함할 것입니다. 픽셀당 normal map에 기반한 반사 벡터를 얻기 위해서 WorldReflectionVector (IN, o.Normal)을 사용하시기 바랍니다. 예를 위해서Reflect-Bumped를 참고하시기 바랍니다.
  • float3 worldNormal; INTERNAL_DATA - 표면 쉐이더가o.Normal로 쓰여진다면 세계 normal 벡터를 포함할 것입니다. 픽셀당 normal map에 기반한 반사 벡터를 얻기 위해서 WorldNormalVector (IN, o.Normal)을 사용하시기 바랍니다(IN, o.Normal)..

Further Documentation

'TA > Unity Shader 레퍼런스' 카테고리의 다른 글

Custom Lighting models in Surface Shaders  (0) 2012.08.24
SurfaceShaderLighting  (0) 2012.07.26
한방에 모아보는 레퍼런스  (1) 2012.07.20
Pass  (0) 2012.07.19
Category  (0) 2012.07.18
Posted by 프리랜서 디자이너

이제 뭘 만들어 볼까 하다가 얼마전 회사 셰이더에 플레그먼트로 짜 넣었던 염색 셰이더가 생각이나서

고정함수 셰이더로 만들었다.. 고민고민하다... 알파 테스팅에 패스를 두번그리는걸로 만들었다..

제대로만든건지 몰겠네;; 잘되긴 하는데;;ㅋㅋㅋ

아이퐁에선 투패스가 안그려진다는 말도있던데...뭐 연습이니까..

 

Shader "DY/charTest" {
 Properties {
  _MainTex ("Base", 2D) = "white" {}
  _Color("Color",Color) = (1,1,1,1)
  _TeamColor("TeamColor",Color) = (1,1,1,1)
  _Emission("Emisive Color",Color)=(0,0,0,0)
     _SpecColor("Spec Color",Color)=(1,1,1,1)
     _Shininess("Shininess",Range(0.01,1))= 0.5
 }
 SubShader {

//기본적인 텍스쳐와 라이트를 합성해주는 패스
  pass{
   Material{
    Diffuse[_Color]
    Ambient[_Color]
    Specular[_SpecColor]
    Shininess[_Shininess]
          Emission[_Emission]
   }
   
   Lighting On
   SeparateSpecular On
   
   SetTexture[_MainTex]{
   constantColor[_ConsColor]
    Combine Texture * Primary DOUBLE
    
   }
  }

//알파테스팅을 활용해 염색을 구현해주는 패스
  pass{
   Material{
    Diffuse[_Color]
    Ambient[_Color]
    Specular[_SpecColor]
    Shininess[_Shininess]
          Emission[_Emission]
   }
   
   Lighting On
   SeparateSpecular On
   AlphaTest Greater 0.5
   
   SetTexture[_MainTex]{
   constantColor[_TeamColor]
    Combine Texture * constant
   }
    //알파 테스팅에 라이트 적용을 위한 SetTexture
   SetTexture[_MainTex]{
    Combine previous * primary DOUBLE
   }
  }
  //pass    
 }
 //subShader
}
//Shader

 

 

 

 

Posted by 프리랜서 디자이너

한방에 모아보는 Unity Shader 레퍼런스

 

Properties

 

Properties {
    // properties for water shader
    _WaveScale ("Wave scale", Range (0.02,0.15)) = 0.07 // sliders
    _ReflDistort ("Reflection distort", Range (0,1.5)) = 0.5
    _RefrDistort ("Refraction distort", Range (0,1.5)) = 0.4
    _RefrColor ("Refraction color", Color)  = (.34, .85, .92, 1) // color
    _ReflectionTex ("Environment Reflection", 2D) = "" {} // textures
    _RefractionTex ("Environment Refraction", 2D) = "" {}
    _Fresnel ("Fresnel (A) ", 2D) = "" {}
    _BumpMap ("Bumpmap (RGB) ", 2D) = "" {}
}

 

Syntax

Properties { Property [Property ...] }
속성 블록을 정의합니다. 중괄호안에 다수의 속성은 다음과 같이 정의됩니다.
name ("display name", Range (min, max)) = number
인스펙터에서 minmax 사이의 슬라이더로 나타나는 소수점 속성을 정의합니다.
name ("display name", Color) = (number,number,number,number)
색상 속성을 정의합니다.
name ("display name", 2D) = "name" { options }
2D 텍스쳐 속성을 정의합니다.
name ("display name", Rect) = "name" { options }
직사각형 (2의 지수가 아닌) 텍스쳐 속성을 정의합니다.
name ("display name", Cube) = "name" { options }
Cubemap 텍스쳐 속성을 정의합니다.
name ("display name", Float) = number
소수점 속성을 정의합니다.
name ("display name", Vector) = (number,number,number,number)
네 개의 컴포넌트 벡터 속성을 정의합니다.

 

 

 

Texture property options

텍스쳐 속성의 괄호안의 옵션은 선택적입니다. 가능한 옵션은 다음과 같습니다:

TexGen texgenmode
이 텍스쳐를 위한 자동적인 텍스쳐 좌표 생성 모드. ObjectLinear, EyeLinear, SphereMap, CubeReflect, CubeNormal 중 하나일 수 있습니다; 이러한 것들은 직접적으로OpenGL texgen 모드와 관련됩니다. 사용자 정의 꼭지점 프로그램이 사용되면 TexGen이 무시되는 것을 참고하시기 바랍니다.
LightmapMode
주어지면 이 텍스쳐는 렌더러 당 lightmap 파라미터에 의해서 영향을 받을 것입니다. 즉 사용하는 텍스쳐는 재질안에 있을 수 없습니다. 그러나 그것은 렌더러의 세팅으로부터 취해질 수 있습니다. Renderer scripting documentation을 참고하시기 바랍니다.

Example

// EyeLinear texgen mode example
Shader "Texgen/Eye Linear" {
    Properties {
        _MainTex ("Base", 2D) = "white" { TexGen EyeLinear }
    }
    SubShader {
        Pass {
            SetTexture [_MainTex] { combine texture }
        }
    }
} 

----------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------

Render Setup

패스는 그래픽 하드웨어의 다양한 상태를 셋업합니다. 예를 들어 알파 블렌딩이 켜져야 하고 연기가 사용되야 하는 등등. 명령은 이것들과 같습니다:

Material { Material Block }
정점 조명 파이프라인에서 사용하는 재질을 정의합니다. 자세한 내용을 위해서 material page을 참고 합니다.
Lighting On | Off
정점 조명을 켜거나 끄는 것을 세팅합니다. 자세한 내용을 위해서 material page을 참고 합니다.
Cull Back | Front | Off
다각형 culling 모드를 세팅합니다.
ZTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always)
깊이 테스팅 모드를 세팅합니다.
ZWrite On | Off
깊이 쓰기 모드를 세팅합니다.
Fog { Fog Block }
연기 파라미터를 세팅합니다.
AlphaTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always) CutoffValue
알파 테스팅을 합니다.
Blend SourceBlendMode DestBlendMode
알파 블렌딩 모드를 세팅합니다.
Color Color value
정점 조명이 꺼지지 위해서 사용하는 색상을 세팅합니다.
ColorMask RGB | A | 0 | any combination of R, G, B, A
색상 쓰기 마스크를 세팅합니다. ColorMask 0 쓰는 것은 모든 색상 채널로 렌더링하는 것을 끕니다.
Offset OffsetFactor , OffsetUnits
깊이 오프셋을 세팅합니다.
SeparateSpecular On | Off
정점 조명을 위한 별개의 반사적인 색상을 크거나 끕니다. 자세한 내용을 위해서 material page 살펴봅니다.
ColorMaterial AmbientAndDiffuse | Emission
정점 조명을 계산할 때 꼭지점 당 색상을 사용합니다. 자세한 내용을 위해서 material page 살펴봅니다.

 

Texture Setup

SetTexture texture property { [Combine options] }

 

Per-pixel Lighting

픽셀당 조명 파이프라인이 다수의 패스에서 물체를 렌더링하는 것에 의해 작동합니다. Unity는 주변의 그리고 정점 조명을 얻기 위해 물체를 한 번 렌더합니다. 그 후에 그것은 별개의 첨가적인 패스에서 물체에 영향을 주는 각 픽셀 조명을 렌더합니다. 자세한 내용을 위해서는 Render Pipeline 살펴보시기 바랍니다.

Per-vertex Lighting

꼭지점 당 조명은 각 꼭지점을 위해 계산되는 기본적인 Direct3D/OpenGL 조명 모델입니다. 조명은 켜집니다. 조명은 Material block, ColorMaterial 그리고 SeparateSpecular 명령에 의해 영향을 받습니다. 자세한 내용을 위해서는 material page 살펴보시기 바랍니다.

 

----------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------

 

Lighting

Color Color
물체를 단색으로 세팅합니다. 색상은 괄호안의 RGBA 값이거나 또는 사각 괄호안에서 색상 속성 이름입니다.
Material { Material Block }
Material block은 물체의 재질적인 소성을 정의하기 위해서 사용됩니다.
Lighting On | Off
Material block에서 정의된 세팅이 어떠한 효과를 가지기 위해서 사용자는 Lighting On 명령을 가지고 조명을 활성화해야 합니다. 조명이 꺼지면 대신 색상이 Color 명령어로 부터 직접적으로 취해집니다.
SeparateSpecular On | Off
이 명령은 쉐이더의 패스의 끝에 추가될 반사적인 조명을 만들고 반사적인 조명은 텍스쳐링에 영향을 받지 않습니다. Lighting On이 사용될 때의 효과만을 가집니다.

:ColorMaterial AmbientAndDiffuse | 재질에서 세팅된 색상 대신에 사용되는 색상을 만듭니다. AmbientAndDiffuse는 재질의 Ambient와Diffuse값을 대체합니다; 발산은 재질의 발산 값을 대체합니다.

 

 

Material Block

이것은 재질이 조명에 어떻게 반응하는지에 대한 세팅을 포함합니다. 이러한 속성들 중 어떠한 것도 검정을 기본 세팅으로 하는 경우에 남겨지지 않을 수 있습니다 (즉. 효과가 없습니다).

Diffuse Color
확산 색상 컴포넌트. 이것은 물체의 기본 색상입니다.
Ambient Color
주명의 색상 컴포넌트. 이것은 class-RenderSettings에 세팅된 주변 조명 세팅에 의해 그것이 부딪힐 때 물체가 가지는 색상을 의미합니다..
Specular Color
물체의 반적인 하이라이트 색상.
Shininess Number
조명의 날카로움을 0과 1 사이 값으로 표현. 0에서 사용자는 퍼져있는 조명처럼 보이는 커다란 하이라이트를 얻을 것이고 0에서는 아주 작은 얇은 자국을 얻습니다.
Emission Color
어떠한 조명에서도 부딪히지 않을 때 물체의 색상.

Shader "VertexLit" {
    Properties {
        _Color ("Main Color", Color) = (1,1,1,0)
        _SpecColor ("Spec Color", Color) = (1,1,1,1)
        _Emission ("Emmisive Color", Color) = (0,0,0,0)
        _Shininess ("Shininess", Range (0.01, 1)) = 0.7
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }
    SubShader {
        Pass {
            Material {
                Diffuse [_Color]
                Ambient [_Color]
                Shininess [_Shininess]
                Specular [_SpecColor]
                Emission [_Emission]
            }
            Lighting On
            SeparateSpecular On
            SetTexture [_MainTex] {
                Combine texture * primary DOUBLE, texture * primary
            }
        }
    }
}

 

----------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------

 

Culling & Depth Testing

 

Cull Back | Front | Off
다각형의 어떤 면이 그려지지 않을 지를 조절합니다.
Back 뷰어로 부터 벗어나 있는 다각형은 그리지 않습니다 (기본 설정).
Front 뷰어를 향하는 다각형은 그리지 않습니다. 물체를 내부로 보낼 때 사용됩니다.
Off culling을 비활성화 – 모든 면을 그립니다. 특별한 효과를 위해서 사용됩니다.
ZWrite On | Off
이 물체로 부터 픽셀들이 깊이 버퍼로 쓰여지는지 여부를 결정 (기본값은On). 사용자가 고체의 물체를 그리고 있다면 이것을 on으로 합니다. 사용자가 반투명한 효과를 그리고 있다면 ZWrite Off 로 바꿉니다. 자세한 내용을 위해서는 아래의 내용을 읽어보시기 바랍니다.
ZTest Less | Greater | LEqual | GEqual | Equal | NotEqual | Always
깊이 테스팅이 어떻게 실행되는지를 나타냅니다. 기본값은 LEqual (기존 물체로서 거리에서 또는 그것으로 부터 물체를 그립니다; 그것들 뒤에서 물체를 숨깁니다).
Offset Factor , Units
사용자가 두 개의 파라미터로 깊이 오프셋을 정하는 것을 허락합니다. factorunitsFactor 는 최대의 Z 기울기를 다각형의 X 또는 Y에 따라 스케일 하고 units은 최소 깊이 버퍼 값을 스케일 합니다. 이것은 사용자가 다각형들이 같은 위치에 있음에도 불구하고 하나의 다각형이 다른 것 위에서 그려지도록 할 수 있습니다. 예를 들어 Offset 0, -1 은 다각형의 기울기를 무시하고 다각형을 카메라 가까이로 당깁니다. 반면 Offset -1, -1 은 방목 각도를 볼 때 심지어 더 가깝게 다각형을 끌어 당깁니다.

 

----------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------

 

Texture block combine command

 

  • Previous 는 이전 SetTexture의 결과입니다.
  • Primarylighting calculation 로부터의 색상이거나 또는 그것이 bound 되어지면 꼭지점 색상입니다.
  • Texture 는SetTexture에서 [TextureName] 에서 지정된 텍스쳐의 색상입니다 (위를 참고하세요).
  • ConstantConstantColor에서 지정된 색상입니다.
  • SetTexture [TexturePropertyName] { Texture Block }ne src1 * src2

    src1과src2를 함께 곱합니다. 결과는 입력값보다 더 어두울 것입니다.
    combine src1 + src2
    src1과src2를 함께 더합니다. 결과는 입력값보다 더 밝을 것입니다.
    combine src1 - src2
    src1에서 src2를 뺍니다.
    combine src1 +- src2
    src1과src2를 함께 더하고나서 0.5를 뺍니다 (부호가 적용되는 덧셈).
    combine src1 lerp (src2) src3
    src2의 알파를 사용해서 src3와src1 사이에서 보간합니다. 보간은 반대 방향임을 주의하시기 바랍니다: 알파가 1일 때src1가 사용되고 알파가 0일 때src3에서 사용됩니다.
    combine src1 * src2 + src3
    src1을src2의 알파 컴포넌트에 곱하고 나서 src3을 더합니다.
    combine src1 * src2 +- src3
    src1을src2의 알파 컴포넌트에 곱하고 나서src3과 함께 부호를 적용하는 덧셈을 합니다.
    combine src1 * src2 - src3
    src1을src2의 알파 컴포넌트에 곱하고 나서src3을 뺍니다.

    모든 src 속성들은 previous, constant, primary 또는 texture 중의 하나일 수 있습니다.

     

    Separate Alpha & Color blending

    기본적으로, 결합 공식은RGB와 색상settexture의 알파 컴포넌트 둘 다를 계산하기 위해서 사용됩니다. 선택적으로 사용자는 알파 계산을 위해서 별개의 공식을 지정할 수 있습니다. 이것은 다음과 같습니다:

    SetTexture [_MainTex] { combine previous * texture, previous + texture }

     

     

    Texture block constantColor command

    ConstantColor color
    결합된 명령에서 사용될 수 있는 상수 색을 정의합니다.

    Texture block matrix command

    matrix [MatrixPropertyName]
    주어진 매트릭스와 함께 이 명령에서 사용된 변형 텍스쳐 좌표.

    Shader "Examples/Self-Illumination 3" {
        Properties {
            _IlluminCol ("Self-Illumination color (RGB)", Color) = (1,1,1,1)
            _Color ("Main Color", Color) = (1,1,1,0)
            _SpecColor ("Spec Color", Color) = (1,1,1,1)
            _Emission ("Emmisive Color", Color) = (0,0,0,0)
            _Shininess ("Shininess", Range (0.01, 1)) = 0.7
            _MainTex ("Base (RGB)", 2D) = "white" {}
        }

        SubShader {
            Pass {
                // Set up basic vertex lighting
                Material {
                    Diffuse [_Color]
                    Ambient [_Color]
                    Shininess [_Shininess]
                    Specular [_SpecColor]
                    Emission [_Emission]
                }
                Lighting On

                // Use texture alpha to blend up to white (= full illumination)
                SetTexture [_MainTex] {
                    constantColor [_IlluminCol]
                    combine constant lerp(texture) previous
                }
                // Multiply in texture
                SetTexture [_MainTex] {
                    combine previous * texture
                }
            }
        }
    }

    ----------------------------------------------------------------------------------------------------------------------------------

    ----------------------------------------------------------------------------------------------------------------------------------

     

    Fog

    Fog { Fog Commands }
    괄호안의fog 명령어를 명세합니다.
    Mode Off | Global | Linear | Exp | Exp2
    Fog 모드를 정의합니다. 기본값은 글로벌입니다. 그것은 렌더링 세팅에서 fog가 켜졌는지 여부에 따라서 Off 또는 Exp2로 번역합니다.
    Color ColorValue
    Fog 색을 세팅합니다.
    Density FloatValue
    기하급수적인 fog를 위한 밀도를 세팅합니다.
    Range FloatValue , FloatValue
    선형 fog를 위해 근거리 그리고 원거리의 범위를 세팅합니다.

    Details

    기본적인 fog 세팅은 Render Settings에 기반합니다: fog 모델은 Exp2 또는 Off 입니다; 세팅으로부터 취해진 밀도 & 색.

    사용자가 fragment programs를 사용한다면 그 쉐이더의 Fog 세팅은 여전히 적용될 것입니다. 고정된 Fog 기능이 없는 플랫폼에서 Unity는 요청되는 Fog 모드를 지원하기 위해서 실시간으로 쉐이더를 패치할 것입니다.

     

    ----------------------------------------------------------------------------------------------------------------------------------

    ----------------------------------------------------------------------------------------------------------------------------------

     

    Alpha testing

     

    AlphaTest Off
    모든 픽셀을 그립니다 (기본 세팅).
    AlphaTest comparison AlphaValue
    그것의 알파 값이 특정 범위안에 있는 픽셀들만 그리기 위한 알파 테스트를 세팅합니다.

    Comparison

    비교는 다음 단어들 중 하나입니다:

    Greater 그것의 알파가 AlphaValue보다 큰 픽셀들만 그립니다.
    GEqual 그것의 알파가’‘AlphaValue’’ 보다 크거나 같은 픽셀들만 그립니다.
    Less 그것의 알파값이’‘AlphaValue’’ 보다 적은 픽셀들만 그립니다.
    LEqual 그것의 알파값이’‘AlphaValue’’ 보다 적거나 같은 픽셀들만 그립니다.
    Equal 그것의 알파값이’‘AlphaValue’’ 과 같은 픽셀들만 그립니다.
    NotEqual 그것의 알파값이’‘AlphaValue’’ 과 다른 픽셀들만 그립니다.
    Always 모든 픽셀을 그립니다. 이것은 AlphaTest Off와 기능적으로 동일합니다.
    Never 어떠한 픽셀도 그리지 않습니다.

    AlphaValue

    0과 1사이의 소수점 숫자. 이것은 기본적인 사각형 타입의 괄호 포맷([변수 이름])을 사용해서 쓰여져야 하는 경우에 하나의 float 또는 범위 속성을 레퍼런스하는 변수를 위해 사용될 수 있습니다.

    Details

    알파 테스트는 투명한 부분들을 가지는 물체를 오목하게 표현할 때 중요합니다. 그래픽 카드는 스크린에 쓰여지는 모든 픽셀의 깊이의 레코드를 유지합니다. 하나의 새로운 픽셀이 이전에 그려진 픽셀보다 멀리 있다면 새로운 픽셀은 디스플레이에 쓰여지지 않습니다. 이것은 Blending과 함께 임에도 불구하고 물체가 들여다 보지 않을 것입니다.

    Shader "Vegetation" {
    Properties {
    _Color ("Main Color", Color) = (.5, .5, .5, .5)
    _MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
    _Cutoff ("Base Alpha cutoff", Range (0,.9)) = .5
    }
    SubShader {
    // Set up basic lighting
    Material {
    Diffuse [_Color]
    Ambient [_Color]
    }
    Lighting On

    // Render both front and back facing polygons.
    Cull Off

    // first pass:
    //   render any pixels that are more than [_Cutoff] opaque
    Pass {
    AlphaTest Greater [_Cutoff]
    SetTexture [_MainTex] {
    combine texture * primary, texture
    }
    }

    // Second pass:
    //   render in the semitransparent details.
    Pass {
    // Dont write to the depth buffer
    ZWrite off
    // Don't write pixels we have already written.
    ZTest Less
    // Only render pixels less or equal to the value
    AlphaTest LEqual [_Cutoff]

    // Set up alpha blending
    Blend SrcAlpha OneMinusSrcAlpha

    SetTexture [_MainTex] {
    combine texture * primary, texture
    }
    }
    }
    }

     

    ----------------------------------------------------------------------------------------------------------------------------------

    ----------------------------------------------------------------------------------------------------------------------------------

     

    Blending

    Syntax

    Blend Off
    블렌딩 기능 취소
    Blend SrcFactor DstFactor
    블렌딩을 구성 & 활성화. 생성된 색상은 SrcFactor를 곱합니다. 스크린에 이미 있던 색상은 DstFactor 에 의해 곱해지고 두 개는 함께 더해집니다.

    Properties

    모든 다음의 속성들은SrcFactor와DstFactor 둘 다를 위해서 유효합니다. Source 는 계산되어지는 색상을 의미하고 Destination 는 이미 스크린에 있는 색상을 의미합니다.

    One 1의 값 – 소스 또는 데스티네이션 색상이 온전히 오게 합니다.
    Zero 0의 값 – 소스 또는데스티네이션 값을 삭제하게 합니다.
    SrcColor 이 스테이지의 값은 소스 색상 값에 의해 곱해집니다.
    SrcAlpha 이 스테이지의 값은 소스 알파 값에 의해 곱해집니다.
    DstColor 이 스테이지의 값은 프레임 버퍼 소스 색상 값에 의해 곱해집니다.
    DstAlpha 이 스테이지의 값은 프레임 버퍼 소스 알파 값에 의해 곱해집니다.
    OneMinusSrcColor 이 스테이지의 값은 (1 – 소스 색상)에 의해 곱해집니다.
    OneMinusSrcAlpha 이 스테이지의 값은 (1 – 소스 알파)에 의해 곱해집니다.
    OneMinusDstColor 이 스테이지의 값은 (1 – 데스티네이션 색상)에 의해 곱해집니다.
    OneMinusDstAlpha 이 스테이지의 값은 (1 – 데스티네이션 알파)에 의해 곱해집니다.

    Details

    아래는 가장 흔한 블렌드 타입입니다:

    Blend SrcAlpha OneMinusSrcAlpha     // Alpha blending
    Blend One One                       // Additive
    Blend One OneMinusDstColor          // Soft Additive
    Blend DstColor Zero                 // Multiplicative
    Blend DstColor SrcColor             // 2x Multiplicative
    

     

    ----------------------------------------------------------------------------------------------------------------------------------

    ----------------------------------------------------------------------------------------------------------------------------------

    LightMode tag

    LightMode 태그는 조명 파이프라인에서 패스의 역할을 정의합니다. 자세한 내용을 위해서 render pipeline를 참고하시기 바랍니다. 이러한 태그는 수동적으로 거의 사용되지 않습니다; 조명과 상호작용할 필요가 있는 쉐이더는Surface Shaders로서 쓰여지고 그 후에 모든 디테일들이 처리됩니다.

    LightMode 태그를 위한 가능한 값:

    • Always: 항상 렌더됩니다; 조명이 적용되지 않습니다.
    • ForwardBase: Forward rendering에서 사용됩니다, 주변의 주요한 방향성있는 조명과vertex/SH 조명이 적용됩니다.
    • ForwardAdd: Forward rendering에서 사용됩니다; 첨가되는 픽셀당 조명이 적용됩니다, 조명당 한 번의 패스.
    • PrepassBase: Deferred Lighting에서 사용됩니다, normals & specular 대표자를 렌더합니다.
    • PrepassFinal: Deferred Lighting에서 사용됩니다, 텍스쳐, 조명 그리고 방사를 결합해서 마지막 색상을 렌더합니다.
    • Vertex: 물체가 조명에 매핑되지 않을 때 Vertex Lit rendering에서 사용됩니다; 모든 정점 조명이 적용됩니다.
    • VertexLMRGBM: 물체가 조명에 매핑되지 않을 때 Vertex Lit rendering 에서 사용됩니다; lightmap이 RGBM으로 인코딩되는 플랫폼.
    • VertexLM: 물체가 조명에 매핑되지 않을 때 Vertex Lit rendering 에서 사용됩니다; lightmap이double-LDR으로 인코딩되는 플랫폼 (일반적으로 모바일 플랫폼 & 오래된 데스크탑 GPUs).
    • ShadowCaster: 그림자 캐스터로 물체를 렌더합니다.
    • ShadowCollector: Forward 렌더링 경로를 위해서 스크린 공간 버퍼로 물체의 그림자를 모읍니다.

    ----------------------------------------------------------------------------------------------------------------------------------

    ----------------------------------------------------------------------------------------------------------------------------------

     

    Name
    Name "PassName"
    PassName 이름을 현재 패스에게 전달합니다.

    Details

    하나의 패스는 하나의 UsePass 명령이 그것을 레퍼런스할 수 있기 위해서 이름이 주어질 수 있습니다.

     

     

    ----------------------------------------------------------------------------------------------------------------------------------

    ----------------------------------------------------------------------------------------------------------------------------------

     

    BindChannels

    BindChannels 명령은 사용자가 그래픽 하드웨어에 꼭지점 데이터를 어떻게 매핑할지를 정하는 것을 허락합니다.

    BindChannels은 바인딩이 정점 쉐이더 입력값에 따라 조절되는 경우로서 프로그래밍이 가능한 정점 쉐이더가 사용될 때 어떠한 영향도 미치지 않습니다.

    기본적으로 Unity는 사용자를 위한 바인딩을 찾아내나 어떠한 경우에는 사용자가 사용자가 정의한 것이 사용되어지기를 원하기도 합니다.

    예를 들어 사용자는 주요한 UV 세트를 첫 번째 텍스쳐 스테이지에서 사용되기 위해 매핑할 수 있고 부가적인 UV 세트를 두 번째 텍스쳐 스테이지에서 사용되도록 매핑할 수 있습니다. 또는 사용자는 정점 색상이 고려되어져야 하는 것을 하드웨어에 말할 수도 있습니다.

    Syntax

    BindChannels { Bind "source", target }
    정점 데이터 source를 하드웨어 target에 매핑하는 것을 지정합니다.

    Source 다음 중에 하나일 수 있습니다:

    • Vertex: 꼭지점 위치
    • Normal: 꼭지점 normal
    • Tangent: 꼭지점 탄젠트
    • Texcoord: 주요 UV 좌표
    • Texcoord1: 부가적인 UV 좌표
    • Color: 픽셀당 색상

    Target 다음 중에 하나일 수 있습니다:

    • Vertex: 꼭지점 위치
    • Normal: 꼭지점 normal
    • Tangent: 꼭지점 탄젠트
    • Texcoord0, Texcoord1, ...: 해당 텍스쳐 스테이지를 위한 텍스쳐 좌표
    • Texcoord: 모든 텍스쳐 스테이지들을 위한 텍스쳐 좌표들
    • Color: 꼭지점 색상

    Details

    Unity는 어떤 소스가 어떤 타겟에 매핑될 수 있는지에 대한 제한사항들을 가집니다. 소스와 타겟은Vertex, Normal,Tangent 그리고 Color를 위해서 반드시 매치되어야 합니다. 메쉬(TexcoordTexcoord1) 로 부터 텍스쳐 좌표는 텍스쳐 좌표 타겟으로 매핑될 수 있습니다(모든 텍스쳐 스테이지를 위해서는 Texcoord 그리고 특정한 스테이지를 위해서는 TexcoordN).

    BindChannels를 위한 두 가지의 일반적인 사용 케이스가 있습니다:

    • 꼭지점 색상을 고려하는 쉐이더.
    • 두 가지의 UV 세트를 사용하는 쉐이더.

    Examples

    // Maps the first UV set to the first texture stage
    // and the second UV set to the second texture stage
    BindChannels {
       Bind "Vertex", vertex
       Bind "texcoord", texcoord0
       Bind "texcoord1", texcoord1
    } 
    // Maps the first UV set to all texture stages
    // and uses vertex colors
    BindChannels {
       Bind "Vertex", vertex
       Bind "texcoord", texcoord
       Bind "Color", color
    } 

     

    ----------------------------------------------------------------------------------------------------------------------------------

    ----------------------------------------------------------------------------------------------------------------------------------

     

    UsePass
    UsePass "Shader/Name"
    주어진 쉐이더로 부터 주어진 이름과 함께 모든 패스들을 넣으십시오. 쉐이더/이름은 슬래시 기호에 의해 쉐이더의 이름과 패스의 이름을 포함합니다. Shader/Name은 슬래시 기호에 의해 쉐이더의 이름과 패스의 이름을 포함합니다. .

    Details

    쉐이더 중 몇몇은 코드 중복을 감소하면서 다른 쉐이더로 부터 존재하는 패스들을 재사용할 수 있습니다. 예를 들어, 대부분의 픽셀 기반 조명 쉐이더에서 주위의 또는 정점 조명 패스는 상응하는 VertexLit 쉐이더에서 같습니다. UsePass 명령은 또다른 쉐이더로부터 주어진 패스를 포함합니다. 예로서 다음의 명령은 내장된 Specular쉐이더로부터 "BASE"라는 이름의 패스를 사용합니다:

        UsePass "Specular/BASE"
    

    UsePass가 작동하기 위해서는 하나의 이름이 사용자가 사용하기를 원하는 패스로 주어져야 합니다. 패스안에서 Name 명령은 그것에 이름을 줍니다 command inside the pass gives it a name:

        Name "MyPassName"
    

    내부적으로 모든 패스의 이름은 대분자이기 때문에 UsePass는 이름을 반드시 대분자로 참조해야 합니다.

     

    ----------------------------------------------------------------------------------------------------------------------------------

    ----------------------------------------------------------------------------------------------------------------------------------

     

    GrabPass

    GrabPass은 특별한 패스 타입입니다 – 그것은 물체가 하나의 텍스쳐로 그려질 스크린의 내용물을 차지합니다. 이런 텍쳐는 좀 더 발전된 이미지 기반의 효과를 만들기 위해 일련의 하위 패스들에서 사용될 수 있습니다.

    Syntax

    GrabPass는 subshader안에 속합니다. 그것은 두 개의 형식을 취합니다:

    • GrabPass { } 는 텍스쳐로 현재의 스크린 내용을 보낼 것입니다. 텍스쳐는 _GrabTexture_에 의해 앞으로의 패스에서 접근될 수 있습니다. 주의: grab pass의 이 형식은 그것을 사용하는 각 물체를 위해 비용이 많이 드는 스크린 grabbing 오퍼레이션을 할 것입니다!
    • GrabPass { "TextureName" }은 텍스쳐로 스크린 내용을 보낼것이나 주어진 텍스쳐 이름을 사용하는 첫 번째 물체을 위해 프레임당 한 번만 작동할 것입니다. 텍스쳐는 주어진 텍스쳐 이름에 의해서 앞으로의 패스에서 접근될 수 있습니다. 이것은 사용자가 씬에서 grab pass를 사용하는 다수의 물체를 가질 때 더욱 성능이 좋습니다.

    게다가 GrabPass은 NameTags 명령을 사용할 수 있습니다.

    Example

    이것이 이전에 그려졌던 색상을 바꾸는 비용이 많이 드는 방법을 보여줍니다:

    Shader "GrabPassInvert" {
        SubShader {
            // Draw ourselves after all opaque geometry
            Tags { "Queue" = "Transparent" }
    
            // Grab the screen behind the object into _GrabTexture
            GrabPass { }
    
            // Render the object with the texture generated above, and invert it's colors
            Pass {
                SetTexture [_GrabTexture] { combine one-texture }
            }
        }
    } 

    이 쉐이더는 두 가지의 패스를 가집니다: 첫 번째 패스는 렌더링이 될 때 물체의 뒤에 무엇이 있던지 잡아내고 그 후에 두 번째 패스에서 그것을 적용합니다. 물론 지금은 같은 효과가 역blend mode을 사용해서 훨씬 저렴하게 얻어질 수 있습니다.

     

     

    ----------------------------------------------------------------------------------------------------------------------------------

    ----------------------------------------------------------------------------------------------------------------------------------

     

    Fallback

    모든Subshaders후에 Fallback이 정의될 수 있습니다. 그것은 기본적으로 어떠한 서브 쉐이더를 하드웨어 위에서 실행될 수 없으면 또다른 쉐이더로부터의 그것들을 사용하는 것을 시도해보라고 말합니다.

    Syntax

    Fallback "name"
    주어진 이름으로 쉐이더에 대체.
    Fallback Off
    심지어 어떠한 서브 쉐이더가 하드웨어에서 실행될 수 없음에도 명확하게 어떠한 대체도 없고 어떠한 주의 메세지도 프린트되어 지지말아야 한다고 나타냅니다.

    Details

    대체를 나타내는 서술은 마치 그 다른 쉐이더로부터 모든 서브 쉐이더가 그것의 위치에 삽입되어지는 것처럼 같은 효과를 가집니다.

    Example

    Shader "example" {
        // properties and subshaders here...
        Fallback "otherexample"
    } 

    ----------------------------------------------------------------------------------------------------------------------------------

    ----------------------------------------------------------------------------------------------------------------------------------

     

    Category

    Category는 어떠한 명령어들의 논리적인 그룹입니다. 이것은 대체로 렌더링 상태를 "상속"하기 위해 사용됩니다. 예를 들어, 사용자의 쉐이더가 다수의 subshaders를 가지고 그들 각자가 fog를 없애야 하고 추가되는 형태의 blending세팅을 가질지도 모릅니다. 사용자는 그것을 위해서 Category를 사용할 수 있습니다.

    Shader "example" {
    Category {
        Fog { Mode Off }
        Blend One One
        SubShader {
            // ...
        }
        SubShader {
            // ...
        }
        // ...
    }
    }
    

    ----------------------------------------------------------------------------------------------------------------------------------

    ----------------------------------------------------------------------------------------------------------------------------------

     

     

     

     

     

     

     

     

     

     

     

     

     

    'TA > Unity Shader 레퍼런스' 카테고리의 다른 글

    SurfaceShaderLighting  (0) 2012.07.26
    SurfaceShaders  (0) 2012.07.26
    Pass  (0) 2012.07.19
    Category  (0) 2012.07.18
    SubShader Tags  (0) 2012.07.18
    Posted by 프리랜서 디자이너

    유니티 기반의 라이트맵 모바일 셰이더분석?

     

    유니티라이트맵 기번 모바일 셰이더는 유니티에서 만들어 주는 라이트 맵 시스템을 따른다.

    그래서 인지 솅;더에 라이트 맵을 따로 넣은  프로퍼티가 없다.

    대신 셰이더 코드에서 texcoord를 추가하고 매트릭스를 유니티 라이트 맵으로 지정해준다.

    패스는 총 3번을 그려서 적용한다.

     

     

     

    // Unlit shader. Simplest possible textured shader.
    // - SUPPORTS lightmap
    // - no lighting
    // - no per-material color

     

    Shader "Mobile/Unlit (Supports Lightmap)" {


    Properties {
     _MainTex ("Base (RGB)", 2D) = "white" {}
    }

     

    SubShader {


     Tags { "RenderType"="Opaque" }
     LOD 100
     
     // Non-lightmapped 첫번째 패스는 라이트를 받지않은 기본 텍스쳐만 그리는 패스.
     Pass {
      Tags { "LightMode" = "Vertex" }
      Lighting Off
      SetTexture [_MainTex] { combine texture }
     }
     //pass
     
     // Lightmapped, encoded as dLDR 두번째 패스 라이트맵이 들어 갈수 있는 texcoord를 추가하고 유니티 라이트맵 매트릭스를 적용한다.

    //VertexLM: 물체가 조명에 매핑되지 않을 때 Vertex Lit rendering 에서 사용됩니다; lightmap이double-LDR으로 인코딩되는

    //플랫폼 (일반적으로 모바일 플랫폼 & 오래된 데스크탑 GPUs).
     Pass {
      Tags { "LightMode" = "VertexLM" }

      Lighting Off
      BindChannels {
       Bind "Vertex", vertex
       Bind "texcoord1", texcoord0 // lightmap uses 2nd uv
       Bind "texcoord", texcoord1 // main uses 1st uv
      }
      
      SetTexture [unity_Lightmap] {
       matrix [unity_LightmapMatrix]
       combine texture
      }
      SetTexture [_MainTex] {
       combine texture * previous DOUBLE, texture * primary
      }
     }
     //pass
     
     // Lightmapped, encoded as RGBM 세번째 패스는 테그에 VertexLMRGBM를 적용하고

    //유니티 라이트 맵에 알파를 적용하고, 최종 결과물에 Quad로 어두어진 맵을 밝게 해준다?(테스트를 안해봐서 ㅎㅎ)
     Pass {
      Tags { "LightMode" = "VertexLMRGBM" }
      
      Lighting Off
      BindChannels {
       Bind "Vertex", vertex
       Bind "texcoord1", texcoord0 // lightmap uses 2nd uv
       Bind "texcoord", texcoord1 // main uses 1st uv
      }
      
      SetTexture [unity_Lightmap] {
       matrix [unity_LightmapMatrix]
       combine texture * texture alpha DOUBLE
      }
      SetTexture [_MainTex] {
       combine texture * previous QUAD, texture * primary
      }
     }
     //pass
     

    }
    //subshader
    }
    //shader

     

     

     

    Posted by 프리랜서 디자이너