SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SLGLProgramGenerated Class Reference

Generated Shader Program class inherited from SLGLProgram. More...

#include <SLGLProgramGenerated.h>

Inheritance diagram for SLGLProgramGenerated:
[legend]

Public Member Functions

 ~SLGLProgramGenerated () override=default
 
 SLGLProgramGenerated (SLAssetManager *am, const string &programName, SLMaterial *mat, SLVLight *lights, SLbool supportGPUSkinning)
 ctor for generated shader program More...
 
 SLGLProgramGenerated (SLAssetManager *am, const string &programName, SLMaterial *mat, bool isDrawProg, SLstring geomShader="")
 ctor for generated shader program PS More...
 
void buildProgramCodePS (SLMaterial *mat, bool isDrawProg, bool drawInstanced=false)
 
void buildProgramCode (SLMaterial *mat, SLVLight *lights, SLbool supportGPUSkinning)
 
void beginShader (SLCamera *cam, SLMaterial *mat, SLVLight *lights) override
 starter for derived classes More...
 
void endShader () override
 
- Public Member Functions inherited from SLGLProgram
 SLGLProgram (SLAssetManager *am, const string &vertShaderFile, const string &fragShaderFile, const string &geomShaderFile="", const string &programName="")
 Ctor with a vertex and a fragment shader filename. More...
 
 ~SLGLProgram () override
 
void deleteDataGpu ()
 Delete all Gpu data. More...
 
void addShader (SLGLShader *shader)
 SLGLProgram::addShader adds a shader to the shader list. More...
 
void init (SLVLight *lights)
 
void initTF (const char *writeBackAttrib[], int size)
 
void beginUse (SLCamera *cam, SLMaterial *mat, SLVLight *lights)
 
SLint passLightsToUniforms (SLVLight *lights, SLuint nextTexUnit) const
 
void endUse ()
 SLGLProgram::endUse stops the shader program. More...
 
void useProgram ()
 
void addUniform1f (SLGLUniform1f *u)
 add float uniform More...
 
void addUniform1i (SLGLUniform1i *u)
 add int uniform More...
 
SLuint progID () const
 
SLVGLShadershaders ()
 
SLint getUniformLocation (const SLchar *name) const
 
SLint uniform1f (const SLchar *name, SLfloat v0) const
 Passes the float value v0 to the uniform variable "name". More...
 
SLint uniform2f (const SLchar *name, SLfloat v0, SLfloat v1) const
 Passes the float values v0 & v1 to the uniform variable "name". More...
 
SLint uniform3f (const SLchar *name, SLfloat v0, SLfloat v1, SLfloat v2) const
 Passes the float values v0, v1 & v2 to the uniform variable "name". More...
 
SLint uniform4f (const SLchar *name, SLfloat v0, SLfloat v1, SLfloat v2, SLfloat v3) const
 Passes the float values v0,v1,v2 & v3 to the uniform variable "name". More...
 
SLint uniform1i (const SLchar *name, SLint v0) const
 Passes the int values v0 to the uniform variable "name". More...
 
SLint uniform2i (const SLchar *name, SLint v0, SLint v1) const
 Passes the int values v0 & v1 to the uniform variable "name". More...
 
SLint uniform3i (const SLchar *name, SLint v0, SLint v1, SLint v2) const
 Passes the int values v0, v1 & v2 to the uniform variable "name". More...
 
SLint uniform4i (const SLchar *name, SLint v0, SLint v1, SLint v2, SLint v3) const
 Passes the int values v0, v1, v2 & v3 to the uniform variable "name". More...
 
SLint uniform1fv (const SLchar *name, SLsizei count, const SLfloat *value) const
 Passes 1 float value py pointer to the uniform variable "name". More...
 
SLint uniform2fv (const SLchar *name, SLsizei count, const SLfloat *value) const
 Passes 2 float values py pointer to the uniform variable "name". More...
 
SLint uniform3fv (const SLchar *name, SLsizei count, const SLfloat *value) const
 Passes 3 float values py pointer to the uniform variable "name". More...
 
SLint uniform4fv (const SLchar *name, SLsizei count, const SLfloat *value) const
 Passes 4 float values py pointer to the uniform variable "name". More...
 
SLint uniform1iv (const SLchar *name, SLsizei count, const SLint *value) const
 Passes 1 int value py pointer to the uniform variable "name". More...
 
SLint uniform2iv (const SLchar *name, SLsizei count, const SLint *value) const
 Passes 2 int values py pointer to the uniform variable "name". More...
 
SLint uniform3iv (const SLchar *name, SLsizei count, const SLint *value) const
 Passes 3 int values py pointer to the uniform variable "name". More...
 
SLint uniform4iv (const SLchar *name, GLsizei count, const SLint *value) const
 Passes 4 int values py pointer to the uniform variable "name". More...
 
SLint uniformMatrix2fv (const SLchar *name, SLsizei count, const SLfloat *value, GLboolean transpose=false) const
 Passes a 2x2 float matrix values py pointer to the uniform variable "name". More...
 
void uniformMatrix2fv (SLint loc, SLsizei count, const SLfloat *value, GLboolean transpose=false) const
 Passes a 2x2 float matrix values py pointer to the uniform at location loc. More...
 
SLint uniformMatrix3fv (const SLchar *name, SLsizei count, const SLfloat *value, GLboolean transpose=false) const
 Passes a 3x3 float matrix values py pointer to the uniform variable "name". More...
 
void uniformMatrix3fv (SLint loc, SLsizei count, const SLfloat *value, GLboolean transpose=false) const
 Passes a 3x3 float matrix values py pointer to the uniform at location loc. More...
 
SLint uniformMatrix4fv (const SLchar *name, SLsizei count, const SLfloat *value, GLboolean transpose=false) const
 Passes a 4x4 float matrix values py pointer to the uniform variable "name". More...
 
void uniformMatrix4fv (SLint loc, SLsizei count, const SLfloat *value, GLboolean transpose=false) const
 Passes a 4x4 float matrix values py pointer to the uniform at location loc. More...
 
- Public Member Functions inherited from SLObject
 SLObject (const SLstring &Name="", const SLstring &url="")
 
virtual ~SLObject ()
 
void name (const SLstring &Name)
 
void url (const SLstring &url)
 
const SLstringname () const
 
const SLstringurl () const
 

Static Public Member Functions

static bool lightsDoShadowMapping (SLVLight *lights)
 Returns true if at least one of the light does shadow mapping. More...
 
static void buildProgramName (SLMaterial *mat, SLVLight *lights, SLbool supportGPUSkinning, string &programName)
 Builds unique program name that identifies shader program. More...
 
static void buildProgramNamePS (SLMaterial *mat, string &programName, bool isDrawProg, bool drawInstanced)
 

Private Member Functions

void buildPerPixCook (SLMaterial *mat, SLVLight *lights, SLbool supportGPUSkinning)
 
void buildPerPixBlinn (SLMaterial *mat, SLVLight *lights, SLbool supportGPUSkinning)
 
void buildPerPixParticle (SLMaterial *mat)
 
void buildPerPixParticleInstanced (SLMaterial *mat)
 
void buildPerPixParticleUpdate (SLMaterial *mat)
 
void buildPerPixVideoBkgdSm (SLVLight *lights)
 Assemble shaders for video on background. More...
 

Static Private Member Functions

static string fragInput_u_lightSm (SLVLight *lights)
 
static string fragInput_u_shadowMaps (SLVLight *lights)
 
static string fragFunctionShadowTest (SLVLight *lights)
 Adds the core shadow mapping test routine depending on the lights. More...
 
static string shaderHeader (int numLights)
 Adds shader header code. More...
 
static string shaderHeader ()
 Adds shader header code. More...
 
static void addCodeToShader (SLGLShader *shader, const string &code, const string &name)
 Add vertex shader code to the SLGLShader instance. More...
 
static void setVariable (std::string &code, const std::string &name, const std::string &value)
 Sets a variable in the shader code. More...
 

Static Private Attributes

static string generatedShaderPath
 

Additional Inherited Members

- Protected Attributes inherited from SLGLProgram
SLuint _progID
 OpenGL shader program object ID. More...
 
SLbool _isLinked
 Flag if program is linked. More...
 
SLVGLShader _shaders
 Vector of all shader objects. More...
 
SLVUniform1f _uniforms1f
 Vector of uniform1f variables. More...
 
SLVUniform1i _uniforms1i
 Vector of uniform1i variables. More...
 
- Protected Attributes inherited from SLObject
SLstring _name
 name of an object More...
 
SLstring _url
 uniform resource locator More...
 

Detailed Description

Generated Shader Program class inherited from SLGLProgram.

An instance of this class generates the shader code on the fly at construction time based on the information of the passed material and lights vector. The generated program depends on the following parameters:

  • mat->reflectionModel (Blinn-Phong or Cook-Torrance)
  • mat->textures
  • light->createsShadows
  • active camera for the fog and projection parameters

The shader program gets a unique name with the following pattern:

 genCook-D00-N00-E00-O01-RM00-Sky-C4s
    |    |   |   |   |   |    |   |
    |    |   |   |   |   |    |   + Directional light w. 4 shadow cascades
    |    |   |   |   |   |    + Ambient light from skybox
    |    |   |   |   |   + Roughness-metallic map with index 0 and uv 0
    |    |   |   |   + Ambient Occlusion map with index 0 and uv 1
    |    |   |   + Emissive Map with index 0 and uv 0
    |    |   + Normal Map with index 0 and uv 0
    |    + Diffuse Texture Mapping with index 0 and uv 0
    + Cook-Torrance or Blinn-Phong lighting model

The above example is for a material with 5 textures and a scene with one light. The shader program is constructed when a material is for the first time activated (SLMaterial::activate) and it's program pointer is null. The old system of custom written GLSL shader program is still valid. At the end of SLMaterial::activate the generated vertex and fragment shader get compiled, linked and activated with the OpenGL functions in SLGLShader and SLGLProgram. After successful compilation the shader get exported into the applications config directory if they not yet exist there.

Definition at line 53 of file SLGLProgramGenerated.h.

Constructor & Destructor Documentation

◆ ~SLGLProgramGenerated()

SLGLProgramGenerated::~SLGLProgramGenerated ( )
overridedefault

◆ SLGLProgramGenerated() [1/2]

SLGLProgramGenerated::SLGLProgramGenerated ( SLAssetManager am,
const string &  programName,
SLMaterial mat,
SLVLight lights,
SLbool  supportGPUSkinning 
)
inline

ctor for generated shader program

Definition at line 59 of file SLGLProgramGenerated.h.

64  : SLGLProgram(am,
65  "",
66  "",
67  "",
68  programName)
69  {
70  buildProgramCode(mat, lights, supportGPUSkinning);
71  }
void buildProgramCode(SLMaterial *mat, SLVLight *lights, SLbool supportGPUSkinning)
SLGLProgram(SLAssetManager *am, const string &vertShaderFile, const string &fragShaderFile, const string &geomShaderFile="", const string &programName="")
Ctor with a vertex and a fragment shader filename.
Definition: SLGLProgram.cpp:39

◆ SLGLProgramGenerated() [2/2]

