Review PBR shaders
Issue was related to vertex tangent attibutes not uploaded to GPU, a quick solution was implemented for new vertex attributes loading for already existing meshes... I don't like it specially but it will work for now.
This commit is contained in:
parent
0f9fe34c3a
commit
c600dd0766
6 changed files with 41 additions and 6 deletions
|
@ -38,7 +38,11 @@ int main()
|
||||||
|
|
||||||
// Load model and PBR material
|
// Load model and PBR material
|
||||||
Model model = LoadModel("resources/pbr/trooper.obj");
|
Model model = LoadModel("resources/pbr/trooper.obj");
|
||||||
|
|
||||||
|
// Mesh tangents are generated... and uploaded to GPU
|
||||||
|
// NOTE: New VBO for tangents is generated at default location and also binded to mesh VAO
|
||||||
MeshTangents(&model.meshes[0]);
|
MeshTangents(&model.meshes[0]);
|
||||||
|
|
||||||
model.materials[0] = LoadMaterialPBR((Color){ 255, 255, 255, 255 }, 1.0f, 1.0f);
|
model.materials[0] = LoadMaterialPBR((Color){ 255, 255, 255, 255 }, 1.0f, 1.0f);
|
||||||
|
|
||||||
// Define lights attributes
|
// Define lights attributes
|
||||||
|
@ -143,9 +147,13 @@ static Material LoadMaterialPBR(Color albedo, float metalness, float roughness)
|
||||||
#define PATH_BRDF_FS "resources/shaders/brdf.fs" // Path to bidirectional reflectance distribution function fragment shader
|
#define PATH_BRDF_FS "resources/shaders/brdf.fs" // Path to bidirectional reflectance distribution function fragment shader
|
||||||
|
|
||||||
Shader shdrCubemap = LoadShader(PATH_CUBEMAP_VS, PATH_CUBEMAP_FS);
|
Shader shdrCubemap = LoadShader(PATH_CUBEMAP_VS, PATH_CUBEMAP_FS);
|
||||||
|
printf("Loaded shader: cubemap\n");
|
||||||
Shader shdrIrradiance = LoadShader(PATH_SKYBOX_VS, PATH_IRRADIANCE_FS);
|
Shader shdrIrradiance = LoadShader(PATH_SKYBOX_VS, PATH_IRRADIANCE_FS);
|
||||||
|
printf("Loaded shader: irradiance\n");
|
||||||
Shader shdrPrefilter = LoadShader(PATH_SKYBOX_VS, PATH_PREFILTER_FS);
|
Shader shdrPrefilter = LoadShader(PATH_SKYBOX_VS, PATH_PREFILTER_FS);
|
||||||
|
printf("Loaded shader: prefilter\n");
|
||||||
Shader shdrBRDF = LoadShader(PATH_BRDF_VS, PATH_BRDF_FS);
|
Shader shdrBRDF = LoadShader(PATH_BRDF_VS, PATH_BRDF_FS);
|
||||||
|
printf("Loaded shader: brdf\n");
|
||||||
|
|
||||||
// Setup required shader locations
|
// Setup required shader locations
|
||||||
SetShaderValue(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, UNIFORM_INT);
|
SetShaderValue(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, UNIFORM_INT);
|
||||||
|
|
|
@ -10,13 +10,13 @@
|
||||||
|
|
||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
#define MAX_SAMPLES 1024u
|
|
||||||
|
|
||||||
// Input vertex attributes (from vertex shader)
|
// Input vertex attributes (from vertex shader)
|
||||||
in vec2 fragTexCoord;
|
in vec2 fragTexCoord;
|
||||||
|
|
||||||
// Constant values
|
// Constant values
|
||||||
const float PI = 3.14159265359;
|
const float PI = 3.14159265359;
|
||||||
|
const uint MAX_SAMPLES = 1024u;
|
||||||
|
|
||||||
// Output fragment color
|
// Output fragment color
|
||||||
out vec4 finalColor;
|
out vec4 finalColor;
|
||||||
|
@ -93,7 +93,7 @@ vec2 IntegrateBRDF(float NdotV, float roughness)
|
||||||
vec3 V = vec3(sqrt(1.0 - NdotV*NdotV), 0.0, NdotV);
|
vec3 V = vec3(sqrt(1.0 - NdotV*NdotV), 0.0, NdotV);
|
||||||
vec3 N = vec3(0.0, 0.0, 1.0);
|
vec3 N = vec3(0.0, 0.0, 1.0);
|
||||||
|
|
||||||
for (int i = 0; i < MAX_SAMPLES; i++)
|
for (uint i = 0u; i < MAX_SAMPLES; i++)
|
||||||
{
|
{
|
||||||
// Generate a sample vector that's biased towards the preferred alignment direction (importance sampling)
|
// Generate a sample vector that's biased towards the preferred alignment direction (importance sampling)
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
// Input vertex attributes (from vertex shader)
|
// Input vertex attributes (from vertex shader)
|
||||||
in vec3 fragPos;
|
in vec3 fragPosition;
|
||||||
|
|
||||||
// Input uniform values
|
// Input uniform values
|
||||||
uniform samplerCube environmentMap;
|
uniform samplerCube environmentMap;
|
||||||
|
@ -23,7 +23,7 @@ out vec4 finalColor;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// The sample direction equals the hemisphere's orientation
|
// The sample direction equals the hemisphere's orientation
|
||||||
vec3 normal = normalize(fragPos);
|
vec3 normal = normalize(fragPosition);
|
||||||
|
|
||||||
vec3 irradiance = vec3(0.0);
|
vec3 irradiance = vec3(0.0);
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#define CUBEMAP_RESOLUTION 1024.0
|
#define CUBEMAP_RESOLUTION 1024.0
|
||||||
|
|
||||||
// Input vertex attributes (from vertex shader)
|
// Input vertex attributes (from vertex shader)
|
||||||
in vec3 fragPos;
|
in vec3 fragPosition;
|
||||||
|
|
||||||
// Input uniform values
|
// Input uniform values
|
||||||
uniform samplerCube environmentMap;
|
uniform samplerCube environmentMap;
|
||||||
|
@ -79,7 +79,7 @@ vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Make the simplyfying assumption that V equals R equals the normal
|
// Make the simplyfying assumption that V equals R equals the normal
|
||||||
vec3 N = normalize(fragPos);
|
vec3 N = normalize(fragPosition);
|
||||||
vec3 R = N;
|
vec3 R = N;
|
||||||
vec3 V = R;
|
vec3 V = R;
|
||||||
|
|
||||||
|
|
|
@ -2303,6 +2303,9 @@ void MeshTangents(Mesh *mesh)
|
||||||
free(tan1);
|
free(tan1);
|
||||||
free(tan2);
|
free(tan2);
|
||||||
|
|
||||||
|
// Load a new tangent attributes buffer
|
||||||
|
mesh->vboId[LOC_VERTEX_TANGENT] = rlLoadAttribBuffer(mesh->vaoId, LOC_VERTEX_TANGENT, mesh->tangents, mesh->vertexCount*4*sizeof(float), false);
|
||||||
|
|
||||||
TraceLog(LOG_INFO, "Tangents computed for mesh");
|
TraceLog(LOG_INFO, "Tangents computed for mesh");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
24
src/rlgl.h
24
src/rlgl.h
|
@ -456,6 +456,7 @@ void rlDeleteBuffers(unsigned int id); // Unload vertex data (V
|
||||||
void rlClearColor(byte r, byte g, byte b, byte a); // Clear color buffer with color
|
void rlClearColor(byte r, byte g, byte b, byte a); // Clear color buffer with color
|
||||||
void rlClearScreenBuffers(void); // Clear used screen buffers (color and depth)
|
void rlClearScreenBuffers(void); // Clear used screen buffers (color and depth)
|
||||||
void rlUpdateBuffer(int bufferId, void *data, int dataSize); // Update GPU buffer with new data
|
void rlUpdateBuffer(int bufferId, void *data, int dataSize); // Update GPU buffer with new data
|
||||||
|
unsigned int rlLoadAttribBuffer(unsigned int vaoId, int shaderLoc, void *buffer, int size, bool dynamic); // Load a new attributes buffer
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Functions Declaration - rlgl functionality
|
// Functions Declaration - rlgl functionality
|
||||||
|
@ -2532,6 +2533,29 @@ void rlLoadMesh(Mesh *mesh, bool dynamic)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load a new attributes buffer
|
||||||
|
unsigned int rlLoadAttribBuffer(unsigned int vaoId, int shaderLoc, void *buffer, int size, bool dynamic)
|
||||||
|
{
|
||||||
|
unsigned int id = 0;
|
||||||
|
|
||||||
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
|
int drawHint = GL_STATIC_DRAW;
|
||||||
|
if (dynamic) drawHint = GL_DYNAMIC_DRAW;
|
||||||
|
|
||||||
|
if (vaoSupported) glBindVertexArray(vaoId);
|
||||||
|
|
||||||
|
glGenBuffers(1, &id);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, id);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, size, buffer, drawHint);
|
||||||
|
glVertexAttribPointer(shaderLoc, 2, GL_FLOAT, 0, 0, 0);
|
||||||
|
glEnableVertexAttribArray(shaderLoc);
|
||||||
|
|
||||||
|
if (vaoSupported) glBindVertexArray(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
// Update vertex data on GPU (upload new data to one buffer)
|
// Update vertex data on GPU (upload new data to one buffer)
|
||||||
void rlUpdateMesh(Mesh mesh, int buffer, int numVertex)
|
void rlUpdateMesh(Mesh mesh, int buffer, int numVertex)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue