1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0030700: Visualization, TKOpenGl - support PBR Metallic-Roughness shading model

Metallic-Roughness shading model Graphic3d_TOSM_PBR has been implemented.
New materials descriptors Graphic3d_PBRMaterial have been added to Graphic3d_MaterialAspect.
PBR shading model requires OpenGL 3.0+ or OpenGL ES 3.0+ hardware.
Environment cubemap is expected to be provided for realistic look of metallic materials.

occLight_IsHeadlight() now returns bool instead of int.
Avoid using lowp for enumerations to workaround occLight_IsHeadlight()
ignorance on Adreno 308 caused by some GLSL optimizator bugs.

OpenGl_Texture::EstimatedDataSize() - fixed estimation for Cubemap textures.
OpenGl_Sampler::applySamplerParams() - fixed uninitialized GL_TEXTURE_WRAP_R in case of GL_TEXTURE_CUBE_MAP target.
This commit is contained in:
iko
2019-06-20 09:53:20 +03:00
committed by apn
parent f4a7308f61
commit 67312b7991
75 changed files with 7204 additions and 272 deletions

View File

@@ -21,6 +21,8 @@
#define occTexture1D texture
#define occTexture2D texture
#define occTexture3D texture
#define occTextureCube texture
#define occTextureCubeLod textureLod
#else
#define THE_ATTRIBUTE attribute
#define THE_SHADER_IN varying
@@ -29,10 +31,16 @@
#define occTexture1D texture1D
#define occTexture2D texture2D
#define occTexture3D texture3D
#define occTextureCube textureCube
#define occTextureCubeLod textureCubeLod
#endif
#ifdef GL_ES
#define THE_PREC_ENUM lowp // enumerations should fit into lowp range
#if (__VERSION__ >= 300)
#define THE_PREC_ENUM highp // lowp should be enough for enums but triggers driver bugs
#else
#define THE_PREC_ENUM lowp
#endif
#else
#define THE_PREC_ENUM
#endif
@@ -85,6 +93,15 @@
void occSetFragColor (in vec4 theColor);
#endif
// Pi number definitions
#define PI 3.141592654
#define PI_2 6.283185307
#define PI_DIV_2 1.570796327
#define PI_DIV_3 1.047197551
#define PI_DIV_4 0.785398163
#define INV_PI 0.318309886
#define INV_PI_2 0.159154943
// Matrix state
uniform mat4 occWorldViewMatrix; //!< World-view matrix
uniform mat4 occProjectionMatrix; //!< Projection matrix
@@ -102,6 +119,15 @@ uniform mat4 occWorldViewMatrixInverseTranspose; //!< Transpose of the inverse
uniform mat4 occProjectionMatrixInverseTranspose; //!< Transpose of the inverse of the projection matrix
uniform mat4 occModelWorldMatrixInverseTranspose; //!< Transpose of the inverse of the model-world matrix
#if defined(THE_IS_PBR)
uniform sampler2D occEnvLUT; //!< Environment Lookup Table
uniform sampler2D occDiffIBLMapSHCoeffs; //!< Packed diffuse (irradiance) IBL map's spherical harmonics coefficients
uniform samplerCube occSpecIBLMap; //!< Specular IBL map
uniform int occNbSpecIBLLevels; //!< Number of mipmap levels used in occSpecIBLMap to store different roughness values maps
vec3 occDiffIBLMap (in vec3 theNormal); //!< Unpacks spherical harmonics coefficients to diffuse IBL map's values
#endif
// light type enumeration (same as Graphic3d_TypeOfLightSource)
const int OccLightType_Direct = 1; //!< directional light source
const int OccLightType_Point = 2; //!< isotropic point light source
@@ -116,7 +142,7 @@ uniform THE_PREC_ENUM int occLightSourcesCount; //!< Total number of light sour
#define occLight_Type(theId) occLightSourcesTypes[theId].x
//! Is light a headlight, int?
#define occLight_IsHeadlight(theId) occLightSourcesTypes[theId].y
#define occLight_IsHeadlight(theId) (occLightSourcesTypes[theId].y != 0)
//! Specular intensity (equals to diffuse), vec4.
#define occLight_Specular(theId) occLightSources[theId * 4 + 0]
@@ -133,6 +159,11 @@ uniform THE_PREC_ENUM int occLightSourcesCount; //!< Total number of light sour
//! Attenuation of the spot light intensity (from 0 to 1), float.
#define occLight_SpotExponent(theId) occLightSources[theId * 4 + 3].w
#if defined(THE_IS_PBR)
//! Intensity of light source (>= 0), float.
#define occLight_Intensity(theId) occLightSources[theId * 4 + 0].a
#else
//! Diffuse intensity (equals to Specular), vec4.
#define occLight_Diffuse(theId) occLightSources[theId * 4 + 0]
@@ -142,22 +173,44 @@ uniform THE_PREC_ENUM int occLightSourcesCount; //!< Total number of light sour
//! Linear attenuation factor of positional light source, float.
#define occLight_LinearAttenuation(theId) occLightSources[theId * 4 + 3].y
#endif
#endif
// Converts roughness value from range [0, 1] to real value for calculations
float occRoughness (in float theNormalizedRoughness);
// Front material properties accessors
vec4 occFrontMaterial_Emission(void); //!< Emission color
vec4 occFrontMaterial_Ambient(void); //!< Ambient reflection
vec4 occFrontMaterial_Diffuse(void); //!< Diffuse reflection
vec4 occFrontMaterial_Specular(void); //!< Specular reflection
float occFrontMaterial_Shininess(void); //!< Specular exponent
float occFrontMaterial_Transparency(void); //!< Transparency coefficient
#if !defined(THE_IS_PBR)
vec4 occFrontMaterial_Emission(void); //!< Emission color
vec4 occFrontMaterial_Ambient(void); //!< Ambient reflection
vec4 occFrontMaterial_Diffuse(void); //!< Diffuse reflection
vec4 occFrontMaterial_Specular(void); //!< Specular reflection
float occFrontMaterial_Shininess(void); //!< Specular exponent
float occFrontMaterial_Transparency(void); //!< Transparency coefficient
#else
vec4 occPBRFrontMaterial_Color(void); //!< Base color of PBR material
float occPBRFrontMaterial_Metallic(void); //!< Metallic coefficient
float occPBRFrontMaterial_Roughness(void); //!< Roughness coefficient
float occPBRFrontMaterial_NormalizedRoughness(void); //!< Normalized roughness coefficient
vec3 occPBRFrontMaterial_Emission(void); //!< Light intensity emitted by material
float occPBRFrontMaterial_IOR(void); //!< Index of refraction
#endif
// Back material properties accessors
vec4 occBackMaterial_Emission(void); //!< Emission color
vec4 occBackMaterial_Ambient(void); //!< Ambient reflection
vec4 occBackMaterial_Diffuse(void); //!< Diffuse reflection
vec4 occBackMaterial_Specular(void); //!< Specular reflection
float occBackMaterial_Shininess(void); //!< Specular exponent
float occBackMaterial_Transparency(void); //!< Transparency coefficient
#if !defined(THE_IS_PBR)
vec4 occBackMaterial_Emission(void); //!< Emission color
vec4 occBackMaterial_Ambient(void); //!< Ambient reflection
vec4 occBackMaterial_Diffuse(void); //!< Diffuse reflection
vec4 occBackMaterial_Specular(void); //!< Specular reflection
float occBackMaterial_Shininess(void); //!< Specular exponent
float occBackMaterial_Transparency(void); //!< Transparency coefficient
#else
vec4 occPBRBackMaterial_Color(void); //!< Base color of PBR material
float occPBRBackMaterial_Metallic(void); //!< Metallic coefficient
float occPBRBackMaterial_Roughness(void); //!< Roughness coefficient
float occPBRBackMaterial_NormalizedRoughness(void); //!< Normalized roughness coefficient
vec3 occPBRBackMaterial_Emission(void); //!< Light intensity emitted by material
float occPBRBackMaterial_IOR(void); //!< Index of refraction
#endif
#ifdef THE_HAS_DEFAULT_SAMPLER
#define occActiveSampler occSampler0 //!< alias for backward compatibility