SLGLProgramGenerated::SLGLProgramGenerated ( SLAssetManager am,
const string &  programName,
SLMaterial mat,
bool  isDrawProg,
SLstring  geomShader = "" 
)
inline

ctor for generated shader program PS

Definition at line 74 of file SLGLProgramGenerated.h.

79  : SLGLProgram(am,
80  "",
81  "",
82  geomShader,
83  programName)
84  {
85 
86  if (geomShader != "")
87  {
88  buildProgramCodePS(mat, isDrawProg, false);
89  }
90  else
91  {
92  buildProgramCodePS(mat, isDrawProg, true);
93  }
94  }
void buildProgramCodePS(SLMaterial *mat, bool isDrawProg, bool drawInstanced=false)

Member Function Documentation

◆ addCodeToShader()

void SLGLProgramGenerated::addCodeToShader ( SLGLShader shader,
const string &  code,
const string &  name 
)
staticprivate

Add vertex shader code to the SLGLShader instance.

Definition at line 2944 of file SLGLProgramGenerated.cpp.

2947 {
2948 
2949 #if defined(DEBUG) && defined(_DEBUG)
2950  shader->code(SLGLShader::removeComments(code));
2951 #else
2952  shader->code(code);
2953 #endif
2954  shader->name(name);
2955 
2956 #ifndef SL_EMSCRIPTEN
2957  // Check if generatedShaderPath folder exists
2958  generatedShaderPath = SLGLProgramManager::configPath + "generatedShaders/";
2960  SL_EXIT_MSG("SLGLProgramGenerated::addCodeToShader: SLGLProgramManager::configPath not existing");
2961 
2963  {
2964  bool dirCreated = Utils::makeDir(generatedShaderPath); // dirCreated is still false on MacOS after creation
2966  SL_EXIT_MSG("SLGLProgramGenerated::addCodeToShader: Failed to created SLGLProgramManager::configPath/generatedShaders");
2967  }
2968 
2969  shader->file(generatedShaderPath + name);
2970 #endif
2971 }
#define SL_EXIT_MSG(message)
Definition: SL.h:240
static string generatedShaderPath
static string configPath
Contains the global writable configuration path.
SLstring code()
Definition: SLGLShader.h:42
void file(SLstring strFile)
Definition: SLGLShader.h:46
static SLstring removeComments(SLstring src)
SLGLShader::removeComments for C/C++ comments removal from shader code.
Definition: SLGLShader.cpp:201
void name(const SLstring &Name)
Definition: SLObject.h:34
const SLstring & name() const
Definition: SLObject.h:38
bool dirExists(const string &path)
Returns true if a directory exists.
Definition: Utils.cpp:790
bool makeDir(const string &path)
Creates a directory with given path.
Definition: Utils.cpp:810

◆ beginShader()

void SLGLProgramGenerated::beginShader ( SLCamera cam,
SLMaterial mat,
SLVLight lights 
)
inlineoverridevirtual

starter for derived classes

Implements SLGLProgram.

Definition at line 112 of file SLGLProgramGenerated.h.

114  { beginUse(cam, mat, lights); }
void beginUse(SLCamera *cam, SLMaterial *mat, SLVLight *lights)

◆ buildPerPixBlinn()

void SLGLProgramGenerated::buildPerPixBlinn ( SLMaterial mat,
SLVLight lights,
SLbool  supportGPUSkinning 
)
private

Definition at line 2069 of file SLGLProgramGenerated.cpp.

2072 {
2073  assert(mat && lights);
2074  assert(_shaders.size() > 1 &&
2075  _shaders[0]->type() == ST_vertex &&
2076  _shaders[1]->type() == ST_fragment);
2077 
2078  // Check what textures the material has
2079  bool Dm = mat->hasTextureType(TT_diffuse);
2080  bool Nm = mat->hasTextureType(TT_normal);
2081  bool Hm = mat->hasTextureType(TT_height);
2082  bool Em = mat->hasTextureType(TT_emissive);
2083  bool Om0 = mat->hasTextureTypeWithUVIndex(TT_occlusion, 0, 0);
2084  bool Om1 = mat->hasTextureTypeWithUVIndex(TT_occlusion, 0, 1);
2085  bool Sm = lightsDoShadowMapping(lights);
2086  bool uv0 = mat->usesUVIndex(0);
2087  bool uv1 = mat->usesUVIndex(1);
2088 
2089  // Assemble vertex shader code
2090  string vertCode;
2091  vertCode += shaderHeader((int)lights->size());
2092 
2093  // Vertex shader inputs
2094  vertCode += vertInput_a_pn;
2095  if (uv0) vertCode += vertInput_a_uv0;
2096  if (uv1) vertCode += vertInput_a_uv1;
2097  if (Nm) vertCode += vertInput_a_tangent;
2098  if (supportGPUSkinning) vertCode += vertInput_a_skinning;
2099  vertCode += vertInput_u_matrices_all;
2100  if (Nm) vertCode += vertInput_u_lightNm;
2101  if (supportGPUSkinning) vertCode += vertInput_u_skinning;
2102 
2103  // Vertex shader outputs
2104  vertCode += vertOutput_v_P_VS;
2105  if (Sm) vertCode += vertOutput_v_P_WS;
2106  vertCode += vertOutput_v_N_VS;
2107  if (uv0) vertCode += vertOutput_v_uv0;
2108  if (uv1) vertCode += vertOutput_v_uv1;
2109  if (Nm) vertCode += vertOutput_v_lightVecTS;
2110 
2111  // Vertex shader main loop
2112  vertCode += main_Begin;
2113  if (supportGPUSkinning) vertCode += Nm ? vertMain_skinning_Nm : vertMain_skinning;
2114  vertCode += vertMain_v_P_VS;
2115  if (Sm) vertCode += vertMain_v_P_WS_Sm;
2116  vertCode += vertMain_v_N_VS;
2117  if (uv0) vertCode += vertMain_v_uv0;
2118  if (uv1) vertCode += vertMain_v_uv1;
2119  if (Nm) vertCode += vertMain_TBN_Nm;
2120  vertCode += vertMain_EndAll;
2121 
2122  // Vertex shader variables
2123  setVariable(vertCode, "localPosition", supportGPUSkinning ? "skinnedPosition" : "a_position");
2124  setVariable(vertCode, "localNormal", supportGPUSkinning ? "skinnedNormal" : "a_normal");
2125  if (Nm) setVariable(vertCode, "localTangent", supportGPUSkinning ? "skinnedTangent" : "a_tangent");
2126 
2127  addCodeToShader(_shaders[0], vertCode, _name + ".vert");
2128 
2129  // Assemble fragment shader code
2130  string fragCode;
2131  fragCode += shaderHeader((int)lights->size());
2132 
2133  // Fragment shader inputs
2134  fragCode += fragInput_v_P_VS;
2135  if (Sm) fragCode += fragInput_v_P_WS;
2136  fragCode += fragInput_v_N_VS;
2137  if (uv0) fragCode += fragInput_v_uv0;
2138  if (uv1) fragCode += fragInput_v_uv1;
2139  if (Nm) fragCode += fragInput_v_lightVecTS;
2140 
2141  // Fragment shader uniforms
2142  fragCode += fragInput_u_lightAll;
2143  fragCode += fragInput_u_matBlinnAll;
2144  if (Sm) fragCode += fragInput_u_lightSm(lights);
2145  if (Dm) fragCode += fragInput_u_matTexDm;
2146  if (Nm) fragCode += fragInput_u_matTexNm;
2147  if (Em) fragCode += fragInput_u_matTexEm;
2148  if (Om0 || Om1) fragCode += fragInput_u_matTexOm;
2149  if (Sm) fragCode += fragInput_u_matGetsSm;
2150  if (Sm) fragCode += fragInput_u_shadowMaps(lights);
2151  fragCode += fragInput_u_cam;
2152 
2153  // Fragment shader outputs
2154  fragCode += fragOutputs_o_fragColor;
2155 
2156  // Fragment shader functions
2157  fragCode += fragFunctionsLightingBlinnPhong;
2158  fragCode += fragFunctionFogBlend;
2159  fragCode += fragFunctionDoStereoSeparation;
2160  if (Sm) fragCode += fragFunctionShadowTest(lights);
2161  if (Sm) fragCode += fragFunctionDoColoredShadows;
2162 
2163  // Fragment shader main loop
2164  fragCode += main_Begin;
2165  fragCode += fragMain_0_Intensities;
2166  fragCode += Nm ? fragMain_1_EN_in_TS : fragMain_1_EN_in_VS;
2167  fragCode += Em ? fragMain_1_matEmis_Em : fragMain_1_matEmis;
2168 
2169  fragCode += Om0 ? fragMain_1_matOccl_Om0 : Om1 ? fragMain_1_matOccl_Om1
2171 
2172  fragCode += Nm && Sm ? fragMainBlinn_2_LightLoopNmSm : Nm ? fragMainBlinn_2_LightLoopNm
2176  if (Sm) fragCode += fragMain_4_ColoredShadows;
2177  fragCode += fragMain_5_FogGammaStereo;
2178 
2179  addCodeToShader(_shaders[1], fragCode, _name + ".frag");
2180 }
@ ST_vertex
Definition: SLEnums.h:224
@ ST_fragment
Definition: SLEnums.h:225
const string vertMain_EndAll
const string vertOutput_v_uv1
const string fragMain_1_matOccl_Om0
const string fragInput_v_uv0
const string vertMain_v_P_VS
const string fragOutputs_o_fragColor
const string fragMainBlinn_3_FragColor
const string main_Begin
const string fragMain_5_FogGammaStereo
const string fragMainBlinn_2_LightLoopSm
const string fragMain_1_matOccl_Om1
const string fragMain_1_matEmis_Em
const string fragMain_1_EN_in_VS
const string vertOutput_v_N_VS
const string vertMain_v_uv0
const string fragMainBlinn_2_LightLoopNm
const string fragFunctionFogBlend
const string fragFunctionsLightingBlinnPhong
const string vertInput_a_tangent
const string fragInput_u_matTexEm
const string fragInput_u_lightAll
const string vertMain_v_N_VS
const string vertOutput_v_lightVecTS
const string vertInput_a_uv0
const string fragInput_u_matGetsSm
const string fragInput_u_cam
const string vertInput_a_skinning
const string fragFunctionDoStereoSeparation
const string fragInput_u_matTexOm
const string vertInput_a_pn
const string vertMain_v_P_WS_Sm
const string fragInput_u_matBlinnAll
const string vertInput_u_skinning
const string fragInput_v_N_VS
const string fragInput_v_lightVecTS
const string fragMainBlinn_2_LightLoopNmSm
const string vertMain_v_uv1
const string fragInput_v_P_VS
const string vertMain_TBN_Nm
const string vertMain_skinning_Nm
const string vertOutput_v_uv0
const string fragInput_v_P_WS
const string vertOutput_v_P_WS
const string vertInput_u_lightNm
const string fragMain_4_ColoredShadows
const string vertInput_u_matrices_all
const string fragMain_1_EN_in_TS
const string fragFunctionDoColoredShadows
const string vertInput_a_uv1
const string fragInput_v_uv1
const string fragMainBlinn_2_LightLoop
const string fragMain_1_matEmis
const string fragMain_0_Intensities
const string fragInput_u_matTexDm
const string fragMain_1_matOccl
const string vertMain_skinning
const string vertOutput_v_P_VS
const string fragMainBlinn_3_FragColorDm
const string fragInput_u_matTexNm
@ TT_height
Definition: SLGLTexture.h:80
@ TT_normal
Definition: SLGLTexture.h:79
@ TT_diffuse
Definition: SLGLTexture.h:78
@ TT_occlusion
Definition: SLGLTexture.h:83
@ TT_emissive
Definition: SLGLTexture.h:82
static string fragInput_u_lightSm(SLVLight *lights)
static bool lightsDoShadowMapping(SLVLight *lights)
Returns true if at least one of the light does shadow mapping.
static void addCodeToShader(SLGLShader *shader, const string &code, const string &name)
Add vertex shader code to the SLGLShader instance.
static void setVariable(std::string &code, const std::string &name, const std::string &value)
Sets a variable in the shader code.
static string fragFunctionShadowTest(SLVLight *lights)
Adds the core shadow mapping test routine depending on the lights.
static string shaderHeader()
Adds shader header code.
static string fragInput_u_shadowMaps(SLVLight *lights)
SLVGLShader _shaders
Vector of all shader objects.
Definition: SLGLProgram.h:143
SLbool hasTextureTypeWithUVIndex(SLTextureType tt, SLuint texIndex, SLbyte uvIndex)
Definition: SLMaterial.h:153
SLbool hasTextureType(SLTextureType tt)
Definition: SLMaterial.h:149
SLbool usesUVIndex(SLbyte uvIndex)
Returns true if the specified uvIndex is used by one of the textures.
Definition: SLMaterial.cpp:707
SLstring _name
name of an object
Definition: SLObject.h:42

