Matcap Shader support Directional Lighting (VertexShader based.)

Matcap Shader 를 사용 하는 분 중에 혹 디렉셔널 라이팅은 됬으면 좋겠다 하신 분도 있을 듯 해서

개선 했습니다.

버택스 쉐이더 기반이고요.

모바일 쉐이더쪽에 최적화 되어 있습니다.

셀프 쉐도우 부분에서 좀 오류가 있는데 스케일이 너무 작을 경우에 좀 이상하게 나오네요.

변수가 좀 많기는 한데...

이 부분은 서브스턴스 에서 텍스처 제네레이터를 만들어 붙혀서 쓰는게 빠른지 아니면

함수 부에서 변수쪽을 계산을 계속 업데이트 시키는 쉐이더 방식이 좋을지 솔직히 테스트 안하고는 뭐라 확답하기 힘드네요.


보시는 거 처럼 디렉셔널 라이팅 1개를 지원 하고 쉐도우 지원.
라이트 프로브 지원을 합니다.

일루미네이션 에미시브 값을 3 으로 상승 했을 경우.


유니티 패키지 추가.
드롭박스 공유.



// unit added Customizing Author (c) 2013 JP.Lee

Shader "PocketCom/MatCap_Diffuse_Rim_VertexLit (Only Directional Lights)"{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
_MatCap ("MatCap (RGB)", 2D) = "white" {}
_MatCapSourceRGB ("SourceRGB" , Color) = (255 , 255 , 255 , 255)
_MatCapBlendFactor ("MatCap Blend Factor" , Range(0.5,1.5)) =1
_MatRim ("RimTex (RGB)", 2D) = "white" {}
_RimPower ("RimPower", Range(0,3)) = 1
_RimColor("Rim Color" , Color) = (255 , 255 , 255 , 255)
}
Subshader
{
Tags { "RenderType"="Opaque" }
Pass
{
NAME "FORWARD"
Tags { "LightMode" = "ForwardBase" }

CGPROGRAM
#pragma vertex vert_surf
#pragma fragment frag_surf ARB_precision_hint_fastest
#pragma multi_compile_fwdbase


#define UNITY_PASS_FORWARDBASE
//#include "HLSLSupport.cginc"
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"

#define INTERNAL_DATA
#define WorldReflectionVector(data,normal) data.worldRefl
#define WorldNormalVector(data,normal) normal

inline float3 LightingLambertVS (float3 normal, float3 lightDir)
{
fixed diff = max (0, dot (normal, lightDir));
return _LightColor0.rgb * (diff * 2);
}

uniform sampler2D _MainTex;
uniform sampler2D _MatCap;
uniform sampler2D _MatRim;
uniform float _RimPower;
uniform float4 _RimColor;
uniform float _MatCapBlendFactor;
uniform float4 _MatCapSourceRGB;


struct SurfaceOutputMatcap
{
fixed3 Albedo;
fixed3 Normal;
fixed3 Emission;
fixed Specular;
fixed Alpha;
fixed3 Matcap;
fixed3 Rim;
};

struct Input 
{
float2 uv_MainTex;
float2 cap_Tex;
};

void surf (Input IN, inout SurfaceOutputMatcap o) 
{
fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;

fixed4 mc = tex2D(_MatCap, IN.cap_Tex) * _MatCapBlendFactor;
o.Matcap = mc;

fixed4 mcRim = tex2D(_MatRim, IN.cap_Tex) * _RimColor;
o.Rim = mcRim;

}

struct v2f_surf
{
float4 pos    : SV_POSITION;
float2 pack0    : TEXCOORD0;
float2 pack1   : TEXCOORD2;
fixed3 vlight    : TEXCOORD3;
#ifdef LIGHTMAP_OFF
fixed3 normal    : TEXCOORD1;
#endif
LIGHTING_COORDS(4,5)
};

uniform float4 _MainTex_ST;

v2f_surf vert_surf (appdata_full v)
{
v2f_surf o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.pack0 = TRANSFORM_TEX(v.texcoord, _MainTex);

fixed2 capCoord;
capCoord.x = dot(UNITY_MATRIX_IT_MV[0].xyz,v.normal);
capCoord.y = dot(UNITY_MATRIX_IT_MV[1].xyz,v.normal);
o.pack1.xy = capCoord * 0.5 + 0.5;

float3 worldN = mul((float3x3)_Object2World, SCALED_NORMAL);
#ifdef LIGHTMAP_OFF
o.normal = worldN;
#endif
#ifdef LIGHTMAP_OFF

o.vlight = ShadeSH9 (float4(worldN,1.0));
o.vlight += LightingLambertVS (worldN, _WorldSpaceLightPos0.xyz);
#endif // LIGHTMAP_OFF
TRANSFER_VERTEX_TO_FRAGMENT(o);
return o;
}




fixed4 frag_surf (v2f_surf IN) : COLOR
{
Input surfIN;
surfIN.uv_MainTex = IN.pack0;
surfIN.cap_Tex = IN.pack1;
SurfaceOutputMatcap o;
surf (surfIN, o);
fixed atten = LIGHT_ATTENUATION(IN);

fixed4 c = 0;

#ifdef LIGHTMAP_OFF

c.rgb = (o.Albedo * (o.Matcap * _MatCapSourceRGB) * 2.0 + (o.Rim * _RimPower)) * IN.vlight * atten;
#endif // LIGHTMAP_OFF
c.a = o.Alpha;
return c;

}
ENDCG
}
}

Fallback "VertexLit"
}


개발중인 쉐이더를 적용 하여 모바일 기기에서 테스트 한 사진 모음.
모두 언라이팅 기반이다. 라이팅 벡터 부분에 대해서는 좀 더 생각 해 봐야겠지만 모바일 게임이라는 특성상 라이팅 벡터가 꼭 중요 한 것은 아니다.
뷰스페이스 기반의 좌표계라고는 하지만 좀 더 머리를 쓰면 더 좋은 결과물을 낼 수 있을 듯.

디퓨즈 범프 림라이팅 언릿은 패키지에 포함 되어 있지 않아요.(개선 중.)




 








Game Developer Leegoon copyright all right reserved since 2010.

Comments

  1. 일정 부분 파라메터 변수를 Clamp 로 강제화 했어요. 슬라이더 보다는 다른 메트리얼과 값을 맞추기 편하게 플롯 타입으로 바꿨거든요.

    ReplyDelete

Post a Comment

덧글쓰기 기능 있는거 아시죠? ㅋㅋ