Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: Please help! About BRDF

  1. #1
    Newbie Newbie
    Join Date
    Jan 2017
    Posts
    5

    Please help! About BRDF

    I am the new comer of opengl. My boss asked me to write a opengl program which has used brdf inside the shader.
    Is there any demo code or tutorial can I follow?
    I am very frustrated about that. Please help me

  2. #2
    Intern Contributor
    Join Date
    May 2016
    Posts
    75
    I am trying to figure out how to do that myself.

    Here is a good place to start.

    If you have an extremely solid math background you might pick up a copy of Real Time Rendering. That's the best book on the subject I've found although I'm very comfortable with linear algebra (but not Calculus) and I don't understand a good portion of what he's talking about because he describes everything in Calculus equations. Still, I'm able to gleam a little from his descriptions of the algorithms. It's probably a really well written book if you understand Calculus; unfortunately, I do not.

    You can probably find a BRDF shader on GitHub or something and work on reverse engineering it. That's probably what I'm going to do.

    I'm learning to make PBR models right now and I'm probably going to be importing my model back into Blender this weekend to render it after texturing it in Substance. That should give me some idea of how PBR and the metalic work flow is actually rendered, which should make it a little easier to understand how to render it myself in GLSL. Once I see how Blender uses the maps exported by Substance, it should be a little more clear what my GLSL render needs to do.

    But if someone has a GLSL shader for the PBR metalic work flow or even the smoothness glossiness work flow, I'd love to see it with an explanation.

  3. #3
    Newbie Newbie
    Join Date
    Jan 2017
    Posts
    5
    Quote Originally Posted by BBeck1 View Post
    I am trying to figure out how to do that myself.

    Here is a good place to start.

    If you have an extremely solid math background you might pick up a copy of Real Time Rendering. That's the best book on the subject I've found although I'm very comfortable with linear algebra (but not Calculus) and I don't understand a good portion of what he's talking about because he describes everything in Calculus equations. Still, I'm able to gleam a little from his descriptions of the algorithms. It's probably a really well written book if you understand Calculus; unfortunately, I do not.

    You can probably find a BRDF shader on GitHub or something and work on reverse engineering it. That's probably what I'm going to do.

    I'm learning to make PBR models right now and I'm probably going to be importing my model back into Blender this weekend to render it after texturing it in Substance. That should give me some idea of how PBR and the metalic work flow is actually rendered, which should make it a little easier to understand how to render it myself in GLSL. Once I see how Blender uses the maps exported by Substance, it should be a little more clear what my GLSL render needs to do.

    But if someone has a GLSL shader for the PBR metalic work flow or even the smoothness glossiness work flow, I'd love to see it with an explanation.

    Thanks. Are you also doing the BRDF rendering projects? Is there any small program about BRDF implementation that I can follow to know how to do it? Appreciate. XD

  4. #4
    Newbie Newbie
    Join Date
    Jan 2017
    Posts
    4
    Hey !

    This might not be the best ressource out there, but I'm working on a rendering project myself and had to write BRDF code in some fragment shader.

    Here's the source if you want to take a look at it : https://github.com/rivten/gliewer/bl...mapping_f.glsl

    I do not claim this is a perfect not even correct code, but it seems to work fine for me and if it can help you in some way, that'd be great. There are also a loooot of ressources online for BRDF if you google just a little bit, but examples are hard to come by unfortunately.

  5. #5
    Intern Contributor
    Join Date
    May 2016
    Posts
    75
    Quote Originally Posted by thedarkknight1717 View Post
    Thanks. Are you also doing the BRDF rendering projects? Is there any small program about BRDF implementation that I can follow to know how to do it? Appreciate. XD
    Not yet. I've been reading up on the subject. I'm learning how to model PBR models and my Blinn-Phong shader isn't going to be able to display the art I'm learning how to make. I'm going to have to build a PBR shader or two and get it working to have any of the work I'm doing in my OGL programs. (Although at this point, I can just import them back into Blender and use Cycles to render pictures of the models which should give me a little more insight into the process of rendering them setting up the shader in Cycles. At some point though, I want to get these types of models into my OGL programs. So, that will require building PBR shaders in GLSL which will have BRDF's at their core.)

    I'm more focused on making the art right now than I am figuring out the GLSL. But hopefully in the next few months I'll turn my attention back to code and try and figure out how to write the GLSL. So, thanks rivten, that looks helpful to have a working code example.

    Of course, BRDF's are just a part of PBR, but it looks to me that all Physically Based Rendering is built around BRDF's.

  6. #6
    Intern Contributor
    Join Date
    May 2016
    Posts
    75
    I thought this video was pretty good at explaining PBR. And of course, PBR is built on top of BRDF's.

  7. #7
    Newbie Newbie
    Join Date
    Jan 2017
    Posts
    5
    Quote Originally Posted by rivten View Post
    Hey !

    This might not be the best ressource out there, but I'm working on a rendering project myself and had to write BRDF code in some fragment shader.

    Here's the source if you want to take a look at it : https://github.com/rivten/gliewer/bl...mapping_f.glsl

    I do not claim this is a perfect not even correct code, but it seems to work fine for me and if it can help you in some way, that'd be great. There are also a loooot of ressources online for BRDF if you google just a little bit, but examples are hard to come by unfortunately.
    Thanks. But I have no ideal how to implement the BRDF in the program. Is there any good tutorial for that? I am scare to be blamed by my boss. I need to finish it asap.

  8. #8
    Intern Contributor
    Join Date
    May 2016
    Posts
    75
    You may just want to admit to your boss you don't know how to do it. Sometimes honesty is the best policy.

    Every day I learn more about this subject and yet, I still have a very long way to go. I finished my (well really not mine because I followed a tutorial) PBR shader in Blender Cycles and learned quite a bit from it. One thing that became clear from that is that there are a lot of BRDF shaders. Wikipedia lists 12 different BRDF algorithms.

    From what you've said, your boss did not specify which one, which makes me question whether your boss has any idea what a BRDF is. Although, I'm far from an expert on this subject. So, I'm probably the last person who should be criticizing someone for not knowing what a BRDF is. But it would seem to me that requesting a BRDF is almost as generic as asking for a shader. I think pretty much the only non-BRDF shaders are maybe toon shaders and artistic shaders that are not realistic. So, the term "BRDF" would eliminate those, but otherwise says almost nothing about what is required.

    But from what I'm reading, Blinn-Phong is a BRDF (which I did not know having assumed all BRDF's are more complex than Blinn-Phong). So "technically" I think you could hand over a Blinn-Phong shader and honestly say it is a BRDF. And in that case, I can actually help you. Besides, Blinn-Phong is a really good place to start because, with my limited knowledge on the subject, most of the others seem to kind of build on the same BRDF ideas of Blinn-Phong with more and more advanced algorithms and then joining those algorithms together in a single shader. Physically Based Rendering, for example, uses at least Cook-Torrance and Fresnel in a single mathematical equation. All that's explained in Real Time Rendering which has a pretty indepth look at the math.

    If you can sell Blinn-Phong as a BRDF, you should probably check out my video series on Blinn-Phong which is a series on HLSL. It walks you through step by step in creating a Blinn-Phong shader with texturing in HLSL. That's a good starting point to learn other shaders too. The next video in the series would have been normal mapping, because once you get that far you're ready for other stuff like normal mapping. I did a proto-type program but never got around to making that video.

    Anyway, its HLSL and not GLSL, but the math is the main thing. It's also XNA instead of OpenGL, but the basic principles are the same. On top of that, I have pretty much the exact same shader written in GLSL in my OpenGL basic engine project on my website. That's a complete Visual Studio C++, OpenGL 4.5, GLSL shader and the calling program that uses Blinn-Phong with texturing. So, you can see how the GLSL is called in code.

    So, as long as you can pass Blinn-Phong off as a BRDF, there's a working code example for you complete with everything needed to make it run. (I do use several libraries as stated, like GLFW and GLM and FreeImage.) And from what I'm reading, Blinn-Phong is technically a BRDF. I think my confusion is that I immediately start thinking "Cook-Torrance"+"Fresnel" where you are using an incoming area of light, rather than a single ray and use a cubemap to determine the incoming light rather than single directional light. But apparently you don't have to get nearly that complicated for it to be a BRDF. I guess I'm thinking that all BRDF's are what the Wikipedia article calls "Physically Based BDRF's" which appears to be where the tie in with Physically Based Rendering comes in. And I think I may also have been confusing BRDF's with BSDF's as well.

    If the Blinn-Phong shader can "get you there", then the links above should help substantially. Short of that though, I've been trying to figure this stuff out for a couple of months now, and granted I have a whole lot of other stuff that is higher priority taking me away from it, but it's still a pretty big complex subject. There might be enough in the links above to learn Blinn-Phong in an 8 hour day (the videos assume you know almost nothing other than trig and algebra and start almost too far towards the beginning of the subject), but the broader subject of BRDF's is something that I would expect to take months to learn unless you really have someone holding your hand through the learning process.

    And as far as the videos being HLSL instead of GLSL, it's good to know HLSL anyway just so you can read example code from books and such. And if you compare it to the GLSL shader I linked above, it should be pretty obvious how they are alike and how they are different. HLSL Constant Buffers are basically GLSL Uniforms.

    Just for good measure, I'll throw in the GLSL Blinn-Phong shader here(I've posted it on the Internet before. The code includes both a Blinn specular function and a Phong specular function as in the videos. You only need one or the other, but it's two different algorithms that do the same thing.):

    BlinnPhong.vrt
    Code :
    #version 450 core
    layout (location = 0) in vec3 Pos;
    layout (location = 1) in vec2 UV;
    layout (location = 2) in vec3 Normal;
    layout (location = 3) in vec4 Color;
     
    uniform mat4 WorldMatrix;
    uniform mat4 ViewMatrix;
    uniform mat4 ProjectionMatrix;
     
     
     
    smooth out vec2 TextureCoordinates;
    smooth out vec3 VertexNormal;
    smooth out vec4 RGBAColor;
    smooth out vec4 PositionRelativeToCamera;
    out vec3 WorldSpacePosition;
     
     
    void main()
    {
    	gl_Position = WorldMatrix * vec4(Pos, 1.0f);				//Apply object's world matrix.
    	WorldSpacePosition = gl_Position.xyz;						//Save the position of the vertex in the 3D world just calculated. Convert to vec3 because it will be used with other vec3's.
    	gl_Position = ViewMatrix * gl_Position;						//Apply the view matrix for the camera.
    	PositionRelativeToCamera = gl_Position;
    	gl_Position = ProjectionMatrix * gl_Position;				//Apply the Projection Matrix to project it on to a 2D plane.
    	TextureCoordinates = UV;									//Pass through the texture coordinates to the fragment shader.
    	VertexNormal = mat3(WorldMatrix) * Normal;					//Rotate the normal according to how the model is oriented in the 3D world.
    	RGBAColor = Color;											//Pass through the color to the fragment shader.
    };

    BlinnPhong.frg
    Code :
    #version 450 core
     
    in vec2 TextureCoordinates;
    in vec3 VertexNormal;
    in vec4 RGBAColor;
    in float FogFactor;
    in vec4 PositionRelativeToCamera;
    in vec3 WorldSpacePosition;
     
    layout (location = 0) out vec4 OutputColor;
     
     
    uniform vec4 AmbientLightColor;
    uniform vec3 DiffuseLightDirection;
    uniform vec4 DiffuseLightColor;
    uniform vec3 CameraPosition;
    uniform float SpecularPower;
    uniform vec4 FogColor;
    uniform float FogStartDistance;
    uniform float FogMaxDistance;
    uniform bool UseTexture;
    uniform sampler2D Texture0;
     
     
     
    vec4 BlinnSpecular(in vec3 LightDirection, in vec4 LightColor, in vec3 PixelNormal, in vec3 CameraDirection, in float SpecularPower)
    {
    	vec3 HalfwayNormal;
    	vec4 SpecularLight;
    	float SpecularHighlightAmount;
     
     
    	HalfwayNormal = normalize(LightDirection + CameraDirection);
    	SpecularHighlightAmount = pow(clamp(dot(PixelNormal, HalfwayNormal), 0.0, 1.0), SpecularPower);
    	SpecularLight = SpecularHighlightAmount * LightColor; 
     
    	return SpecularLight;
    }
     
     
    vec4 PhongSpecular(in vec3 LightDirection, in vec4 LightColor, in vec3 PixelNormal, in vec3 CameraDirection, in float SpecularPower)
    {
    	vec3 ReflectedLightDirection;	
    	vec4 SpecularLight;
    	float SpecularHighlightAmount;
     
     
    	ReflectedLightDirection = 2.0 * PixelNormal * clamp(dot(PixelNormal, LightDirection), 0.0, 1.0) - LightDirection;
    	SpecularHighlightAmount = pow(clamp(dot(ReflectedLightDirection, CameraDirection), 0.0, 1.0), SpecularPower);
    	SpecularLight = SpecularHighlightAmount * LightColor; 
     
     
    	return SpecularLight;
    }
     
     
    void main()
    {
    	vec3 LightDirection;
    	float DiffuseLightPercentage;
    	vec4 SpecularColor;
    	vec3 CameraDirection;	//Float3 because the w component really doesn't belong in a 3D vector normal.
    	vec4 AmbientLight;
    	vec4 DiffuseLight;
    	vec4 InputColor;
     
     
    	if (UseTexture) 
    	{
    		InputColor = texture(Texture0, TextureCoordinates);
    	}
    	else
    	{
    		InputColor = RGBAColor; // vec4(0.0, 0.0, 0.0, 1.0);
    	}
     
     
    	LightDirection = -normalize(DiffuseLightDirection);	//Normal must face into the light, rather than WITH the light to be lit up.
    	DiffuseLightPercentage = max(dot(VertexNormal, LightDirection), 0.0);	//Percentage is based on angle between the direction of light and the vertex's normal. 
    	DiffuseLight = clamp((DiffuseLightColor * InputColor) * DiffuseLightPercentage, 0.0, 1.0);	//Apply only the percentage of the diffuse color. Saturate clamps output between 0.0 and 1.0.
     
    	CameraDirection = normalize(CameraPosition - WorldSpacePosition);	//Create a normal that points in the direction from the pixel to the camera.
     
    	if (DiffuseLightPercentage == 0.0f) 
    	{
    		SpecularColor  = vec4(0.0f, 0.0f, 0.0f, 1.0f);
    	}
    	else
    	{
    		//SpecularColor = BlinnSpecular(LightDirection, DiffuseLightColor, normalize(VertexNormal), CameraDirection, SpecularPower);
    		SpecularColor = PhongSpecular(LightDirection, DiffuseLightColor, normalize(VertexNormal), CameraDirection, SpecularPower);
    	}
     
    	float FogDensity = 0.01f;
    	float LOG2 = 1.442695f;
    	float FogFactor = exp2(-FogDensity * FogDensity * PositionRelativeToCamera.z * PositionRelativeToCamera.z * LOG2);
    	FogFactor = 1 - FogFactor;
    	//float FogFactor = clamp((FogMaxDistance - PositionRelativeToCamera.z)/(FogMaxDistance - FogStartDistance), 0.0, 1.0);
     
    	OutputColor = RGBAColor * (AmbientLightColor * InputColor) + DiffuseLight + SpecularColor;
    	OutputColor = mix (OutputColor, FogColor, FogFactor);
    	//OutputColor = vec4(0.0f, 0.5f, 0.0f, 1.0f);
    };
    Last edited by BBeck1; 01-16-2017 at 06:29 AM.

  9. #9
    Newbie Newbie
    Join Date
    Jan 2017
    Posts
    5
    Thanks for your great help.
    I have seen there are some BRDF dataset. And people use them to render image. What is the different between using equations and using dataset to rendering?

  10. #10
    Newbie Newbie
    Join Date
    Jan 2017
    Posts
    5
    Quote Originally Posted by BBeck1 View Post
    I thought this video was pretty good at explaining PBR. And of course, PBR is built on top of BRDF's.
    Thanks you help. May I have the source code of the whole project using the blinn-phong in glsl shader and opengl to construct the cubemap. I really need this program as a start-point to study brdf. THanks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •