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 2943 of file SLGLProgramGenerated.cpp.

2946 {
2947 
2948 #if defined(DEBUG) && defined(_DEBUG)
2949  shader->code(SLGLShader::removeComments(code));
2950 #else
2951  shader->code(code);
2952 #endif
2953  shader->name(name);
2954 
2955 #ifndef SL_EMSCRIPTEN
2956  // Check if generatedShaderPath folder exists
2957  generatedShaderPath = SLGLProgramManager::configPath + "generatedShaders/";
2959  SL_EXIT_MSG("SLGLProgramGenerated::addCodeToShader: SLGLProgramManager::configPath not existing");
2960 
2962  {
2963  bool dirCreated = Utils::makeDir(generatedShaderPath);
2964  if (!dirCreated)
2965  SL_EXIT_MSG("SLGLProgramGenerated::addCodeToShader: Failed to created SLGLProgramManager::configPath/generatedShaders");
2966  }
2967 
2968  shader->file(generatedShaderPath + name);
2969 #endif
2970 }
#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 2068 of file SLGLProgramGenerated.cpp.

2071 {
2072  assert(mat && lights);
2073  assert(_shaders.size() > 1 &&
2074  _shaders[0]->type() == ST_vertex &&
2075  _shaders[1]->type() == ST_fragment);
2076 
2077  // Check what textures the material has
2078  bool Dm = mat->hasTextureType(TT_diffuse);
2079  bool Nm = mat->hasTextureType(TT_normal);
2080  bool Hm = mat->hasTextureType(TT_height);
2081  bool Em = mat->hasTextureType(TT_emissive);
2082  bool Om0 = mat->hasTextureTypeWithUVIndex(TT_occlusion, 0, 0);
2083  bool Om1 = mat->hasTextureTypeWithUVIndex(TT_occlusion, 0, 1);
2084  bool Sm = lightsDoShadowMapping(lights);
2085  bool uv0 = mat->usesUVIndex(0);
2086  bool uv1 = mat->usesUVIndex(1);
2087 
2088  // Assemble vertex shader code
2089  string vertCode;
2090  vertCode += shaderHeader((int)lights->size());
2091 
2092  // Vertex shader inputs
2093  vertCode += vertInput_a_pn;
2094  if (uv0) vertCode += vertInput_a_uv0;
2095  if (uv1) vertCode += vertInput_a_uv1;
2096  if (Nm) vertCode += vertInput_a_tangent;
2097  if (supportGPUSkinning) vertCode += vertInput_a_skinning;
2098  vertCode += vertInput_u_matrices_all;
2099  if (Nm) vertCode += vertInput_u_lightNm;
2100  if (supportGPUSkinning) vertCode += vertInput_u_skinning;
2101 
2102  // Vertex shader outputs
2103  vertCode += vertOutput_v_P_VS;
2104  if (Sm) vertCode += vertOutput_v_P_WS;
2105  vertCode += vertOutput_v_N_VS;
2106  if (uv0) vertCode += vertOutput_v_uv0;
2107  if (uv1) vertCode += vertOutput_v_uv1;
2108  if (Nm) vertCode += vertOutput_v_lightVecTS;
2109 
2110  // Vertex shader main loop
2111  vertCode += main_Begin;
2112  if (supportGPUSkinning) vertCode += Nm ? vertMain_skinning_Nm : vertMain_skinning;
2113  vertCode += vertMain_v_P_VS;
2114  if (Sm) vertCode += vertMain_v_P_WS_Sm;
2115  vertCode += vertMain_v_N_VS;
2116  if (uv0) vertCode += vertMain_v_uv0;
2117  if (uv1) vertCode += vertMain_v_uv1;
2118  if (Nm) vertCode += vertMain_TBN_Nm;
2119  vertCode += vertMain_EndAll;
2120 
2121  // Vertex shader variables
2122  setVariable(vertCode, "localPosition", supportGPUSkinning ? "skinnedPosition" : "a_position");
2123  setVariable(vertCode, "localNormal", supportGPUSkinning ? "skinnedNormal" : "a_normal");
2124  if (Nm) setVariable(vertCode, "localTangent", supportGPUSkinning ? "skinnedTangent" : "a_tangent");
2125 
2126  addCodeToShader(_shaders[0], vertCode, _name + ".vert");
2127 
2128  // Assemble fragment shader code
2129  string fragCode;
2130  fragCode += shaderHeader((int)lights->size());
2131 
2132  // Fragment shader inputs
2133  fragCode += fragInput_v_P_VS;
2134  if (Sm) fragCode += fragInput_v_P_WS;
2135  fragCode += fragInput_v_N_VS;
2136  if (uv0) fragCode += fragInput_v_uv0;
2137  if (uv1) fragCode += fragInput_v_uv1;
2138  if (Nm) fragCode += fragInput_v_lightVecTS;
2139 
2140  // Fragment shader uniforms
2141  fragCode += fragInput_u_lightAll;
2142  fragCode += fragInput_u_matBlinnAll;
2143  if (Sm) fragCode += fragInput_u_lightSm(lights);
2144  if (Dm) fragCode += fragInput_u_matTexDm;
2145  if (Nm) fragCode += fragInput_u_matTexNm;
2146  if (Em) fragCode += fragInput_u_matTexEm;
2147  if (Om0 || Om1) fragCode += fragInput_u_matTexOm;
2148  if (Sm) fragCode += fragInput_u_matGetsSm;
2149  if (Sm) fragCode += fragInput_u_shadowMaps(lights);
2150  fragCode += fragInput_u_cam;
2151 
2152  // Fragment shader outputs
2153  fragCode += fragOutputs_o_fragColor;
2154 
2155  // Fragment shader functions
2156  fragCode += fragFunctionsLightingBlinnPhong;
2157  fragCode += fragFunctionFogBlend;
2158  fragCode += fragFunctionDoStereoSeparation;
2159  if (Sm) fragCode += fragFunctionShadowTest(lights);
2160  if (Sm) fragCode += fragFunctionDoColoredShadows;
2161 
2162  // Fragment shader main loop
2163  fragCode += main_Begin;
2164  fragCode += fragMain_0_Intensities;
2165  fragCode += Nm ? fragMain_1_EN_in_TS : fragMain_1_EN_in_VS;
2166  fragCode += Em ? fragMain_1_matEmis_Em : fragMain_1_matEmis;
2167 
2168  fragCode += Om0 ? fragMain_1_matOccl_Om0 : Om1 ? fragMain_1_matOccl_Om1
2170 
2171  fragCode += Nm && Sm ? fragMainBlinn_2_LightLoopNmSm : Nm ? fragMainBlinn_2_LightLoopNm
2175  if (Sm) fragCode += fragMain_4_ColoredShadows;
2176  fragCode += fragMain_5_FogGammaStereo;
2177 
2178  addCodeToShader(_shaders[1], fragCode, _name + ".frag");
2179 }
@ 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 1934 of file SLGLProgramGenerated.cpp.

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

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

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

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

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

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

