Working on materials PBR...

Some issues with the shader (GPU dependant)
This commit is contained in:
Ray 2017-07-14 01:16:22 +02:00
parent de80808dbe
commit 28679e3c79
5 changed files with 125 additions and 88 deletions

View File

@ -30,11 +30,9 @@ int main()
Texture2D texHDR = LoadTexture("resources/pinetree.hdr");
model.material = LoadMaterialPBR(texHDR, (Color){ 255, 255, 255, 255 }, 1.0f, 1.0f);
model.material.maps[TEXMAP_ALBEDO].tex = LoadTexture("resources/pbr/trooper_albedo.png");
SetShaderValuei(model.material.shader, GetShaderLocation(model.material.shader, "albedo.sampler"), (int[1]){ TEXMAP_ALBEDO }, 1);
SetShaderValuei(model.material.shader, GetShaderLocation(model.material.shader, "albedo.useSampler"), (int[1]){ 1 }, 1);
//model.material.maps[TEXMAP_ALBEDO].tex = LoadTexture("resources/pbr/trooper_albedo.png");
SetMaterialTexture(&model.material, TEXMAP_ALBEDO, LoadTexture("resources/pbr/trooper_albedo.png"));
/*
SetMaterialTexture(&model.material, TEXMAP_NORMAL, LoadTexture("resources/pbr/trooper_normals.png"));
SetTextureFilter(model.material.maps[TEXMAP_NORMAL].tex, FILTER_BILINEAR);
@ -49,8 +47,9 @@ int main()
for (int i = 0; i < 12; i++)
{
printf("TexMap %i ID: %i\n", i, model.material.maps[i].tex.id);
//printf("TexMap %i ID: %i\n", i, model.material.maps[i].tex.id);
}
*/
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
@ -73,7 +72,7 @@ int main()
Begin3dMode(camera);
DrawModel(model, VectorZero(), 1.0f, RED);
DrawModel(model, VectorZero(), 1.0f, WHITE);
DrawGrid(10, 1.0f);

View File

@ -41,18 +41,23 @@ uniform MaterialProperty albedo;
uniform MaterialProperty normals;
uniform MaterialProperty metalness;
uniform MaterialProperty roughness;
uniform MaterialProperty ao;
uniform MaterialProperty occlusion;
uniform MaterialProperty emission;
uniform MaterialProperty height;
// Input lighting values
uniform Light lights[MAX_LIGHTS];
// Input uniform values
uniform samplerCube irradianceMap;
uniform samplerCube prefilterMap;
uniform sampler2D brdfLUT;
//uniform sampler2D albedo;
//uniform sampler2D normals;
//uniform sampler2D metalness;
// Input lighting values
uniform Light lights[MAX_LIGHTS];
// Other uniform values
uniform int renderMode;
uniform vec3 viewPos;
@ -184,17 +189,19 @@ void main()
else texCoord = fragTexCoord; // Use default texture coordinates
// Fetch material values from texture sampler or color attributes
vec3 color = pow(ComputeMaterialProperty(albedo), vec3(2.2));
vec3 metal = ComputeMaterialProperty(metalness);
vec3 rough = ComputeMaterialProperty(roughness);
vec3 emiss = ComputeMaterialProperty(emission);
vec3 occlusion = ComputeMaterialProperty(ao);
vec3 color = pow(texture(albedo.sampler, texCoord).rgb, vec3(2.2));//pow(ComputeMaterialProperty(albedo), vec3(2.2));
vec3 metal = texture(metalness.sampler, texCoord).rgb; //ComputeMaterialProperty(metalness);
vec3 rough = texture(roughness.sampler, texCoord).rgb; //ComputeMaterialProperty(roughness);
vec3 emiss = texture(emission.sampler, texCoord).rgb; //ComputeMaterialProperty(emission);
vec3 ao = texture(occlusion.sampler, texCoord).rgb; //ComputeMaterialProperty(occlusion);
vec3 all = color + metal + rough + emiss + ao;
// Check if normal mapping is enabled
if (normals.useSampler == 1)
{
// Fetch normal map color and transform lighting values to tangent space
normal = ComputeMaterialProperty(normals);
normal = texture(normals.sampler, texCoord).rgb; //ComputeMaterialProperty(normals);
normal = normalize(normal*2.0 - 1.0);
normal = normalize(normal*TBN);
@ -210,6 +217,7 @@ void main()
vec3 Lo = vec3(0.0);
vec3 lightDot = vec3(0.0);
/*
for (int i = 0; i < MAX_LIGHTS; i++)
{
if (lights[i].enabled == 1)
@ -251,6 +259,7 @@ void main()
lightDot += radiance*NdotL + brdf*lights[i].color.a;
}
}
*/
// Calculate ambient lighting using IBL
vec3 F = fresnelSchlickRoughness(max(dot(normal, view), 0.0), F0, rough.r);
@ -268,7 +277,7 @@ void main()
vec3 reflection = prefilterColor*(F*brdf.x + brdf.y);
// Calculate final lighting
vec3 ambient = (kD*diffuse + reflection)*occlusion;
vec3 ambient = (kD*diffuse + reflection)*ao;
// Calculate fragment color based on render mode
vec3 fragmentColor = ambient + Lo + emiss; // Physically Based Rendering
@ -277,7 +286,7 @@ void main()
else if (renderMode == 2) fragmentColor = normal; // Normals
else if (renderMode == 3) fragmentColor = metal; // Metalness
else if (renderMode == 4) fragmentColor = rough; // Roughness
else if (renderMode == 5) fragmentColor = occlusion; // Ambient Occlusion
else if (renderMode == 5) fragmentColor = ao; // Ambient Occlusion
else if (renderMode == 6) fragmentColor = emiss; // Emission
else if (renderMode == 7) fragmentColor = lightDot; // Lighting
else if (renderMode == 8) fragmentColor = kS; // Fresnel
@ -291,5 +300,5 @@ void main()
fragmentColor = pow(fragmentColor, vec3(1.0/2.2));
// Calculate final fragment color
finalColor = vec4(fragmentColor, 1.0);
finalColor = vec4(all, 1.0);//vec4(fragmentColor, 1.0); // It works, so texture is correctly binded!
}

View File

@ -1305,20 +1305,20 @@ Material LoadMaterialPBR(Texture2D hdr, Color albedo, float metalness, float rou
mat.shader = LoadShader(PATH_PBR_VS, PATH_PBR_FS);
// Set up PBR shader material texture units
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "albedo.sampler"), (int[1]){ TEXMAP_ALBEDO }, 1);
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "normals.sampler"), (int[1]){ TEXMAP_NORMAL }, 1);
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "metalness.sampler"), (int[1]){ TEXMAP_METALNESS }, 1);
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "roughness.sampler"), (int[1]){ TEXMAP_ROUGHNESS }, 1);
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "occlusion.sampler"), (int[1]){ TEXMAP_OCCLUSION }, 1);
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "emission.sampler"), (int[1]){ TEXMAP_EMISSION }, 1);
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "height.sampler"), (int[1]){ TEXMAP_HEIGHT }, 1);
// Set up environment shader texture units
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "irradianceMap"), (int[1]){ TEXMAP_IRRADIANCE }, 1);
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "prefilterMap"), (int[1]){ TEXMAP_PREFILTER }, 1);
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "brdfLUT"), (int[1]){ TEXMAP_BRDF }, 1);
// Get required locations points for PBR material
// NOTE: Those location names must be available and used in the shader code
mat.shader.locs[LOC_TEXMAP_ALBEDO] = GetShaderLocation(mat.shader, "albedo.sampler");
mat.shader.locs[LOC_TEXMAP_METALNESS] = GetShaderLocation(mat.shader, "metalness.sampler");
mat.shader.locs[LOC_TEXMAP_NORMAL] = GetShaderLocation(mat.shader, "normals.sampler");
mat.shader.locs[LOC_TEXMAP_ROUGHNESS] = GetShaderLocation(mat.shader, "roughness.sampler");
mat.shader.locs[LOC_TEXMAP_OCCUSION] = GetShaderLocation(mat.shader, "occlusion.sampler");
mat.shader.locs[LOC_TEXMAP_EMISSION] = GetShaderLocation(mat.shader, "emission.sampler");
mat.shader.locs[LOC_TEXMAP_HEIGHT] = GetShaderLocation(mat.shader, "height.sampler");
mat.shader.locs[LOC_TEXMAP_IRRADIANCE] = GetShaderLocation(mat.shader, "irradianceMap");
mat.shader.locs[LOC_TEXMAP_PREFILTER] = GetShaderLocation(mat.shader, "prefilterMap");
mat.shader.locs[LOC_TEXMAP_BRDF] = GetShaderLocation(mat.shader, "brdfLUT");
// Set view matrix location
mat.shader.locs[LOC_MATRIX_VIEW] = GetShaderLocation(mat.shader, "viewPos");
// Set up material properties color
@ -1337,8 +1337,8 @@ Material LoadMaterialPBR(Texture2D hdr, Color albedo, float metalness, float rou
// Set up environment materials cubemap
Texture2D cubemap = rlGenMapCubemap(hdr, CUBEMAP_SIZE);
mat.maps[TEXMAP_IRRADIANCE].tex = rlGenMapIrradiance(cubemap, IRRADIANCE_SIZE);
mat.maps[TEXMAP_PREFILTER].tex = rlGenMapPrefilter(cubemap, PREFILTERED_SIZE);
// mat.maps[TEXMAP_IRRADIANCE].tex = rlGenMapIrradiance(cubemap, IRRADIANCE_SIZE);
// mat.maps[TEXMAP_PREFILTER].tex = rlGenMapPrefilter(cubemap, PREFILTERED_SIZE);
mat.maps[TEXMAP_BRDF].tex = rlGenMapBRDF(cubemap, BRDF_SIZE);
UnloadTexture(cubemap);

View File

@ -530,53 +530,47 @@ typedef enum {
LOC_VERTEX_POSITION = 0,
LOC_VERTEX_TEXCOORD01,
LOC_VERTEX_TEXCOORD02,
LOC_VERTEX_TEXCOORD03,
LOC_VERTEX_TEXCOORD04,
LOC_VERTEX_NORMAL,
LOC_VERTEX_TANGENT,
LOC_VERTEX_COLOR,
LOC_MATRIX_MVP,
LOC_MATRIX_VIEW,
LOC_MATRIX_PROJECTION,
LOC_TEXTURE_MAP01,
LOC_TEXTURE_MAP02,
LOC_TEXTURE_MAP03,
LOC_TEXTURE_MAP04,
LOC_TEXTURE_MAP05,
LOC_TEXTURE_MAP06,
LOC_TEXTURE_MAP07,
LOC_TEXTURE_MAP08,
LOC_TEXTURE_COLOR01,
LOC_TEXTURE_COLOR02,
LOC_TEXTURE_COLOR03,
LOC_TEXTURE_COLOR04,
LOC_TEXTURE_COLOR05,
LOC_TEXTURE_COLOR06,
LOC_TEXTURE_COLOR07,
LOC_TEXTURE_COLOR08
LOC_COLOR_DIFFUSE,
LOC_COLOR_SPECULAR,
LOC_COLOR_AMBIENT,
LOC_TEXMAP_ALBEDO, // LOC_TEXMAP_DIFFUSE
LOC_TEXMAP_METALNESS, // LOC_TEXMAP_SPECULAR
LOC_TEXMAP_NORMAL,
LOC_TEXMAP_ROUGHNESS,
LOC_TEXMAP_OCCUSION,
LOC_TEXMAP_EMISSION,
LOC_TEXMAP_HEIGHT,
LOC_TEXMAP_CUBEMAP,
LOC_TEXMAP_IRRADIANCE,
LOC_TEXMAP_PREFILTER,
LOC_TEXMAP_BRDF
} ShaderLocationIndex;
typedef enum {
TEXMAP_DIFFUSE = 0,
TEXMAP_SPECULAR = 1,
} TexmapBasicIndex;
#define LOC_TEXMAP_DIFFUSE LOC_TEXMAP_ALBEDO
#define LOC_TEXMAP_SPECULAR LOC_TEXMAP_METALNESS
typedef enum {
TEXMAP_ALBEDO = 0,
TEXMAP_METALNESS = 1,
TEXMAP_ALBEDO = 0, // TEXMAP_DIFFUSE
TEXMAP_METALNESS = 1, // TEXMAP_SPECULAR
TEXMAP_NORMAL = 2,
TEXMAP_ROUGHNESS = 3,
TEXMAP_OCCLUSION,
TEXMAP_EMISSION,
TEXMAP_HEIGHT
} TexmapPBRIndex;
TEXMAP_HEIGHT,
TEXMAP_CUBEMAP, // NOTE: Uses GL_TEXTURE_CUBE_MAP
TEXMAP_IRRADIANCE, // NOTE: Uses GL_TEXTURE_CUBE_MAP
TEXMAP_PREFILTER, // NOTE: Uses GL_TEXTURE_CUBE_MAP
TEXMAP_BRDF
} TexmapIndex;
typedef enum {
TEXMAP_CUBEMAP = 8,
TEXMAP_IRRADIANCE,
TEXMAP_PREFILTER,
TEXMAP_BRDF,
} TexmapEnvIndex;
#define TEXMAP_DIFFUSE TEXMAP_ALBEDO
#define TEXMAP_SPECULAR TEXMAP_METALNESS
// Texture formats
// NOTE: Support depends on OpenGL version and platform

View File

@ -337,7 +337,7 @@ static void LoadTextureCompressed(unsigned char *data, int width, int height, in
static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShaderStr); // Load custom shader strings and return program id
static Shader LoadShaderDefault(void); // Load default shader (just vertex positioning and texture coloring)
static void LoadShaderDefaultLocations(Shader *shader); // Bind default shader locations (attributes and uniforms)
static void SetShaderDefaultLocations(Shader *shader); // Bind default shader locations (attributes and uniforms)
static void UnLoadShaderDefault(void); // Unload default shader
static void LoadDefaultBuffers(void); // Load default internal buffers (lines, triangles, quads)
@ -2383,7 +2383,7 @@ void rlDrawMesh(Mesh mesh, Material material, Matrix transform)
*/
// Upload to shader material.colDiffuse
glUniform4f(material.shader.locs[LOC_TEXTURE_COLOR01], (float)material.maps[TEXMAP_DIFFUSE].color.r/255,
glUniform4f(material.shader.locs[LOC_COLOR_DIFFUSE], (float)material.maps[TEXMAP_DIFFUSE].color.r/255,
(float)material.maps[TEXMAP_DIFFUSE].color.g/255,
(float)material.maps[TEXMAP_DIFFUSE].color.b/255,
(float)material.maps[TEXMAP_DIFFUSE].color.a/255);
@ -2396,8 +2396,8 @@ void rlDrawMesh(Mesh mesh, Material material, Matrix transform)
// (float)material.colAmbient.a/255);
// Upload to shader material.colSpecular (if available)
if (material.shader.locs[LOC_TEXTURE_COLOR03] != -1)
glUniform4f(material.shader.locs[LOC_TEXTURE_COLOR03], (float)material.maps[TEXMAP_SPECULAR].color.r/255,
if (material.shader.locs[LOC_COLOR_SPECULAR] != -1)
glUniform4f(material.shader.locs[LOC_COLOR_SPECULAR], (float)material.maps[TEXMAP_SPECULAR].color.r/255,
(float)material.maps[TEXMAP_SPECULAR].color.g/255,
(float)material.maps[TEXMAP_SPECULAR].color.b/255,
(float)material.maps[TEXMAP_SPECULAR].color.a/255);
@ -2419,7 +2419,8 @@ void rlDrawMesh(Mesh mesh, Material material, Matrix transform)
glActiveTexture(GL_TEXTURE0 + i);
if ((i == TEXMAP_IRRADIANCE) || (i == TEXMAP_PREFILTER) || (i == TEXMAP_CUBEMAP)) glBindTexture(GL_TEXTURE_CUBE_MAP, material.maps[i].tex.id);
else glBindTexture(GL_TEXTURE_2D, material.maps[i].tex.id);
glUniform1i(material.shader.locs[LOC_TEXTURE_MAP01 + i], i);
glUniform1i(material.shader.locs[LOC_TEXMAP_DIFFUSE + i], i);
}
}
@ -2794,8 +2795,8 @@ Shader LoadShader(char *vsFileName, char *fsFileName)
{
shader.id = LoadShaderProgram(vShaderStr, fShaderStr);
// After shader loading, we try to load default location names
if (shader.id > 0) LoadShaderDefaultLocations(&shader);
// After shader loading, we TRY to set default location names
if (shader.id > 0) SetShaderDefaultLocations(&shader);
// Shader strings must be freed
free(vShaderStr);
@ -2807,6 +2808,32 @@ Shader LoadShader(char *vsFileName, char *fsFileName)
TraceLog(WARNING, "Custom shader could not be loaded");
shader = defaultShader;
}
// Get available shader uniforms
// NOTE: This information is useful for debug...
int uniformCount = -1;
glGetProgramiv(shader.id, GL_ACTIVE_UNIFORMS, &uniformCount);
for(int i = 0; i < uniformCount; i++)
{
int namelen = -1;
int num = -1;
char name[256]; // Assume no variable names longer than 256
GLenum type = GL_ZERO;
// Get the name of the uniforms
glGetActiveUniform(shader.id, i,sizeof(name) - 1, &namelen, &num, &type, name);
name[namelen] = 0;
// Get the location of the named uniform
GLuint location = glGetUniformLocation(shader.id, name);
TraceLog(INFO, "[SHDR ID %i] Active uniform [%s] set at location: %i", shader.id, name, location);
}
#endif
return shader;
@ -2860,7 +2887,8 @@ int GetShaderLocation(Shader shader, const char *uniformName)
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
location = glGetUniformLocation(shader.id, uniformName);
if (location == -1) TraceLog(DEBUG, "[SHDR ID %i] Shader location for %s could not be found", shader.id, uniformName);
if (location == -1) TraceLog(WARNING, "[SHDR ID %i] Shader uniform [%s] COULD NOT BE FOUND", shader.id, uniformName);
else TraceLog(INFO, "[SHDR ID %i] Shader uniform [%s] set at location: %i", shader.id, uniformName, location);
#endif
return location;
}
@ -3019,7 +3047,7 @@ void InitVrSimulator(int vrDevice)
#if defined(SUPPORT_DISTORTION_SHADER)
// Load distortion shader (initialized by default with Oculus Rift CV1 parameters)
vrConfig.distortionShader.id = LoadShaderProgram(vDistortionShaderStr, fDistortionShaderStr);
if (vrConfig.distortionShader.id > 0) LoadShaderDefaultLocations(&vrConfig.distortionShader);
if (vrConfig.distortionShader.id > 0) SetShaderDefaultLocations(&vrConfig.distortionShader);
#endif
SetStereoConfig(hmd);
@ -3423,7 +3451,17 @@ static Shader LoadShaderDefault(void)
if (shader.id > 0)
{
TraceLog(INFO, "[SHDR ID %i] Default shader loaded successfully", shader.id);
LoadShaderDefaultLocations(&shader);
// Set default shader locations
// Get handles to GLSL input attibute locations
shader.locs[LOC_VERTEX_POSITION] = glGetAttribLocation(shader.id, "vertexPosition");
shader.locs[LOC_VERTEX_TEXCOORD01] = glGetAttribLocation(shader.id, "vertexTexCoord");
shader.locs[LOC_VERTEX_COLOR] = glGetAttribLocation(shader.id, "vertexColor");
// Get handles to GLSL uniform locations
shader.locs[LOC_MATRIX_MVP] = glGetUniformLocation(shader.id, "mvpMatrix");
shader.locs[LOC_COLOR_DIFFUSE] = glGetUniformLocation(shader.id, "colDiffuse");
shader.locs[LOC_TEXMAP_DIFFUSE] = glGetUniformLocation(shader.id, "texture0");
}
else TraceLog(WARNING, "[SHDR ID %i] Default shader could not be loaded", shader.id);
@ -3432,7 +3470,7 @@ static Shader LoadShaderDefault(void)
// Get location handlers to for shader attributes and uniforms
// NOTE: If any location is not found, loc point becomes -1
static void LoadShaderDefaultLocations(Shader *shader)
static void SetShaderDefaultLocations(Shader *shader)
{
// NOTE: Default shader attrib locations have been fixed before linking:
// vertex position location = 0
@ -3454,13 +3492,10 @@ static void LoadShaderDefaultLocations(Shader *shader)
shader->locs[LOC_MATRIX_MVP] = glGetUniformLocation(shader->id, "mvpMatrix");
// Get handles to GLSL uniform locations (fragment shader)
shader->locs[LOC_TEXTURE_COLOR01] = glGetUniformLocation(shader->id, "colDiffuse");
shader->locs[LOC_TEXTURE_COLOR02] = glGetUniformLocation(shader->id, "colAmbient");
shader->locs[LOC_TEXTURE_COLOR03] = glGetUniformLocation(shader->id, "colSpecular");
shader->locs[LOC_TEXTURE_MAP01] = glGetUniformLocation(shader->id, "texture0");
shader->locs[LOC_TEXTURE_MAP02] = glGetUniformLocation(shader->id, "texture1");
shader->locs[LOC_TEXTURE_MAP03] = glGetUniformLocation(shader->id, "texture2");
shader->locs[LOC_COLOR_DIFFUSE] = glGetUniformLocation(shader->id, "colDiffuse");
shader->locs[LOC_TEXMAP_DIFFUSE] = glGetUniformLocation(shader->id, "texture0");
shader->locs[LOC_TEXMAP_NORMAL] = glGetUniformLocation(shader->id, "texture1");
shader->locs[LOC_TEXMAP_SPECULAR] = glGetUniformLocation(shader->id, "texture2");
// TODO: Try to find all expected/recognized shader locations (predefined names, must be documented)
}
@ -3746,8 +3781,8 @@ static void DrawDefaultBuffers()
Matrix matMVP = MatrixMultiply(modelview, projection);
glUniformMatrix4fv(currentShader.locs[LOC_MATRIX_MVP], 1, false, MatrixToFloat(matMVP));
glUniform4f(currentShader.locs[LOC_TEXTURE_COLOR01], 1.0f, 1.0f, 1.0f, 1.0f);
glUniform1i(currentShader.locs[LOC_TEXTURE_MAP01], 0);
glUniform4f(currentShader.locs[LOC_COLOR_DIFFUSE], 1.0f, 1.0f, 1.0f, 1.0f);
glUniform1i(currentShader.locs[LOC_TEXMAP_DIFFUSE], 0);
// NOTE: Additional map textures not considered for default buffers drawing
}