revamp all shaders

main
Dominik Madarász 2024-08-24 18:03:23 +02:00
parent 444285ca59
commit 2eca87099a
12 changed files with 291 additions and 464 deletions

View File

@ -1,3 +1,5 @@
#include "brdf.glsl"
uniform int u_num_lights;
struct light_t {
@ -25,8 +27,16 @@ const int LIGHT_SPOT = 2;
uniform light_t u_lights[MAX_LIGHTS];
#ifdef SHADING_PHONG
vec3 shading_phong(light_t l) {
struct material_t {
vec3 albedo;
vec3 normal;
vec3 F0;
float roughness;
float metallic;
float alpha;
};
vec3 shading_light(light_t l, material_t m) {
vec3 lightDir;
float attenuation = 1.0;
@ -59,77 +69,61 @@ vec3 shading_phong(light_t l) {
return vec3(0,0,0);
}
vec3 n = normalize(v_normal_ws);
float diffuse = max(dot(n, lightDir), 0.0);
vec3 halfVec = normalize(lightDir + u_cam_dir);
float specular = pow(max(dot(n, halfVec), 0.0), l.power);
return (attenuation*l.ambient + diffuse*attenuation*l.diffuse + specular*attenuation*l.specular);
}
#endif
#ifdef SHADING_VERTEXLIT
vec3 shading_vertexlit(light_t l) {
vec3 lightDir;
float attenuation = 1.0;
if (l.type == LIGHT_DIRECTIONAL) {
lightDir = normalize(-l.dir);
} else if (l.type == LIGHT_POINT || l.type == LIGHT_SPOT) {
vec3 toLight = l.pos - v_position_ws;
lightDir = normalize(toLight);
float distance = length(toLight);
/* fast-reject based on radius */
if (l.radius != 0.0 && distance > l.radius) {
return vec3(0,0,0);
}
attenuation = 1.0 / (l.constant + l.linear * distance + l.quadratic * (distance * distance));
if (l.type == LIGHT_SPOT) {
float angle = dot(l.dir, -lightDir);
if (angle > l.outerCone) {
float intensity = (angle-l.outerCone)/(l.innerCone-l.outerCone);
attenuation *= clamp(intensity, 0.0, 1.0);
} else {
attenuation = 0.0;
}
}
}
// fast-rejection for faraway vertices
if (attenuation <= 0.01) {
return vec3(0,0,0);
}
vec3 n = normalize(v_normal_ws);
float diffuse = max(dot(n, lightDir), 0.0);
vec3 halfVec = normalize(lightDir + u_cam_dir);
float specular = pow(max(dot(n, halfVec), 0.0), l.power);
return (attenuation*l.ambient + diffuse*attenuation*l.diffuse + specular*attenuation*l.specular);
}
#endif
vec3 lighting() {
vec3 lit = vec3(0,0,0);
#ifndef SHADING_NONE
#ifdef SHADING_PHONG
for (int i=0; i<u_num_lights; i++) {
lit += shading_phong(u_lights[i]);
}
vec3 n = normalize(v_normal_ws);
float diffuse = max(dot(n, lightDir), 0.0);
vec3 halfVec = normalize(lightDir + u_cam_dir);
float specular = pow(max(dot(n, halfVec), 0.0), l.power);
return (attenuation*l.ambient + diffuse*attenuation*l.diffuse + specular*attenuation*l.specular);
#endif
#ifdef SHADING_VERTEXLIT
for (int i=0; i<u_num_lights; i++) {
lit += shading_vertexlit(u_lights[i]);
}
vec3 n = normalize(v_normal_ws);
float diffuse = max(dot(n, lightDir), 0.0);
vec3 halfVec = normalize(lightDir + u_cam_dir);
float specular = pow(max(dot(n, halfVec), 0.0), l.power);
return (attenuation*l.ambient + diffuse*attenuation*l.diffuse + specular*attenuation*l.specular);
#endif
#ifdef SHADING_PBR
vec3 radiance = l.diffuse * BOOST_LIGHTING;
vec3 V = normalize( v_to_camera );
vec3 N = m.normal;
vec3 L = normalize( lightDir );
vec3 H = normalize( V + L );
vec3 F = fresnel_schlick( H, V, m.F0 );
vec3 kS = F;
vec3 kD = vec3(1.0) - kS;
kD *= 1.0 - m.metallic;
// Premultiplied alpha applied to the diffuse component only
kD *= m.alpha;
float D = distribution_ggx( N, H, m.roughness );
float G = geometry_smith( N, V, L, m.roughness );
vec3 num = D * F * G;
float denom = 4. * max( 0., dot( N, V ) ) * max( 0., dot( N, L ) );
vec3 specular = kS * (num / max( 0.001, denom ));
float NdotL = max( 0., dot( N, L ) );
return ( kD * ( m.albedo / PI ) + specular ) * radiance * NdotL * attenuation;
#endif
}
vec3 lighting(material_t m) {
vec3 lit = vec3(0,0,0);
#ifndef SHADING_NONE
for (int i=0; i<u_num_lights; i++) {
lit += shading_light(u_lights[i], m);
}
#endif
return lit;
}

View File

@ -116,7 +116,7 @@ vec3 get_object_pos() {
return objPos;
}
void setup_billboards(mat4 modelView, mat4 l_model) {
void setup_billboard(mat4 modelView, mat4 l_model) {
if(u_billboard > 0) {
vec3 cameraPosition = -transpose(mat3(view)) * view[3].xyz;
vec3 lookDir = normalize(cameraPosition - v_position_ws);

View File

@ -0,0 +1,15 @@
vec3 get_rimlight() {
#ifdef RIM
vec3 n = normalize(mat3(M) * v_normal); // convert normal to view space
vec3 p = (M * vec4(v_position,1.0)).xyz; // convert position to view space
vec3 v = vec3(0,-1,0);
if (!u_rimambient) {
v = normalize(u_rimpivot-p);
}
float rim = 1.0 - max(dot(v,n), 0.0);
vec3 col = u_rimcolor*(pow(smoothstep(1.0-u_rimrange.x,u_rimrange.y,rim), u_rimrange.z));
return col;
#else
return vec3(0);
#endif
}

View File

@ -0,0 +1,201 @@
#include "sh_lighting.glsl"
#include "rimlight.glsl"
#include "light.glsl"
struct surface_t {
vec3 normal;
vec4 albedo;
vec4 fragcolor;
vec3 light_direct;
vec3 light_indirect;
vec3 emissive;
float roughness;
float metallic;
float ao;
float alpha;
};
surface_t surface() {
surface_t s;
s.normal = normalize(v_normal_ws);
s.light_direct = vec3(0.0, 0.0, 0.0);
s.light_indirect = vec3(1.0, 1.0, 1.0);
s.albedo = vec4(0.5, 0.5, 0.5, 1.0);
s.emissive = vec3(0.0, 0.0, 0.0);
s.roughness = 1.0;
s.metallic = 0.0;
s.ao = 1.0;
s.alpha = 1.0;
// SH lighting
if (!u_texlit) {
vec3 result = sh_lighting(s.normal);
if( (result.x*result.x+result.y*result.y+result.z*result.z) > 0.0 ) s.light_indirect = result;
}
#ifdef SHADING_PHONG
material_t dummy_mat;
s.light_direct = lighting(dummy_mat);
#endif
#ifdef SHADING_VERTEXLIT
s.light_direct = v_vertcolor;
#endif
#ifdef SHADING_PBR
vec4 baseColor_alpha;
if ( map_albedo.has_tex )
baseColor_alpha = sample_colormap( map_albedo, v_texcoord );
else
baseColor_alpha = sample_colormap( map_diffuse, v_texcoord );
s.albedo = baseColor_alpha;
if( map_metallic.has_tex && map_roughness.has_tex ) {
s.metallic = sample_colormap( map_metallic, v_texcoord ).x;
s.roughness = sample_colormap( map_roughness, v_texcoord ).x;
}
else if( map_roughness.has_tex ) {
s.metallic = sample_colormap( map_roughness, v_texcoord ).b;
s.roughness = sample_colormap( map_roughness, v_texcoord ).g;
}
if ( map_ao.has_tex )
s.ao = sample_colormap( map_ao, v_texcoord ).x;
else if ( map_ambient.has_tex )
s.ao = sample_colormap( map_ambient, v_texcoord ).x;
s.emissive = sample_colormap( map_emissive, v_texcoord ).rgb;
vec3 normalmap = texture( map_normals_tex, v_texcoord ).xyz * vec3(2.0) - vec3(1.0);
float normalmap_mip = textureQueryLod( map_normals_tex, v_texcoord ).x;
float normalmap_length = length(normalmap);
normalmap /= normalmap_length;
s.normal = v_normal_ws;
if ( map_normals.has_tex )
{
// Mikkelsen's tangent space normal map decoding. See http://mikktspace.com/ for rationale.
vec3 bi = cross( v_normal_ws, v_tangent );
vec3 nmap = normalmap.xyz;
s.normal = nmap.x * v_tangent + nmap.y * bi + nmap.z * v_normal_ws;
}
s.normal = normalize( s.normal );
if (USE_NORMAL_VARIATION_TO_ROUGHNESS)
{
// Try to reduce specular aliasing by increasing roughness when minified normal maps have high variation.
float variation = 1. - pow( normalmap_length, 8. );
float minification = clamp( normalmap_mip - 2., 0., 1. );
s.roughness = mix( s.roughness, 1.0, variation * minification );
}
vec3 N = s.normal;
vec3 V = normalize( v_to_camera );
vec3 Lo = vec3(0.);
vec3 F0 = vec3(0.04);
F0 = mix( F0, s.albedo.rgb, s.metallic );
bool use_ibl = has_tex_skysphere;
material_t pbr_mat;
pbr_mat.albedo = s.albedo.rgb;
pbr_mat.normal = N;
pbr_mat.F0 = F0;
pbr_mat.roughness = s.roughness;
pbr_mat.metallic = s.metallic;
pbr_mat.alpha = s.alpha;
// Lo += lighting(pbr_mat);
s.light_indirect = sample_colormap( map_ambient, v_texcoord ).xyz;
vec3 diffuse_ambient;
vec3 specular_ambient;
if ( use_ibl )
{
// Image based lighting.
// Based on https://learnopengl.com/PBR/IBL/Diffuse-irradiance
vec3 irradiance = vec3(0.);
if ( USE_BRUTEFORCE_IRRADIANCE )
{
irradiance = sample_irradiance_slow( N, v_tangent );
}
else
{
irradiance = sample_irradiance_fast( N, v_tangent );
}
// Compute the Fresnel term for a perfect mirror reflection with L = R.
// In this case the halfway vector H = N.
//
// We use a modified Fresnel function that dampens specular reflections of very
// rough surfaces to avoid too bright pixels at grazing angles.
vec3 F = fresnel_schlick_roughness( N, V, F0, s.roughness );
vec3 kS = F;
// Subtract the amount of reflected light (specular) to get the energy left for
// absorbed (diffuse) light.
vec3 kD = vec3(1.) - kS;
// Metallic surfaces have only a specular reflection.
kD *= 1.0 - s.metallic;
// Premultiplied alpha applied to the diffuse component only
kD *= s.alpha;
// Modulate the incoming lighting with the diffuse color: some wavelengths get absorbed.
diffuse_ambient = irradiance * s.albedo.rgb;
// Ambient light also has a specular part.
specular_ambient = specular_ibl( V, N, s.roughness, F );
// Ambient occlusion tells us the fraction of sky light that reaches this point.
if (USE_SPECULAR_AO_ATTENUATION)
{
s.light_indirect += s.ao * (kD * diffuse_ambient + specular_ambient);
}
else
{
// We don't attenuate specular_ambient ambient here with AO which might cause flickering in dark cavities.
s.light_indirect += s.ao * (kD * diffuse_ambient) + specular_ambient;
}
}
#else
if(u_matcaps) {
vec2 muv = vec2(view * vec4(v_normal_ws, 0))*0.5+vec2(0.5,0.5); // normal (model space) to view space
s.albedo = texture(u_texture2d, vec2(muv.x, 1.0-muv.y));
} else if(u_textured) {
s.albedo = texture(u_texture2d, v_texcoord);
} else {
s.albedo = u_diffuse;
}
if (u_texlit) {
vec4 litsample = texture(u_lightmap, v_texcoord);
if (u_texmod) {
s.albedo *= litsample;
} else {
s.albedo += litsample;
}
s.albedo.rgb += sh_lighting(s.normal);
}
#endif
s.albedo *= v_color;
s.fragcolor = s.albedo;
s.fragcolor.rgb *= s.light_direct + s.light_indirect;
s.fragcolor.rgb += s.emissive;
s.fragcolor *= shadowing();
s.fragcolor.rgb += get_rimlight();
return s;
}

View File

@ -1,387 +1,10 @@
#include "model_fs.glsl"
#include "light.glsl"
#include "brdf.glsl"
#include "sh_lighting.glsl"
#include "lightmap.glsl"
#include "surface.glsl"
#ifdef SHADING_PHONG
#ifndef LIGHTMAP_BAKING
void main() {
vec3 n = normalize(v_normal_ws);
vec4 lit = vec4(1.0, 1.0, 1.0, 1.0);
// SH lighting
if (!u_texlit) {
vec3 result = sh_lighting(n);
if( (result.x*result.x+result.y*result.y+result.z*result.z) > 0.0 ) lit = vec4(result, 1.0);
}
// analytical lights
lit += vec4(lighting(), 0.0);
// base
vec4 diffuse;
if(u_matcaps) {
vec2 muv = vec2(view * vec4(v_normal_ws, 0))*0.5+vec2(0.5,0.5); // normal (model space) to view space
diffuse = texture(u_texture2d, vec2(muv.x, 1.0-muv.y));
} else if(u_textured) {
diffuse = texture(u_texture2d, v_texcoord);
} else {
diffuse = u_diffuse; // * v_color;
}
diffuse *= v_color;
if (u_texlit) {
vec4 litsample = texture(u_lightmap, v_texcoord);
if (u_texmod) {
diffuse *= litsample;
} else {
diffuse += litsample;
}
diffuse.rgb += sh_lighting(n);
}
// lighting mix
fragcolor = diffuse * lit * shadowing();
// rimlight
#ifdef RIM
{
vec3 n = normalize(mat3(M) * v_normal); // convert normal to view space
vec3 p = (M * vec4(v_position,1.0)).xyz; // convert position to view space
vec3 v = vec3(0,-1,0);
if (!u_rimambient) {
v = normalize(u_rimpivot-p);
}
float rim = 1.0 - max(dot(v,n), 0.0);
vec3 col = u_rimcolor*(pow(smoothstep(1.0-u_rimrange.x,u_rimrange.y,rim), u_rimrange.z));
fragcolor += vec4(col, 0.0);
surface_t surf = surface();
fragcolor = surf.fragcolor;
}
#endif
}
#endif
#ifdef SHADING_VERTEXLIT
void main() {
vec3 n = normalize(v_normal_ws);
vec4 lit = vec4(1.0, 1.0, 1.0, 1.0);
// SH lighting
if (!u_texlit) {
vec3 result = sh_lighting(n);
if( (result.x*result.x+result.y*result.y+result.z*result.z) > 0.0 ) lit = vec4(result, 1.0);
}
lit += vec4(v_vertcolor, 0.0);
// base
vec4 diffuse;
if(u_matcaps) {
vec2 muv = vec2(view * vec4(v_normal_ws, 0))*0.5+vec2(0.5,0.5); // normal (model space) to view space
diffuse = texture(u_texture2d, vec2(muv.x, 1.0-muv.y));
} else if(u_textured) {
diffuse = texture(u_texture2d, v_texcoord);
} else {
diffuse = u_diffuse; // * v_color;
}
// vec4 vertcolor4 = vec4(v_vertcolor, 1.0);
// if (length(diffuse*v_color) > length(vertcolor4)) {
diffuse *= v_color;
// }
if (u_texlit) {
vec4 litsample = texture(u_lightmap, v_texcoord);
if (u_texmod) {
diffuse *= litsample;
} else {
diffuse += litsample;
}
diffuse.rgb += sh_lighting(n);
}
// lighting mix
fragcolor = diffuse * lit * shadowing();
// rimlight
#ifdef RIM
{
vec3 n = normalize(mat3(M) * v_normal); // convert normal to view space
vec3 p = (M * vec4(v_position,1.0)).xyz; // convert position to view space
vec3 v = vec3(0,-1,0);
if (!u_rimambient) {
v = normalize(u_rimpivot-p);
}
float rim = 1.0 - max(dot(v,n), 0.0);
vec3 col = u_rimcolor*(pow(smoothstep(1.0-u_rimrange.x,u_rimrange.y,rim), u_rimrange.z));
fragcolor += vec4(col, 0.0);
}
#endif
}
#endif
#ifdef SHADING_PBR
void main(void)
{
vec3 baseColor = vec3( 0.5, 0.5, 0.5 );
float roughness = 1.0;
float metallic = 0.0;
float ao = 1.0;
float alpha = 1.0;
vec4 baseColor_alpha;
if ( map_albedo.has_tex )
baseColor_alpha = sample_colormap( map_albedo, v_texcoord );
else
baseColor_alpha = sample_colormap( map_diffuse, v_texcoord );
baseColor = baseColor_alpha.xyz;
alpha = baseColor_alpha.w;
if( map_metallic.has_tex && map_roughness.has_tex ) {
metallic = sample_colormap( map_metallic, v_texcoord ).x;
roughness = sample_colormap( map_roughness, v_texcoord ).x;
}
else if( map_roughness.has_tex ) {
//< @r-lyeh, metalness B, roughness G, (@todo: self-shadowing occlusion R; for now, any of R/B are metallic)
metallic = sample_colormap( map_roughness, v_texcoord ).b;// + sample_colormap( map_roughness, v_texcoord ).r;
roughness = sample_colormap( map_roughness, v_texcoord ).g;
}
if ( map_ao.has_tex )
ao = sample_colormap( map_ao, v_texcoord ).x;
else if ( map_ambient.has_tex )
ao = sample_colormap( map_ambient, v_texcoord ).x;
vec3 emissive = sample_colormap( map_emissive, v_texcoord ).rgb;
vec3 normalmap = texture( map_normals_tex, v_texcoord ).xyz * vec3(2.0) - vec3(1.0);
float normalmap_mip = textureQueryLod( map_normals_tex, v_texcoord ).x;
float normalmap_length = length(normalmap);
normalmap /= normalmap_length;
vec3 normal = v_normal_ws;
if ( map_normals.has_tex )
{
// Mikkelsen's tangent space normal map decoding. See http://mikktspace.com/ for rationale.
vec3 bi = cross( v_normal_ws, v_tangent );
vec3 nmap = normalmap.xyz;
normal = nmap.x * v_tangent + nmap.y * bi + nmap.z * v_normal_ws;
}
normal = normalize( normal );
if( USE_MAP_DEBUGGING && !USE_AMBIENT_DEBUGGING )
{
vec3 c = vec3(1., 0., 0.);
float x = gl_FragCoord.x / resolution.x;
float y = gl_FragCoord.y / resolution.y;
if ( y < (7.0/7.0) ) c = vec3(.5) + .5*v_normal_ws;
if ( y < (6.0/7.0) ) c = vec3(.5) + .5*normalmap;
if ( y < (5.0/7.0) ) c = vec3(ao);
if ( y < (4.0/7.0) ) c = vec3(emissive);
if ( y < (3.0/7.0) ) c = vec3(metallic);
if ( y < (2.0/7.0) ) c = vec3(roughness);
if ( y < (1.0/7.0) ) c = baseColor;
fragcolor = vec4(c, 1.);
return;
}
if (USE_NORMAL_VARIATION_TO_ROUGHNESS)
{
// Try to reduce specular aliasing by increasing roughness when minified normal maps have high variation.
float variation = 1. - pow( normalmap_length, 8. );
float minification = clamp( normalmap_mip - 2., 0., 1. );
roughness = mix( roughness, 1.0, variation * minification );
}
fragcolor = baseColor_alpha;
vec3 N = normal;
vec3 V = normalize( v_to_camera );
vec3 Lo = vec3(0.);
vec3 F0 = vec3(0.04);
F0 = mix( F0, baseColor, metallic );
bool use_ibl = has_tex_skysphere;
// use_ibl = false;
// Add contributions from analytic lights.
{
for ( int i = 0; i < u_num_lights; i++ )
{
light_t l = u_lights[i];
vec3 lightDir;
float attenuation = 1.0;
if (l.type == LIGHT_DIRECTIONAL) {
lightDir = normalize(-l.dir);
} else if (l.type == LIGHT_POINT || l.type == LIGHT_SPOT) {
vec3 toLight = l.pos - v_position_ws;
lightDir = normalize(toLight);
float distance = length(toLight);
attenuation = 1.0 / (l.constant + l.linear * distance + l.quadratic * (distance * distance));
if (l.type == LIGHT_SPOT) {
float angle = dot(l.dir, -lightDir);
if (angle > l.outerCone) {
float intensity = (angle-l.outerCone)/(l.innerCone-l.outerCone);
attenuation *= clamp(intensity, 0.0, 1.0);
} else {
attenuation = 0.0;
}
}
}
// fast-rejection for faraway vertices
if (attenuation <= 0.01) {
continue;
}
vec3 radiance = l.diffuse * BOOST_LIGHTING;
vec3 L = normalize( lightDir );
vec3 H = normalize( V + L );
vec3 F = fresnel_schlick( H, V, F0 );
vec3 kS = F;
vec3 kD = vec3(1.0) - kS;
kD *= 1.0 - metallic;
// Premultiplied alpha applied to the diffuse component only
kD *= alpha;
float D = distribution_ggx( N, H, roughness );
float G = geometry_smith( N, V, L, roughness );
vec3 num = D * F * G;
float denom = 4. * max( 0., dot( N, V ) ) * max( 0., dot( N, L ) );
vec3 specular = kS * (num / max( 0.001, denom ));
float NdotL = max( 0., dot( N, L ) );
Lo += ( kD * ( baseColor / PI ) + specular ) * radiance * NdotL * attenuation;
}
}
vec3 ambient = sample_colormap( map_ambient, v_texcoord ).xyz;
vec3 diffuse_ambient;
vec3 specular_ambient;
if ( use_ibl )
{
// Image based lighting.
// Based on https://learnopengl.com/PBR/IBL/Diffuse-irradiance
vec3 irradiance = vec3(0.);
if ( USE_BRUTEFORCE_IRRADIANCE )
{
irradiance = sample_irradiance_slow( normal, v_tangent );
}
else
{
irradiance = sample_irradiance_fast( normal, v_tangent );
}
// Compute the Fresnel term for a perfect mirror reflection with L = R.
// In this case the halfway vector H = N.
//
// We use a modified Fresnel function that dampens specular reflections of very
// rough surfaces to avoid too bright pixels at grazing angles.
vec3 F = fresnel_schlick_roughness( N, V, F0, roughness );
vec3 kS = F;
// Subtract the amount of reflected light (specular) to get the energy left for
// absorbed (diffuse) light.
vec3 kD = vec3(1.) - kS;
// Metallic surfaces have only a specular reflection.
kD *= 1.0 - metallic;
// Premultiplied alpha applied to the diffuse component only
kD *= alpha;
// Modulate the incoming lighting with the diffuse color: some wavelengths get absorbed.
diffuse_ambient = irradiance * baseColor;
// Ambient light also has a specular part.
specular_ambient = specular_ibl( V, normal, roughness, F );
// Ambient occlusion tells us the fraction of sky light that reaches this point.
if (USE_SPECULAR_AO_ATTENUATION)
{
ambient = ao * (kD * diffuse_ambient + specular_ambient);
}
else
{
// We don't attenuate specular_ambient ambient here with AO which might cause flickering in dark cavities.
ambient = ao * (kD * diffuse_ambient) + specular_ambient;
}
}
vec3 color = (ambient + Lo) + emissive;
if ( USE_AMBIENT_DEBUGGING )
{
float y = gl_FragCoord.y / resolution.y;
if( USE_MAP_DEBUGGING && y > 0.5 )
{
if ( (y-0.5) < (7.0/7.0/2.0) ) color = vec3(.5) + .5*v_normal_ws;
if ( (y-0.5) < (6.0/7.0/2.0) ) color = vec3(.5) + .5*normalmap;
if ( (y-0.5) < (5.0/7.0/2.0) ) color = vec3(ao);
if ( (y-0.5) < (4.0/7.0/2.0) ) color = vec3(emissive);
if ( (y-0.5) < (3.0/7.0/2.0) ) color = vec3(metallic);
if ( (y-0.5) < (2.0/7.0/2.0) ) color = vec3(roughness);
if ( (y-0.5) < (1.0/7.0/2.0) ) color = baseColor;
} else {
float x = gl_FragCoord.x / resolution.x;
if ( x < 0.33 )
color = specular_ambient;
else if( x > 0.66 )
color = diffuse_ambient;
}
}
// dither with noise.
// float dither = random( uvec3( floatBitsToUint( gl_FragCoord.xy ), frame_count ) );
// color += BOOST_NOISE * vec3( (-1.0/256.) + (2./256.) * dither );
#if 0 // original
// basic tonemap and gamma correction
color = color / ( vec3(1.) + color );
color = pow( color, vec3(1. / 2.2) );
#elif 0
// filmic tonemapper
vec3 linearColor = color;
vec3 x = max(vec3(0.0), linearColor - 0.004);
color = (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06);
// gamma correction
// color = pow( color, vec3(1. / 2.2) );
#elif 0
// aces film (CC0, src: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/)
vec3 x = color;
float a = 2.51f;
float b = 0.03f;
float c = 2.43f;
float d = 0.59f;
float e = 0.14f;
color = clamp((x*(a*x+b))/(x*(c*x+d)+e), 0.0, 1.0);
// gamma correction
#endif
// color = pow( color, vec3(1. / 2.2) );
// Technically this alpha may be too transparent, if there is a lot of reflected light we wouldn't
// see the background, maybe we can approximate it well enough by adding a fresnel term
fragcolor = vec4( color * shadowing().xyz, alpha );
}
#endif

View File

@ -16,31 +16,19 @@ void main() {
mat4 l_model = att_instanced_matrix;
v_position_ws = (l_model * vec4( objPos, 1.0 )).xyz;
setup_billboards(modelView, l_model);
setup_billboard(modelView, l_model);
v_position_ws = (l_model * vec4( objPos, 1.0 )).xyz;
v_tangent = normalize(mat3(att_instanced_matrix) * att_tangent.xyz);
#if 0
// compute tangent T and bitangent B
vec3 Q1 = dFdx(att_position);
vec3 Q2 = dFdy(att_position);
vec2 st1 = dFdx(att_texcoord);
vec2 st2 = dFdy(att_texcoord);
vec3 T = normalize(Q1*st2.t - Q2*st1.t);
vec3 B = normalize(-Q1*st2.s + Q2*st1.s);
vec3 binormal = B;
#else
vec3 binormal = cross(att_normal, att_tangent.xyz) * att_tangent.w;
#endif
v_binormal = normalize(mat3(att_instanced_matrix) * binormal);
vec4 finalPos = modelView * vec4( objPos, 1.0 );
vec3 to_camera = normalize( -finalPos.xyz );
v_to_camera = mat3( inv_view ) * to_camera;
v_vertcolor = lighting();
material_t dummy_mat;
v_vertcolor = lighting(dummy_mat);
gl_Position = P * finalPos;
do_shadow();
}

View File

@ -381964,11 +381964,13 @@ char *shader_preprocess(const char *src, const char *defines) {
"#define textureQueryLod(t,uv) vec2(0.,0.)\n" // "#extension GL_EXT_texture_query_lod : enable\n"
"#define MEDIUMP mediump\n"
"precision MEDIUMP float;\n";
const char *desktop = strstr(src, "textureQueryLod") ? "#version 400\n#define MEDIUMP\n" : "#version 330\n#define MEDIUMP\n";
char *processed_src = shader_process_includes(src);
const char *desktop = strstr(processed_src, "textureQueryLod") ? "#version 400\n#define MEDIUMP\n" : "#version 330\n#define MEDIUMP\n";
const char *glsl_version = ifdef(ems, gles, desktop);
// detect GLSL version if set
if (src[0] == '#' && src[1] == 'v') {
if (processed_src[0] == '#' && processed_src[1] == 'v') {
#if 0
const char *end = strstri(src, "\n");
glsl_version = va("%.*s", (int)(end-src), src);
@ -381978,7 +381980,6 @@ char *shader_preprocess(const char *src, const char *defines) {
#endif
}
char *processed_src = shader_process_includes(src);
return va("%s\n%s\n%s", glsl_version, defines ? defines : "", processed_src);
}
@ -384600,7 +384601,8 @@ bool colormap( colormap_t *cm, const char *texture_name, bool load_as_srgb ) {
FREE(cm->texture), cm->texture = NULL;
}
int srgb = load_as_srgb ? TEXTURE_SRGB : 0;
// int srgb = load_as_srgb ? TEXTURE_SRGB : 0;
int srgb = 0;
int hdr = strendi(texture_name, ".hdr") ? TEXTURE_FLOAT|TEXTURE_RGBA : 0;
texture_t t = texture_compressed(texture_name, TEXTURE_LINEAR | TEXTURE_ANISOTROPY | TEXTURE_MIPMAPS | TEXTURE_REPEAT | hdr | srgb);
@ -385447,7 +385449,7 @@ static char* strcpy_safe(char *d, const char *s) {
static
void model_load_pbr_layer(material_layer_t *layer, const char *texname, bool load_as_srgb) {
strcpy_safe(layer->texname, texname);
colormap(&layer->map, texname, false);
colormap(&layer->map, texname, load_as_srgb);
}
static

View File

@ -308,11 +308,13 @@ char *shader_preprocess(const char *src, const char *defines) {
"#define textureQueryLod(t,uv) vec2(0.,0.)\n" // "#extension GL_EXT_texture_query_lod : enable\n"
"#define MEDIUMP mediump\n"
"precision MEDIUMP float;\n";
const char *desktop = strstr(src, "textureQueryLod") ? "#version 400\n#define MEDIUMP\n" : "#version 330\n#define MEDIUMP\n";
char *processed_src = shader_process_includes(src);
const char *desktop = strstr(processed_src, "textureQueryLod") ? "#version 400\n#define MEDIUMP\n" : "#version 330\n#define MEDIUMP\n";
const char *glsl_version = ifdef(ems, gles, desktop);
// detect GLSL version if set
if (src[0] == '#' && src[1] == 'v') {
if (processed_src[0] == '#' && processed_src[1] == 'v') {
#if 0
const char *end = strstri(src, "\n");
glsl_version = va("%.*s", (int)(end-src), src);
@ -322,7 +324,6 @@ char *shader_preprocess(const char *src, const char *defines) {
#endif
}
char *processed_src = shader_process_includes(src);
return va("%s\n%s\n%s", glsl_version, defines ? defines : "", processed_src);
}
@ -2944,7 +2945,8 @@ bool colormap( colormap_t *cm, const char *texture_name, bool load_as_srgb ) {
FREE(cm->texture), cm->texture = NULL;
}
int srgb = load_as_srgb ? TEXTURE_SRGB : 0;
// int srgb = load_as_srgb ? TEXTURE_SRGB : 0;
int srgb = 0;
int hdr = strendi(texture_name, ".hdr") ? TEXTURE_FLOAT|TEXTURE_RGBA : 0;
texture_t t = texture_compressed(texture_name, TEXTURE_LINEAR | TEXTURE_ANISOTROPY | TEXTURE_MIPMAPS | TEXTURE_REPEAT | hdr | srgb);
@ -3791,7 +3793,7 @@ static char* strcpy_safe(char *d, const char *s) {
static
void model_load_pbr_layer(material_layer_t *layer, const char *texname, bool load_as_srgb) {
strcpy_safe(layer->texname, texname);
colormap(&layer->map, texname, false);
colormap(&layer->map, texname, load_as_srgb);
}
static

View File

@ -17107,11 +17107,13 @@ char *shader_preprocess(const char *src, const char *defines) {
"#define textureQueryLod(t,uv) vec2(0.,0.)\n" // "#extension GL_EXT_texture_query_lod : enable\n"
"#define MEDIUMP mediump\n"
"precision MEDIUMP float;\n";
const char *desktop = strstr(src, "textureQueryLod") ? "#version 400\n#define MEDIUMP\n" : "#version 330\n#define MEDIUMP\n";
char *processed_src = shader_process_includes(src);
const char *desktop = strstr(processed_src, "textureQueryLod") ? "#version 400\n#define MEDIUMP\n" : "#version 330\n#define MEDIUMP\n";
const char *glsl_version = ifdef(ems, gles, desktop);
// detect GLSL version if set
if (src[0] == '#' && src[1] == 'v') {
if (processed_src[0] == '#' && processed_src[1] == 'v') {
#if 0
const char *end = strstri(src, "\n");
glsl_version = va("%.*s", (int)(end-src), src);
@ -17121,7 +17123,6 @@ char *shader_preprocess(const char *src, const char *defines) {
#endif
}
char *processed_src = shader_process_includes(src);
return va("%s\n%s\n%s", glsl_version, defines ? defines : "", processed_src);
}
@ -19743,7 +19744,8 @@ bool colormap( colormap_t *cm, const char *texture_name, bool load_as_srgb ) {
FREE(cm->texture), cm->texture = NULL;
}
int srgb = load_as_srgb ? TEXTURE_SRGB : 0;
// int srgb = load_as_srgb ? TEXTURE_SRGB : 0;
int srgb = 0;
int hdr = strendi(texture_name, ".hdr") ? TEXTURE_FLOAT|TEXTURE_RGBA : 0;
texture_t t = texture_compressed(texture_name, TEXTURE_LINEAR | TEXTURE_ANISOTROPY | TEXTURE_MIPMAPS | TEXTURE_REPEAT | hdr | srgb);
@ -20590,7 +20592,7 @@ static char* strcpy_safe(char *d, const char *s) {
static
void model_load_pbr_layer(material_layer_t *layer, const char *texname, bool load_as_srgb) {
strcpy_safe(layer->texname, texname);
colormap(&layer->map, texname, false);
colormap(&layer->map, texname, load_as_srgb);
}
static