◆ buildPerPixCook()

void SLGLProgramGenerated::buildPerPixCook ( SLMaterial mat,
SLVLight lights,
SLbool  supportGPUSkinning 
)
private

Definition at line 1935 of file SLGLProgramGenerated.cpp.

1938 {
1939  assert(mat && lights);
1940  assert(_shaders.size() > 1 &&
1941  _shaders[0]->type() == ST_vertex &&
1942  _shaders[1]->type() == ST_fragment);
1943 
1944  // Check what textures the material has
1945  bool Dm = mat->hasTextureType(TT_diffuse);
1946  bool Nm = mat->hasTextureType(TT_normal);
1947  bool Hm = mat->hasTextureType(TT_height);
1948  bool Rm = mat->hasTextureType(TT_roughness);
1949  bool Mm = mat->hasTextureType(TT_metallic);
1950  bool RMm = mat->hasTextureType(TT_roughMetal);
1951  bool Em = mat->hasTextureType(TT_emissive);
1952  bool Om0 = mat->hasTextureTypeWithUVIndex(TT_occlusion, 0, 0);
1953  bool Om1 = mat->hasTextureTypeWithUVIndex(TT_occlusion, 0, 1);
1954  bool ORMm = mat->hasTextureType(TT_occluRoughMetal);
1955  bool Vm = mat->hasTextureType(TT_videoBkgd);
1956  bool Sm = lightsDoShadowMapping(lights);
1957  bool uv0 = mat->usesUVIndex(0);
1958  bool uv1 = mat->usesUVIndex(1);
1959  bool sky = mat->skybox() != nullptr;
1960 
1961  // Assemble vertex shader code
1962  string vertCode;
1963  vertCode += shaderHeader((int)lights->size());
1964 
1965  // Vertex shader inputs
1966  vertCode += vertInput_a_pn;
1967  if (uv0) vertCode += vertInput_a_uv0;
1968  if (uv1) vertCode += vertInput_a_uv1;
1969  if (Nm) vertCode += vertInput_a_tangent;
1970  if (supportGPUSkinning) vertCode += vertInput_a_skinning;
1971  vertCode += vertInput_u_matrices_all;
1972  if (Nm) vertCode += vertInput_u_lightNm;
1973  if (supportGPUSkinning) vertCode += vertInput_u_skinning;
1974 
1975  // Vertex shader outputs
1976  vertCode += vertOutput_v_P_VS;
1977  if (Sm) vertCode += vertOutput_v_P_WS;
1978  vertCode += vertOutput_v_N_VS;
1979  if (sky) vertCode += vertOutput_v_R_OS;
1980  if (uv0) vertCode += vertOutput_v_uv0;
1981  if (uv1) vertCode += vertOutput_v_uv1;
1982  if (Nm) vertCode += vertOutput_v_lightVecTS;
1983 
1984  // Vertex shader main loop
1985  vertCode += main_Begin;
1986  if (supportGPUSkinning) vertCode += Nm ? vertMain_skinning_Nm : vertMain_skinning;
1987  vertCode += vertMain_v_P_VS;
1988  if (Sm) vertCode += vertMain_v_P_WS_Sm;
1989  vertCode += vertMain_v_N_VS;
1990  if (sky) vertCode += vertMain_v_R_OS;
1991  if (uv0) vertCode += vertMain_v_uv0;
1992  if (uv1) vertCode += vertMain_v_uv1;
1993  if (Nm) vertCode += vertMain_TBN_Nm;
1994  vertCode += vertMain_EndAll;
1995 
1996  // Vertex shader variables
1997  setVariable(vertCode, "localPosition", supportGPUSkinning ? "skinnedPosition" : "a_position");
1998  setVariable(vertCode, "localNormal", supportGPUSkinning ? "skinnedNormal" : "a_normal");
1999  if (Nm) setVariable(vertCode, "localTangent", supportGPUSkinning ? "skinnedTangent" : "a_tangent");
2000 
2001  addCodeToShader(_shaders[0], vertCode, _name + ".vert");
2002 
2003  // Assemble fragment shader code
2004  string fragCode;
2005  fragCode += shaderHeader((int)lights->size());
2006 
2007  // Fragment shader inputs
2008  fragCode += fragInput_v_P_VS;
2009  if (Sm) fragCode += fragInput_v_P_WS;
2010  fragCode += fragInput_v_N_VS;
2011  if (sky) fragCode += fragInput_v_R_OS;
2012  if (uv0) fragCode += fragInput_v_uv0;
2013  if (uv1) fragCode += fragInput_v_uv1;
2014  if (Nm) fragCode += fragInput_v_lightVecTS;
2015 
2016  // Fragment shader uniforms
2017  fragCode += fragInput_u_lightAll;
2018  if (Sm) fragCode += fragInput_u_lightSm(lights);
2019  fragCode += Dm ? fragInput_u_matTexDm : fragInput_u_matDiff;
2020  fragCode += Em ? fragInput_u_matTexEm : fragInput_u_matEmis;
2021  if (Rm) fragCode += fragInput_u_matTexRm;
2022  if (Mm) fragCode += fragInput_u_matTexMm;
2023  if (RMm) fragCode += fragInput_u_matTexRmMm;
2024  if (ORMm) fragCode += fragInput_u_matTexOmRmMm;
2025  if (!Rm && !RMm && !ORMm) fragCode += fragInput_u_matRough;
2026  if (!Mm && !RMm && !ORMm) fragCode += fragInput_u_matMetal;
2027  if (Nm) fragCode += fragInput_u_matTexNm;
2028  if (Om0 || Om1) fragCode += fragInput_u_matTexOm;
2029  if (Sm) fragCode += fragInput_u_matGetsSm;
2030  if (Sm) fragCode += fragInput_u_shadowMaps(lights);
2031  if (sky) fragCode += fragInput_u_skyCookEnvMaps;
2032  fragCode += fragInput_u_cam;
2033 
2034  // Fragment shader outputs
2035  fragCode += fragOutputs_o_fragColor;
2036 
2037  // Fragment shader functions
2039  fragCode += fragFunctionFogBlend;
2040  fragCode += fragFunctionDoStereoSeparation;
2041  if (Sm) fragCode += fragFunctionShadowTest(lights);
2042  if (Sm) fragCode += fragFunctionDoColoredShadows;
2043 
2044  // Fragment shader main loop
2045  fragCode += main_Begin;
2046  fragCode += fragMain_0_Intensities;
2047  fragCode += Nm ? fragMain_1_EN_in_TS : fragMain_1_EN_in_VS;
2059  fragCode += Nm && Sm ? fragMainCook_2_LightLoopNmSm : Nm ? fragMainCook_2_LightLoopNm
2063  if (Sm) fragCode += fragMain_4_ColoredShadows;
2064  fragCode += fragMain_5_FogGammaStereo;
2065 
2066  addCodeToShader(_shaders[1], fragCode, _name + ".frag");
2067 }
const string fragMainCook_3_FragColorSky
const string fragMainCook_1_matRough
const string fragMainCook_1_matOcclu_ORMm
const string fragInput_u_matTexRm
const string fragInput_u_matTexRmMm
const string fragInput_v_R_OS
const string fragMainCook_3_FragColor
const string fragMainCook_1_matOcclu_Om0
const string fragInput_u_matMetal
const string fragMainCook_2_LightLoopNm
const string fragMainCook_1_matDiff
const string fragInput_u_matRough
const string fragInput_u_matDiff
const string fragMainCook_1_matDiff_Dm
const string fragMainCook_1_matOcclu_1
const string fragMainCook_2_LightLoop
const string fragMainCook_1_matMetal_RMm
const string fragMainCook_1_matEmis_Em
const string fragMainCook_1_matRough_RMm
const string fragMainCook_1_matMetal_Mm
const string fragMainCook_2_LightLoopSm
const string fragMainCook_1_matEmis
const string fragInput_u_skyCookEnvMaps
const string fragInput_u_matTexOmRmMm
const string fragMainCook_1_matMetal
const string fragFunctionsLightingCookTorrance
const string fragMainCook_1_matOcclu_Om1
const string vertMain_v_R_OS
const string fragMainCook_1_matRough_ORMm
const string fragInput_u_matEmis
const string vertOutput_v_R_OS
const string fragMainCook_1_matMetal_ORMm
const string fragMainCook_1_matRough_Rm
const string fragInput_u_matTexMm
const string fragMainCook_2_LightLoopNmSm
@ TT_occluRoughMetal
Definition: SLGLTexture.h:87
@ TT_videoBkgd
Definition: SLGLTexture.h:94
@ TT_metallic
Definition: SLGLTexture.h:85
@ TT_roughMetal
Definition: SLGLTexture.h:86
@ TT_roughness
Definition: SLGLTexture.h:84
void skybox(SLSkybox *sb)
Definition: SLMaterial.h:207

◆ buildPerPixParticle()

void SLGLProgramGenerated::buildPerPixParticle ( SLMaterial mat)
private

Definition at line 2316 of file SLGLProgramGenerated.cpp.

2317 {
2318  assert(_shaders.size() > 2 &&
2319  _shaders[0]->type() == ST_vertex &&
2320  _shaders[1]->type() == ST_fragment &&
2321  _shaders[2]->type() == ST_geometry);
2322 
2323  // Check what textures the material has
2324  bool Dm = mat->hasTextureType(TT_diffuse);
2325  GLint billboardType = mat->ps()->billboardType(); // Billboard type (0 -> default; 1 -> vertical billboard, 2 -> horizontal billboard)
2326  bool rot = mat->ps()->doRotation(); // Rotation
2327  bool AlOvLi = mat->ps()->doAlphaOverLT(); // Alpha over life
2328  bool Co = mat->ps()->doColor(); // Color over life
2329  bool CoOvLi = mat->ps()->doColorOverLT(); // Color over life
2330  bool AlOvLiCu = mat->ps()->doAlphaOverLTCurve(); // Alpha over life curve
2331  bool SiOvLi = mat->ps()->doSizeOverLT(); // Size over life
2332  bool SiOvLiCu = mat->ps()->doSizeOverLTCurve(); // Size over life curve
2333  bool FlBoTex = mat->ps()->doFlipBookTexture(); // Flipbook texture
2334 
2335  //////////////////////////////
2336  // Assemble vertex shader code
2337  //////////////////////////////
2338 
2339  string vertCode;
2340  vertCode += shaderHeader();
2341 
2342  // Vertex shader inputs
2343  vertCode += vertInput_PS_a_p;
2344  vertCode += vertInput_PS_a_st;
2345  if (rot) vertCode += vertInput_PS_a_r;
2346  if (FlBoTex) vertCode += vertInput_PS_a_texNum;
2347 
2348  // Vertex shader uniforms
2349  vertCode += vertInput_PS_u_time;
2350  vertCode += vertInput_u_matrix_vOmv;
2351  if (AlOvLi && AlOvLiCu) vertCode += vertInput_PS_u_al_bernstein_alpha;
2352  if (SiOvLi && SiOvLiCu) vertCode += vertInput_PS_u_al_bernstein_size;
2353  if (Co && CoOvLi) vertCode += vertInput_PS_u_colorOvLF;
2354 
2355  // Vertex shader outputs
2356  vertCode += vertOutput_PS_struct_Begin;
2357  vertCode += vertOutput_PS_struct_t;
2358  if (rot) vertCode += vertOutput_PS_struct_r;
2359  if (SiOvLi) vertCode += vertOutput_PS_struct_s;
2360  if (Co && CoOvLi) vertCode += vertOutput_PS_struct_c;
2361  if (FlBoTex) vertCode += vertOutput_PS_struct_texNum;
2362  vertCode += vertOutput_PS_struct_End;
2363 
2364  // Vertex shader functions
2365  if (Co && CoOvLi) vertCode += vertFunction_PS_ColorOverLT;
2366 
2367  // Vertex shader main loop
2368  vertCode += main_Begin;
2369  vertCode += vertMain_PS_v_a;
2370  if (AlOvLi)
2371  vertCode += vertMain_PS_v_t_begin;
2372  else
2373  vertCode += vertMain_PS_v_t_default;
2374 
2375  if (AlOvLi) vertCode += AlOvLiCu ? vertMain_PS_v_t_curve : vertMain_PS_v_t_linear;
2376  if (AlOvLi) vertCode += vertMain_PS_v_t_end;
2377  if (rot) vertCode += vertMain_PS_v_r;
2378  if (SiOvLi) vertCode += vertMain_PS_v_s;
2379  if (SiOvLi && SiOvLiCu) vertCode += vertMain_PS_v_s_curve;
2380  if (Co && CoOvLi) vertCode += vertMain_PS_v_doColorOverLT;
2381  if (FlBoTex) vertCode += vertMain_PS_v_texNum;
2382  if (billboardType == BT_Vertical || billboardType == BT_Horizontal)
2384  else
2385  vertCode += vertMain_PS_EndAll;
2386 
2387  addCodeToShader(_shaders[0], vertCode, _name + ".vert");
2388 
2389  ////////////////////////////////
2390  // Assemble geometry shader code
2391  ////////////////////////////////
2392 
2393  string geomCode;
2394  geomCode += shaderHeader();
2395 
2396  // geometry shader inputs
2397  geomCode += geomConfig_PS;
2398 
2399  geomCode += geomInput_PS_struct_Begin;
2400  geomCode += geomInput_PS_struct_t;
2401  if (rot) geomCode += geomInput_PS_struct_r;
2402  if (SiOvLi) geomCode += geomInput_PS_struct_s;
2403  if (Co && CoOvLi) geomCode += geomInput_PS_struct_c;
2404  if (FlBoTex) geomCode += geomInput_PS_struct_texNum;
2405  geomCode += geomInput_PS_struct_End;
2406 
2407  // geometry shader uniforms
2408  geomCode += geomInput_PS_u_ScaRa;
2409  if (Co && !CoOvLi) geomCode += geomInput_PS_u_c;
2410  if (FlBoTex) geomCode += geomInput_PS_u_col;
2411  if (FlBoTex) geomCode += geomInput_PS_u_row;
2412  geomCode += geomInput_u_matrix_p;
2413  if (billboardType == BT_Vertical)
2415  else if (billboardType == BT_Horizontal)
2416  geomCode += vertInput_u_matrix_vOmv;
2417 
2418  // geometry shader outputs
2419  geomCode += geomOutput_PS_v_pC;
2420  geomCode += geomOutput_PS_v_tC;
2421 
2422  // geometry shader main loop
2423  geomCode += main_Begin;
2424  geomCode += geomMain_PS_v_s;
2425  if (SiOvLi) geomCode += geomMain_PS_v_sS;
2426  geomCode += geomMain_PS_v_rad;
2427  geomCode += geomMain_PS_v_p;
2428  geomCode += rot ? geomMain_PS_v_rot : geomMain_PS_v_rotIden;
2429  geomCode += Co && CoOvLi ? geomMain_PS_v_doColorOverLT : Co ? geomMain_PS_v_c
2431  geomCode += geomMain_PS_v_cT;
2432  if (billboardType == BT_Vertical)
2434  else if (billboardType == BT_Horizontal)
2436  else
2438 
2439  geomCode += geomMain_PS_EndAll;
2440 
2441  addCodeToShader(_shaders[2], geomCode, _name + ".geom");
2442 
2443  ////////////////////////////////
2444  // Assemble fragment shader code
2445  ////////////////////////////////
2446 
2447  string fragCode;
2448  fragCode += shaderHeader();
2449 
2450  // Fragment shader inputs
2451  fragCode += fragInput_PS_v_pC;
2452  fragCode += fragInput_PS_v_tC;
2453 
2454  // Fragment shader uniforms
2455  if (Dm) fragCode += fragInput_u_matTexDm;
2456  fragCode += fragInput_PS_u_overG;
2457  fragCode += fragInput_PS_u_wireFrame;
2458 
2459  // Fragment shader outputs
2460  fragCode += fragOutputs_o_fragColor;
2461 
2462  // Fragment shader main loop
2463  fragCode += main_Begin;
2464  fragCode += Co ? fragMain_PS : fragMain_PS_withoutColor;
2465  fragCode += fragMain_PS_endAll;
2466 
2467  addCodeToShader(_shaders[1], fragCode, _name + ".frag");
2468 }
@ ST_geometry
Definition: SLEnums.h:226
@ BT_Horizontal
Definition: SLEnums.h:274
@ BT_Vertical
Definition: SLEnums.h:273
const string geomMain_PS_fourCorners_horizBillboard
const string geomMain_PS_Flipbook_fourCorners
const string fragInput_PS_u_wireFrame
const string geomMain_PS_v_rot
const string geomInput_PS_u_ScaRa
const string vertOutput_PS_struct_Begin
const string vertMain_PS_v_texNum
const string geomInput_u_matrix_vertBillboard
const string fragInput_PS_v_pC
const string geomInput_PS_u_row
const string geomInput_PS_struct_s
const string geomInput_PS_struct_t
const string geomInput_PS_struct_texNum
const string vertMain_PS_EndAll
const string fragMain_PS_withoutColor
const string vertInput_PS_u_time
const string geomInput_PS_u_col
const string geomMain_PS_EndAll
const string vertInput_PS_u_al_bernstein_size
const string geomOutput_PS_v_pC
const string vertMain_PS_v_t_end
const string vertInput_PS_a_p
const string vertFunction_PS_ColorOverLT
const string geomMain_PS_fourCorners_vertBillboard
const string geomInput_PS_struct_r
const string fragMain_PS_endAll
const string vertMain_PS_v_t_curve
const string vertOutput_PS_struct_texNum
const string vertMain_PS_v_t_default
const string vertInput_PS_a_texNum
const string geomMain_PS_fourCorners
const string vertOutput_PS_struct_c
const string vertInput_u_matrix_vOmv
const string vertMain_PS_EndAll_VertBillboard
const string geomMain_PS_v_withoutColor
const string vertInput_PS_u_colorOvLF
const string geomOutput_PS_v_tC
const string geomInput_u_matrix_p
const string geomMain_PS_v_p
const string geomConfig_PS
const string vertMain_PS_v_t_linear
const string geomMain_PS_v_cT
const string geomInput_PS_struct_Begin
const string fragInput_PS_u_overG
const string vertOutput_PS_struct_s
const string vertMain_PS_v_s_curve
const string vertOutput_PS_struct_End
const string geomMain_PS_v_doColorOverLT
const string vertInput_PS_a_st
const string geomInput_PS_struct_c
const string vertOutput_PS_struct_t
const string fragMain_PS
const string geomMain_PS_Flipbook_fourCorners_horizBillboard
const string vertMain_PS_v_a
const string geomMain_PS_v_c
const string geomInput_PS_u_c
const string geomMain_PS_v_sS
const string vertMain_PS_v_doColorOverLT
const string vertInput_PS_u_al_bernstein_alpha
const string geomMain_PS_v_s
const string vertOutput_PS_struct_r
const string vertMain_PS_v_t_begin
const string fragInput_PS_v_tC
const string vertMain_PS_v_s
const string vertInput_PS_a_r
const string geomMain_PS_v_rad
const string vertMain_PS_v_r
const string geomMain_PS_v_rotIden
const string geomInput_PS_struct_End
const string geomMain_PS_Flipbook_fourCorners_vertBillboard
void ps(SLParticleSystem *ps)
Definition: SLMaterial.h:208

◆ buildPerPixParticleInstanced()

void SLGLProgramGenerated::buildPerPixParticleInstanced ( SLMaterial mat)
private

Definition at line 2182 of file SLGLProgramGenerated.cpp.

2183 {
2184  assert(_shaders.size() == 2 &&
2185  _shaders[0]->type() == ST_vertex &&
2186  _shaders[1]->type() == ST_fragment);
2187 
2188  // Check what textures the material has
2189  bool Dm = mat->hasTextureType(TT_diffuse);
2190  GLint billboardType = mat->ps()->billboardType(); // Billboard type (0 -> default; 1 -> vertical billboard, 2 -> horizontal billboard)
2191  bool rot = mat->ps()->doRotation(); // Rotation
2192  bool AlOvLi = mat->ps()->doAlphaOverLT(); // Alpha over life
2193  bool Co = mat->ps()->doColor(); // Color over life
2194  bool CoOvLi = mat->ps()->doColorOverLT(); // Color over life
2195  bool AlOvLiCu = mat->ps()->doAlphaOverLTCurve(); // Alpha over life curve
2196  bool SiOvLi = mat->ps()->doSizeOverLT(); // Size over life
2197  bool SiOvLiCu = mat->ps()->doSizeOverLTCurve(); // Size over life curve
2198  bool FlBoTex = mat->ps()->doFlipBookTexture(); // Flipbook texture
2199 
2200  //////////////////////////////
2201  // Assemble vertex shader code
2202  //////////////////////////////
2203 
2204  string vertCode;
2205  vertCode += shaderHeader();
2206 
2207  // Vertex shader inputs
2208  vertCode += vertInput_PS_a_InstPos; // instance position
2209  vertCode += vertInput_PS_a_p; // position
2210  vertCode += vertInput_PS_a_st; // start time
2211  if (rot) vertCode += vertInput_PS_a_r; // rotation as float
2212 
2213  if (FlBoTex)
2214  {
2215  vertCode += vertInput_PS_a_texNum; // per particle texture number
2216  vertCode += vertInput_PS_u_col;
2217  vertCode += vertInput_PS_u_row;
2218  }
2219 
2220  // Vertex shader uniforms
2221  vertCode += vertInput_PS_u_ScaRa;
2222  vertCode += vertInput_u_matrix_p;
2223  vertCode += vertInput_PS_u_time;
2224 
2225  if (billboardType == BT_Vertical)
2227 
2228  vertCode += vertInput_u_matrix_vOmv;
2229 
2230  if (AlOvLi && AlOvLiCu) vertCode += vertInput_PS_u_al_bernstein_alpha;
2231  if (SiOvLi && SiOvLiCu) vertCode += vertInput_PS_u_al_bernstein_size;
2232 
2233  // Vertex shader outputs
2235  vertCode += vertOutput_PS_v_tC;
2236 
2237  if (CoOvLi) vertCode += vertOutput_PS_age;
2238 
2239  // Vertex shader main loop
2240  vertCode += main_Begin;
2241  vertCode += vertMain_PS_instanced_position;
2242  vertCode += vertMain_PS_v_a;
2243  if (FlBoTex)
2244  vertCode += vertMain_PS_v_tC_flipbook;
2245  else
2246  vertCode += vertMain_PS_v_tC;
2247 
2248  if (AlOvLi)
2249  vertCode += vertMain_PS_instanced_v_t_begin;
2250  else
2252  if (AlOvLi) vertCode += AlOvLiCu ? vertMain_PS_instanced_v_t_curve : vertMain_PS_instanced_v_t_linear;
2253  if (AlOvLi) vertCode += vertMain_PS_v_t_end;
2254  vertCode += vertMain_PS_instanced_scale;
2255  if (SiOvLi) vertCode += vertMain_PS_instanced_v_s;
2256  if (SiOvLi && SiOvLiCu) vertCode += vertMain_PS_instanced_v_s_curve;
2257  if (SiOvLi) vertCode += vertMain_PS_instanced_v_sS;
2258  if (rot) vertCode += vertMain_PS_instanced_rotate;
2259  if (CoOvLi) vertCode += vertMain_PS_v_age;
2260 
2261  if (billboardType == BT_Vertical || billboardType == BT_Horizontal)
2263  else
2264  vertCode += vertMain_PS_instanced_EndAll;
2265 
2266  addCodeToShader(_shaders[0], vertCode, _name + ".vert");
2267 
2268  ////////////////////////////////
2269  // Assemble fragment shader code
2270  ////////////////////////////////
2271 
2272  string fragCode;
2273  fragCode += shaderHeader();
2274 
2275  // Fragment shader inputs
2276  fragCode += fragInput_PS_v_tC;
2277  if (Co && !CoOvLi) fragCode += fragInput_PS_u_c;
2278  if (CoOvLi)
2279  {
2280  fragCode += fragInput_PS_u_tTL;
2281  fragCode += fragInput_PS_age;
2282  fragCode += fragInput_PS_u_colorOvLF;
2283  }
2285 
2286  // Fragment shader uniforms
2287  if (Dm) fragCode += fragInput_u_matTexDm;
2288  fragCode += fragInput_PS_u_overG;
2289  fragCode += fragInput_PS_u_wireFrame;
2290 
2291  // Fragment shader outputs
2292  fragCode += fragOutputs_o_fragColor;
2293 
2294  if (CoOvLi) fragCode += fragFunction_PS_ColorOverLT;
2295 
2296  // Fragment shader main loop
2297  fragCode += main_Begin;
2298 
2299  if (Co && !CoOvLi) fragCode += fragMain_PS_instanced_c;
2300 
2301  if (CoOvLi) fragCode += fragMain_PS_instanced_v_doColorOverLT;
2302 
2303  if (Co || CoOvLi)
2304  {
2306  fragCode += fragMain_instanced_PS_end;
2307  }
2308  else
2310 
2311  fragCode += fragMain_PS_endAll;
2312 
2313  addCodeToShader(_shaders[1], fragCode, _name + ".frag");
2314 }
const string vertMain_PS_instanced_v_t_begin
const string vertMain_PS_v_age
const string vertInput_PS_u_row
const string vertMain_PS_instanced_v_s_curve
const string fragInput_PS_age
const string vertMain_PS_instanced_EndAll
const string vertMain_PS_instanced_v_sS
const string vertInput_PS_u_ScaRa
const string fragInput_PS_u_c
const string vertMain_PS_instanced_v_t_curve
const string fragInput_PS_u_colorOvLF
const string fragInput_PS_u_tTL
const string fragMain_PS_instanced_transparency
const string vertMain_PS_instanced_v_t_linear
const string vertMain_PS_instanced_rotate
const string vertMain_PS_instanced_v_t_default
const string vertInput_u_matrix_p
const string fragMain_instanced_PS_end
const string fragFunction_PS_ColorOverLT
const string fragMain_PS_instanced_c
const string vertOutput_PS_age
const string vertInput_PS_u_col
const string vertMain_PS_instanced_v_s
const string vertMain_PS_instanced_EndAll_VertBillboard
const string vertOutput_PS_v_tC
const string vertMain_PS_v_tC
const string vertMain_PS_instanced_position
const string vertMain_PS_v_tC_flipbook
const string vertInput_u_matrix_vertBillboard
const string fragMain_PS_instanced_withoutColor
const string vertMain_PS_instanced_scale
const string fragInput_PS_instanced_transparency
const string vertInput_PS_a_InstPos
const string fragMain_PS_instanced_v_doColorOverLT
const string vertOutput_PS_instanced_transparency

◆ buildPerPixParticleUpdate()

void SLGLProgramGenerated::buildPerPixParticleUpdate ( SLMaterial mat)
private

Definition at line 2470 of file SLGLProgramGenerated.cpp.

2471 {
2472  assert(_shaders.size() > 1 &&
2473  _shaders[0]->type() == ST_vertex &&
2474  _shaders[1]->type() == ST_fragment);
2475 
2476  bool counterGap = mat->ps()->doCounterGap(); // Counter gap/lag
2477  bool acc = mat->ps()->doAcc(); // Acceleration
2478  bool accDiffDir = mat->ps()->doAccDiffDir(); // Acceleration different direction
2479  bool gravity = mat->ps()->doGravity(); // Gravity
2480  bool FlBoTex = mat->ps()->doFlipBookTexture(); // Flipbook texture
2481  bool rot = mat->ps()->doRotation(); // Rotation
2482  bool rotRange = mat->ps()->doRotRange(); // Rotation range
2483  bool shape = mat->ps()->doShape(); // Shape
2484 
2485  string vertCode;
2486  vertCode += shaderHeader();
2487 
2488  // Vertex shader inputs
2489  vertCode += vertInput_PS_a_p;
2490  vertCode += vertInput_PS_a_v;
2491  vertCode += vertInput_PS_a_st;
2492  if (acc || gravity) vertCode += vertInput_PS_a_initV;
2493  if (rot) vertCode += vertInput_PS_a_r;
2494  if (rot && rotRange) vertCode += vertInput_PS_a_r_angularVelo;
2495  if (FlBoTex) vertCode += vertInput_PS_a_texNum;
2496  if (shape) vertCode += vertInput_PS_a_initP;
2497 
2498  // Vertex shader uniforms
2499  vertCode += vertInput_PS_u_time;
2500  vertCode += vertInput_PS_u_deltaTime;
2501  vertCode += vertInput_PS_u_pgPos;
2502  if (rot && !rotRange) vertCode += vertInput_PS_u_angularVelo;
2503  if (acc) vertCode += accDiffDir ? vertInput_PS_u_a_diffDir : vertInput_PS_u_a_const;
2504  if (gravity) vertCode += vertInput_PS_u_g;
2505  if (FlBoTex) vertCode += vertInput_PS_u_col;
2506  if (FlBoTex) vertCode += vertInput_PS_u_row;
2507  if (FlBoTex) vertCode += vertInput_PS_u_condFB;
2508 
2509  // Vertex shader outputs
2510  vertCode += vertOutput_PS_tf_p;
2511  vertCode += vertOutput_PS_tf_v;
2512  vertCode += vertOutput_PS_tf_st;
2513  if (acc || gravity) vertCode += vertOutput_PS_tf_initV;
2514  if (rot) vertCode += vertOutput_PS_tf_r;
2515  if (rot && rotRange) vertCode += vertOutput_PS_tf_r_angularVelo;
2516  if (FlBoTex) vertCode += vertOutput_PS_tf_texNum;
2517  if (shape) vertCode += vertOutput_PS_tf_initP;
2518 
2519  if (rot) vertCode += vertConstant_PS_pi; // Add constant PI
2520 
2521  // Vertex shader main loop
2522  vertCode += main_Begin;
2523  vertCode += vertMain_PS_U_Begin;
2524  vertCode += vertMain_PS_U_v_init_p;
2525  vertCode += vertMain_PS_U_v_init_v;
2526  vertCode += vertMain_PS_U_v_init_st;
2527  if (acc || gravity) vertCode += vertMain_PS_U_v_init_initV;
2528  if (rot) vertCode += vertMain_PS_U_v_init_r;
2529  if (rot && rotRange) vertCode += vertMain_PS_U_v_init_r_angularVelo;
2530  if (FlBoTex) vertCode += vertMain_PS_U_v_init_texNum;
2531  if (shape) vertCode += vertMain_PS_U_v_init_initP;
2532  vertCode += vertMain_PS_U_bornDead;
2533  vertCode += shape ? vertMain_PS_U_reset_shape_p : vertMain_PS_U_reset_p;
2534  if (acc || gravity) vertCode += vertMain_PS_U_reset_v;
2535  vertCode += counterGap ? vertMain_PS_U_reset_st_counterGap : vertMain_PS_U_reset_st;
2536  vertCode += vertMain_PS_U_alive_p;
2537  if (rot) vertCode += rotRange ? vertMain_PS_U_v_rRange : vertMain_PS_U_v_rConst;
2538  if (FlBoTex) vertCode += vertMain_PS_U_alive_texNum;
2539  if (acc) vertCode += accDiffDir ? vertMain_PS_U_alive_a_diffDir : vertMain_PS_U_alive_a_const;
2540  if (gravity) vertCode += vertMain_PS_U_alive_g;
2541  vertCode += vertMain_PS_U_EndAll;
2542 
2543  addCodeToShader(_shaders[0], vertCode, _name + ".vert");
2544 
2545  // Assemble fragment shader code
2546  string fragCode;
2547  fragCode += shaderHeader();
2548 
2549  // Fragment shader inputs
2550  fragCode += fragOutputs_o_fragColor;
2551  fragCode += main_Begin;
2552  fragCode += fragMain_PS_TF;
2553 
2554  addCodeToShader(_shaders[1], fragCode, _name + ".frag");
2555 }
const string vertOutput_PS_tf_initP
const string vertInput_PS_a_v
const string vertMain_PS_U_reset_v
const string vertInput_PS_u_g
const string vertMain_PS_U_v_rRange
const string vertMain_PS_U_reset_shape_p
const string vertMain_PS_U_v_init_v
const string vertMain_PS_U_alive_a_const
const string vertMain_PS_U_v_init_st
const string vertMain_PS_U_EndAll
const string vertMain_PS_U_reset_st
const string vertMain_PS_U_v_init_texNum
const string vertMain_PS_U_Begin
const string vertInput_PS_a_initP
const string vertInput_PS_u_deltaTime
const string vertOutput_PS_tf_r
const string vertMain_PS_U_v_init_r
const string vertInput_PS_u_a_diffDir
const string vertInput_PS_u_pgPos
const string vertMain_PS_U_v_init_r_angularVelo
const string vertInput_PS_u_angularVelo
const string vertMain_PS_U_reset_p
const string vertMain_PS_U_alive_g
const string vertOutput_PS_tf_p
const string vertInput_PS_u_condFB
const string vertOutput_PS_tf_st
const string vertConstant_PS_pi
const string vertInput_PS_u_a_const
const string vertOutput_PS_tf_r_angularVelo
const string vertInput_PS_a_r_angularVelo
const string vertMain_PS_U_alive_a_diffDir
const string vertInput_PS_a_initV
const string vertOutput_PS_tf_v
const string vertOutput_PS_tf_texNum
const string vertMain_PS_U_alive_texNum
const string vertMain_PS_U_v_init_initP
const string vertMain_PS_U_v_init_initV
const string vertMain_PS_U_alive_p
const string vertMain_PS_U_v_init_p
const string vertMain_PS_U_bornDead
const string vertMain_PS_U_v_rConst
const string vertOutput_PS_tf_initV
const string vertMain_PS_U_reset_st_counterGap
const string fragMain_PS_TF

◆ buildPerPixVideoBkgdSm()

void SLGLProgramGenerated::buildPerPixVideoBkgdSm ( SLVLight lights)
private

Assemble shaders for video on background.

Definition at line 2558 of file SLGLProgramGenerated.cpp.

2559 {
2560  assert(_shaders.size() > 1 &&
2561  _shaders[0]->type() == ST_vertex &&
2562  _shaders[1]->type() == ST_fragment);
2563 
2564  // Assemble vertex shader code
2565  string vertCode;
2566  vertCode += shaderHeader((int)lights->size());
2567  vertCode += vertInput_a_pn;
2568  vertCode += vertInput_u_matrices_all;
2569  vertCode += vertOutput_v_P_VS;
2570  vertCode += vertOutput_v_P_WS;
2571  vertCode += vertOutput_v_N_VS;
2572  vertCode += main_Begin;
2573  vertCode += vertMain_v_P_VS;
2574  vertCode += vertMain_v_P_WS_Sm;
2575  vertCode += vertMain_v_N_VS;
2576  vertCode += vertMain_EndAll;
2577 
2578  // Vertex shader variables
2579  setVariable(vertCode, "localPosition", "a_position");
2580  setVariable(vertCode, "localNormal", "a_normal");
2581 
2582  addCodeToShader(_shaders[0], vertCode, _name + ".vert");
2583 
2584  // Assemble fragment shader code
2585  string fragCode;
2586  fragCode += shaderHeader((int)lights->size());
2587  fragCode += R"(
2588 in vec3 v_P_VS; // Interpol. point of illumination in view space (VS)
2589 in vec3 v_P_WS; // Interpol. point of illumination in world space (WS)
2590 in vec3 v_N_VS; // Interpol. normal at v_P_VS in view space
2591 )";
2592  fragCode += fragInput_u_lightAll;
2593  fragCode += fragInput_u_lightSm(lights);
2594  fragCode += fragInput_u_cam;
2595  fragCode += fragInput_u_matAmbi;
2596  fragCode += fragInput_u_matTexDm;
2597  fragCode += fragInput_u_matGetsSm;
2598  fragCode += fragInput_u_shadowMaps(lights);
2599  fragCode += fragOutputs_o_fragColor;
2600  fragCode += fragFunctionFogBlend;
2601  fragCode += fragFunctionDoStereoSeparation;
2602  fragCode += fragFunctionShadowTest(lights);
2603  fragCode += fragFunctionDoColoredShadows;
2604  fragCode += main_Begin;
2605  fragCode += fragMainVideoBkgd;
2606  fragCode += fragMain_5_FogGammaStereo;
2607  addCodeToShader(_shaders[1], fragCode, _name + ".frag");
2608 }
const string fragMainVideoBkgd
const string fragInput_u_matAmbi

◆ buildProgramCode()

void SLGLProgramGenerated::buildProgramCode ( SLMaterial mat,
SLVLight lights,
SLbool  supportGPUSkinning 
)

Builds the GLSL program code for the vertex and fragment shaders. The code is only assembled but not compiled and linked. This happens within the before the first draw call from within SLMesh::draw.

Parameters
matParent material pointer
lightsPointer of vector of lights

Definition at line 1863 of file SLGLProgramGenerated.cpp.

1866 {
1867  assert(mat && "No material pointer passed!");
1868  assert(!lights->empty() && "No lights passed!");
1869  assert(_shaders.size() > 1 &&
1870  _shaders[0]->type() == ST_vertex &&
1871  _shaders[1]->type() == ST_fragment);
1872 
1873  // Check what textures the material has
1874  bool Dm = mat->hasTextureType(TT_diffuse); // Texture Mapping
1875  bool Nm = mat->hasTextureType(TT_normal); // Normal Mapping
1876  bool Hm = mat->hasTextureType(TT_height); // Height Mapping
1877  bool Om = mat->hasTextureType(TT_occlusion); // Ambient Occlusion Mapping
1878  bool Vm = mat->hasTextureType(TT_videoBkgd); // Video Background Mapping
1879  bool env = mat->skybox() != nullptr; // Environment Mapping from skybox
1880 
1881  // Check if any of the scene lights does shadow mapping
1882  bool Sm = lightsDoShadowMapping(lights);
1883 
1884  if (mat->reflectionModel() == RM_BlinnPhong)
1885  {
1886  buildPerPixBlinn(mat, lights, supportGPUSkinning);
1887  }
1888  else if (mat->reflectionModel() == RM_CookTorrance)
1889  {
1890  buildPerPixCook(mat, lights, supportGPUSkinning);
1891  }
1892  else if (mat->reflectionModel() == RM_Custom)
1893  {
1894  if (Vm && Sm)
1895  buildPerPixVideoBkgdSm(lights);
1896  else
1897  SL_EXIT_MSG("SLGLProgramGenerated::buildProgramCode: Unknown program for RM_Custom.");
1898  }
1899  else
1900  SL_EXIT_MSG("SLGLProgramGenerated::buildProgramCode: Unknown Lighting Model.");
1901 }
@ RM_BlinnPhong
Definition: SLEnums.h:289
@ RM_Custom
Definition: SLEnums.h:292
@ RM_CookTorrance
Definition: SLEnums.h:290
void buildPerPixCook(SLMaterial *mat, SLVLight *lights, SLbool supportGPUSkinning)
void buildPerPixBlinn(SLMaterial *mat, SLVLight *lights, SLbool supportGPUSkinning)
void buildPerPixVideoBkgdSm(SLVLight *lights)
Assemble shaders for video on background.
void reflectionModel(SLReflectionModel rm)
Definition: SLMaterial.h:169

◆ buildProgramCodePS()

void SLGLProgramGenerated::buildProgramCodePS ( SLMaterial mat,
bool  isDrawProg,
bool  drawInstanced = false 
)

Builds the GLSL program code for the vertex, geometry and fragment shaders (for particle system drawing). The code is only assembled but not compiled and linked. This happens within the before the first draw call from within SLMesh::draw.

Parameters
matParent material pointer
isDrawProgFlag if program is for drawing instead of update

Definition at line 1909 of file SLGLProgramGenerated.cpp.

1912 {
1913  if (mat->name() == "IBLMat")
1914  {
1915  std::cout << "build program code for IBLMat" << std::endl;
1916  }
1917  assert(mat && "No material pointer passed!");
1918  assert(_shaders.size() > 1 &&
1919  _shaders[0]->type() == ST_vertex &&
1920  _shaders[1]->type() == ST_fragment);
1921 
1922  if (isDrawProg)
1923  {
1924  if (drawInstanced)
1926  else
1927  buildPerPixParticle(mat);
1928  }
1929  else
1931 }
void buildPerPixParticleUpdate(SLMaterial *mat)
void buildPerPixParticle(SLMaterial *mat)
void buildPerPixParticleInstanced(SLMaterial *mat)

◆ buildProgramName()

void SLGLProgramGenerated::buildProgramName ( SLMaterial mat,
SLVLight lights,
SLbool  supportGPUSkinning,
string &  programName 
)
static

Builds unique program name that identifies shader program.

See the class information for more insights of the generated name. This function is used in advance of the code generation to check if the program already exists in the asset manager. See SLMaterial::activate.

Parameters
matParent material pointer
lightsPointer of vector of lights
programNameReference to program name string that gets built

The shader program gets a unique name with the following pattern:

genCook-D00-N00-E00-O01-RM00-Sky-C4s-S
   |    |   |   |   |   |    |   |   |
   |    |   |   |   |   |    |   |   + Support for GPU skinning
   |    |   |   |   |   |    |   + Directional light w. 4 shadow cascades
   |    |   |   |   |   |    + Ambient light from skybox
   |    |   |   |   |   + Roughness-metallic map with index 0 and uv 0
   |    |   |   |   + Ambient Occlusion map with index 0 and uv 1
   |    |   |   + Emissive Map with index 0 and uv 0
   |    |   + Normal Map with index 0 and uv 0
   |    + Diffuse Texture Mapping with index 0 and uv 0
   + Cook-Torrance or Blinn-Phong reflection model

Definition at line 1724 of file SLGLProgramGenerated.cpp.

1728 {
1729  assert(mat && "No material pointer passed!");
1730  assert(lights && !lights->empty() && "No lights passed!");
1731 
1732  programName = "gen";
1733 
1734  if (mat->hasTextureType(TT_videoBkgd))
1735  programName += "VideoBkgdDm";
1736  else if (mat->reflectionModel() == RM_BlinnPhong)
1737  programName += "Blinn";
1738  else if (mat->reflectionModel() == RM_CookTorrance)
1739  programName += "Cook";
1740  else
1741  programName += "Custom";
1742 
1743  programName += mat->texturesString();
1744  programName += "-";
1745 
1746  // Add letter per light type
1747  for (auto light : *lights)
1748  {
1749  if (light->positionWS().w == 0.0f)
1750  {
1751  if (light->doCascadedShadows())
1752  programName += "C" + std::to_string(light->shadowMap()->numCascades()); // Directional light with cascaded shadowmap
1753  else
1754  programName += "D"; // Directional light
1755  }
1756  else if (light->spotCutOffDEG() < 180.0f)
1757  programName += "S"; // Spotlight
1758  else
1759  programName += "P"; // Pointlight
1760  if (light->createsShadows())
1761  programName += "s"; // Creates shadows
1762  }
1763 
1764  if (supportGPUSkinning)
1765  programName += "-S";
1766 }
SLstring texturesString()
Returns a unique string that represent all textures used.
Definition: SLMaterial.cpp:687

◆ buildProgramNamePS()

void SLGLProgramGenerated::buildProgramNamePS ( SLMaterial mat,
string &  programName,
bool  isDrawProg,
bool  drawInstanced 
)
static

See the class information for more insights of the generated name. This function is used in advance of the code generation to check if the program already exists in the asset manager. See SLMaterial::activate.

Parameters
matParent material pointer
programNameReference to program name string that gets built
isDrawProgFlag if program is for drawing instead of updating

The shader program gets a unique name with the following pattern:

genCook-D00-N00-E00-O01-RM00-Sky-C4s
   |    |   |   |   |   |    |   |
   |    |   |   |   |   |    |   + Directional light w. 4 shadow cascades
   |    |   |   |   |   |    + Ambient light from skybox
   |    |   |   |   |   + Roughness-metallic map with index 0 and uv 0
   |    |   |   |   + Ambient Occlusion map with index 0 and uv 1
   |    |   |   + Emissive Map with index 0 and uv 0
   |    |   + Normal Map with index 0 and uv 0
   |    + Diffuse Texture Mapping with index 0 and uv 0
   + Cook-Torrance or Blinn-Phong reflection model

Definition at line 1789 of file SLGLProgramGenerated.cpp.

1793 {
1794  assert(mat && "No material pointer passed!");
1795  programName = "gen";
1796 
1797  if (mat->reflectionModel() == RM_Particle)
1798  programName += "Particle";
1799  else
1800  programName += "Custom";
1801 
1802  // programName += "-";
1803  if (isDrawProg) // Drawing program
1804  {
1805  programName += "-Draw";
1806 
1807  if (drawInstanced)
1808  programName += "-Inst";
1809 
1810  programName += mat->texturesString();
1811  GLint billboardType = mat->ps()->billboardType(); // Billboard type (0 -> default; 1 -> vertical billboard, 2 -> horizontal billboard)
1812  bool AlOvLi = mat->ps()->doAlphaOverLT(); // Alpha over life
1813  bool AlOvLiCu = mat->ps()->doAlphaOverLTCurve(); // Alpha over life curve
1814  bool SiOvLi = mat->ps()->doSizeOverLT(); // Size over life
1815  bool SiOvLiCu = mat->ps()->doSizeOverLTCurve(); // Size over life curve
1816  bool Co = mat->ps()->doColor(); // Color over life
1817  bool CoOvLi = mat->ps()->doColorOverLT(); // Color over life
1818  bool FlBoTex = mat->ps()->doFlipBookTexture(); // Flipbook texture
1819  bool WS = mat->ps()->doWorldSpace(); // World space or local space
1820  bool rot = mat->ps()->doRotation(); // Rotation
1821  programName += "-B" + std::to_string(billboardType);
1822  if (rot) programName += "-RT";
1823  if (AlOvLi) programName += "-AL";
1824  if (AlOvLi && AlOvLiCu) programName += "cu";
1825  if (SiOvLi) programName += "-SL";
1826  if (SiOvLi && SiOvLiCu) programName += "cu";
1827  if (Co) programName += "-CO";
1828  if (Co && CoOvLi) programName += "cl";
1829  if (FlBoTex) programName += "-FB";
1830  if (WS) programName += "-WS";
1831  }
1832  else // Updating program
1833  {
1834  bool counterGap = mat->ps()->doCounterGap(); // Counter gap/lag
1835  bool acc = mat->ps()->doAcc(); // Acceleration
1836  bool accDiffDir = mat->ps()->doAccDiffDir(); // Acceleration different direction
1837  bool gravity = mat->ps()->doGravity(); // Gravity
1838  bool FlBoTex = mat->ps()->doFlipBookTexture(); // Flipbook texture
1839  bool rot = mat->ps()->doRotation(); // Rotation
1840  bool rotRange = mat->ps()->doRotRange(); // Rotation range
1841  bool shape = mat->ps()->doShape(); // Shape
1842  programName += "-Update";
1843  if (counterGap) programName += "-CG";
1844  if (rot) programName += "-RT";
1845  if (rot) programName += rotRange ? "ra" : "co";
1846  if (acc)
1847  {
1848  programName += "-AC";
1849  programName += accDiffDir ? "di" : "co";
1850  }
1851  if (gravity) programName += "-GR";
1852  if (FlBoTex) programName += "-FB";
1853  if (shape) programName += "-SH";
1854  }
1855 }
@ RM_Particle
Definition: SLEnums.h:291

◆ endShader()

void SLGLProgramGenerated::endShader ( )
inlineoverridevirtual

Implements SLGLProgram.

Definition at line 115 of file SLGLProgramGenerated.h.

115 { endUse(); }
void endUse()
SLGLProgram::endUse stops the shader program.

◆ fragFunctionShadowTest()

string SLGLProgramGenerated::fragFunctionShadowTest ( SLVLight lights)
staticprivate

Adds the core shadow mapping test routine depending on the lights.

Definition at line 2686 of file SLGLProgramGenerated.cpp.

