some basic GLSL fragment shader show casing physical correct lighting
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
in vec3 normal; | |
in vec3 eye;//from vertex to eye/origin | |
const light = vec3(0.12708472893924555, -2.5399460893115735, 2.8320502943377743) // from vertex to lightsource | |
const vec3 LIGHT_COLOR = vec3(1, 0.7, 0.4); | |
//created textures have to have realistic values | |
//Fresh asphalt 0.04 | |
//Worn asphalt 0.12 | |
//Bare soil 0.17 | |
//Green grass 0.25 | |
//Desert sand 0.40 | |
//New concrete 0.55 | |
//Fresh snow 0.80–0.90 | |
const vec3 directDiffuse = vec3(0.5);//normal diffuse color, from a texture i.e. | |
//the following values should be used: | |
//No value under 0.02 | |
// gemstones 0.05-0.17 | |
// liquids 0.02-0.04 | |
//Skin 0.028 | |
// when no idea set value of 0.04 (around plastic) | |
// for metals: | |
//Silver 0.971519 0.959915 0.915324 | |
//Aluminium 0.913183 0.921494 0.924524 | |
//Gold 1 0.765557 0.336057 | |
//Copper 0.955008 0.637427 0.538163 | |
const vec3 specColor = vec3(0.0225); | |
//how shiny things should be | |
const float gloss = 0.9; | |
const float SpecularPower = exp2(10 * gloss + 1); | |
const float normFactor = ((SpecularPower + 2) / 8 ); | |
//about textures: directDiffuse, specColor or gloss can of course be read from textures or mixed with uniforms before they are used. | |
//remember when you want to use a diffuse texture that to have gamma correct colors to linearize the color after the texture read | |
// e.g. vec4 diff = toLinear(texture(sampler, uv)) | |
vec4 toLinear(vec4 x){ return pow(x, vec4(2.2)) } | |
vec4 toGamma(vec4 x){ return pow(x, vec4(1/2.2)) } | |
float saturate(float a) | |
{ | |
return min(1,max(0,a)); | |
} | |
#define OneOnLN2_x6 8.656170 // == 1/ln(2) * 6 (6 is SpecularPower of 5 + 1) | |
vec3 FresnelSchlick(vec3 E,vec3 H) | |
{ | |
return specColor + (1.0f - specColor) * exp2(-OneOnLN2_x6 * saturate(dot(E, H))); | |
} | |
float BlinnPhong(vec3 N, vec3 H) | |
{ | |
return pow(saturate(dot(N, H)), SpecularPower); | |
} | |
vec3 light(vec3 N, vec3 V, vec3 L, vec3 lightColor) | |
{ | |
vec3 H = normalize(L+V); | |
float NdotL = dot(N, L); | |
vec3 directSpecular = FresnelSchlick(L, H) * BlinnPhong(N, H) * normFactor; | |
return (directDiffuse + directSpecular) * lightColor * max(0,NdotL); | |
} | |
void main() | |
{ | |
vec3 N = normalize(normal); | |
vec3 V = normalize(eye); | |
vec3 L = normalize(light); | |
vec3 color = light(N, V, L, LIGHT_COLOR); | |
//color += ... now add other lightsource or ambient light(directDiffuse * ambientLigthColor) | |
FragColor = toGamma(vec4(color, 1)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment