OSDN Git Service

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