0030700: Visualization, TKOpenGl - support PBR Metallic-Roughness shading model
[occt.git] / src / Shaders / Shaders_PBREnvBaking_fs.pxx
1 // This file has been automatically generated from resource file src/Shaders/PBREnvBaking.fs
2
3 static const char Shaders_PBREnvBaking_fs[] =
4   "THE_SHADER_IN vec3 ViewDirection; //!< direction of fetching from environment cubemap\n"
5   "\n"
6   "uniform int uSamplesNum;     //!< number of samples in Monte-Carlo integration\n"
7   "uniform int uCurrentLevel;   //!< current level of specular IBL map (ignored in case of diffuse map's processing)\n"
8   "uniform int uEnvMapSize;     //!< one edge's size of source environtment map's zero mipmap level\n"
9   "uniform int uYCoeff;         //!< coefficient of Y controlling horizontal flip of cubemap\n"
10   "uniform int uZCoeff;         //!< coefficient of Z controlling vertical flip of cubemap\n"
11   "uniform samplerCube uEnvMap; //!< source of baking (environment cubemap)\n"
12   "\n"
13   "//! Returns coordinates of point theNumber from Hammersley point set having size theSize.\n"
14   "vec2 hammersley (in int theNumber,\n"
15   "                 in int theSize)\n"
16   "{\n"
17   "  int aDenominator = 2;\n"
18   "  int aNumber = theNumber;\n"
19   "  float aVanDerCorput = 0.0;\n"
20   "  for (int i = 0; i < 32; ++i)\n"
21   "  {\n"
22   "    if (aNumber > 0)\n"
23   "    {\n"
24   "      aVanDerCorput += float(aNumber % 2) / float(aDenominator);\n"
25   "      aNumber /= 2;\n"
26   "      aDenominator *= 2;\n"
27   "    }\n"
28   "  }\n"
29   "  return vec2(float(theNumber) / float(theSize), aVanDerCorput);\n"
30   "}\n"
31   "\n"
32   "//! This function does importance sampling on hemisphere surface using GGX normal distribution function\n"
33   "//! in tangent space (positive z axis is surface normal direction).\n"
34   "vec3 importanceSample (in vec2  theHammersleyPoint,\n"
35   "                       in float theRoughness)\n"
36   "{\n"
37   "  float aPhi = PI_2 * theHammersleyPoint.x;\n"
38   "  theRoughness *= theRoughness;\n"
39   "  theRoughness *= theRoughness;\n"
40   "  float aCosTheta = sqrt((1.0 - theHammersleyPoint.y) / (1.0 + (theRoughness - 1.0) * theHammersleyPoint.y));\n"
41   "  float aSinTheta = sqrt(1.0 - aCosTheta * aCosTheta);\n"
42   "  return vec3(aSinTheta * cos(aPhi),\n"
43   "              aSinTheta * sin(aPhi),\n"
44   "              aCosTheta);\n"
45   "}\n"
46   "\n"
47   "//! This function uniformly generates samples on whole sphere.\n"
48   "vec3 sphereUniformSample (in vec2 theHammersleyPoint)\n"
49   "{\n"
50   "  float aPhi = PI_2 * theHammersleyPoint.x;\n"
51   "  float aCosTheta = 2.0 * theHammersleyPoint.y - 1.0;\n"
52   "  float aSinTheta = sqrt(1.0 - aCosTheta * aCosTheta);\n"
53   "  return vec3(aSinTheta * cos(aPhi),\n"
54   "              aSinTheta * sin(aPhi),\n"
55   "              aCosTheta);\n"
56   "}\n"
57   "\n"
58   "//! Transforms resulted sampled direction from tangent space to world space considering the surface normal.\n"
59   "vec3 fromTangentSpace (in vec3 theVector,\n"
60   "                       in vec3 theNormal)\n"
61   "{\n"
62   "  vec3 anUp = (abs(theNormal.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);\n"
63   "  vec3 anX = normalize(cross(anUp, theNormal));\n"
64   "  vec3 anY = cross(theNormal, anX);\n"
65   "  return anX * theVector.x + anY * theVector.y + theNormal * theVector.z;\n"
66   "}\n"
67   "\n"
68   "const float aSHBasisFuncCoeffs[9] = float[9]\n"
69   "(\n"
70   "  0.282095 * 0.282095,\n"
71   "  0.488603 * 0.488603,\n"
72   "  0.488603 * 0.488603,\n"
73   "  0.488603 * 0.488603,\n"
74   "  1.092548 * 1.092548,\n"
75   "  1.092548 * 1.092548,\n"
76   "  1.092548 * 1.092548,\n"
77   "  0.315392 * 0.315392,\n"
78   "  0.546274 * 0.546274\n"
79   ");\n"
80   "\n"
81   "const float aSHCosCoeffs[9] = float[9]\n"
82   "(\n"
83   "  3.141593,\n"
84   "  2.094395,\n"
85   "  2.094395,\n"
86   "  2.094395,\n"
87   "  0.785398,\n"
88   "  0.785398,\n"
89   "  0.785398,\n"
90   "  0.785398,\n"
91   "  0.785398\n"
92   ");\n"
93   "\n"
94   "//! Bakes diffuse IBL map's spherical harmonics coefficients.\n"
95   "vec3 bakeDiffuseSH()\n"
96   "{\n"
97   "  int anIndex = int(gl_FragCoord.x);\n"
98   "  vec3 aResult = vec3 (0.0);\n"
99   "  for (int aSampleIter = 0; aSampleIter < uSamplesNum; ++aSampleIter)\n"
100   "  {\n"
101   "    vec2 aHammersleyPoint = hammersley (aSampleIter, uSamplesNum);\n"
102   "    vec3 aDirection = sphereUniformSample (aHammersleyPoint);\n"
103   "\n"
104   "    vec3 aValue = occTextureCube (uEnvMap, cubemapVectorTransform (aDirection, uYCoeff, uZCoeff)).rgb;\n"
105   "\n"
106   "    float aBasisFunc[9];\n"
107   "    aBasisFunc[0] = 1.0;\n"
108   "\n"
109   "    aBasisFunc[1] = aDirection.x;\n"
110   "    aBasisFunc[2] = aDirection.y;\n"
111   "    aBasisFunc[3] = aDirection.z;\n"
112   "\n"
113   "    aBasisFunc[4] = aDirection.x * aDirection.z;\n"
114   "    aBasisFunc[5] = aDirection.y * aDirection.z;\n"
115   "    aBasisFunc[6] = aDirection.x * aDirection.y;\n"
116   "\n"
117   "    aBasisFunc[7] = 3.0 * aDirection.z * aDirection.z - 1.0;\n"
118   "    aBasisFunc[8] = aDirection.x * aDirection.x - aDirection.y * aDirection.y;\n"
119   "\n"
120   "    aResult += aValue * aBasisFunc[anIndex];\n"
121   "  }\n"
122   "\n"
123   "  aResult *= 4.0 * aSHCosCoeffs[anIndex] * aSHBasisFuncCoeffs[anIndex] / float(uSamplesNum);\n"
124   "  return aResult;\n"
125   "}\n"
126   "\n"
127   "//! Bakes specular IBL map.\n"
128   "vec3 bakeSpecularMap (in vec3  theNormal,\n"
129   "                      in float theRoughness)\n"
130   "{\n"
131   "  vec3 aResult = vec3(0.0);\n"
132   "  float aWeightSum = 0.0;\n"
133   "  int aSamplesNum = (theRoughness == 0.0) ? 1 : uSamplesNum;\n"
134   "  float aSolidAngleSource = 4.0 * PI / (6.0 * float(uEnvMapSize * uEnvMapSize));\n"
135   "  for (int aSampleIter = 0; aSampleIter < aSamplesNum; ++aSampleIter)\n"
136   "  {\n"
137   "    vec2 aHammersleyPoint = hammersley (aSampleIter, aSamplesNum);\n"
138   "    vec3 aHalf = importanceSample (aHammersleyPoint, occRoughness (theRoughness));\n"
139   "    float aHdotV = aHalf.z;\n"
140   "    aHalf = fromTangentSpace (aHalf, theNormal);\n"
141   "    vec3  aLight = -reflect (theNormal, aHalf);\n"
142   "    float aNdotL = dot (aLight, theNormal);\n"
143   "    if (aNdotL > 0.0)\n"
144   "    {\n"
145   "      float aSolidAngleSample = 1.0 / (float(aSamplesNum) * (occPBRDistribution (aHdotV, theRoughness) * 0.25 + 0.0001) + 0.0001);\n"
146   "      float aLod = (theRoughness == 0.0) ? 0.0 : 0.5 * log2 (aSolidAngleSample / aSolidAngleSource);\n"
147   "      aResult += occTextureCubeLod (uEnvMap, aLight, aLod).rgb * aNdotL;\n"
148   "      aWeightSum += aNdotL;\n"
149   "    }\n"
150   "  }\n"
151   "  return aResult / aWeightSum;\n"
152   "}\n"
153   "\n"
154   "void main()\n"
155   "{\n"
156   "  vec3 aViewDirection = normalize (ViewDirection);\n"
157   "  if (occNbSpecIBLLevels == 0)\n"
158   "  {\n"
159   "    occSetFragColor (vec4 (bakeDiffuseSH (), 1.0));\n"
160   "  }\n"
161   "  else\n"
162   "  {\n"
163   "    occSetFragColor (vec4 (bakeSpecularMap (aViewDirection, float(uCurrentLevel) / float(occNbSpecIBLLevels - 1)), 1.0));\n"
164   "  }\n"
165   "}\n";