OSDN Git Service

ddd449b92db7cf2d300f4492221ee2236667b118
[mikumikustudio/MikuMikuStudio.git] / src / MatDefs / pmd / pmd.frag
1 #import "Common/ShaderLib/Optics.glsllib"\r
2 \r
3 #ifdef SPHERE_MAP_A\r
4   uniform sampler2D m_SphereMap_A;\r
5 #endif\r
6 #ifdef SPHERE_MAP_H\r
7   uniform sampler2D m_SphereMap_H;\r
8 #endif\r
9 \r
10 \r
11 #define ATTENUATION\r
12 //#define HQ_ATTENUATION\r
13 \r
14 \r
15 varying vec2 texCoord;\r
16 \r
17 varying vec4 AmbientSum;\r
18 varying vec4 DiffuseSum;\r
19 varying vec4 SpecularSum;\r
20 \r
21 #ifndef VERTEX_LIGHTING\r
22   varying vec3 vPosition;\r
23   varying vec3 vViewDir;\r
24   varying vec4 vLightDir;\r
25 #endif\r
26 \r
27 #ifdef DIFFUSEMAP\r
28   uniform sampler2D m_DiffuseMap;\r
29 #endif\r
30 \r
31 #ifdef SPECULARMAP\r
32   uniform sampler2D m_SpecularMap;\r
33 #endif\r
34 \r
35 #ifdef PARALLAXMAP\r
36   uniform sampler2D m_ParallaxMap;\r
37 #endif\r
38   \r
39 #ifdef NORMALMAP\r
40   uniform sampler2D m_NormalMap;\r
41 #else\r
42   varying vec3 vNormal;\r
43 #endif\r
44 \r
45 #ifdef ALPHAMAP\r
46   uniform sampler2D m_AlphaMap;\r
47 #endif\r
48 \r
49 #ifdef COLORRAMP\r
50   uniform sampler2D m_ColorRamp;\r
51 #endif\r
52 uniform float m_AlphaDiscardThreshold;\r
53 #ifndef VERTEX_LIGHTING\r
54 uniform float m_Shininess;\r
55 \r
56 #ifdef HQ_ATTENUATION\r
57 uniform vec4 g_LightPosition;\r
58 varying vec3 lightVec;\r
59 #endif\r
60 \r
61 #ifdef USE_REFLECTION \r
62     uniform float m_ReflectionPower;\r
63     uniform float m_ReflectionIntensity;\r
64 //    varying vec4 refVec;\r
65 \r
66     uniform ENVMAP m_EnvMap;\r
67 #endif\r
68     varying vec4 refVec;\r
69 \r
70 float tangDot(in vec3 v1, in vec3 v2){\r
71     float d = dot(v1,v2);\r
72     #ifdef V_TANGENT\r
73         d = 1.0 - d*d;\r
74         return step(0.0, d) * sqrt(d);\r
75     #else\r
76         return d;\r
77     #endif\r
78 }\r
79 \r
80 float lightComputeDiffuse(in vec3 norm, in vec3 lightdir, in vec3 viewdir){\r
81     #ifdef MINNAERT\r
82         float NdotL = max(0.0, dot(norm, lightdir));\r
83         float NdotV = max(0.0, dot(norm, viewdir));\r
84         return NdotL * pow(max(NdotL * NdotV, 0.1), -1.0) * 0.5;\r
85     #else\r
86         return max(0.0, dot(norm, lightdir));\r
87     #endif\r
88 }\r
89 \r
90 float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){\r
91     #ifdef LOW_QUALITY\r
92        // Blinn-Phong\r
93        // Note: preferably, H should be computed in the vertex shader\r
94        vec3 H = (viewdir + lightdir) * vec3(0.5);\r
95        return pow(max(tangDot(H, norm), 0.0), shiny);\r
96     #elif defined(WARDISO)\r
97         // Isotropic Ward\r
98         vec3 halfVec = normalize(viewdir + lightdir);\r
99         float NdotH  = max(0.001, tangDot(norm, halfVec));\r
100         float NdotV  = max(0.001, tangDot(norm, viewdir));\r
101         float NdotL  = max(0.001, tangDot(norm, lightdir));\r
102         float a      = tan(acos(NdotH));\r
103         float p      = max(shiny/128.0, 0.001);\r
104         return NdotL * (1.0 / (4.0*3.14159265*p*p)) * (exp(-(a*a)/(p*p)) / (sqrt(NdotV * NdotL)));\r
105     #else\r
106        // Standard Phong\r
107        vec3 R = reflect(-lightdir, norm);\r
108        return pow(max(tangDot(R, viewdir), 0.0), shiny);\r
109     #endif\r
110 }\r
111 \r
112 vec2 computeLighting(in vec3 wvPos, in vec3 wvNorm, in vec3 wvViewDir, in vec3 wvLightDir){\r
113    float diffuseFactor = lightComputeDiffuse(wvNorm, wvLightDir, wvViewDir);\r
114    float specularFactor = lightComputeSpecular(wvNorm, wvViewDir, wvLightDir, m_Shininess);\r
115    specularFactor *= step(1.0, m_Shininess);\r
116 \r
117    #ifdef HQ_ATTENUATION\r
118     float att = clamp(1.0 - g_LightPosition.w * length(lightVec), 0.0, 1.0);\r
119    #else\r
120     float att = vLightDir.w;\r
121    #endif\r
122 \r
123    return vec2(diffuseFactor, specularFactor) * vec2(att);\r
124 }\r
125 #endif\r
126 vec2 Optics_SphereCoord2(in vec3 dir){\r
127     float dzplus1 = dir.z + 1.0;\r
128     float m = 2.0 * sqrt(dir.x * dir.x + dir.y * dir.y + dzplus1 * dzplus1);\r
129     return vec2(dir.x / m + 0.5, dir.y / m + 0.5);\r
130 }\r
131 \r
132 void main(){\r
133     vec2 newTexCoord;\r
134  \r
135     #if defined(PARALLAXMAP) || defined(NORMALMAP_PARALLAX)\r
136        float h;\r
137        #ifdef PARALLAXMAP\r
138           h = texture2D(m_ParallaxMap, texCoord).r;\r
139        #else\r
140           h = texture2D(m_NormalMap, texCoord).a;\r
141        #endif\r
142        float heightScale = 0.05;\r
143        float heightBias = heightScale * -0.5;\r
144        vec3 normView = normalize(vViewDir);\r
145        h = (h * heightScale + heightBias) * normView.z;\r
146        newTexCoord = texCoord + (h * -normView.xy);\r
147     #else\r
148        newTexCoord = texCoord;\r
149     #endif\r
150     \r
151    #ifdef DIFFUSEMAP\r
152       vec4 diffuseColor = texture2D(m_DiffuseMap, newTexCoord);\r
153     #else\r
154       vec4 diffuseColor = vec4(1.0);\r
155     #endif\r
156     float alpha = DiffuseSum.a * diffuseColor.a;\r
157     //float alpha = (DiffuseSum.a + diffuseColor.a)/2;\r
158     #ifdef ALPHAMAP\r
159        alpha = alpha * texture2D(m_AlphaMap, newTexCoord).r;\r
160     #endif\r
161     if(alpha < m_AlphaDiscardThreshold){\r
162         discard;\r
163     }\r
164 \r
165     // ***********************\r
166     // Read from textures\r
167     // ***********************\r
168     #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)\r
169       vec4 normalHeight = texture2D(m_NormalMap, newTexCoord);\r
170       vec3 normal = (normalHeight.xyz * vec3(2.0) - vec3(1.0));\r
171       #ifdef LATC\r
172         normal.z = sqrt(1.0 - (normal.x * normal.x) - (normal.y * normal.y));\r
173       #endif\r
174       normal.y = -normal.y;\r
175     #elif !defined(VERTEX_LIGHTING)\r
176       vec3 normal = vNormal;\r
177       #if !defined(LOW_QUALITY) && !defined(V_TANGENT)\r
178          normal = normalize(normal);\r
179       #endif\r
180     #endif\r
181 \r
182     #ifdef SPECULARMAP\r
183       vec4 specularColor = texture2D(m_SpecularMap, newTexCoord);\r
184     #else\r
185       vec4 specularColor = vec4(1.0);\r
186     #endif\r
187 \r
188     #ifdef VERTEX_LIGHTING\r
189        vec2 light = vec2(AmbientSum.a, SpecularSum.a);\r
190        #ifdef COLORRAMP\r
191            // light.x = texture2D(m_ColorRamp, vec2(light.x, 0.0)).r;\r
192            // light.y = texture2D(m_ColorRamp, vec2(light.y, 0.0)).r;\r
193            light.x = texture2D(m_ColorRamp, vec2(0.0,light.x)).r;\r
194            light.y = texture2D(m_ColorRamp, vec2(0.0,light.y)).r;\r
195        #endif\r
196 \r
197        gl_FragColor =  AmbientSum * diffuseColor + \r
198                        DiffuseSum * diffuseColor  * light.x +\r
199                        SpecularSum * specularColor * light.y;\r
200            diffuseColor.rgb  *= texture2D(m_ColorRamp, vec2(0.0,light.x)).rgb;\r
201            specularColor.rgb *= texture2D(m_ColorRamp, vec2(0.0,light.y)).rgb;\r
202        gl_FragColor =  AmbientSum * diffuseColor + \r
203                        DiffuseSum * diffuseColor   +\r
204                        SpecularSum * specularColor ;\r
205     #else\r
206        vec4 lightDir = vLightDir;\r
207        lightDir.xyz = normalize(lightDir.xyz);\r
208 \r
209        vec2 light = computeLighting(vPosition, normal, vViewDir.xyz, lightDir.xyz);\r
210        #ifdef COLORRAMP\r
211            // diffuseColor.rgb  *= texture2D(m_ColorRamp, vec2(light.x, 0.0)).rgb;\r
212            // specularColor.rgb *= texture2D(m_ColorRamp, vec2(light.y, 0.0)).rgb;\r
213            diffuseColor.rgb  *= texture2D(m_ColorRamp, vec2(0.0,light. x)).rgb;\r
214            specularColor.rgb *= texture2D(m_ColorRamp, vec2(0.0,light. y)).rgb;\r
215        #endif\r
216 \r
217        // Workaround, since it is not possible to modify varying variables\r
218        vec4 SpecularSum2 = SpecularSum;\r
219        #ifdef USE_REFLECTION\r
220             vec4 refColor = Optics_GetEnvColor(m_EnvMap, refVec.xyz);\r
221 \r
222             // Interpolate light specularity toward reflection color\r
223             // Multiply result by specular map\r
224             specularColor = mix(SpecularSum2 * light.y, refColor, refVec.w) * specularColor;\r
225 \r
226             SpecularSum2 = vec4(1.0);\r
227             light.y = 1.0;\r
228        #endif\r
229 //       if (isnan(light.y)) {\r
230        if (light.y != light.y) {\r
231             light.y = 0.0;\r
232        }\r
233 //       gl_FragColor =  (AmbientSum * diffuseColor +\r
234 //                       DiffuseSum * diffuseColor + //* light.x +\r
235 //                       SpecularSum2 * specularColor * light.y ) * 0.8;\r
236        vec4 output_color = (((AmbientSum + DiffuseSum) * diffuseColor)  +\r
237                        SpecularSum2 * specularColor * light.y );\r
238 // output_color=vec4(0);\r
239 #ifdef SPHERE_MAP_A\r
240         vec2 v2 = Optics_SphereCoord(normalize(refVec.xyz));\r
241         v2.y = 1.0 - v2.y;\r
242         output_color.xyz +=  (texture2D(m_SphereMap_A, v2).xyz);\r
243         // output_color.xyz = vec3(normalize(refVec.xyz).x);\r
244 #endif\r
245 #ifdef SPHERE_MAP_H\r
246         vec2 v2 = Optics_SphereCoord(normalize(refVec.xyz));\r
247         v2.y = 1.0 - v2.y;\r
248         output_color.xyz *= (texture2D(m_SphereMap_H, v2).xyz);\r
249 #endif\r
250 \r
251     #endif\r
252     output_color.a = alpha;\r
253     // output_color.a = diffuseColor.a;\r
254 \r
255     // gl_FragColor = 0.5 + 0.5 * light.x;//output_color;\r
256     gl_FragColor = output_color;\r
257 }\r