- 일단 기본적으로 Standard Shader는 Uber Shader로 짜여져 있다.
- 그래서 중간에 주요 라이팅 함수들이 분기가 된다. 특히 핵심 조명 코드인 BRDF 코드는 3.0 지원버전, 2.0 지원 버전, 모바일 버전으로 3가지로 분기된다 (어, 맞던가? 좀전에 봤는데 기억이 안나..)
- 지금 아래는 서피스 쉐이더로 구현하던 것이다. 분기는 없애고 걍 3.0 지원버전으로 ...
- 라이팅을 커스텀으로 한 것 뿐이다.
- 분석하다가 중간에 정지한 것. 지금 라이팅 구문에서는 light.ndotl이 부분을 찾아야 한다. 일단 결과물만 테스트 해 보게 만든 녀석이다. 이 녀석은 어디 숨어 있는 걸까...
- 그래서 지금 결과물 리턴은 NdotL이다.
- 하프 렘버트라도 구현하려면 일단 ndotl 을 saturate 시키지 않는 선에서 마무리되도록 만들어야 한다. 근데 일단 그냥 되어서 넘어오게 만들어져 있다. 음. 수동으로 값 받아서 구현해 버릴까?
- 분기까지 만들면 일이 너무 커지는데다가 귀차니즘에다가 지금 나가야 한다는게 문제.
- 차분히 앉아서 하루만 공부해보면 좋겠다 찌발 ㅜ
Shader "Custom/Standard" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
cull off
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf JP fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
#include "UnityPBSLighting.cginc"
//safe noramlize
inline half3 Unity_SafeNormalize(half3 inVec)
{
half dp3 = max(0.001f, dot(inVec, inVec));
return inVec * rsqrt(dp3);
}
//BRDF1
half4 BRDFjp_Unity_PBS (half3 diffColor, half3 specColor, half oneMinusReflectivity, half oneMinusRoughness,half3 normal, half3 viewDir,UnityLight light, UnityIndirect gi)
{
half roughness = 1-oneMinusRoughness;
half3 halfDir = Unity_SafeNormalize (light.dir + viewDir);
half nl = light.ndotl;
half nh = BlinnTerm (normal, halfDir);
half nv = DotClamped (normal, viewDir);
half lv = DotClamped (light.dir, viewDir);
half lh = DotClamped (light.dir, halfDir);
#if UNITY_BRDF_GGX
half V = SmithGGXVisibilityTerm (nl, nv, roughness);
half D = GGXTerm (nh, roughness);
#else
half V = SmithBeckmannVisibilityTerm (nl, nv, roughness);
half D = NDFBlinnPhongNormalizedTerm (nh, RoughnessToSpecPower (roughness));
#endif
half nlPow5 = Pow5 (1-nl);
half nvPow5 = Pow5 (1-nv);
half Fd90 = 0.5 + 2 * lh * lh * roughness;
half disneyDiffuse = (1 + (Fd90-1) * nlPow5) * (1 + (Fd90-1) * nvPow5);
// HACK: theoretically we should divide by Pi diffuseTerm and not multiply specularTerm!
// BUT 1) that will make shader look significantly darker than Legacy ones
// and 2) on engine side "Non-important" lights have to be divided by Pi to in cases when they are injected into ambient SH
// NOTE: multiplication by Pi is part of single constant together with 1/4 now
half specularTerm = max(0, (V * D * nl) * unity_LightGammaCorrectionConsts_PIDiv4);// Torrance-Sparrow model, Fresnel is applied later (for optimization reasons)
half diffuseTerm = disneyDiffuse * nl;
half grazingTerm = saturate(oneMinusRoughness + (1-oneMinusReflectivity));
half3 color = diffColor * (gi.diffuse + light.color * diffuseTerm)
+ specularTerm * light.color * FresnelTerm (specColor, lh)
+ gi.specular * FresnelLerp (specColor, grazingTerm, nv);
// return float4 (light.ndotl.xxx+0.5,1);
return half4(color, 1);
}
inline half4 LightingJP (SurfaceOutputStandard s, half3 viewDir, UnityGI gi)
{
s.Normal = normalize(s.Normal);
half oneMinusReflectivity;
half3 specColor;
s.Albedo = DiffuseAndSpecularFromMetallic (s.Albedo, s.Metallic, /*out*/ specColor, /*out*/ oneMinusReflectivity);
// shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha)
// this is necessary to handle transparency in physically correct way - only diffuse component gets affected by alpha
half outputAlpha;
s.Albedo = PreMultiplyAlpha (s.Albedo, s.Alpha, oneMinusReflectivity, /*out*/ outputAlpha);
half4 c = BRDFjp_Unity_PBS (s.Albedo, specColor, oneMinusReflectivity, s.Smoothness, s.Normal, viewDir, gi.light, gi.indirect);
// c.rgb += UNITY_BRDF_GI (s.Albedo, specColor, oneMinusReflectivity, s.Smoothness, s.Normal, viewDir, s.Occlusion, gi);
c.a = outputAlpha;
return c;
}
inline void LightingJP_GI (
SurfaceOutputStandard s,
UnityGIInput data,
inout UnityGI gi)
{
gi = UnityGlobalIllumination (data, s.Occlusion, s.Smoothness, s.Normal);
}
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
'유니티 엔진' 카테고리의 다른 글
유니티5 실시간 GI 이상현상 연구 : Unity5 Realtime GI (1) | 2015.06.16 |
---|---|
유니티 안드로이드 텍스쳐 포맷 (Unity Android Texture Format) 의 비밀 (8) | 2015.06.05 |
Unity 5 standard 2side shader (0) | 2015.05.27 |
UV scroll script (2) | 2015.05.07 |
Unity 5.0 Shader 자료들 (0) | 2015.04.23 |
댓글