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:
@@ -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
|
||||
|
@@ -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; }
|
||||
|
@@ -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
|
||||
|
20
src/Shaders/PBRCookTorrance.glsl
Normal file
20
src/Shaders/PBRCookTorrance.glsl
Normal 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;
|
||||
}
|
9
src/Shaders/PBRDistribution.glsl
Normal file
9
src/Shaders/PBRDistribution.glsl
Normal 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
162
src/Shaders/PBREnvBaking.fs
Normal 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));
|
||||
}
|
||||
}
|
35
src/Shaders/PBREnvBaking.vs
Normal file
35
src/Shaders/PBREnvBaking.vs
Normal 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);
|
||||
}
|
36
src/Shaders/PBRFresnel.glsl
Normal file
36
src/Shaders/PBRFresnel.glsl
Normal 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;
|
||||
}
|
13
src/Shaders/PBRGeometry.glsl
Normal file
13
src/Shaders/PBRGeometry.glsl
Normal 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;
|
||||
}
|
28
src/Shaders/PBRIllumination.glsl
Normal file
28
src/Shaders/PBRIllumination.glsl
Normal 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));
|
||||
}
|
@@ -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));
|
||||
}
|
||||
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
23
src/Shaders/Shaders_PBRCookTorrance_glsl.pxx
Normal file
23
src/Shaders/Shaders_PBRCookTorrance_glsl.pxx
Normal 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";
|
12
src/Shaders/Shaders_PBRDistribution_glsl.pxx
Normal file
12
src/Shaders/Shaders_PBRDistribution_glsl.pxx
Normal 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";
|
165
src/Shaders/Shaders_PBREnvBaking_fs.pxx
Normal file
165
src/Shaders/Shaders_PBREnvBaking_fs.pxx
Normal 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";
|
38
src/Shaders/Shaders_PBREnvBaking_vs.pxx
Normal file
38
src/Shaders/Shaders_PBREnvBaking_vs.pxx
Normal 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";
|
39
src/Shaders/Shaders_PBRFresnel_glsl.pxx
Normal file
39
src/Shaders/Shaders_PBRFresnel_glsl.pxx
Normal 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";
|
16
src/Shaders/Shaders_PBRGeometry_glsl.pxx
Normal file
16
src/Shaders/Shaders_PBRGeometry_glsl.pxx
Normal 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";
|
31
src/Shaders/Shaders_PBRIllumination_glsl.pxx
Normal file
31
src/Shaders/Shaders_PBRIllumination_glsl.pxx
Normal 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";
|
Reference in New Issue
Block a user