View File

@@ -19,15 +19,59 @@ void occSetFragColor (in vec4 theColor)
#if defined(THE_MAX_LIGHTS) && (THE_MAX_LIGHTS > 0)
// arrays of light sources
uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types
uniform vec4 occLightSources[THE_MAX_LIGHTS * 4]; //!< packed light sources parameters
uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types
#endif
// material state
#if defined(THE_IS_PBR)
vec3 occDiffIBLMap (in vec3 theNormal)
{
vec3 aSHCoeffs[9];
for (int i = 0; i < 9; ++i)
{
aSHCoeffs[i] = occTexture2D (occDiffIBLMapSHCoeffs, vec2 ((float(i) + 0.5) / 9.0, 0.0)).rgb;
}
return aSHCoeffs[0]
+ aSHCoeffs[1] * theNormal.x
+ aSHCoeffs[2] * theNormal.y
+ aSHCoeffs[3] * theNormal.z
+ aSHCoeffs[4] * theNormal.x * theNormal.z
+ aSHCoeffs[5] * theNormal.y * theNormal.z
+ aSHCoeffs[6] * theNormal.x * theNormal.y
+ aSHCoeffs[7] * (3.0 * theNormal.z * theNormal.z - 1.0)
+ aSHCoeffs[8] * (theNormal.x * theNormal.x - theNormal.y * theNormal.y);
}
#endif
// front and back material properties accessors
#if defined(THE_IS_PBR)
uniform vec4 occPbrFrontMaterial[3];
uniform vec4 occPbrBackMaterial[3];
#define MIN_ROUGHNESS 0.01
// Converts roughness value from range [0, 1] to real value for calculations
float occRoughness (in float theNormalizedRoughness) { return theNormalizedRoughness * (1.0 - MIN_ROUGHNESS) + MIN_ROUGHNESS; }
vec4 occPBRFrontMaterial_Color(void) { return occPbrFrontMaterial[0]; }
vec3 occPBRFrontMaterial_Emission(void) { return occPbrFrontMaterial[1].rgb; }
float occPBRFrontMaterial_IOR(void) { return occPbrFrontMaterial[1].w; }
float occPBRFrontMaterial_Metallic(void) { return occPbrFrontMaterial[2].b; }
float occPBRFrontMaterial_Roughness(void) { return occRoughness (occPbrFrontMaterial[2].g); }
float occPBRFrontMaterial_NormalizedRoughness(void) { return occPbrFrontMaterial[2].g; }
vec4 occPBRBackMaterial_Color(void) { return occPbrBackMaterial[0]; }
vec3 occPBRBackMaterial_Emission(void) { return occPbrBackMaterial[1].rgb; }
float occPBRBackMaterial_IOR(void) { return occPbrBackMaterial[1].w; }
float occPBRBackMaterial_Metallic(void) { return occPbrBackMaterial[2].b; }
float occPBRBackMaterial_Roughness(void) { return occRoughness (occPbrBackMaterial[2].g); }
float occPBRBackMaterial_NormalizedRoughness(void) { return occPbrBackMaterial[2].g; }
#else
uniform vec4 occFrontMaterial[5];
uniform vec4 occBackMaterial[5];
// front material properties accessors
vec4 occFrontMaterial_Ambient(void) { return occFrontMaterial[0]; }
vec4 occFrontMaterial_Diffuse(void) { return occFrontMaterial[1]; }
vec4 occFrontMaterial_Specular(void) { return occFrontMaterial[2]; }
@@ -35,13 +79,13 @@ vec4 occFrontMaterial_Emission(void) { return occFrontMaterial[3]; }
float occFrontMaterial_Shininess(void) { return occFrontMaterial[4].x; }
float occFrontMaterial_Transparency(void) { return occFrontMaterial[4].y; }
// back material properties accessors
vec4 occBackMaterial_Ambient(void) { return occBackMaterial[0]; }
vec4 occBackMaterial_Diffuse(void) { return occBackMaterial[1]; }
vec4 occBackMaterial_Specular(void) { return occBackMaterial[2]; }
vec4 occBackMaterial_Emission(void) { return occBackMaterial[3]; }
float occBackMaterial_Shininess(void) { return occBackMaterial[4].x; }
float occBackMaterial_Transparency(void) { return occBackMaterial[4].y; }
#endif
// 2D texture coordinates transformation
vec2 occTextureTrsf_Translation(void) { return occTexTrsf2d[0].xy; }

View File

@@ -1,5 +1,12 @@
srcinc:::Declarations.glsl
srcinc:::DeclarationsImpl.glsl
srcinc:::PBRCookTorrance.glsl
srcinc:::PBRDistribution.glsl
srcinc:::PBREnvBaking.fs
srcinc:::PBREnvBaking.vs
srcinc:::PBRFresnel.glsl
srcinc:::PBRGeometry.glsl
srcinc:::PBRIllumination.glsl
srcinc:::PhongShading.fs
srcinc:::PhongShading.vs
srcinc:::Display.fs
@@ -11,6 +18,13 @@ srcinc:::RaytraceSmooth.fs
Shaders_Declarations_glsl.pxx
Shaders_DeclarationsImpl_glsl.pxx
Shaders_Display_fs.pxx
Shaders_PBRCookTorrance_glsl.pxx
Shaders_PBRDistribution_glsl.pxx
Shaders_PBREnvBaking_fs.pxx
Shaders_PBREnvBaking_vs.pxx
Shaders_PBRFresnel_glsl.pxx
Shaders_PBRGeometry_glsl.pxx
Shaders_PBRIllumination_glsl.pxx
Shaders_RaytraceBase_fs.pxx
Shaders_RaytraceRender_fs.pxx
Shaders_PathtraceBase_fs.pxx

View File

@@ -0,0 +1,20 @@
//! Calculates Cook-Torrance BRDF.
vec3 occPBRCookTorrance (in vec3 theView,
in vec3 theLight,
in vec3 theNormal,
in vec3 theBaseColor,
in float theMetallic,
in float theRoughness,
in float theIOR)
{
vec3 aHalf = normalize (theView + theLight);
float aCosV = max(dot(theView, theNormal), 0.0);
float aCosL = max(dot(theLight, theNormal), 0.0);
float aCosH = max(dot(aHalf, theNormal), 0.0);
float aCosVH = max(dot(aHalf, theView), 0.0);
vec3 aCookTorrance = occPBRDistribution (aCosH, theRoughness)
* occPBRGeometry (aCosV, aCosL, theRoughness)
* occPBRFresnel (theBaseColor, theMetallic, theIOR, aCosVH);
aCookTorrance /= 4.0;
return aCookTorrance;
}

View File

@@ -0,0 +1,9 @@
//! Calculates micro facet normals distribution.
float occPBRDistribution (in float theCosH,
in float theRoughness)
{
float aDistribution = theRoughness * theRoughness;
aDistribution = aDistribution / (theCosH * theCosH * (aDistribution * aDistribution - 1.0) + 1.0);
aDistribution = INV_PI * aDistribution * aDistribution;
return aDistribution;
}

162
src/Shaders/PBREnvBaking.fs Normal file
View File

