diff options
author | omniscient <17525998+omnisci3nce@users.noreply.github.com> | 2024-06-17 22:17:48 +1000 |
---|---|---|
committer | omniscient <17525998+omnisci3nce@users.noreply.github.com> | 2024-06-18 10:30:28 +1000 |
commit | 4b5695ce26a8f821dfac987e8e11a6ba5eeff610 (patch) | |
tree | 0cd8f80bdb0520ffcf0cd62851f72055d4ee5546 /assets | |
parent | f1cb5bece520dba63fa77e4721909ab8f0a6c26f (diff) |
start working on a immediate mode drawing API
Diffstat (limited to 'assets')
-rw-r--r-- | assets/shaders/pbr_textured.frag | 134 | ||||
-rw-r--r-- | assets/shaders/pbr_textured.vert | 28 |
2 files changed, 162 insertions, 0 deletions
diff --git a/assets/shaders/pbr_textured.frag b/assets/shaders/pbr_textured.frag new file mode 100644 index 0000000..132c449 --- /dev/null +++ b/assets/shaders/pbr_textured.frag @@ -0,0 +1,134 @@ +#version 410 core + +out vec4 FragColor; + +in vec3 fragWorldPos; +in vec3 fragNormal; +in vec2 fragTexCoords; + +struct PointLight { + vec4 position; + vec4 color; +}; + +// --- Uniforms + +// Lights data +#define NUM_POINT_LIGHTS 4 +uniform Scene_Lights { + PointLight pointLights[NUM_POINT_LIGHTS]; + vec4 viewPos; +} scene; + +// Material Textures +uniform sampler2D albedoMap; +uniform sampler2D metallicRoughnessMap; +// uniform sampler2D roughnessMap; +uniform sampler2D aoMap; +uniform sampler2D normalMap; + +const float PI = 3.14; + +// Forward declarations +vec3 fresnelSchlick(float cosTheta, vec3 F0); +float DistributionGGX(vec3 N, vec3 H, float roughness); +float GeometrySchlickGGX(float NdotV, float roughness); +float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness); + +void main() { + vec3 albedo = pow(texture(albedoMap, fragTexCoords).rgb, vec3(2.2)); + // vec3 normal = getNormalFromNormalMap(); + float metallic = texture(metallicRoughnessMap, fragTexCoords).g; + float roughness = texture(metallicRoughnessMap, fragTexCoords).b; + float ao = texture(aoMap, fragTexCoords).r; + + vec3 norm = normalize(fragNormal); // N + vec3 N = norm; + vec3 viewDir = normalize(vec3(scene.viewPos) - fragWorldPos); // V + vec3 V = viewDir; + + vec3 F0 = vec3(0.04); + F0 = mix(F0, albedo, metallic); + + vec3 Lo = vec3(0.0); + for (int i = 0; i < 4; ++i) { + vec3 lightVec = normalize(vec3(scene.pointLights[i].position) - fragWorldPos); // L + vec3 L = lightVec; + vec3 halfway = normalize(viewDir + lightVec); // H + vec3 H = halfway; + float distance = length(vec3(scene.pointLights[i].position) - fragWorldPos); + float attenuation = 1.0 / (distance * distance); + vec3 radiance = vec3(scene.pointLights[i].color) * attenuation; + + // cook-torrance brdf + float NDF = DistributionGGX(norm, halfway, roughness); + float G = GeometrySmith(norm, viewDir, lightVec, roughness); + // vec3 F = fresnelSchlick(max(dot(halfway, viewDir), 0.0), F0); + vec3 F = fresnelSchlick(clamp(dot(H, V), 0.0, 1.0), F0); + + vec3 numerator = NDF * G * F; + float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.0001; + vec3 specular = numerator / denominator; + + vec3 kS = F; + + vec3 kD = vec3(1.0) - kS; + kD *= 1.0 - metallic; + + // add to outgoing radiance Lo + float NdotL = max(dot(N, L), 0.0); + Lo += (kD * albedo / PI + specular) * radiance * NdotL; + // Lo += radiance; + } + + vec3 ambient = vec3(0.03) * albedo * ao; + vec3 color = ambient + Lo; //ambient + Lo; + + color = color / (color + vec3(1.0)); + color = pow(color, vec3(1.0/2.2)); + + FragColor = vec4(color, 1.0); + // FragColor = vec4(1.0); + // FragColor = vec4(scene.pointLights[0].position); + FragColor = vec4(albedo, 1.0); + // FragColor = vec4(pbr.metallic, pbr.roughness, pbr.ao, 1.0); + // FragColor = scene.viewPos; +} + +/* The below are from https://learnopengl.com/PBR/Lighting */ + +vec3 fresnelSchlick(float cosTheta, vec3 F0) { + return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0); +} +float DistributionGGX(vec3 N, vec3 H, float roughness) { + float a = roughness*roughness; + float a2 = a*a; + float NdotH = max(dot(N, H), 0.0); + float NdotH2 = NdotH*NdotH; + + float num = a2; + float denom = (NdotH2 * (a2 - 1.0) + 1.0); + denom = PI * denom * denom; + + return num / denom; +} + +float GeometrySchlickGGX(float NdotV, float roughness) +{ + float r = (roughness + 1.0); + float k = (r*r) / 8.0; + + float num = NdotV; + float denom = NdotV * (1.0 - k) + k; + + return num / denom; +} +float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) +{ + float NdotV = max(dot(N, V), 0.0); + float NdotL = max(dot(N, L), 0.0); + float ggx2 = GeometrySchlickGGX(NdotV, roughness); + float ggx1 = GeometrySchlickGGX(NdotL, roughness); + + return ggx1 * ggx2; +} diff --git a/assets/shaders/pbr_textured.vert b/assets/shaders/pbr_textured.vert new file mode 100644 index 0000000..40a6f29 --- /dev/null +++ b/assets/shaders/pbr_textured.vert @@ -0,0 +1,28 @@ +#version 410 core + +// Vertex attributes +layout(location = 0) in vec3 inPosition; +layout(location = 1) in vec3 inNormal; +layout(location = 2) in vec2 inTexCoords; + +// Uniforms +uniform MVP_Matrices { + mat4 model; // TODO: make model a push constant/raw uniform + mat4 view; + mat4 proj; +} mvp; + +// Outputs +layout(location = 0) out vec3 fragWorldPos; +layout(location = 1) out vec3 fragNormal; +layout(location = 2) out vec2 fragTexCoords; + +void main() { + fragWorldPos = vec3(mvp.model * vec4(inPosition, 1.0)); + fragNormal = mat3(transpose(inverse(mvp.model))) * inNormal; + // fragNormal = inNormal; + + fragTexCoords = inTexCoords; + + gl_Position = mvp.proj * mvp.view * mvp.model * vec4(inPosition, 1.0); +} |