2687 {
2688  bool doCascadedSM = false;
2689  for (SLLight* light : *lights)
2690  {
2691  if (light->doCascadedShadows())
2692  {
2693  doCascadedSM = true;
2694  break;
2695  }
2696  }
2697 
2698  string shadowTestCode = R"(
2699 //-----------------------------------------------------------------------------
2700 int vectorToFace(vec3 vec) // Vector to process
2701 {
2702  vec3 absVec = abs(vec);
2703  if (absVec.x > absVec.y && absVec.x > absVec.z)
2704  return vec.x > 0.0 ? 0 : 1;
2705  else if (absVec.y > absVec.x && absVec.y > absVec.z)
2706  return vec.y > 0.0 ? 2 : 3;
2707  else
2708  return vec.z > 0.0 ? 4 : 5;
2709 }
2710 //-----------------------------------------------------------------------------
2711 int getCascadesDepthIndex(in int i, int numCascades)
2712 {
2713  float factor;
2714 )";
2715 
2716  for (SLuint i = 0; i < lights->size(); ++i)
2717  {
2718  SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2719  if (shadowMap && shadowMap->useCascaded())
2720  {
2721  shadowTestCode += " if (i == " + std::to_string(i) + ")\n";
2722  shadowTestCode += " {\n";
2723  shadowTestCode += " factor = u_cascadesFactor_" + std::to_string(i) + ";\n";
2724  shadowTestCode += " }\n";
2725  }
2726  }
2727 
2728  shadowTestCode += R"(
2729  float fi = u_camClipNear;
2730  float ni;
2731 
2732  for (int i = 0; i < numCascades-1; i++)
2733  {
2734  ni = fi;
2735  fi = factor * u_camClipNear * pow((u_camClipFar/(factor*u_camClipNear)), float(i+1)/float(numCascades));
2736  if (-v_P_VS.z < fi)
2737  return i;
2738  }
2739  return numCascades-1;
2740 }
2741 //-----------------------------------------------------------------------------
2742 float shadowTest(in int i, in vec3 N, in vec3 lightDir)
2743 {
2744  if (u_lightCreatesShadows[i])
2745  {
2746  // Calculate position in light space
2747  mat4 lightSpace;
2748  vec3 lightToFragment = v_P_WS - u_lightPosWS[i].xyz;
2749 )";
2750 
2751  if (doCascadedSM > 0)
2752  {
2753  shadowTestCode += R"(
2754  int index = 0;
2755 
2756  if (u_lightNumCascades[i] > 0)
2757  {
2758  index = getCascadesDepthIndex(i, u_lightNumCascades[i]);
2759  )";
2760  for (SLuint i = 0; i < lights->size(); ++i)
2761  {
2762  SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2763  if (shadowMap && shadowMap->useCascaded())
2764  shadowTestCode += " if (i == " + std::to_string(i) + ") { lightSpace = u_lightSpace_" + std::to_string(i) + "[index]; }\n";
2765  }
2766  shadowTestCode += R"(
2767  }
2768  else if (u_lightUsesCubemap[i])
2769  {)";
2770  for (SLuint i = 0; i < lights->size(); ++i)
2771  {
2772  SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2773  if (shadowMap && shadowMap->useCubemap())
2774  shadowTestCode += " if (i == " + std::to_string(i) + ") { lightSpace = u_lightSpace_" + std::to_string(i) + "[vectorToFace(lightToFragment)]; }\n";
2775  }
2776  shadowTestCode += R"(
2777  }
2778  else
2779  {
2780  )";
2781  for (SLuint i = 0; i < lights->size(); ++i)
2782  {
2783  SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2784  if (shadowMap && !shadowMap->useCubemap() && !shadowMap->useCascaded())
2785  shadowTestCode += "if (i == " + std::to_string(i) + ") { lightSpace = u_lightSpace_" + std::to_string(i) + "}\n";
2786  }
2787  shadowTestCode += R"(
2788  }
2789  )";
2790  }
2791  else
2792  {
2793  shadowTestCode += R"(
2794  if (u_lightUsesCubemap[i])
2795  {
2796 )";
2797  for (SLuint i = 0; i < lights->size(); ++i)
2798  {
2799  SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2800  if (shadowMap && shadowMap->useCubemap())
2801  shadowTestCode += " if (i == " + std::to_string(i) + ") lightSpace = u_lightSpace_" + std::to_string(i) + "[vectorToFace(lightToFragment)];\n";
2802  }
2803  shadowTestCode += R"(
2804  }
2805  else
2806  {
2807 )";
2808  for (SLuint i = 0; i < lights->size(); ++i)
2809  {
2810  SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2811  if (shadowMap && !shadowMap->useCubemap() && !shadowMap->useCascaded())
2812  shadowTestCode += " if (i == " + std::to_string(i) + ") lightSpace = u_lightSpace_" + std::to_string(i) + ";\n";
2813  }
2814  shadowTestCode += R"(
2815  }
2816  )";
2817  }
2818 
2819  shadowTestCode += R"(
2820  vec4 lightSpacePosition = lightSpace * vec4(v_P_WS, 1.0);
2821 
2822  // Normalize lightSpacePosition
2823  vec3 projCoords = lightSpacePosition.xyz / lightSpacePosition.w;
2824 
2825  // Convert to texture coordinates
2826  projCoords = projCoords * 0.5 + 0.5;
2827 
2828  float currentDepth = projCoords.z;
2829 
2830  // Look up depth from shadow map
2831  float shadow = 0.0;
2832  float closestDepth;
2833 
2834  // calculate bias between min. and max. bias depending on the angle between N and lightDir
2835  float bias = max(u_lightShadowMaxBias[i] * (1.0 - dot(N, lightDir)), u_lightShadowMinBias[i]);
2836 
2837  // Use percentage-closer filtering (PCF) for softer shadows (if enabled)
2838  if (u_lightDoSmoothShadows[i])
2839  {
2840  int level = u_lightSmoothShadowLevel[i];
2841  vec2 texelSize;
2842 )";
2843 
2844  for (SLuint i = 0; i < lights->size(); ++i)
2845  {
2846  SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2847  if (!shadowMap->useCascaded() && !shadowMap->useCubemap())
2848  shadowTestCode += " if (i == " + to_string(i) + ") { texelSize = 1.0 / vec2(textureSize(u_shadowMap_" + to_string(i) + ", 0)); }\n";
2849  else if (shadowMap->useCascaded())
2850  {
2851  shadowTestCode += " if (i == " + to_string(i) + ")\n {\n";
2852  for (int j = 0; j < shadowMap->depthBuffers().size(); j++)
2853  shadowTestCode += " if (index == " + to_string(j) + ") { texelSize = 1.0 / vec2(textureSize(u_cascadedShadowMap_" + to_string(i) + "_" + to_string(j) + ", 0)); }\n";
2854 
2855  shadowTestCode += " }\n";
2856  }
2857  }
2858  shadowTestCode += R"(
2859  for (int x = -level; x <= level; ++x)
2860  {
2861  for (int y = -level; y <= level; ++y)
2862  {
2863  )";
2864  for (SLuint i = 0; i < lights->size(); ++i)
2865  {
2866  SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2867  if (!shadowMap->useCascaded() && !shadowMap->useCubemap())
2868  shadowTestCode += " if (i == " + to_string(i) + ") { closestDepth = texture(u_shadowMap_" + to_string(i) + ", projCoords.xy + vec2(x, y) * texelSize).r; }\n";
2869  else if (shadowMap->useCascaded())
2870  {
2871  shadowTestCode += " if (i == " + to_string(i) + ")\n {\n";
2872  for (int j = 0; j < shadowMap->depthBuffers().size(); j++)
2873  shadowTestCode += " if (index == " + to_string(j) + ") { closestDepth = texture(u_cascadedShadowMap_" + to_string(i) + "_" + to_string(j) + ", projCoords.xy + vec2(x, y) * texelSize).r; }\n";
2874  shadowTestCode += " }\n";
2875  }
2876  }
2877 
2878  shadowTestCode += R"(
2879  shadow += currentDepth - bias > closestDepth ? 1.0 : 0.0;
2880  }
2881  }
2882  shadow /= pow(1.0 + 2.0 * float(level), 2.0);
2883  }
2884  else
2885  {
2886  if (u_lightUsesCubemap[i])
2887  {
2888 )";
2889  for (SLuint i = 0; i < lights->size(); ++i)
2890  {
2891  SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2892  if (shadowMap->useCubemap())
2893  shadowTestCode += " if (i == " + to_string(i) + ") closestDepth = texture(u_shadowMapCube_" + to_string(i) + ", lightToFragment).r;\n";
2894  }
2895  shadowTestCode += R"(
2896  }
2897  else if (u_lightNumCascades[i] > 0)
2898  {
2899 )";
2900  for (SLuint i = 0; i < lights->size(); ++i)
2901  {
2902  SLLight* light = lights->at(i);
2903  SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2904  if (light->doCascadedShadows())
2905  {
2906  shadowTestCode += " if (i == " + to_string(i) + ")\n {\n";
2907  for (int j = 0; j < shadowMap->depthBuffers().size(); j++)
2908  shadowTestCode += " if (index == " + to_string(j) + ") { closestDepth = texture(u_cascadedShadowMap_" + to_string(i) + "_" + to_string(j) + ", projCoords.xy).r; }\n";
2909  shadowTestCode += " }";
2910  }
2911  }
2912 
2913  shadowTestCode += R"(
2914  }
2915  else
2916  {
2917 )";
2918 
2919  for (SLuint i = 0; i < lights->size(); ++i)
2920  {
2921  SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2922  if (!shadowMap->useCubemap() && !shadowMap->useCascaded())
2923  shadowTestCode += " if (i == " + to_string(i) + ") closestDepth = texture(u_shadowMap_" + to_string(i) + ", projCoords.xy).r;\n";
2924  }
2925 
2926  shadowTestCode += R"(
2927  }
2928 
2929  // The fragment is in shadow if the light doesn't "see" it
2930  if (currentDepth > closestDepth + bias)
2931  shadow = 1.0;
2932  }
2933 
2934  return shadow;
2935  }
2936 
2937  return 0.0;
2938 })";
2939 
2940  return shadowTestCode;
2941 }
unsigned int SLuint
Definition: SL.h:171
Abstract Light class for OpenGL light sources.
Definition: SLLight.h:61
virtual SLbool doCascadedShadows() const
Definition: SLLight.h:154
Class for standard and cascaded shadow mapping.
Definition: SLShadowMap.h:39
SLbool useCascaded() const
Definition: SLShadowMap.h:78
SLGLVDepthBuffer depthBuffers()
Definition: SLShadowMap.h:81
void useCubemap(SLbool useCubemap)
Definition: SLShadowMap.h:62

◆ fragInput_u_lightSm()

string SLGLProgramGenerated::fragInput_u_lightSm ( SLVLight lights)
staticprivate

Definition at line 2623 of file SLGLProgramGenerated.cpp.

2624 {
2625  string u_lightSm = R"(
2626 uniform vec4 u_lightPosWS[NUM_LIGHTS]; // position of light in world space
2627 uniform bool u_lightCreatesShadows[NUM_LIGHTS]; // flag if light creates shadows
2628 uniform int u_lightNumCascades[NUM_LIGHTS]; // number of cascades for cascaded shadowmap
2629 uniform bool u_lightDoSmoothShadows[NUM_LIGHTS]; // flag if percentage-closer filtering is enabled
2630 uniform int u_lightSmoothShadowLevel[NUM_LIGHTS]; // radius of area to sample for PCF
2631 uniform float u_lightShadowMinBias[NUM_LIGHTS]; // min. shadow bias value at 0° to N
2632 uniform float u_lightShadowMaxBias[NUM_LIGHTS]; // min. shadow bias value at 90° to N
2633 uniform bool u_lightUsesCubemap[NUM_LIGHTS]; // flag if light has a cube shadow map
2634 uniform bool u_lightsDoColoredShadows; // flag if shadows should be colored
2635 )";
2636  for (SLuint i = 0; i < lights->size(); ++i)
2637  {
2638  SLLight* light = lights->at(i);
2639  if (light->createsShadows())
2640  {
2641  SLShadowMap* shadowMap = light->shadowMap();
2642 
2643  if (shadowMap->useCubemap())
2644  {
2645  u_lightSm += "uniform mat4 u_lightSpace_" + std::to_string(i) + "[6];\n";
2646  }
2647  else if (light->doCascadedShadows())
2648  {
2649  u_lightSm += "uniform mat4 u_lightSpace_" + std::to_string(i) + "[" + std::to_string(shadowMap->numCascades()) + "];\n";
2650  }
2651  else
2652  {
2653  u_lightSm += "uniform mat4 u_lightSpace_" + std::to_string(i) + ";\n";
2654  }
2655  }
2656  }
2657  return u_lightSm;
2658 }
void createsShadows(SLbool createsShadows)
Definition: SLLight.cpp:98
void shadowMap(SLShadowMap *shadowMap)
Definition: SLLight.h:125
void numCascades(int numCascades)
Definition: SLShadowMap.h:72

◆ fragInput_u_shadowMaps()

string SLGLProgramGenerated::fragInput_u_shadowMaps ( SLVLight lights)
staticprivate

Definition at line 2660 of file SLGLProgramGenerated.cpp.

2661 {
2662  string smDecl = "\n";
2663  for (SLuint i = 0; i < lights->size(); ++i)
2664  {
2665  SLLight* light = lights->at(i);
2666  if (light->createsShadows())
2667  {
2668  SLShadowMap* shadowMap = light->shadowMap();
2669  if (shadowMap->useCubemap())
2670  smDecl += "uniform samplerCube u_shadowMapCube_" + to_string(i) + ";\n";
2671  else if (light->doCascadedShadows())
2672  {
2673  for (int j = 0; j < light->shadowMap()->depthBuffers().size(); j++)
2674  smDecl += "uniform sampler2D u_cascadedShadowMap_" + to_string(i) + "_" + std::to_string(j) + ";\n";
2675 
2676  smDecl += "uniform float u_cascadesFactor_" + to_string(i) + ";\n";
2677  }
2678  else
2679  smDecl += "uniform sampler2D u_shadowMap_" + to_string(i) + ";\n";
2680  }
2681  }
2682  return smDecl;
2683 }

◆ lightsDoShadowMapping()

bool SLGLProgramGenerated::lightsDoShadowMapping ( SLVLight lights)
static

Returns true if at least one of the light does shadow mapping.

Definition at line 2613 of file SLGLProgramGenerated.cpp.

2614 {
2615  for (auto light : *lights)
2616  {
2617  if (light->createsShadows())
2618  return true;
2619  }
2620  return false;
2621 }

◆ setVariable()

void SLGLProgramGenerated::setVariable ( std::string &  code,
const std::string &  name,
const std::string &  value 
)
staticprivate

Sets a variable in the shader code.

A variable is specified in templates like this: ${variableName}.

Definition at line 2976 of file SLGLProgramGenerated.cpp.

2979 {
2980  std::string placeholder = "${" + name + "}";
2981 
2982  std::string::size_type pos = 0;
2983  while ((pos = code.find(placeholder)) != std::string::npos)
2984  {
2985  code.replace(pos, placeholder.size(), value);
2986  pos += value.size();
2987  }
2988 }

◆ shaderHeader() [1/2]

string SLGLProgramGenerated::shaderHeader ( )
staticprivate

Adds shader header code.

Definition at line 3001 of file SLGLProgramGenerated.cpp.

3003 {
3004  string header = "\nprecision highp float;\n";
3005  return header;
3006 }

◆ shaderHeader() [2/2]

string SLGLProgramGenerated::shaderHeader ( int  numLights)
staticprivate

Adds shader header code.

Definition at line 2991 of file SLGLProgramGenerated.cpp.

2993 {
2994  string header = "\nprecision highp float;\n";
2995  header += "\n#define NUM_LIGHTS " + to_string(numLights) + "\n";
2996  return header;
2997 }

Member Data Documentation

◆ generatedShaderPath

string SLGLProgramGenerated::generatedShaderPath
staticprivate

Definition at line 140 of file SLGLProgramGenerated.h.


The documentation for this class was generated from the following files: