mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2024-11-25 09:08:22 -05:00
259 lines
9.9 KiB
Text
259 lines
9.9 KiB
Text
|
#extension GL_ARB_shader_texture_lod : require
|
||
|
|
||
|
vec4 xll_texCUBElod(samplerCube s, vec4 coord) {
|
||
|
return textureCubeLod( s, coord.xyz, coord.w);
|
||
|
}
|
||
|
mat3 xll_transpose_mf3x3(mat3 m) {
|
||
|
return mat3( m[0][0], m[1][0], m[2][0],
|
||
|
m[0][1], m[1][1], m[2][1],
|
||
|
m[0][2], m[1][2], m[2][2]);
|
||
|
}
|
||
|
float xll_saturate_f( float x) {
|
||
|
return clamp( x, 0.0, 1.0);
|
||
|
}
|
||
|
vec3 xll_saturate_vf3( vec3 x) {
|
||
|
return clamp( x, 0.0, 1.0);
|
||
|
}
|
||
|
vec3 xll_matrixindex_mf3x3_i (mat3 m, int i) { vec3 v; v.x=m[0][i]; v.y=m[1][i]; v.z=m[2][i]; return v; }
|
||
|
struct VertexOutput {
|
||
|
vec4 pos;
|
||
|
vec4 tex;
|
||
|
vec4 posWorld;
|
||
|
vec3 normalWorld;
|
||
|
vec4 tangentWorld;
|
||
|
vec3 extra;
|
||
|
vec4 _ShadowCoord;
|
||
|
vec3 lightDir;
|
||
|
};
|
||
|
uniform vec3 _WorldSpaceCameraPos;
|
||
|
uniform vec4 _ProjectionParams;
|
||
|
uniform vec4 _ScreenParams;
|
||
|
uniform vec4 _ZBufferParams;
|
||
|
uniform vec4 _WorldSpaceLightPos0;
|
||
|
uniform vec4 unity_SHAr;
|
||
|
uniform vec4 unity_SHAg;
|
||
|
uniform vec4 unity_SHAb;
|
||
|
uniform vec4 unity_SHBr;
|
||
|
uniform vec4 unity_SHBg;
|
||
|
uniform vec4 unity_SHBb;
|
||
|
uniform vec4 unity_SHC;
|
||
|
uniform vec4 _LightShadowData;
|
||
|
|
||
|
|
||
|
uniform mat4 _Object2World;
|
||
|
uniform mat4 _World2Object;
|
||
|
uniform vec4 unity_Scale;
|
||
|
uniform mat4 glstate_matrix_transpose_modelview0;
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
uniform mat4 unity_MatrixV;
|
||
|
uniform mat4 unity_MatrixVP;
|
||
|
uniform samplerCube _Cube;
|
||
|
uniform sampler2D _MainTex;
|
||
|
uniform vec4 _MainTex_ST;
|
||
|
uniform sampler2D _DetailAlbedoMap;
|
||
|
uniform vec4 _DetailAlbedoMap_ST;
|
||
|
uniform sampler2D _AlphaMap;
|
||
|
uniform sampler2D _Occlusion;
|
||
|
uniform sampler2D _DetailNormalMap;
|
||
|
uniform vec4 _DetailNormalMap_ST;
|
||
|
uniform float _DetailNormalMapScale;
|
||
|
uniform sampler2D _BumpMap;
|
||
|
uniform float _BumpScale;
|
||
|
uniform float _Exposure;
|
||
|
uniform float _DetailBumpScale;
|
||
|
uniform float _AlphaTestRef;
|
||
|
uniform float _DetailBumpTiling;
|
||
|
uniform vec4 _Color;
|
||
|
uniform vec4 _SpecularColor;
|
||
|
uniform sampler2D _SpecGlossMap;
|
||
|
uniform float _Glossiness;
|
||
|
|
||
|
uniform vec4 unity_ColorSpaceGrey;
|
||
|
|
||
|
uniform sampler2D _ShadowMapTexture;
|
||
|
uniform vec4 _LightColor0;
|
||
|
|
||
|
uniform samplerCube _SpecCube;
|
||
|
uniform vec4 unity_LightmapST;
|
||
|
uniform sampler2D unity_Lightmap;
|
||
|
uniform sampler2D unity_LightmapInd;
|
||
|
uniform float _SelfIllumScale;
|
||
|
uniform sampler2D _SelfIllum;
|
||
|
|
||
|
vec3 Albedo( in vec4 texcoords ) {
|
||
|
vec3 albedo = (_Color.xyz * texture2D( _MainTex, texcoords.xy).xyz);
|
||
|
albedo *= (2.0 * texture2D( _DetailAlbedoMap, texcoords.zw).xyz);
|
||
|
return albedo;
|
||
|
}
|
||
|
float Alpha( in vec2 uv ) {
|
||
|
return (texture2D( _AlphaMap, uv).w * _Color.w);
|
||
|
}
|
||
|
float BlinnPhongTerm( in float roughness, in float NdotH ) {
|
||
|
float m = (pow( roughness, 4.0) + 1e-05);
|
||
|
float n = ((1.0 / m) - 2.0);
|
||
|
float normTerm = ((n + 1.0) / 6.28318);
|
||
|
float specTerm = pow( NdotH, n);
|
||
|
return (specTerm * normTerm);
|
||
|
}
|
||
|
float BlinnTerm( in vec3 normal, in vec3 halfDir ) {
|
||
|
return max( 0.0, dot( normal, halfDir));
|
||
|
}
|
||
|
float FresnelTerm( in float F0, in float cosA ) {
|
||
|
float _Falloff = 5.0;
|
||
|
float t = pow( abs((1.0 - cosA)), _Falloff);
|
||
|
return (F0 + ((1.0 - F0) * t));
|
||
|
}
|
||
|
float CTGeometricTerm( in float NdotL, in float NdotH, in float NdotV, in float VdotH ) {
|
||
|
VdotH += 1e-05;
|
||
|
return min( 1.0, min( (((2.0 * NdotH) * NdotV) / VdotH), (((2.0 * NdotH) * NdotL) / VdotH)));
|
||
|
}
|
||
|
float GeometricTerm( in float NdotL, in float NdotH, in float NdotV, in float VdotH, in float LdotV ) {
|
||
|
return CTGeometricTerm( NdotL, NdotH, NdotV, VdotH);
|
||
|
}
|
||
|
float LambertTerm( in vec3 normal, in vec3 lightDir ) {
|
||
|
return max( 0.0, dot( normal, lightDir));
|
||
|
}
|
||
|
float RGBToLuminance( in vec3 color ) {
|
||
|
vec3 lumSensitivity = vec3( 0.299, 0.587, 0.114);
|
||
|
float luminance = dot( color, lumSensitivity);
|
||
|
return luminance;
|
||
|
}
|
||
|
vec3 BRDF_Disney_PBS( in vec3 baseColor, in vec3 lightColor, in vec3 specColor, in float specular, in float roughness, in vec3 normal, in vec3 lightDir, in vec3 viewDir, in vec3 ambient, in vec3 env ) {
|
||
|
vec3 halfDir = normalize((lightDir + viewDir));
|
||
|
float nl = LambertTerm( normal, lightDir);
|
||
|
float nh = BlinnTerm( normal, halfDir);
|
||
|
float nv = max( 0.0, dot( normal, viewDir));
|
||
|
float vh = max( 0.0, dot( viewDir, halfDir));
|
||
|
float lv = max( 0.0, dot( lightDir, viewDir));
|
||
|
float lh = max( 0.0, dot( lightDir, halfDir));
|
||
|
float F = FresnelTerm( specular, vh);
|
||
|
float G = GeometricTerm( nl, nh, nv, vh, lv);
|
||
|
float R = BlinnPhongTerm( roughness, nh);
|
||
|
R = max( 0.0, R);
|
||
|
float Fd90 = (0.5 + ((2.0 * pow( lh, 2.0)) * roughness));
|
||
|
float nlPow = pow( (1.00001 - nl), 5.0);
|
||
|
float nvPow = pow( (1.00001 - nv), 5.0);
|
||
|
float disneyDiffuse = ((1.0 + ((Fd90 - 1.0) * nlPow)) * (1.0 + ((Fd90 - 1.0) * nvPow)));
|
||
|
float specularTerm = max( 0.0, (((F * G) * R) / ((4.0 * nv) + 1e-05)));
|
||
|
float diffuseTerm = (disneyDiffuse * nl);
|
||
|
vec3 diffuseColor = baseColor;
|
||
|
vec3 color = (((diffuseColor * (ambient + (diffuseTerm * lightColor))) + (specColor * (env + (lightColor * specularTerm)))) + ((((1.0 - RGBToLuminance( specColor)) * (1.0 - roughness)) * FresnelTerm( 0.0, nv)) * env));
|
||
|
return color;
|
||
|
}
|
||
|
vec3 DecodeLightmap( in vec4 color ) {
|
||
|
return ((8.0 * color.w) * color.xyz);
|
||
|
}
|
||
|
vec3 DirLightmapDiffuse( in mat3 dirBasis, in vec4 color, in vec4 scale, in vec3 normal, in bool surfFuncWritesNormal, out vec3 scalePerBasisVector ) {
|
||
|
vec3 lm = DecodeLightmap( color);
|
||
|
scalePerBasisVector = DecodeLightmap( scale);
|
||
|
if (surfFuncWritesNormal){
|
||
|
vec3 normalInRnmBasis = xll_saturate_vf3((dirBasis * normal));
|
||
|
lm *= dot( normalInRnmBasis, scalePerBasisVector);
|
||
|
}
|
||
|
return lm;
|
||
|
}
|
||
|
void DecodeDirLightmap( in vec3 normal, in vec4 colorLM, in vec4 scaleLM, out vec3 lightColor, out vec3 lightDir ) {
|
||
|
mat3 unity_DirBasis = xll_transpose_mf3x3(mat3( vec3( 0.816497, 0.0, 0.57735), vec3( -0.408248, 0.707107, 0.57735), vec3( -0.408248, -0.707107, 0.57735)));
|
||
|
vec3 scalePerBasisVector;
|
||
|
lightColor = DirLightmapDiffuse( unity_DirBasis, colorLM, scaleLM, normal, true, scalePerBasisVector);
|
||
|
lightDir = normalize((((scalePerBasisVector.x * xll_matrixindex_mf3x3_i (unity_DirBasis, 0)) + (scalePerBasisVector.y * xll_matrixindex_mf3x3_i (unity_DirBasis, 1))) + (scalePerBasisVector.z * xll_matrixindex_mf3x3_i (unity_DirBasis, 2))));
|
||
|
}
|
||
|
vec3 EnergyCalculator( in vec3 specColor, in float specular, in vec3 baseColor ) {
|
||
|
return min( baseColor, (vec3( 1.0, 1.0, 1.0) - specular));
|
||
|
}
|
||
|
float toLinearFast1( in float c ) {
|
||
|
float c2 = (c * c);
|
||
|
return dot( vec2( 0.7532, 0.2468), vec2( c2, (c * c2)));
|
||
|
}
|
||
|
vec3 fromRGBM( in vec4 c ) {
|
||
|
return ((c.xyz * toLinearFast1( c.w)) * _Exposure);
|
||
|
}
|
||
|
vec3 EnvMap( in vec4 worldNormal ) {
|
||
|
vec4 envTexel = xll_texCUBElod( _SpecCube, vec4( worldNormal.xyz, worldNormal.w));
|
||
|
return fromRGBM( envTexel);
|
||
|
}
|
||
|
float Occlusion( in vec2 uv ) {
|
||
|
return texture2D( _Occlusion, uv).x;
|
||
|
}
|
||
|
vec4 SpecularGloss( in vec2 uv ) {
|
||
|
vec4 specGloss = texture2D( _SpecGlossMap, uv);
|
||
|
return vec4( specGloss.xyz, specGloss.w);
|
||
|
}
|
||
|
vec3 BlendNormals( in vec3 n1, in vec3 n2 ) {
|
||
|
return normalize(vec3( (n1.xy + n2.xy), (n1.z * n2.z)));
|
||
|
}
|
||
|
vec3 UnpackScaleNormal( in vec4 packednormal, in float bumpScale ) {
|
||
|
vec3 normal;
|
||
|
normal.xy = ((packednormal.wy * 2.0) - 1.0);
|
||
|
normal.xy *= bumpScale;
|
||
|
normal.z = sqrt((1.0 - xll_saturate_f(dot( normal.xy, normal.xy))));
|
||
|
return normal;
|
||
|
}
|
||
|
vec3 TangentNormal( in vec4 texcoords ) {
|
||
|
vec3 normalTangent = UnpackScaleNormal( texture2D( _BumpMap, texcoords.xy), _BumpScale);
|
||
|
vec3 detailNormalTangent = UnpackScaleNormal( texture2D( _DetailNormalMap, texcoords.zw), _DetailNormalMapScale);
|
||
|
normalTangent = BlendNormals( normalTangent, detailNormalTangent);
|
||
|
return normalTangent;
|
||
|
}
|
||
|
mat3 TangentToWorld( in vec3 normal, in vec3 tangent, in vec3 flip ) {
|
||
|
vec3 binormal = (cross( normal, tangent) * flip);
|
||
|
return xll_transpose_mf3x3(mat3( tangent, binormal, normal));
|
||
|
}
|
||
|
float unitySampleShadow( in vec4 shadowCoord ) {
|
||
|
float shadow = texture2DProj( _ShadowMapTexture, shadowCoord).x;
|
||
|
return shadow;
|
||
|
}
|
||
|
vec4 frag( in VertexOutput i ) {
|
||
|
float atten = unitySampleShadow( i._ShadowCoord);
|
||
|
mat3 tanToWorld = TangentToWorld( i.normalWorld, i.tangentWorld.xyz, vec3( i.tangentWorld.w));
|
||
|
i.normalWorld = normalize(i.normalWorld);
|
||
|
vec3 normalTangent = TangentNormal( i.tex);
|
||
|
vec3 normalWorld = (normalTangent * tanToWorld);
|
||
|
vec3 eyeVec = normalize((i.posWorld.xyz - _WorldSpaceCameraPos));
|
||
|
vec4 specGloss = SpecularGloss( i.tex.xy);
|
||
|
vec3 specColor = specGloss.xyz;
|
||
|
float specular = RGBToLuminance( specGloss.xyz);
|
||
|
float roughness = (1.0 - specGloss.w);
|
||
|
vec3 env = vec3( 0.0);
|
||
|
env = (EnvMap( vec4( reflect( eyeVec, normalWorld), (roughness * 5.0))) * Occlusion( i.tex.xy));
|
||
|
vec3 lightColor = (_LightColor0.xyz * 2.0);
|
||
|
vec3 lightDir = _WorldSpaceLightPos0.xyz;
|
||
|
float subsurface = 1.0;
|
||
|
vec3 ambient = vec3( 0.0);
|
||
|
vec4 lmtex = texture2D( unity_Lightmap, i.extra.xy);
|
||
|
vec4 lmIndTex = texture2D( unity_LightmapInd, i.extra.xy);
|
||
|
vec3 lightDirTangent;
|
||
|
DecodeDirLightmap( normalTangent, lmtex, lmIndTex, lightColor, lightDirTangent);
|
||
|
lightDir = (lightDirTangent * tanToWorld);
|
||
|
lightDir = normalize(lightDir);
|
||
|
vec3 baseColor = EnergyCalculator( specColor, specular, Albedo( i.tex));
|
||
|
vec3 color = BRDF_Disney_PBS( baseColor, (atten * lightColor), specColor, specular, roughness, normalWorld, lightDir, (-eyeVec), ambient, env);
|
||
|
color += (texture2D( _SelfIllum, i.tex.xy).xyz * _SelfIllumScale);
|
||
|
float alpha = Alpha( i.tex.xy);
|
||
|
return vec4( color, alpha);
|
||
|
}
|
||
|
varying vec4 xlv_TEXCOORD0;
|
||
|
varying vec4 xlv_TEXCOORD1;
|
||
|
varying vec3 xlv_TEXCOORD2;
|
||
|
varying vec4 xlv_TEXCOORD3;
|
||
|
varying vec3 xlv_TEXCOORD4;
|
||
|
varying vec4 xlv_TEXCOORD5;
|
||
|
varying vec3 xlv_TEXCOORD7;
|
||
|
void main() {
|
||
|
vec4 xl_retval;
|
||
|
VertexOutput xlt_i;
|
||
|
xlt_i.pos = vec4(0.0);
|
||
|
xlt_i.tex = vec4(xlv_TEXCOORD0);
|
||
|
xlt_i.posWorld = vec4(xlv_TEXCOORD1);
|
||
|
xlt_i.normalWorld = vec3(xlv_TEXCOORD2);
|
||
|
xlt_i.tangentWorld = vec4(xlv_TEXCOORD3);
|
||
|
xlt_i.extra = vec3(xlv_TEXCOORD4);
|
||
|
xlt_i._ShadowCoord = vec4(xlv_TEXCOORD5);
|
||
|
xlt_i.lightDir = vec3(xlv_TEXCOORD7);
|
||
|
xl_retval = frag( xlt_i);
|
||
|
gl_FragData[0] = vec4(xl_retval);
|
||
|
}
|