1911 {
1912  if (mat->name() == "IBLMat")
1913  {
1914  std::cout << "build program code for IBLMat" << std::endl;
1915  }
1916  assert(mat && "No material pointer passed!");
1917  assert(_shaders.size() > 1 &&
1918  _shaders[0]->type() == ST_vertex &&
1919  _shaders[1]->type() == ST_fragment);
1920 
1921  if (isDrawProg)
1922  {
1923  if (drawInstanced)
1925  else
1926  buildPerPixParticle(mat);
1927  }
1928  else
1930 }
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 1723 of file SLGLProgramGenerated.cpp.

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

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

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

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

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

◆ lightsDoShadowMapping()

bool SLGLProgramGenerated::lightsDoShadowMapping ( SLVLight lights)
static

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

Definition at line 2612 of file SLGLProgramGenerated.cpp.

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

◆ 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 2975 of file SLGLProgramGenerated.cpp.

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

◆ shaderHeader() [1/2]

string SLGLProgramGenerated::shaderHeader ( )
staticprivate

Adds shader header code.

Definition at line 3000 of file SLGLProgramGenerated.cpp.

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

◆ shaderHeader() [2/2]

string SLGLProgramGenerated::shaderHeader ( int  numLights)
staticprivate

Adds shader header code.

Definition at line 2990 of file SLGLProgramGenerated.cpp.

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

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: