Przeglądaj źródła

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.
Ray 6 lat temu
rodzic
commit
c600dd0766

+ 8 - 0
examples/models/models_material_pbr.c

@@ -38,7 +38,11 @@ int main()
 
     // Load model and PBR material
     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]);
+
     model.materials[0] = LoadMaterialPBR((Color){ 255, 255, 255, 255 }, 1.0f, 1.0f);
 
     // 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
     
     Shader shdrCubemap = LoadShader(PATH_CUBEMAP_VS, PATH_CUBEMAP_FS);
+    printf("Loaded shader: cubemap\n");
     Shader shdrIrradiance = LoadShader(PATH_SKYBOX_VS, PATH_IRRADIANCE_FS);
+    printf("Loaded shader: irradiance\n");
     Shader shdrPrefilter = LoadShader(PATH_SKYBOX_VS, PATH_PREFILTER_FS);
+    printf("Loaded shader: prefilter\n");
     Shader shdrBRDF = LoadShader(PATH_BRDF_VS, PATH_BRDF_FS);
+    printf("Loaded shader: brdf\n");
     
     // Setup required shader locations
     SetShaderValue(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, UNIFORM_INT);

+ 2 - 2
examples/models/resources/shaders/brdf.fs

@@ -10,13 +10,13 @@
 
 #version 330
 
-#define         MAX_SAMPLES        1024u
 
 // Input vertex attributes (from vertex shader)
 in vec2 fragTexCoord;
 
 // Constant values
 const float PI = 3.14159265359;
+const uint MAX_SAMPLES = 1024u;
 
 // Output fragment color
 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 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)
         

+ 2 - 2
examples/models/resources/shaders/irradiance.fs

@@ -9,7 +9,7 @@
 #version 330
 
 // Input vertex attributes (from vertex shader)
-in vec3 fragPos;
+in vec3 fragPosition;
 
 // Input uniform values
 uniform samplerCube environmentMap;
@@ -23,7 +23,7 @@ out vec4 finalColor;
 void main()
 {
     // The sample direction equals the hemisphere's orientation
-    vec3 normal = normalize(fragPos);
+    vec3 normal = normalize(fragPosition);
 
     vec3 irradiance = vec3(0.0);  
 

+ 2 - 2
examples/models/resources/shaders/prefilter.fs

@@ -11,7 +11,7 @@
 #define     CUBEMAP_RESOLUTION      1024.0
 
 // Input vertex attributes (from vertex shader)
-in vec3 fragPos;
+in vec3 fragPosition;
 
 // Input uniform values
 uniform samplerCube environmentMap;
@@ -79,7 +79,7 @@ vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
 void main()
 {
     // Make the simplyfying assumption that V equals R equals the normal 
-    vec3 N = normalize(fragPos);
+    vec3 N = normalize(fragPosition);
     vec3 R = N;
     vec3 V = R;
 

+ 3 - 0
src/models.c

@@ -2302,6 +2302,9 @@ void MeshTangents(Mesh *mesh)
 
     free(tan1);
     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");
 }

+ 24 - 0
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 rlClearScreenBuffers(void);                        // Clear used screen buffers (color and depth)
 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
@@ -2532,6 +2533,29 @@ void rlLoadMesh(Mesh *mesh, bool dynamic)
 #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)
 void rlUpdateMesh(Mesh mesh, int buffer, int numVertex)
 {