pbr.glsl 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. //@import "std"
  2. //@vertex
  3. //@fragment
  4. float pointAtten( float d,float r ){
  5. // float atten=1.0-min( (d*d)/(r*r),1.0 );atten*=atten;
  6. float atten=1.0-min( d/r,1.0 );atten*=atten;
  7. // float atten=1.0/(1.0+d*d);
  8. return atten;
  9. }
  10. #if MX2_QUADPASS && MX2_LIGHTINGPASS
  11. void emitPbrFragment( vec3 color,float metalness,float roughness,vec3 position,vec3 normal ){
  12. float glosiness=1.0-roughness;
  13. vec3 color0=vec3( 0.04,0.04,0.04 );
  14. vec3 diffuse=color * (1.0-metalness);
  15. vec3 specular=(color-color0) * metalness + color0;
  16. #if MX2_DIRECTIONALLIGHT
  17. vec3 lvec=normalize( -r_LightViewMatrix[2].xyz );
  18. float atten=1.0;
  19. #elif MX2_POINTLIGHT
  20. vec3 lvec=r_LightViewMatrix[3].xyz-position;
  21. float atten=pointAtten( length( lvec ),r_LightRange );
  22. lvec=normalize( lvec );
  23. #elif MX2_SPOTLIGHT
  24. vec3 lvec=r_LightViewMatrix[3].xyz-position;
  25. float atten=pointAtten( length( lvec ),r_LightRange );
  26. lvec=normalize( lvec );
  27. float cosangle=dot( -lvec,r_LightViewMatrix[2].xyz );
  28. if( cosangle<0.0 ) return; //behind spotlight direction
  29. float angle=acos( cosangle );
  30. if( angle>r_LightOuterAngle ) return; //outside outer cone
  31. atten*=1.0-max( (angle-r_LightInnerAngle)/(r_LightOuterAngle-r_LightInnerAngle),0.0 );
  32. #endif
  33. vec3 vvec=normalize( -position );
  34. vec3 hvec=normalize( lvec+vvec );
  35. float hdotl=max( dot( hvec,lvec ),0.0 );
  36. float ndotl=max( dot( normal,lvec ),0.0 );
  37. float ndoth=max( dot( normal,hvec ),0.0 );
  38. float spow=pow( 2.0,glosiness * 12.0 );
  39. // float spow=pow( 2048.0,glosiness );
  40. float fnorm=(spow+2.0)/8.0;
  41. vec3 fschlick=specular + (1.0-specular) * pow( 1.0-hdotl,5.0 ) * glosiness;
  42. specular=fschlick * pow( ndoth,spow ) * fnorm;
  43. vec3 light=r_LightColor.rgb * ndotl * atten;
  44. #if MX2_POINTLIGHT
  45. vec3 lpos=(r_InverseLightViewMatrix * vec4( position,1.0 )).xyz;
  46. light*=pow( textureCube( r_LightCubeTexture,lpos ).rgb,vec3( 2.2 ) );
  47. #elif MX2_SPOTLIGHT
  48. vec3 lpos=(r_InverseLightViewMatrix * vec4( position,1.0 )).xyz;
  49. lpos.xy=lpos.xy/lpos.z * 0.5 + 0.5;
  50. lpos.y=1.0-lpos.y;
  51. light*=pow( texture2D( r_LightTexture,lpos.xy ).rgb,vec3( 2.2 ) );
  52. #endif
  53. #if MX2_SHADOWTYPE
  54. light*=shadowColor( position );
  55. #endif
  56. vec3 frag=(diffuse+specular) * light;
  57. gl_FragColor=vec4( frag,1.0 );
  58. }
  59. #endif
  60. #if MX2_COLORPASS && MX2_DEFERREDPASS
  61. //deferred PBR lighting
  62. //
  63. void emitPbrFragment( vec4 color,vec3 ambient,vec3 emissive,float metalness,float roughness,float occlusion,vec3 normal ){
  64. color*=v_Color;
  65. float glosiness=1.0-roughness;
  66. vec3 color0=vec3( 0.04,0.04,0.04 );
  67. vec3 diffuse=color.rgb * (1.0-metalness);
  68. vec3 specular=(color.rgb-color0) * metalness + color0;
  69. vec3 vvec=normalize( -v_Position );
  70. float ndotv=max( dot( normal,vvec ),0.0 );
  71. vec3 ambEnv=sampleEnv( reflect( v_Position,normal ),roughness );
  72. /*
  73. vec3 rvec=r_EnvMatrix * reflect( v_Position,normal );
  74. float lod=textureCube( r_EnvTexture,rvec,r_EnvTextureMaxLod ).a * 255.0 - r_EnvTextureMaxLod;
  75. if( lod>0.0 ) lod=textureCube( r_EnvTexture,rvec ).a * 255.0;
  76. // float lod=textureCube( r_EnvTexture,rvec ).a * 255.0;
  77. // if( lod==0.0 ) lod=textureCube( r_EnvTexture,rvec,r_EnvTextureMaxLod ).a * 255.0 - r_EnvTextureMaxLod;
  78. vec3 ambEnv=pow( textureCube( r_EnvTexture,rvec,max( roughness*r_EnvTextureMaxLod-lod,0.0 ) ).rgb,vec3( 2.2 ) ) * r_EnvColor.rgb;
  79. */
  80. vec3 fschlick0=specular + (1.0-specular) * pow( 1.0-ndotv,5.0 ) * glosiness;
  81. vec3 ambDiffuse=diffuse * (r_AmbientDiffuse.rgb+ambient);
  82. vec3 ambSpecular=fschlick0 * ambEnv;
  83. vec3 frag=(ambDiffuse + ambSpecular) * occlusion + emissive;
  84. #if MX2_DEFERREDRENDERER
  85. //write ambient
  86. gl_FragData[0]=vec4( min( frag,8.0 ),1.0 );
  87. //write color/metalness
  88. gl_FragData[1]=vec4( color.rgb,metalness );
  89. //write normal/roughness
  90. gl_FragData[2]=vec4( normal * 0.5 + 0.5,roughness );
  91. #endif
  92. }
  93. #endif
  94. #if MX2_COLORPASS && MX2_FORWARDPASS
  95. //forward PBR lighting
  96. //
  97. void emitPbrFragment( vec4 color,vec3 ambient,vec3 emissive,float metalness,float roughness,float occlusion,vec3 normal ){
  98. color*=v_Color;
  99. const vec3 color0=vec3( 0.04,0.04,0.04 );
  100. float glosiness=1.0-roughness;
  101. vec3 diffuse=color.rgb * (1.0-metalness);
  102. vec3 specular=(color.rgb-color0) * metalness + color0;
  103. vec3 vvec=normalize( -v_Position );
  104. float ndotv=dot( normal,vvec );
  105. vec3 frag=vec3( 0.0 );
  106. #if MX2_AMBIENTPASS
  107. //ambient color
  108. vec3 ambEnv=sampleEnv( reflect( v_Position,normal ),roughness );
  109. /*
  110. vec3 rvec=r_EnvMatrix * reflect( v_Position,normal );
  111. float lod=textureCube( r_EnvTexture,rvec,r_EnvTextureMaxLod ).a * 255.0 - r_EnvTextureMaxLod;
  112. if( lod>0.0 ) lod=textureCube( r_EnvTexture,rvec ).a * 255.0;
  113. // float lod=textureCube( r_EnvTexture,rvec ).a * 255.0;
  114. // if( lod==0.0 ) lod=textureCube( r_EnvTexture,rvec,r_EnvTextureMaxLod ).a * 255.0 - r_EnvTextureMaxLod;
  115. vec3 ambEnv=pow( textureCube( r_EnvTexture,rvec,max( roughness*r_EnvTextureMaxLod-lod,0.0 ) ).rgb,vec3( 2.2 ) ) * r_EnvColor.rgb;
  116. */
  117. vec3 fschlick0=specular + (1.0-specular) * pow( 1.0-ndotv,5.0 ) * glosiness;
  118. vec3 ambDiffuse=diffuse * (r_AmbientDiffuse.rgb+ambient);
  119. vec3 ambSpecular=fschlick0 * ambEnv;
  120. frag+=( ambDiffuse + ambSpecular ) * occlusion + emissive;
  121. #endif
  122. #if MX2_LIGHTINGPASS
  123. //lighting color
  124. float spow=pow( 2.0,glosiness * 12.0 ); //specular power
  125. // float spow=pow( 4096.0,glosiness );
  126. float fnorm=(spow+2.0)/8.0; //normalization factor
  127. #if MX2_DIRECTIONALLIGHT
  128. vec3 lvec=normalize( -r_LightViewMatrix[2].xyz );
  129. float atten=1.0;
  130. #elif MX2_POINTLIGHT
  131. vec3 lvec=r_LightViewMatrix[3].xyz-v_Position;
  132. float atten=pointAtten( length( lvec ),r_LightRange );
  133. lvec=normalize( lvec );
  134. #elif MX2_SPOTLIGHT
  135. vec3 lvec=r_LightViewMatrix[3].xyz-v_Position;
  136. float atten=pointAtten( length( lvec ),r_LightRange );
  137. lvec=normalize( lvec );
  138. float cosangle=dot( -lvec,r_LightViewMatrix[2].xyz );
  139. if( cosangle<0.0 ) return; //behind spotlight direction
  140. float angle=acos( cosangle );
  141. if( angle>r_LightOuterAngle ) return; //outside outer cone
  142. atten*=1.0-max( (angle-r_LightInnerAngle)/(r_LightOuterAngle-r_LightInnerAngle),0.0 );
  143. #endif
  144. vec3 hvec=normalize( lvec+vvec );
  145. float ndotl=max( dot( normal,lvec ),0.0 );
  146. float ndoth=max( dot( normal,hvec ),0.0 );
  147. float hdotl=max( dot( hvec,lvec ),0.0 );
  148. vec3 fschlick=specular + (1.0-specular) * pow( 1.0-hdotl,5.0 ) * glosiness;
  149. vec3 fspecular=fschlick * pow( ndoth,spow ) * fnorm;
  150. vec3 light=r_LightColor.rgb * ndotl * atten;
  151. light=(diffuse+fspecular) * light;
  152. #if MX2_SHADOWTYPE
  153. light*=shadowColor( v_Position );
  154. #endif
  155. frag+=light;
  156. #endif //MX2_LIGHTINGPASS
  157. color.rgb=frag;
  158. emitColorFragment( color );
  159. }
  160. #endif