@@ -0,0 +1,162 @@
THE_SHADER_IN vec3 ViewDirection; //!< direction of fetching from environment cubemap
uniform int uSamplesNum; //!< number of samples in Monte-Carlo integration
uniform int uCurrentLevel; //!< current level of specular IBL map (ignored in case of diffuse map's processing)
uniform int uEnvMapSize; //!< one edge's size of source environtment map's zero mipmap level
uniform int uYCoeff; //!< coefficient of Y controlling horizontal flip of cubemap
uniform int uZCoeff; //!< coefficient of Z controlling vertical flip of cubemap
uniform samplerCube uEnvMap; //!< source of baking (environment cubemap)
//! Returns coordinates of point theNumber from Hammersley point set having size theSize.
vec2 hammersley (in int theNumber,
in int theSize)
{
int aDenominator = 2;
int aNumber = theNumber;
float aVanDerCorput = 0.0;
for (int i = 0; i < 32; ++i)
{
if (aNumber > 0)
{
aVanDerCorput += float(aNumber % 2) / float(aDenominator);
aNumber /= 2;
aDenominator *= 2;
}
}
return vec2(float(theNumber) / float(theSize), aVanDerCorput);
}
//! This function does importance sampling on hemisphere surface using GGX normal distribution function
//! in tangent space (positive z axis is surface normal direction).
vec3 importanceSample (in vec2 theHammersleyPoint,
in float theRoughness)
{
float aPhi = PI_2 * theHammersleyPoint.x;
theRoughness *= theRoughness;
theRoughness *= theRoughness;
float aCosTheta = sqrt((1.0 - theHammersleyPoint.y) / (1.0 + (theRoughness - 1.0) * theHammersleyPoint.y));
float aSinTheta = sqrt(1.0 - aCosTheta * aCosTheta);
return vec3(aSinTheta * cos(aPhi),
aSinTheta * sin(aPhi),
aCosTheta);
}
//! This function uniformly generates samples on whole sphere.
vec3 sphereUniformSample (in vec2 theHammersleyPoint)
{
float aPhi = PI_2 * theHammersleyPoint.x;
float aCosTheta = 2.0 * theHammersleyPoint.y - 1.0;
float aSinTheta = sqrt(1.0 - aCosTheta * aCosTheta);
return vec3(aSinTheta * cos(aPhi),
aSinTheta * sin(aPhi),
aCosTheta);
}
//! Transforms resulted sampled direction from tangent space to world space considering the surface normal.
vec3 fromTangentSpace (in vec3 theVector,
in vec3 theNormal)
{
vec3 anUp = (abs(theNormal.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
vec3 anX = normalize(cross(anUp, theNormal));
vec3 anY = cross(theNormal, anX);
return anX * theVector.x + anY * theVector.y + theNormal * theVector.z;
}
const float aSHBasisFuncCoeffs[9] = float[9]
(
0.282095 * 0.282095,
0.488603 * 0.488603,
0.488603 * 0.488603,
0.488603 * 0.488603,
1.092548 * 1.092548,
1.092548 * 1.092548,
1.092548 * 1.092548,
0.315392 * 0.315392,
0.546274 * 0.546274
);
const float aSHCosCoeffs[9] = float[9]
(
3.141593,
2.094395,
2.094395,
2.094395,
0.785398,
0.785398,
0.785398,
0.785398,
0.785398
);
//! Bakes diffuse IBL map's spherical harmonics coefficients.
vec3 bakeDiffuseSH()
{
int anIndex = int(gl_FragCoord.x);
vec3 aResult = vec3 (0.0);
for (int aSampleIter = 0; aSampleIter < uSamplesNum; ++aSampleIter)
{
vec2 aHammersleyPoint = hammersley (aSampleIter, uSamplesNum);
vec3 aDirection = sphereUniformSample (aHammersleyPoint);
vec3 aValue = occTextureCube (uEnvMap, cubemapVectorTransform (aDirection, uYCoeff, uZCoeff)).rgb;
float aBasisFunc[9];
aBasisFunc[0] = 1.0;
aBasisFunc[1] = aDirection.x;
aBasisFunc[2] = aDirection.y;
aBasisFunc[3] = aDirection.z;
aBasisFunc[4] = aDirection.x * aDirection.z;
aBasisFunc[5] = aDirection.y * aDirection.z;
aBasisFunc[6] = aDirection.x * aDirection.y;
aBasisFunc[7] = 3.0 * aDirection.z * aDirection.z - 1.0;
aBasisFunc[8] = aDirection.x * aDirection.x - aDirection.y * aDirection.y;
aResult += aValue * aBasisFunc[anIndex];
}
aResult *= 4.0 * aSHCosCoeffs[anIndex] * aSHBasisFuncCoeffs[anIndex] / float(uSamplesNum);
return aResult;
}
//! Bakes specular IBL map.
vec3 bakeSpecularMap (in vec3 theNormal,
in float theRoughness)
{
vec3 aResult = vec3(0.0);
float aWeightSum = 0.0;
int aSamplesNum = (theRoughness == 0.0) ? 1 : uSamplesNum;
float aSolidAngleSource = 4.0 * PI / (6.0 * float(uEnvMapSize * uEnvMapSize));
for (int aSampleIter = 0; aSampleIter < aSamplesNum; ++aSampleIter)
{
vec2 aHammersleyPoint = hammersley (aSampleIter, aSamplesNum);
vec3 aHalf = importanceSample (aHammersleyPoint, occRoughness (theRoughness));
float aHdotV = aHalf.z;
aHalf = fromTangentSpace (aHalf, theNormal);
vec3 aLight = -reflect (theNormal, aHalf);
float aNdotL = dot (aLight, theNormal);
if (aNdotL > 0.0)
{
float aSolidAngleSample = 1.0 / (float(aSamplesNum) * (occPBRDistribution (aHdotV, theRoughness) * 0.25 + 0.0001) + 0.0001);
float aLod = (theRoughness == 0.0) ? 0.0 : 0.5 * log2 (aSolidAngleSample / aSolidAngleSource);
aResult += occTextureCubeLod (uEnvMap, aLight, aLod).rgb * aNdotL;
aWeightSum += aNdotL;
}
}
return aResult / aWeightSum;
}
void main()
{
vec3 aViewDirection = normalize (ViewDirection);
if (occNbSpecIBLLevels == 0)
{
occSetFragColor (vec4 (bakeDiffuseSH (), 1.0));
}
else
{
occSetFragColor (vec4 (bakeSpecularMap (aViewDirection, float(uCurrentLevel) / float(occNbSpecIBLLevels - 1)), 1.0));
}
}

View File

@@ -0,0 +1,35 @@
THE_SHADER_OUT vec3 ViewDirection; //!< direction of fetching from environment cubemap
uniform int uCurrentSide; //!< current side of cubemap
uniform int uYCoeff; //!< coefficient of Y controlling horizontal flip of cubemap
uniform int uZCoeff; //!< coefficient of Z controlling vertical flip of cubemap
const mat2 cubemapDirectionMatrices[6] = mat2[]
(
mat2 ( 0, -1, -1, 0),
mat2 ( 0, 1, -1, 0),
mat2 ( 0, 1, 1, 0),
mat2 ( 0, 1, -1, 0),
mat2 ( 1, 0, 0, -1),
mat2 (-1, 0, 0, -1)
);
//! Generates environment map fetching direction considering current index of side.
vec3 cubemapBakingViewDirection (in int theSide,
in vec2 theScreenCoord)
{
int anAxis = theSide / 2;
vec3 aDirection = vec3(0.0);
aDirection[anAxis] = float(-(int(theSide) % 2) * 2 + 1);
theScreenCoord = cubemapDirectionMatrices[theSide] * theScreenCoord;
aDirection[(anAxis + 1) % 3] = theScreenCoord.x;
aDirection[(anAxis + 2) % 3] = theScreenCoord.y;
return aDirection;
}
void main()
{
ViewDirection = cubemapBakingViewDirection (uCurrentSide, occVertex.xy);
ViewDirection = cubemapVectorTransform (ViewDirection, uYCoeff, uZCoeff);
gl_Position = vec4 (occVertex.xy, 0.0, 1.0);
}

View File

@@ -0,0 +1,36 @@
//! Functions to calculate fresnel coefficient and approximate zero fresnel value.
vec3 occPBRFresnel (in vec3 theBaseColor,
in float theMetallic,
in float theIOR)
{
theIOR = (1.0 - theIOR) / (1.0 + theIOR);
theIOR *= theIOR;
vec3 f0 = vec3(theIOR);
f0 = mix (f0, theBaseColor.rgb, theMetallic);
return f0;
}
vec3 occPBRFresnel (in vec3 theBaseColor,
in float theMetallic,
in float theIOR,
in float theCosVH)
{
vec3 f0 = occPBRFresnel (theBaseColor, theMetallic, theIOR);
theCosVH = 1.0 - theCosVH;
theCosVH *= theCosVH;
theCosVH *= theCosVH * theCosVH * theCosVH * theCosVH;
return f0 + (vec3 (1.0) - f0) * theCosVH;
}
vec3 occPBRFresnel (in vec3 theBaseColor,
in float theMetallic,
in float theRoughness,
in float theIOR,
in float theCosV)
{
vec3 f0 = occPBRFresnel (theBaseColor, theMetallic, theIOR);
theCosV = 1.0 - theCosV;
theCosV *= theCosV;
theCosV *= theCosV * theCosV * theCosV * theCosV;
return f0 + (max(vec3(1.0 - theRoughness), f0) - f0) * theCosV;
}

View File

@@ -0,0 +1,13 @@
//! Calculates geometry factor for Cook-Torrance BRDF.
float occPBRGeometry (in float theCosV,
in float theCosL,
in float theRoughness)
{
float k = theRoughness + 1.0;
k *= 0.125 * k;
float g1 = 1.0;
g1 /= theCosV * (1.0 - k) + k;
float g2 = 1.0;
g2 /= theCosL * (1.0 - k) + k;
return g1 * g2;
}

View File

@@ -0,0 +1,28 @@
//! Calculates direct illumination using Cook-Torrance BRDF.
vec3 occPBRIllumination (in vec3 theView,
in vec3 theLight,
in vec3 theNormal,
in vec4 theBaseColor,
in float theMetallic,
in float theRoughness,
in float theIOR,
in vec3 theLightColor,
in float theLightIntensity)
{
vec3 aHalf = normalize (theView + theLight);
float aCosVH = max(dot(theView, aHalf), 0.0);
vec3 aFresnel = occPBRFresnel (theBaseColor.rgb, theMetallic, theIOR, aCosVH);
vec3 aSpecular = occPBRCookTorrance (theView,
theLight,
theNormal,
theBaseColor.rgb,
theMetallic,
theRoughness,
theIOR);
vec3 aDiffuse = vec3(1.0) - aFresnel;
aDiffuse *= 1.0 - theMetallic;
aDiffuse *= INV_PI;
aDiffuse *= theBaseColor.rgb;
aDiffuse = mix (vec3(0.0), aDiffuse, theBaseColor.a);
return (aDiffuse + aSpecular) * theLightColor * theLightIntensity * max(0.0, dot(theLight, theNormal));
}

View File

@@ -29,7 +29,7 @@ void pointLight (in int theId,
in vec3 thePoint)
{
vec3 aLight = occLight_Position (theId).xyz;
if (occLight_IsHeadlight (theId) == 0)
if (!occLight_IsHeadlight (theId))
{
aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0));
}

View File

@@ -22,15 +22,59 @@ static const char Shaders_DeclarationsImpl_glsl[] =
"\n"
"#if defined(THE_MAX_LIGHTS) && (THE_MAX_LIGHTS > 0)\n"
"// arrays of light sources\n"
"uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types\n"
"uniform vec4 occLightSources[THE_MAX_LIGHTS * 4]; //!< packed light sources parameters\n"
"uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types\n"
"#endif\n"
"\n"
"// material state\n"
"#if defined(THE_IS_PBR)\n"
"vec3 occDiffIBLMap (in vec3 theNormal)\n"
"{\n"
" vec3 aSHCoeffs[9];\n"
" for (int i = 0; i < 9; ++i)\n"
" {\n"
" aSHCoeffs[i] = occTexture2D (occDiffIBLMapSHCoeffs, vec2 ((float(i) + 0.5) / 9.0, 0.0)).rgb;\n"
" }\n"
" return aSHCoeffs[0]\n"
"\n"
" + aSHCoeffs[1] * theNormal.x\n"
" + aSHCoeffs[2] * theNormal.y\n"
" + aSHCoeffs[3] * theNormal.z\n"
"\n"
" + aSHCoeffs[4] * theNormal.x * theNormal.z\n"
" + aSHCoeffs[5] * theNormal.y * theNormal.z\n"
" + aSHCoeffs[6] * theNormal.x * theNormal.y\n"
"\n"
" + aSHCoeffs[7] * (3.0 * theNormal.z * theNormal.z - 1.0)\n"
" + aSHCoeffs[8] * (theNormal.x * theNormal.x - theNormal.y * theNormal.y);\n"
"}\n"
"#endif\n"
"\n"
"// front and back material properties accessors\n"
"#if defined(THE_IS_PBR)\n"
"uniform vec4 occPbrFrontMaterial[3];\n"
"uniform vec4 occPbrBackMaterial[3];\n"
"\n"
"#define MIN_ROUGHNESS 0.01\n"
"// Converts roughness value from range [0, 1] to real value for calculations\n"
"float occRoughness (in float theNormalizedRoughness) { return theNormalizedRoughness * (1.0 - MIN_ROUGHNESS) + MIN_ROUGHNESS; }\n"
"\n"
"vec4 occPBRFrontMaterial_Color(void) { return occPbrFrontMaterial[0]; }\n"
"vec3 occPBRFrontMaterial_Emission(void) { return occPbrFrontMaterial[1].rgb; }\n"
"float occPBRFrontMaterial_IOR(void) { return occPbrFrontMaterial[1].w; }\n"
"float occPBRFrontMaterial_Metallic(void) { return occPbrFrontMaterial[2].b; }\n"
"float occPBRFrontMaterial_Roughness(void) { return occRoughness (occPbrFrontMaterial[2].g); }\n"
"float occPBRFrontMaterial_NormalizedRoughness(void) { return occPbrFrontMaterial[2].g; }\n"
"\n"
"vec4 occPBRBackMaterial_Color(void) { return occPbrBackMaterial[0]; }\n"
"vec3 occPBRBackMaterial_Emission(void) { return occPbrBackMaterial[1].rgb; }\n"
"float occPBRBackMaterial_IOR(void) { return occPbrBackMaterial[1].w; }\n"
"float occPBRBackMaterial_Metallic(void) { return occPbrBackMaterial[2].b; }\n"
"float occPBRBackMaterial_Roughness(void) { return occRoughness (occPbrBackMaterial[2].g); }\n"
"float occPBRBackMaterial_NormalizedRoughness(void) { return occPbrBackMaterial[2].g; }\n"
"#else\n"
"uniform vec4 occFrontMaterial[5];\n"
"uniform vec4 occBackMaterial[5];\n"
"\n"
"// front material properties accessors\n"
"vec4 occFrontMaterial_Ambient(void) { return occFrontMaterial[0]; }\n"
"vec4 occFrontMaterial_Diffuse(void) { return occFrontMaterial[1]; }\n"
"vec4 occFrontMaterial_Specular(void) { return occFrontMaterial[2]; }\n"
@@ -38,13 +82,13 @@ static const char Shaders_DeclarationsImpl_glsl[] =
"float occFrontMaterial_Shininess(void) { return occFrontMaterial[4].x; }\n"
"float occFrontMaterial_Transparency(void) { return occFrontMaterial[4].y; }\n"
"\n"
"// back material properties accessors\n"
"vec4 occBackMaterial_Ambient(void) { return occBackMaterial[0]; }\n"
"vec4 occBackMaterial_Diffuse(void) { return occBackMaterial[1]; }\n"
"vec4 occBackMaterial_Specular(void) { return occBackMaterial[2]; }\n"
"vec4 occBackMaterial_Emission(void) { return occBackMaterial[3]; }\n"
"float occBackMaterial_Shininess(void) { return occBackMaterial[4].x; }\n"
"float occBackMaterial_Transparency(void) { return occBackMaterial[4].y; }\n"
"#endif\n"
"\n"
"// 2D texture coordinates transformation\n"
"vec2 occTextureTrsf_Translation(void) { return occTexTrsf2d[0].xy; }\n"

View File

@@ -24,6 +24,8 @@ static const char Shaders_Declarations_glsl[] =
" #define occTexture1D texture\n"
" #define occTexture2D texture\n"
" #define occTexture3D texture\n"
" #define occTextureCube texture\n"
" #define occTextureCubeLod textureLod\n"
"#else\n"
" #define THE_ATTRIBUTE attribute\n"
" #define THE_SHADER_IN varying\n"
@@ -32,10 +34,16 @@ static const char Shaders_Declarations_glsl[] =
" #define occTexture1D texture1D\n"
" #define occTexture2D texture2D\n"
" #define occTexture3D texture3D\n"
" #define occTextureCube textureCube\n"
" #define occTextureCubeLod textureCubeLod\n"
"#endif\n"
"\n"
"#ifdef GL_ES\n"
" #define THE_PREC_ENUM lowp // enumerations should fit into lowp range\n"
"#if (__VERSION__ >= 300)\n"
" #define THE_PREC_ENUM highp // lowp should be enough for enums but triggers driver bugs\n"
"#else\n"
" #define THE_PREC_ENUM lowp\n"
"#endif\n"
"#else\n"
" #define THE_PREC_ENUM\n"
"#endif\n"
@@ -88,6 +96,15 @@ static const char Shaders_Declarations_glsl[] =
" void occSetFragColor (in vec4 theColor);\n"
"#endif\n"
"\n"
"// Pi number definitions\n"
"#define PI 3.141592654\n"
"#define PI_2 6.283185307\n"
"#define PI_DIV_2 1.570796327\n"
"#define PI_DIV_3 1.047197551\n"
"#define PI_DIV_4 0.785398163\n"
"#define INV_PI 0.318309886\n"
"#define INV_PI_2 0.159154943\n"
"\n"
"// Matrix state\n"
"uniform mat4 occWorldViewMatrix; //!< World-view matrix\n"
"uniform mat4 occProjectionMatrix; //!< Projection matrix\n"
@@ -105,6 +122,15 @@ static const char Shaders_Declarations_glsl[] =
"uniform mat4 occProjectionMatrixInverseTranspose; //!< Transpose of the inverse of the projection matrix\n"
"uniform mat4 occModelWorldMatrixInverseTranspose; //!< Transpose of the inverse of the model-world matrix\n"
"\n"
"#if defined(THE_IS_PBR)\n"
"uniform sampler2D occEnvLUT; //!< Environment Lookup Table\n"
"uniform sampler2D occDiffIBLMapSHCoeffs; //!< Packed diffuse (irradiance) IBL map's spherical harmonics coefficients\n"
"uniform samplerCube occSpecIBLMap; //!< Specular IBL map\n"
"uniform int occNbSpecIBLLevels; //!< Number of mipmap levels used in occSpecIBLMap to store different roughness values maps\n"
"\n"
"vec3 occDiffIBLMap (in vec3 theNormal); //!< Unpacks spherical harmonics coefficients to diffuse IBL map's values\n"
"#endif\n"
"\n"
"// light type enumeration (same as Graphic3d_TypeOfLightSource)\n"
"const int OccLightType_Direct = 1; //!< directional light source\n"
"const int OccLightType_Point = 2; //!< isotropic point light source\n"
@@ -119,7 +145,7 @@ static const char Shaders_Declarations_glsl[] =
"#define occLight_Type(theId) occLightSourcesTypes[theId].x\n"
"\n"
"//! Is light a headlight, int?\n"
"#define occLight_IsHeadlight(theId) occLightSourcesTypes[theId].y\n"
"#define occLight_IsHeadlight(theId) (occLightSourcesTypes[theId].y != 0)\n"
"\n"
"//! Specular intensity (equals to diffuse), vec4.\n"
"#define occLight_Specular(theId) occLightSources[theId * 4 + 0]\n"
@@ -136,6 +162,11 @@ static const char Shaders_Declarations_glsl[] =
"//! Attenuation of the spot light intensity (from 0 to 1), float.\n"
"#define occLight_SpotExponent(theId) occLightSources[theId * 4 + 3].w\n"
"\n"
"#if defined(THE_IS_PBR)\n"
"//! Intensity of light source (>= 0), float.\n"
"#define occLight_Intensity(theId) occLightSources[theId * 4 + 0].a\n"
"#else\n"
"\n"
"//! Diffuse intensity (equals to Specular), vec4.\n"
"#define occLight_Diffuse(theId) occLightSources[theId * 4 + 0]\n"
"\n"
@@ -145,22 +176,44 @@ static const char Shaders_Declarations_glsl[] =
"//! Linear attenuation factor of positional light source, float.\n"
"#define occLight_LinearAttenuation(theId) occLightSources[theId * 4 + 3].y\n"
"#endif\n"
"#endif\n"
"\n"
"// Converts roughness value from range [0, 1] to real value for calculations\n"
"float occRoughness (in float theNormalizedRoughness);\n"
"\n"
"// Front material properties accessors\n"
"vec4 occFrontMaterial_Emission(void); //!< Emission color\n"
"vec4 occFrontMaterial_Ambient(void); //!< Ambient reflection\n"
"vec4 occFrontMaterial_Diffuse(void); //!< Diffuse reflection\n"
"vec4 occFrontMaterial_Specular(void); //!< Specular reflection\n"
"float occFrontMaterial_Shininess(void); //!< Specular exponent\n"
"float occFrontMaterial_Transparency(void); //!< Transparency coefficient\n"
"#if !defined(THE_IS_PBR)\n"
"vec4 occFrontMaterial_Emission(void); //!< Emission color\n"
"vec4 occFrontMaterial_Ambient(void); //!< Ambient reflection\n"
"vec4 occFrontMaterial_Diffuse(void); //!< Diffuse reflection\n"
"vec4 occFrontMaterial_Specular(void); //!< Specular reflection\n"
"float occFrontMaterial_Shininess(void); //!< Specular exponent\n"
"float occFrontMaterial_Transparency(void); //!< Transparency coefficient\n"
"#else\n"
"vec4 occPBRFrontMaterial_Color(void); //!< Base color of PBR material\n"
"float occPBRFrontMaterial_Metallic(void); //!< Metallic coefficient\n"
"float occPBRFrontMaterial_Roughness(void); //!< Roughness coefficient\n"
"float occPBRFrontMaterial_NormalizedRoughness(void); //!< Normalized roughness coefficient\n"
"vec3 occPBRFrontMaterial_Emission(void); //!< Light intensity emitted by material\n"
"float occPBRFrontMaterial_IOR(void); //!< Index of refraction\n"
"#endif\n"
"\n"
"// Back material properties accessors\n"
"vec4 occBackMaterial_Emission(void); //!< Emission color\n"
"vec4 occBackMaterial_Ambient(void); //!< Ambient reflection\n"
"vec4 occBackMaterial_Diffuse(void); //!< Diffuse reflection\n"
"vec4 occBackMaterial_Specular(void); //!< Specular reflection\n"
"float occBackMaterial_Shininess(void); //!< Specular exponent\n"
"float occBackMaterial_Transparency(void); //!< Transparency coefficient\n"
"#if !defined(THE_IS_PBR)\n"
"vec4 occBackMaterial_Emission(void); //!< Emission color\n"
"vec4 occBackMaterial_Ambient(void); //!< Ambient reflection\n"
"vec4 occBackMaterial_Diffuse(void); //!< Diffuse reflection\n"
"vec4 occBackMaterial_Specular(void); //!< Specular reflection\n"
"float occBackMaterial_Shininess(void); //!< Specular exponent\n"
"float occBackMaterial_Transparency(void); //!< Transparency coefficient\n"
"#else\n"
"vec4 occPBRBackMaterial_Color(void); //!< Base color of PBR material\n"
"float occPBRBackMaterial_Metallic(void); //!< Metallic coefficient\n"
"float occPBRBackMaterial_Roughness(void); //!< Roughness coefficient\n"
"float occPBRBackMaterial_NormalizedRoughness(void); //!< Normalized roughness coefficient\n"
"vec3 occPBRBackMaterial_Emission(void); //!< Light intensity emitted by material\n"
"float occPBRBackMaterial_IOR(void); //!< Index of refraction\n"
"#endif\n"
"\n"
"#ifdef THE_HAS_DEFAULT_SAMPLER\n"
"#define occActiveSampler occSampler0 //!< alias for backward compatibility\n"

View File

@@ -0,0 +1,23 @@
// This file has been automatically generated from resource file src/Shaders/PBRCookTorrance.glsl
static const char Shaders_PBRCookTorrance_glsl[] =
"//! Calculates Cook-Torrance BRDF.\n"
"vec3 occPBRCookTorrance (in vec3 theView,\n"
" in vec3 theLight,\n"
" in vec3 theNormal,\n"
" in vec3 theBaseColor,\n"
" in float theMetallic,\n"
" in float theRoughness,\n"
" in float theIOR)\n"
"{\n"
" vec3 aHalf = normalize (theView + theLight);\n"
" float aCosV = max(dot(theView, theNormal), 0.0);\n"
" float aCosL = max(dot(theLight, theNormal), 0.0);\n"
" float aCosH = max(dot(aHalf, theNormal), 0.0);\n"
" float aCosVH = max(dot(aHalf, theView), 0.0);\n"
" vec3 aCookTorrance = occPBRDistribution (aCosH, theRoughness)\n"
" * occPBRGeometry (aCosV, aCosL, theRoughness)\n"
" * occPBRFresnel (theBaseColor, theMetallic, theIOR, aCosVH);\n"
" aCookTorrance /= 4.0;\n"
" return aCookTorrance;\n"
"}\n";

View File

@@ -0,0 +1,12 @@
// This file has been automatically generated from resource file src/Shaders/PBRDistribution.glsl
static const char Shaders_PBRDistribution_glsl[] =
"//! Calculates micro facet normals distribution.\n"
"float occPBRDistribution (in float theCosH,\n"
" in float theRoughness)\n"
"{\n"
" float aDistribution = theRoughness * theRoughness;\n"
" aDistribution = aDistribution / (theCosH * theCosH * (aDistribution * aDistribution - 1.0) + 1.0);\n"
" aDistribution = INV_PI * aDistribution * aDistribution;\n"
" return aDistribution;\n"
"}\n";

View File

@@ -0,0 +1,165 @@
// This file has been automatically generated from resource file src/Shaders/PBREnvBaking.fs
static const char Shaders_PBREnvBaking_fs[] =
"THE_SHADER_IN vec3 ViewDirection; //!< direction of fetching from environment cubemap\n"
"\n"
"uniform int uSamplesNum; //!< number of samples in Monte-Carlo integration\n"
"uniform int uCurrentLevel; //!< current level of specular IBL map (ignored in case of diffuse map's processing)\n"
"uniform int uEnvMapSize; //!< one edge's size of source environtment map's zero mipmap level\n"
"uniform int uYCoeff; //!< coefficient of Y controlling horizontal flip of cubemap\n"
"uniform int uZCoeff; //!< coefficient of Z controlling vertical flip of cubemap\n"
"uniform samplerCube uEnvMap; //!< source of baking (environment cubemap)\n"
"\n"
"//! Returns coordinates of point theNumber from Hammersley point set having size theSize.\n"
"vec2 hammersley (in int theNumber,\n"
" in int theSize)\n"
"{\n"
" int aDenominator = 2;\n"
" int aNumber = theNumber;\n"
" float aVanDerCorput = 0.0;\n"
" for (int i = 0; i < 32; ++i)\n"
" {\n"
" if (aNumber > 0)\n"
" {\n"
" aVanDerCorput += float(aNumber % 2) / float(aDenominator);\n"
" aNumber /= 2;\n"
" aDenominator *= 2;\n"
" }\n"
" }\n"
" return vec2(float(theNumber) / float(theSize), aVanDerCorput);\n"
"}\n"
"\n"
"//! This function does importance sampling on hemisphere surface using GGX normal distribution function\n"
"//! in tangent space (positive z axis is surface normal direction).\n"
"vec3 importanceSample (in vec2 theHammersleyPoint,\n"
" in float theRoughness)\n"
"{\n"
" float aPhi = PI_2 * theHammersleyPoint.x;\n"
" theRoughness *= theRoughness;\n"
" theRoughness *= theRoughness;\n"
" float aCosTheta = sqrt((1.0 - theHammersleyPoint.y) / (1.0 + (theRoughness - 1.0) * theHammersleyPoint.y));\n"
" float aSinTheta = sqrt(1.0 - aCosTheta * aCosTheta);\n"
" return vec3(aSinTheta * cos(aPhi),\n"
" aSinTheta * sin(aPhi),\n"
" aCosTheta);\n"
"}\n"
"\n"
"//! This function uniformly generates samples on whole sphere.\n"
"vec3 sphereUniformSample (in vec2 theHammersleyPoint)\n"
"{\n"
" float aPhi = PI_2 * theHammersleyPoint.x;\n"
" float aCosTheta = 2.0 * theHammersleyPoint.y - 1.0;\n"
" float aSinTheta = sqrt(1.0 - aCosTheta * aCosTheta);\n"
" return vec3(aSinTheta * cos(aPhi),\n"
" aSinTheta * sin(aPhi),\n"
" aCosTheta);\n"
"}\n"
"\n"
"//! Transforms resulted sampled direction from tangent space to world space considering the surface normal.\n"
"vec3 fromTangentSpace (in vec3 theVector,\n"
" in vec3 theNormal)\n"
"{\n"
" vec3 anUp = (abs(theNormal.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);\n"
" vec3 anX = normalize(cross(anUp, theNormal));\n"
" vec3 anY = cross(theNormal, anX);\n"
" return anX * theVector.x + anY * theVector.y + theNormal * theVector.z;\n"
"}\n"
"\n"
"const float aSHBasisFuncCoeffs[9] = float[9]\n"
"(\n"
" 0.282095 * 0.282095,\n"
" 0.488603 * 0.488603,\n"
" 0.488603 * 0.488603,\n"
" 0.488603 * 0.488603,\n"
" 1.092548 * 1.092548,\n"
" 1.092548 * 1.092548,\n"
" 1.092548 * 1.092548,\n"
" 0.315392 * 0.315392,\n"
" 0.546274 * 0.546274\n"
");\n"
"\n"
"const float aSHCosCoeffs[9] = float[9]\n"
"(\n"
" 3.141593,\n"
" 2.094395,\n"
" 2.094395,\n"
" 2.094395,\n"
" 0.785398,\n"
" 0.785398,\n"
" 0.785398,\n"
" 0.785398,\n"
" 0.785398\n"
");\n"
"\n"
"//! Bakes diffuse IBL map's spherical harmonics coefficients.\n"
"vec3 bakeDiffuseSH()\n"
"{\n"
" int anIndex = int(gl_FragCoord.x);\n"
" vec3 aResult = vec3 (0.0);\n"
" for (int aSampleIter = 0; aSampleIter < uSamplesNum; ++aSampleIter)\n"
" {\n"
" vec2 aHammersleyPoint = hammersley (aSampleIter, uSamplesNum);\n"
" vec3 aDirection = sphereUniformSample (aHammersleyPoint);\n"
"\n"
" vec3 aValue = occTextureCube (uEnvMap, cubemapVectorTransform (aDirection, uYCoeff, uZCoeff)).rgb;\n"
"\n"
" float aBasisFunc[9];\n"
" aBasisFunc[0] = 1.0;\n"
"\n"
" aBasisFunc[1] = aDirection.x;\n"
" aBasisFunc[2] = aDirection.y;\n"
" aBasisFunc[3] = aDirection.z;\n"
"\n"
" aBasisFunc[4] = aDirection.x * aDirection.z;\n"
" aBasisFunc[5] = aDirection.y * aDirection.z;\n"
" aBasisFunc[6] = aDirection.x * aDirection.y;\n"
"\n"
" aBasisFunc[7] = 3.0 * aDirection.z * aDirection.z - 1.0;\n"
" aBasisFunc[8] = aDirection.x * aDirection.x - aDirection.y * aDirection.y;\n"
"\n"
" aResult += aValue * aBasisFunc[anIndex];\n"
" }\n"
"\n"
" aResult *= 4.0 * aSHCosCoeffs[anIndex] * aSHBasisFuncCoeffs[anIndex] / float(uSamplesNum);\n"
" return aResult;\n"
"}\n"
"\n"
"//! Bakes specular IBL map.\n"
"vec3 bakeSpecularMap (in vec3 theNormal,\n"
" in float theRoughness)\n"
"{\n"
" vec3 aResult = vec3(0.0);\n"
" float aWeightSum = 0.0;\n"
" int aSamplesNum = (theRoughness == 0.0) ? 1 : uSamplesNum;\n"
" float aSolidAngleSource = 4.0 * PI / (6.0 * float(uEnvMapSize * uEnvMapSize));\n"
" for (int aSampleIter = 0; aSampleIter < aSamplesNum; ++aSampleIter)\n"
" {\n"
" vec2 aHammersleyPoint = hammersley (aSampleIter, aSamplesNum);\n"
" vec3 aHalf = importanceSample (aHammersleyPoint, occRoughness (theRoughness));\n"
" float aHdotV = aHalf.z;\n"
" aHalf = fromTangentSpace (aHalf, theNormal);\n"
" vec3 aLight = -reflect (theNormal, aHalf);\n"
" float aNdotL = dot (aLight, theNormal);\n"
" if (aNdotL > 0.0)\n"
" {\n"
" float aSolidAngleSample = 1.0 / (float(aSamplesNum) * (occPBRDistribution (aHdotV, theRoughness) * 0.25 + 0.0001) + 0.0001);\n"
" float aLod = (theRoughness == 0.0) ? 0.0 : 0.5 * log2 (aSolidAngleSample / aSolidAngleSource);\n"
" aResult += occTextureCubeLod (uEnvMap, aLight, aLod).rgb * aNdotL;\n"
" aWeightSum += aNdotL;\n"
" }\n"
" }\n"
" return aResult / aWeightSum;\n"
"}\n"
"\n"
"void main()\n"
"{\n"
" vec3 aViewDirection = normalize (ViewDirection);\n"
" if (occNbSpecIBLLevels == 0)\n"
" {\n"
" occSetFragColor (vec4 (bakeDiffuseSH (), 1.0));\n"
" }\n"
" else\n"
" {\n"
" occSetFragColor (vec4 (bakeSpecularMap (aViewDirection, float(uCurrentLevel) / float(occNbSpecIBLLevels - 1)), 1.0));\n"
" }\n"
"}\n";

View File

@@ -0,0 +1,38 @@
// This file has been automatically generated from resource file src/Shaders/PBREnvBaking.vs
static const char Shaders_PBREnvBaking_vs[] =
"THE_SHADER_OUT vec3 ViewDirection; //!< direction of fetching from environment cubemap\n"
"\n"
"uniform int uCurrentSide; //!< current side of cubemap\n"
"uniform int uYCoeff; //!< coefficient of Y controlling horizontal flip of cubemap\n"
"uniform int uZCoeff; //!< coefficient of Z controlling vertical flip of cubemap\n"
"\n"
"const mat2 cubemapDirectionMatrices[6] = mat2[]\n"
"(\n"
" mat2 ( 0, -1, -1, 0),\n"
" mat2 ( 0, 1, -1, 0),\n"
" mat2 ( 0, 1, 1, 0),\n"
" mat2 ( 0, 1, -1, 0),\n"
" mat2 ( 1, 0, 0, -1),\n"
" mat2 (-1, 0, 0, -1)\n"
");\n"
"\n"
"//! Generates environment map fetching direction considering current index of side.\n"
"vec3 cubemapBakingViewDirection (in int theSide,\n"
" in vec2 theScreenCoord)\n"
"{\n"
" int anAxis = theSide / 2;\n"
" vec3 aDirection = vec3(0.0);\n"
" aDirection[anAxis] = float(-(int(theSide) % 2) * 2 + 1);\n"
" theScreenCoord = cubemapDirectionMatrices[theSide] * theScreenCoord;\n"
" aDirection[(anAxis + 1) % 3] = theScreenCoord.x;\n"
" aDirection[(anAxis + 2) % 3] = theScreenCoord.y;\n"
" return aDirection;\n"
"}\n"
"\n"
"void main()\n"
"{\n"
" ViewDirection = cubemapBakingViewDirection (uCurrentSide, occVertex.xy);\n"
" ViewDirection = cubemapVectorTransform (ViewDirection, uYCoeff, uZCoeff);\n"
" gl_Position = vec4 (occVertex.xy, 0.0, 1.0);\n"
"}\n";

View File

@@ -0,0 +1,39 @@
// This file has been automatically generated from resource file src/Shaders/PBRFresnel.glsl
static const char Shaders_PBRFresnel_glsl[] =
"//! Functions to calculate fresnel coefficient and approximate zero fresnel value.\n"
"vec3 occPBRFresnel (in vec3 theBaseColor,\n"
" in float theMetallic,\n"
" in float theIOR)\n"
"{\n"
" theIOR = (1.0 - theIOR) / (1.0 + theIOR);\n"
" theIOR *= theIOR;\n"
" vec3 f0 = vec3(theIOR);\n"
" f0 = mix (f0, theBaseColor.rgb, theMetallic);\n"
" return f0;\n"
"}\n"
"\n"
"vec3 occPBRFresnel (in vec3 theBaseColor,\n"
" in float theMetallic,\n"
" in float theIOR,\n"
" in float theCosVH)\n"
"{\n"
" vec3 f0 = occPBRFresnel (theBaseColor, theMetallic, theIOR);\n"
" theCosVH = 1.0 - theCosVH;\n"
" theCosVH *= theCosVH;\n"
" theCosVH *= theCosVH * theCosVH * theCosVH * theCosVH;\n"
" return f0 + (vec3 (1.0) - f0) * theCosVH;\n"
"}\n"
"\n"
"vec3 occPBRFresnel (in vec3 theBaseColor,\n"
" in float theMetallic,\n"
" in float theRoughness,\n"
" in float theIOR,\n"
" in float theCosV)\n"
"{\n"
" vec3 f0 = occPBRFresnel (theBaseColor, theMetallic, theIOR);\n"
" theCosV = 1.0 - theCosV;\n"
" theCosV *= theCosV;\n"
" theCosV *= theCosV * theCosV * theCosV * theCosV;\n"
" return f0 + (max(vec3(1.0 - theRoughness), f0) - f0) * theCosV;\n"
"}\n";

View File

@@ -0,0 +1,16 @@
// This file has been automatically generated from resource file src/Shaders/PBRGeometry.glsl
static const char Shaders_PBRGeometry_glsl[] =
"//! Calculates geometry factor for Cook-Torrance BRDF.\n"
"float occPBRGeometry (in float theCosV,\n"
" in float theCosL,\n"
" in float theRoughness)\n"
"{\n"
" float k = theRoughness + 1.0;\n"
" k *= 0.125 * k;\n"
" float g1 = 1.0;\n"
" g1 /= theCosV * (1.0 - k) + k;\n"
" float g2 = 1.0;\n"
" g2 /= theCosL * (1.0 - k) + k;\n"
" return g1 * g2;\n"
"}\n";

View File

@@ -0,0 +1,31 @@
// This file has been automatically generated from resource file src/Shaders/PBRIllumination.glsl
static const char Shaders_PBRIllumination_glsl[] =
"//! Calculates direct illumination using Cook-Torrance BRDF.\n"
"vec3 occPBRIllumination (in vec3 theView,\n"
" in vec3 theLight,\n"
" in vec3 theNormal,\n"
" in vec4 theBaseColor,\n"
" in float theMetallic,\n"
" in float theRoughness,\n"
" in float theIOR,\n"
" in vec3 theLightColor,\n"
" in float theLightIntensity)\n"
"{\n"
" vec3 aHalf = normalize (theView + theLight);\n"
" float aCosVH = max(dot(theView, aHalf), 0.0);\n"
" vec3 aFresnel = occPBRFresnel (theBaseColor.rgb, theMetallic, theIOR, aCosVH);\n"
" vec3 aSpecular = occPBRCookTorrance (theView,\n"
" theLight,\n"
" theNormal,\n"
" theBaseColor.rgb,\n"
" theMetallic,\n"
" theRoughness,\n"
" theIOR);\n"
" vec3 aDiffuse = vec3(1.0) - aFresnel;\n"
" aDiffuse *= 1.0 - theMetallic;\n"
" aDiffuse *= INV_PI;\n"
" aDiffuse *= theBaseColor.rgb;\n"
" aDiffuse = mix (vec3(0.0), aDiffuse, theBaseColor.a);\n"
" return (aDiffuse + aSpecular) * theLightColor * theLightIntensity * max(0.0, dot(theLight, theNormal));\n"
"}\n";