TDME2  1.9.200
DeferredLightingRenderShader.cpp
Go to the documentation of this file.
2 
3 #include <string>
4 
5 #include <tdme/tdme.h>
6 #include <tdme/engine/Texture.h>
12 #include <tdme/engine/Engine.h>
14 #include <tdme/math/Math.h>
20 
21 using std::string;
22 using std::to_string;
23 
25 
36 using tdme::math::Math;
42 
43 DeferredLightingRenderShader::DeferredLightingRenderShader(Renderer* renderer)
44 {
45  this->renderer = renderer;
46  initialized = false;
47  isRunning = false;
48 }
49 
51 {
52 }
53 
55 {
56  return initialized;
57 }
58 
60 {
61  auto shaderVersion = renderer->getShaderVersion();
64  "shader/" + shaderVersion + "/framebuffer",
65  "render_vertexshader.vert",
66  "#define HAVE_DEPTH_FOG"
67  );
68  if (vertexShaderId == 0) return;
69 
72  "shader/" + shaderVersion + "/framebuffer",
73  "deferred_lighting_fragmentshader.frag",
74  string() +
75  "#define HAVE_DEPTH_FOG\n" +
76  "#define LIGHT_COUNT " + to_string(Engine::LIGHTS_MAX) + "\n#define USE_PUNCTUAL\n#define MATERIAL_METALLICROUGHNESS\n#define USE_IBL\n" +
77  "#define DECAL_COUNT " + to_string(DECAL_COUNT) + "\n" +
78  FileSystem::getInstance()->getContentAsString(
79  "shader/" + shaderVersion + "/functions/specular",
80  "specular_lighting.inc.glsl"
81  ) +
82  "\n\n" +
83  FileSystem::getInstance()->getContentAsString(
84  "shader/" + shaderVersion + "/functions/pbr",
85  "tonemapping.inc.glsl"
86  ) +
87  "\n\n" +
88  FileSystem::getInstance()->getContentAsString(
89  "shader/" + shaderVersion + "/functions/pbr",
90  "functions.inc.glsl"
91  ) +
92  "\n\n" +
93  FileSystem::getInstance()->getContentAsString(
94  "shader/" + shaderVersion + "/functions/pbr",
95  "pbr_lighting.inc.glsl"
96  ) +
97  "\n\n"
98  );
99  if (fragmentShaderId == 0) return;
100 
104  if (renderer->isUsingProgramAttributeLocation() == true) {
106  renderer->setProgramAttributeLocation(programId, 2, "inTextureUV");
107  }
108  if (renderer->linkProgram(programId) == false) return;
109 
110  // uniforms
111  // geometry buffers
113  if (uniformGeometryBufferTextureId1 == -1) return;
115  if (uniformGeometryBufferTextureId2 == -1) return;
117  if (uniformGeometryBufferTextureId3 == -1) return;
118  // color buffers
120  if (uniformColorBufferTextureUnit1 == -1) return;
122  if (uniformColorBufferTextureUnit2 == -1) return;
124  if (uniformColorBufferTextureUnit3 == -1) return;
126  if (uniformColorBufferTextureUnit4 == -1) return;
128  if (uniformColorBufferTextureUnit5 == -1) return;
129  // depth buffer
131  if (uniformDepthBufferTextureUnit == -1) return;
132 
133  // specular lights
134  for (auto i = 0; i < Engine::LIGHTS_MAX; i++) {
135  uniformSpecularLightEnabled[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) +"].enabled");
136  if (uniformSpecularLightEnabled[i] == -1) return;
137  uniformSpecularLightAmbient[i] = renderer->getProgramUniformLocation(programId,"specularLights[" + to_string(i) + "].ambient");
138  if (uniformSpecularLightAmbient[i] == -1) return;
139  uniformSpecularLightDiffuse[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].diffuse");
140  if (uniformSpecularLightDiffuse[i] == -1) return;
141  uniformSpecularLightSpecular[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].specular");
142  if (uniformSpecularLightSpecular[i] == -1) return;
143  uniformSpecularLightPosition[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].position");
144  if (uniformSpecularLightPosition[i] == -1) return;
145  uniformSpecularLightSpotDirection[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].spotDirection");
146  if (uniformSpecularLightSpotDirection[i] == -1) return;
147  uniformSpecularLightSpotExponent[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].spotExponent");
148  if (uniformSpecularLightSpotExponent[i] == -1) return;
149  uniformSpecularLightSpotCosCutoff[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].spotCosCutoff");
150  if (uniformSpecularLightSpotCosCutoff[i] == -1) return;
151  uniformSpecularLightConstantAttenuation[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].constantAttenuation");
152  if (uniformSpecularLightConstantAttenuation[i] == -1) return;
153  uniformSpecularLightLinearAttenuation[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].linearAttenuation");
154  if (uniformSpecularLightLinearAttenuation[i] == -1) return;
155  uniformSpecularLightQuadraticAttenuation[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].quadraticAttenuation");
156  if (uniformSpecularLightQuadraticAttenuation[i] == -1) return;
157  uniformSpecularLightRadius[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].radius");
158  if (uniformSpecularLightRadius[i] == -1) return;
159  }
160 
161  // camera matrix
163  if (uniformCameraMatrix == -1) return;
164 
165  // projection * view inverted
167  if (uniformProjectionCameraMatrixInverted == -1) return;
168 
169  // PBR
171  if (uniformCamera == -1) return;
172 
173  // lights
174  for (auto i = 0; i < Engine::LIGHTS_MAX; i++) {
175  uniformPBRLightEnabled[i] = renderer->getProgramUniformLocation(programId, "u_PBRLights[" + to_string(i) + "].enabled");
176  if (uniformPBRLightEnabled[i] == -1) return;
177  //uniformLightAmbient[i] = renderer->getProgramUniformLocation(programId, "u_PBRLights[" + to_string(i) + "].ambient");
178  //if (uniformLightAmbient[i] == -1) return;
179  uniformPBRLightDirection[i] = renderer->getProgramUniformLocation(programId, "u_PBRLights[" + to_string(i) + "].direction");
180  if (uniformPBRLightDirection[i] == -1) return;
181  uniformPBRLightRange[i] = renderer->getProgramUniformLocation(programId, "u_PBRLights[" + to_string(i) + "].range");
182  if (uniformPBRLightRange[i] == -1) return;
183  uniformPBRLightColor[i] = renderer->getProgramUniformLocation(programId, "u_PBRLights[" + to_string(i) + "].color");
184  if (uniformPBRLightColor[i] == -1) return;
185  uniformPBRLightIntensity[i] = renderer->getProgramUniformLocation(programId, "u_PBRLights[" + to_string(i) + "].intensity");
186  if (uniformPBRLightIntensity[i] == -1) return;
187  uniformPBRLightPosition[i] = renderer->getProgramUniformLocation(programId, "u_PBRLights[" + to_string(i) + "].position");
188  if (uniformPBRLightPosition[i] == -1) return;
189  uniformPBRLightInnerConeCos[i] = renderer->getProgramUniformLocation(programId, "u_PBRLights[" + to_string(i) + "].innerConeCos");
190  if (uniformPBRLightInnerConeCos[i] == -1) return;
191  uniformPBRLightOuterConeCos[i] = renderer->getProgramUniformLocation(programId, "u_PBRLights[" + to_string(i) + "].outerConeCos");
192  if (uniformPBRLightOuterConeCos[i] == -1) return;
193  uniformPBRLightType[i] = renderer->getProgramUniformLocation(programId, "u_PBRLights[" + to_string(i) + "].type");
194  if (uniformPBRLightType[i] == -1) return;
195  }
196 
197  // IBL
199  if (uniformDiffuseEnvSampler == -1) return;
201  if (uniformSpecularEnvSampler == -1) return;
203  if (uniformbrdfLUT == -1) return;
204 
205  //
206  string environmentType = "studio_grey";
209  "pbr-environment-diffuse",
210  envDiffuseTextures[0] = TextureReader::read("resources/engine/environments/" + environmentType + "/diffuse", "diffuse_left.png"),
211  envDiffuseTextures[1] = TextureReader::read("resources/engine/environments/" + environmentType + "/diffuse", "diffuse_right.png"),
212  envDiffuseTextures[2] = TextureReader::read("resources/engine/environments/" + environmentType + "/diffuse", "diffuse_top.png"),
213  envDiffuseTextures[3] = TextureReader::read("resources/engine/environments/" + environmentType + "/diffuse", "diffuse_bottom.png"),
214  envDiffuseTextures[4] = TextureReader::read("resources/engine/environments/" + environmentType + "/diffuse", "diffuse_front.png"),
215  envDiffuseTextures[5] = TextureReader::read("resources/engine/environments/" + environmentType + "/diffuse", "diffuse_back.png"),
217  );
220  "pbr-environment-specular",
221  envSpecularTextures[0] = TextureReader::read("resources/engine/environments/" + environmentType + "/specular", "specular_left.png"),
222  envSpecularTextures[1] = TextureReader::read("resources/engine/environments/" + environmentType + "/specular", "specular_right.png"),
223  envSpecularTextures[2] = TextureReader::read("resources/engine/environments/" + environmentType + "/specular", "specular_top.png"),
224  envSpecularTextures[3] = TextureReader::read("resources/engine/environments/" + environmentType + "/specular", "specular_bottom.png"),
225  envSpecularTextures[4] = TextureReader::read("resources/engine/environments/" + environmentType + "/specular", "specular_front.png"),
226  envSpecularTextures[5] = TextureReader::read("resources/engine/environments/" + environmentType + "/specular", "specular_back.png"),
228  );
230 
231  // decals
233  if (uniformDecalCount == -1) return;
234 
236  if (uniformDecalsTextureUnit == -1) return;
237 
238  //
239  for (auto i = 0; i < DECAL_COUNT; i++) {
240  uniformDecalWorldToDecalSpace[i] = renderer->getProgramUniformLocation(programId, "decals[" + to_string(i) + "].worldToDecalSpace");
241  if (uniformDecalWorldToDecalSpace[i] == -1) return;
242  uniformDecalAtlasTextureOrientation[i] = renderer->getProgramUniformLocation(programId, "decals[" + to_string(i) + "].texture.orientation");
243  if (uniformDecalAtlasTextureOrientation[i] == -1) return;
244  uniformDecalAtlasTexturePosition[i] = renderer->getProgramUniformLocation(programId, "decals[" + to_string(i) + "].texture.position");
245  if (uniformDecalAtlasTexturePosition[i] == -1) return;
246  uniformDecalAtlasTextureDimension[i] = renderer->getProgramUniformLocation(programId, "decals[" + to_string(i) + "].texture.dimension");
247  if (uniformDecalAtlasTextureDimension[i] == -1) return;
248  uniformDecalSpriteSheetDimension[i] = renderer->getProgramUniformLocation(programId, "decals[" + to_string(i) + "].spriteSheetDimension");
249  if (uniformDecalSpriteSheetDimension[i] == -1) return;
250  uniformDecalSpriteIndex[i] = renderer->getProgramUniformLocation(programId, "decals[" + to_string(i) + "].spriteIndex");
251  if (uniformDecalSpriteIndex[i] == -1) return;
252  }
253 
254  //
255  initialized = true;
256 }
257 
259  //
260  for (auto i = 0; i < envDiffuseTextures.size(); i++) {
261  if (envDiffuseTextures[i] == nullptr) continue;
262  envDiffuseTextures[i]->releaseReference();
263  envDiffuseTextures[i] = nullptr;
264  }
265  //
266  for (auto i = 0; i < envSpecularTextures.size(); i++) {
267  if (envSpecularTextures[i] == nullptr) continue;
268  envSpecularTextures[i]->releaseReference();
269  envSpecularTextures[i] = nullptr;
270  }
271  //
272  Engine::getInstance()->getTextureManager()->removeTexture("pbr-environment-diffuse");
273  Engine::getInstance()->getTextureManager()->removeTexture("pbr-environment-specular");
274 }
275 
276 void DeferredLightingRenderShader::useProgram(Engine* engine, vector<Decal*>& decalEntities)
277 {
278  auto contextIdx = renderer->CONTEXTINDEX_DEFAULT;
279  renderer->useProgram(contextIdx, programId);
290 
291  // Matrices
294 
295  // Specular
296  for (auto lightId = 0; lightId < Engine::LIGHTS_MAX; lightId++) {
297  auto light = engine->getLightAt(lightId);
298  renderer->setProgramUniformInteger(contextIdx, uniformSpecularLightEnabled[lightId], light->isEnabled() == true?1:0);
299  if (light->isEnabled() == false) continue;
300  renderer->setProgramUniformFloatVec4(contextIdx, uniformSpecularLightAmbient[lightId], light->getAmbient().getArray());
301  renderer->setProgramUniformFloatVec4(contextIdx, uniformSpecularLightDiffuse[lightId], light->getDiffuse().getArray());
302  renderer->setProgramUniformFloatVec4(contextIdx, uniformSpecularLightSpecular[lightId], light->getSpecular().getArray());
303  renderer->setProgramUniformFloatVec4(contextIdx, uniformSpecularLightPosition[lightId], light->getPosition().getArray());
304  renderer->setProgramUniformFloatVec3(contextIdx, uniformSpecularLightSpotDirection[lightId], light->getSpotDirection().getArray());
305  renderer->setProgramUniformFloat(contextIdx, uniformSpecularLightSpotExponent[lightId], light->getSpotExponent());
306  renderer->setProgramUniformFloat(contextIdx, uniformSpecularLightSpotCosCutoff[lightId], static_cast<float>(Math::cos(Math::PI / 180.0f * light->getSpotCutOff())));
307  renderer->setProgramUniformFloat(contextIdx, uniformSpecularLightConstantAttenuation[lightId], light->getConstantAttenuation());
308  renderer->setProgramUniformFloat(contextIdx, uniformSpecularLightLinearAttenuation[lightId], light->getLinearAttenuation());
309  renderer->setProgramUniformFloat(contextIdx, uniformSpecularLightQuadraticAttenuation[lightId], light->getQuadraticAttenuation());
310  renderer->setProgramUniformFloat(contextIdx, uniformSpecularLightRadius[lightId], light->getRadius());
311  }
312 
313  // PBR
315 
316  // IBL
320  renderer->setTextureUnit(contextIdx, 9);
322  renderer->setTextureUnit(contextIdx, 10);
324  renderer->setTextureUnit(contextIdx, 11);
325  renderer->bindTexture(contextIdx, texturebrdfLUT);
326 
327  // lights
328  for (auto lightId = 0; lightId < Engine::LIGHTS_MAX; lightId++) {
329  auto light = engine->getLightAt(lightId);
330  if (uniformPBRLightEnabled[lightId] != -1) renderer->setProgramUniformInteger(contextIdx, uniformPBRLightEnabled[lightId], light->isEnabled() == true?1:0);
331  if (light->isEnabled() == false) continue;
332  const auto& ambient = light->getAmbient();
333  const auto& diffuse = light->getDiffuse();
334  const auto& position = light->getPosition();
335  // renderer->setProgramUniformFloatVec3(context, uniformLightAmbient[lightId], {{ ambient[0], ambient[1], ambient[2] }});
336  renderer->setProgramUniformFloatVec3(contextIdx, uniformPBRLightDirection[lightId], light->getSpotDirection().getArray());
337  renderer->setProgramUniformFloat(contextIdx, uniformPBRLightRange[lightId], 0.0f);
338  renderer->setProgramUniformFloatVec3(contextIdx, uniformPBRLightColor[lightId], {{ diffuse[0], diffuse[1], diffuse[2] }});
339  renderer->setProgramUniformFloat(contextIdx, uniformPBRLightIntensity[lightId], 1.0f);
340  renderer->setProgramUniformFloatVec3(contextIdx, uniformPBRLightPosition[lightId],{{ position[0], position[1], position[2] }});
341  if (uniformPBRLightType[lightId] != -1) renderer->setProgramUniformInteger(contextIdx, uniformPBRLightType[lightId], 0);
342  }
343 
344  // decals
345  auto& decalsTextureAtlas = engine->getDecalsTextureAtlas();
346  if (decalsTextureAtlas.isRequiringUpdate() == true) {
347  decalsTextureAtlas.update();
348  if (decalsTextureAtlas.getAtlasTexture() != nullptr) {
350  renderer->setTextureUnit(contextIdx, 12);
352  renderer->uploadTexture(contextIdx, decalsTextureAtlas.getAtlasTexture());
353  } else
357  }
358  }
359  auto decalsTextureAtlasTexture = decalsTextureAtlas.getAtlasTexture();
360  if (decalsTextureAtlasTexture != nullptr) {
361  auto decalCount = Math::min(DECAL_COUNT, decalEntities.size());
362  renderer->setProgramUniformInteger(contextIdx, uniformDecalCount, decalCount);
363  if (decalCount > 0) {
364  auto decalsTextureAtlasTextureWidth = decalsTextureAtlasTexture->getTextureWidth();
365  auto decalsTextureAtlasTextureHeight = decalsTextureAtlasTexture->getTextureHeight();
367  renderer->setTextureUnit(contextIdx, 12);
369  for (auto i = 0; i < decalCount && i < DECAL_COUNT; i++) {
370  auto decalObject = decalEntities[i];
371  auto atlasTextureIdx = decalsTextureAtlas.getTextureIdx(decalObject->getDecalTexture());
372  if (atlasTextureIdx == -1) continue;
373  auto atlasTexture = decalsTextureAtlas.getAtlasTexture(atlasTextureIdx);
374  if (atlasTexture == nullptr) continue;
375  renderer->setProgramUniformFloatMatrix4x4(contextIdx, uniformDecalWorldToDecalSpace[i], decalObject->getWorldToDecalSpaceMatrix().getArray());
376  renderer->setProgramUniformInteger(contextIdx, uniformDecalAtlasTextureOrientation[i], atlasTexture->orientation);
378  contextIdx,
380  {
381  static_cast<float>(atlasTexture->left) / static_cast<float>(decalsTextureAtlasTextureWidth),
382  static_cast<float>(atlasTexture->top) / static_cast<float>(decalsTextureAtlasTextureHeight)
383  }
384  );
386  contextIdx,
388  {
389  static_cast<float>(atlasTexture->width) / static_cast<float>(decalsTextureAtlasTextureWidth),
390  static_cast<float>(atlasTexture->height) / static_cast<float>(decalsTextureAtlasTextureHeight)
391  }
392  );
394  contextIdx,
396  {
397  static_cast<float>(decalObject->getTextureHorizontalSprites()),
398  static_cast<float>(decalObject->getTextureVerticalSprites())
399  }
400  );
401  renderer->setProgramUniformInteger(contextIdx, uniformDecalSpriteIndex[i], decalObject->computeTextureSpriteIdx());
402  }
403  }
404  } else {
406  }
407 
408  //
409  renderer->setTextureUnit(contextIdx, 0);
410 
411  //
412  isRunning = true;
413 }
414 
416 {
417  auto contextIdx = renderer->CONTEXTINDEX_DEFAULT;
418  auto textureUnit = renderer->getTextureUnit(contextIdx);
419  // PBR
420  // IBL
421  renderer->setTextureUnit(contextIdx, 9);
422  renderer->bindTexture(contextIdx, renderer->ID_NONE);
423  renderer->setTextureUnit(contextIdx, 10);
424  renderer->bindTexture(contextIdx, renderer->ID_NONE);
425  renderer->setTextureUnit(contextIdx, 11);
426  renderer->bindTexture(contextIdx, renderer->ID_NONE);
427  renderer->setTextureUnit(contextIdx, textureUnit);
428 
429  //
430  isRunning = false;
431 }
const Matrix4x4 & getModelViewProjectionInvertedMatrix() const
Definition: Camera.h:270
const Matrix4x4 & getCameraMatrix() const
Definition: Camera.h:249
Engine main class.
Definition: Engine.h:131
Light * getLightAt(int32_t idx)
Returns light at idx (0 <= idx < 8)
Definition: Engine.h:1143
TextureAtlas & getDecalsTextureAtlas()
Definition: Engine.h:525
static Engine * getInstance()
Returns engine instance.
Definition: Engine.h:612
Camera * getCamera()
Definition: Engine.h:1071
static TextureManager * getTextureManager()
Definition: Engine.h:627
static BRDFLUTShader * getBRDFLUTShader()
Definition: Engine.h:483
Geometry buffer class.
Texture entity.
Definition: Texture.h:24
void useProgram(Engine *engine, vector< Decal * > &decalEntities)
Use render program.
void removeTexture(Texture *texture)
Removes a texture from manager.
int32_t addCubeMapTexture(const string &id, Texture *textureLeft, Texture *textureRight, Texture *textureTop, Texture *textureBottom, Texture *textureFront, Texture *textureBack, int contextIdx=0)
Adds a cube map texture to manager.
virtual void setTextureUnit(int contextIdx, int32_t textureUnit)=0
Sets up texture unit.
virtual void bindCubeMapTexture(int contextIdx, int32_t textureId)=0
Binds a cube map texture with given id or unbinds when using ID_NONE.
virtual int32_t loadShader(int32_t type, const string &pathName, const string &fileName, const string &definitions=string(), const string &functions=string())=0
Loads a shader.
virtual void setProgramUniformFloatVec4(int contextIdx, int32_t uniformId, const array< float, 4 > &data)=0
Set up a float vec4 uniform value.
virtual int32_t createProgram(int type)=0
Creates a shader program.
virtual void setProgramUniformFloatVec2(int contextIdx, int32_t uniformId, const array< float, 2 > &data)=0
Set up a float vec2 uniform value.
virtual int32_t getTextureUnit(int contextIdx)=0
Get texture unit.
virtual void setProgramAttributeLocation(int32_t programId, int32_t location, const string &name)=0
Bind attribute to a input location.
virtual int32_t createTexture()=0
Creates a texture.
virtual void setProgramUniformInteger(int contextIdx, int32_t uniformId, int32_t value)=0
Set up a integer uniform value.
virtual bool linkProgram(int32_t programId)=0
Links attached shaders to a program.
virtual void bindTexture(int contextIdx, int32_t textureId)=0
Binds a texture with given id or unbinds when using ID_NONE.
void setLighting(int contextIdx, int32_t lighting)
Set current lighting model.
Definition: Renderer.h:504
virtual void attachShaderToProgram(int32_t programId, int32_t shaderId)=0
Attaches a shader to a program.
virtual void setProgramUniformFloatMatrix4x4(int contextIdx, int32_t uniformId, const array< float, 16 > &value)=0
Set up a float matrix 4x4 uniform value.
virtual int32_t getProgramUniformLocation(int32_t programId, const string &name)=0
Returns location of given uniform variable.
virtual void disposeTexture(int32_t textureId)=0
Dispose a texture.
virtual void uploadTexture(int contextIdx, Texture *texture)=0
Uploads texture data to current bound texture.
virtual void useProgram(int contextIdx, int32_t programId)=0
Use shader program.
virtual void setProgramUniformFloatVec3(int contextIdx, int32_t uniformId, const array< float, 3 > &data)=0
Set up a float vec3 uniform value.
virtual void setProgramUniformFloat(int contextIdx, int32_t uniformId, float value)=0
Set up a float uniform value.
Buffers used to transfer data between main memory to graphics board memory.
Definition: ObjectBuffer.h:24
Standard math functions.
Definition: Math.h:19
const array< float, 16 > & getArray() const
Definition: Matrix4x4.h:611
const array< float, 3 > & getArray() const
Definition: Vector3.h:366
File system singleton class.
Definition: FileSystem.h:17
Byte buffer class.
Definition: ByteBuffer.h:27
Float buffer class.
Definition: FloatBuffer.h:18
void update()
Update texture atlas.