gfx: generate brdf lut
parent
b94c56ec58
commit
ff72ac6bc9
|
@ -0,0 +1,100 @@
|
|||
#version 400
|
||||
const float PI = 3.1415926536;
|
||||
|
||||
in vec2 uv;
|
||||
out vec2 fragcolor;
|
||||
|
||||
float RadicalInverse_VdC(uint bits) {
|
||||
bits = (bits << 16u) | (bits >> 16u);
|
||||
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
|
||||
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
|
||||
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
|
||||
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
|
||||
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
|
||||
}
|
||||
|
||||
vec2 Hammersley(uint i, uint N) {
|
||||
return vec2(float(i)/float(N), RadicalInverse_VdC(i));
|
||||
}
|
||||
|
||||
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness) {
|
||||
float a = roughness*roughness;
|
||||
|
||||
float phi = 2.0 * PI * Xi.x;
|
||||
float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y));
|
||||
float sinTheta = sqrt(1.0 - cosTheta*cosTheta);
|
||||
|
||||
// from spherical coordinates to cartesian coordinates
|
||||
vec3 H;
|
||||
H.x = cos(phi) * sinTheta;
|
||||
H.y = sin(phi) * sinTheta;
|
||||
H.z = cosTheta;
|
||||
|
||||
// from tangent-space vector to world-space sample vector
|
||||
vec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
|
||||
vec3 tangent = normalize(cross(up, N));
|
||||
vec3 bitangent = cross(N, tangent);
|
||||
|
||||
vec3 sampleVec = tangent * H.x + bitangent * H.y + N * H.z;
|
||||
return normalize(sampleVec);
|
||||
}
|
||||
|
||||
float GeometrySchlickGGX(float NdotV, float roughness) {
|
||||
float a = roughness;
|
||||
float k = (a * a) / 2.0;
|
||||
|
||||
float nom = NdotV;
|
||||
float denom = NdotV * (1.0 - k) + k;
|
||||
|
||||
return nom / 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;
|
||||
}
|
||||
|
||||
vec2 GenerateBRDF(float NdotV, float roughness) {
|
||||
vec3 V;
|
||||
V.x = sqrt(1.0 - NdotV*NdotV);
|
||||
V.y = 0.0;
|
||||
V.z = NdotV;
|
||||
|
||||
float A = 0.0;
|
||||
float B = 0.0;
|
||||
|
||||
vec3 N = vec3(0.0, 0.0, 1.0);
|
||||
|
||||
const uint SAMPLE_COUNT = 1024u;
|
||||
for(uint i = 0u; i < SAMPLE_COUNT; ++i)
|
||||
{
|
||||
vec2 Xi = Hammersley(i, SAMPLE_COUNT);
|
||||
vec3 H = ImportanceSampleGGX(Xi, N, roughness);
|
||||
vec3 L = normalize(2.0 * dot(V, H) * H - V);
|
||||
|
||||
float NdotL = max(L.z, 0.0);
|
||||
float NdotH = max(H.z, 0.0);
|
||||
float VdotH = max(dot(V, H), 0.0);
|
||||
|
||||
if(NdotL > 0.0)
|
||||
{
|
||||
float G = GeometrySmith(N, V, L, roughness);
|
||||
float G_Vis = (G * VdotH) / (NdotH * NdotV);
|
||||
float Fc = pow(1.0 - VdotH, 5.0);
|
||||
|
||||
A += (1.0 - Fc) * G_Vis;
|
||||
B += Fc * G_Vis;
|
||||
}
|
||||
}
|
||||
A /= float(SAMPLE_COUNT);
|
||||
B /= float(SAMPLE_COUNT);
|
||||
return vec2(A, B);
|
||||
}
|
||||
|
||||
void main() {
|
||||
fragcolor = GenerateBRDF(uv.x, uv.y);
|
||||
}
|
|
@ -227,7 +227,7 @@ float geometry_smith( vec3 N, vec3 V, vec3 L, float roughness )
|
|||
vec2 sphere_to_polar( vec3 normal )
|
||||
{
|
||||
normal = normalize( normal );
|
||||
return vec2( ( atan( normal.z, normal.x ) + skysphere_rotation ) / PI / 2.0 + 0.5, acos( normal.y ) / PI );
|
||||
return vec2( ( atan( normal.z, normal.x ) - PI*0.5f ) / PI / 2.0 + 0.5, acos( normal.y ) / PI );
|
||||
}
|
||||
|
||||
// Our vertically GL_CLAMPed textures seem to blend towards black when sampling the half-pixel edge.
|
||||
|
@ -285,7 +285,7 @@ vec3 sample_irradiance_fast( vec3 normal, vec3 vertex_tangent )
|
|||
// Sample the irradiance map if it exists, otherwise fall back to blurred reflection map.
|
||||
if ( has_tex_skyenv )
|
||||
{
|
||||
vec2 polar = sphere_to_polar_clamp_y( normal, 180.0 );
|
||||
vec2 polar = sphere_to_polar( normal );
|
||||
return textureLod( tex_skyenv, polar, 0.0 ).rgb * exposure;
|
||||
}
|
||||
else
|
||||
|
@ -473,7 +473,7 @@ void main(void)
|
|||
}
|
||||
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;
|
||||
metallic = sample_colormap( map_roughness, v_texcoord ).b;// + sample_colormap( map_roughness, v_texcoord ).r;
|
||||
roughness = sample_colormap( map_roughness, v_texcoord ).g;
|
||||
}
|
||||
|
||||
|
@ -708,21 +708,6 @@ void main(void)
|
|||
// 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 );
|
||||
|
||||
// rimlight
|
||||
#ifdef RIM
|
||||
{
|
||||
vec3 n = normalize(mat3(M) * v_normal_ws); // 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
|
||||
|
|
|
@ -371199,6 +371199,9 @@ texture_t texture_compressed_from_mem(const void *data, int len, unsigned flags)
|
|||
if( dimensions > 0 ) glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
if( dimensions > 1 ) glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
if( dimensions > 2 ) glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
|
||||
if( flags&TEXTURE_CLAMP && dimensions > 0 ) glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
if( flags&TEXTURE_CLAMP && dimensions > 1 ) glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
if( flags&TEXTURE_CLAMP && dimensions > 2 ) glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
|
||||
if( target == GL_TEXTURE_CUBE_MAP ) target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
|
||||
|
@ -372620,15 +372623,55 @@ int ui_fxs() {
|
|||
static texture_t brdf = {0};
|
||||
|
||||
static void brdf_load() {
|
||||
const char *filename;
|
||||
filename = "Skyboxes/brdf_lut1k_256x256_32F.ktx";
|
||||
filename = "Skyboxes/brdf_lut2k_512x512_32F.ktx";
|
||||
// generate texture
|
||||
unsigned tex;
|
||||
glGenTextures(1, &tex);
|
||||
|
||||
brdf = texture_compressed( filename,
|
||||
TEXTURE_CLAMP | TEXTURE_NEAREST | TEXTURE_RG | TEXTURE_FLOAT
|
||||
);
|
||||
unsigned texchecker = texture_checker().id;
|
||||
ASSERT(brdf.id != texchecker, "!Couldn't load BRDF lookup table '%s'!", filename );
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16F, 512, 512, 0, GL_RG, GL_FLOAT, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
brdf.id = tex;
|
||||
brdf.w = 512;
|
||||
brdf.h = 512;
|
||||
|
||||
// create program and generate BRDF LUT
|
||||
unsigned lut_fbo = fbo(tex, 0, 0), rbo=0;
|
||||
fbo_bind(lut_fbo);
|
||||
|
||||
static int program = -1, vao = -1;
|
||||
if( program < 0 ) {
|
||||
const char* vs = vfs_read("shaders/vs_0_2_fullscreen_quad_B_flipped.glsl");
|
||||
const char* fs = vfs_read("shaders/brdf.glsl");
|
||||
|
||||
program = shader(vs, fs, "", "fragcolor", NULL);
|
||||
glGenVertexArrays( 1, (GLuint*)&vao );
|
||||
}
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
handle old_shader = last_shader;
|
||||
glUseProgram( program );
|
||||
|
||||
glViewport(0, 0, 512, 512);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glBindVertexArray( vao );
|
||||
|
||||
glDrawArrays( GL_TRIANGLES, 0, 6 );
|
||||
profile_incstat("Render.num_drawcalls", +1);
|
||||
profile_incstat("Render.num_triangles", +2);
|
||||
|
||||
glBindVertexArray( 0 );
|
||||
|
||||
glUseProgram( last_shader );
|
||||
|
||||
fbo_unbind();
|
||||
fbo_destroy(lut_fbo);
|
||||
}
|
||||
|
||||
texture_t brdf_lut() {
|
||||
|
@ -372649,7 +372692,7 @@ bool colormap( colormap_t *cm, const char *texture_name, bool load_as_srgb ) {
|
|||
|
||||
int srgb = load_as_srgb ? TEXTURE_SRGB : 0;
|
||||
int hdr = strendi(texture_name, ".hdr") ? TEXTURE_FLOAT|TEXTURE_RGBA : 0;
|
||||
texture_t t = texture_compressed(texture_name, TEXTURE_LINEAR | TEXTURE_MIPMAPS | TEXTURE_REPEAT | hdr | srgb);
|
||||
texture_t t = texture_compressed(texture_name, TEXTURE_LINEAR | TEXTURE_ANISOTROPY | TEXTURE_MIPMAPS | TEXTURE_REPEAT | hdr | srgb);
|
||||
|
||||
if( t.id == texture_checker().id ) {
|
||||
cm->texture = NULL;
|
||||
|
@ -373028,7 +373071,7 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view,
|
|||
shader_bool( "has_tex_skysphere", has_tex_skysphere );
|
||||
shader_bool( "has_tex_skyenv", has_tex_skyenv );
|
||||
if( has_tex_skysphere ) {
|
||||
float mipCount = floor( log2( m.sky_refl.h ) );
|
||||
float mipCount = floor( log2( max(m.sky_refl.w, m.sky_refl.h) ) );
|
||||
shader_texture("tex_skysphere", m.sky_refl);
|
||||
shader_float( "skysphere_mip_count", mipCount );
|
||||
}
|
||||
|
@ -382654,6 +382697,9 @@ static void v4k_post_init(float refresh_rate) {
|
|||
|
||||
hz = refresh_rate;
|
||||
// t = glfwGetTime();
|
||||
|
||||
// preload brdf LUT early
|
||||
(void)brdf_lut();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
@ -48,6 +48,9 @@ static void v4k_post_init(float refresh_rate) {
|
|||
|
||||
hz = refresh_rate;
|
||||
// t = glfwGetTime();
|
||||
|
||||
// preload brdf LUT early
|
||||
(void)brdf_lut();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
@ -1180,6 +1180,9 @@ texture_t texture_compressed_from_mem(const void *data, int len, unsigned flags)
|
|||
if( dimensions > 0 ) glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
if( dimensions > 1 ) glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
if( dimensions > 2 ) glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
|
||||
if( flags&TEXTURE_CLAMP && dimensions > 0 ) glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
if( flags&TEXTURE_CLAMP && dimensions > 1 ) glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
if( flags&TEXTURE_CLAMP && dimensions > 2 ) glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
|
||||
if( target == GL_TEXTURE_CUBE_MAP ) target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
|
||||
|
@ -2601,15 +2604,55 @@ int ui_fxs() {
|
|||
static texture_t brdf = {0};
|
||||
|
||||
static void brdf_load() {
|
||||
const char *filename;
|
||||
filename = "Skyboxes/brdf_lut1k_256x256_32F.ktx";
|
||||
filename = "Skyboxes/brdf_lut2k_512x512_32F.ktx";
|
||||
// generate texture
|
||||
unsigned tex;
|
||||
glGenTextures(1, &tex);
|
||||
|
||||
brdf = texture_compressed( filename,
|
||||
TEXTURE_CLAMP | TEXTURE_NEAREST | TEXTURE_RG | TEXTURE_FLOAT
|
||||
);
|
||||
unsigned texchecker = texture_checker().id;
|
||||
ASSERT(brdf.id != texchecker, "!Couldn't load BRDF lookup table '%s'!", filename );
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16F, 512, 512, 0, GL_RG, GL_FLOAT, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
brdf.id = tex;
|
||||
brdf.w = 512;
|
||||
brdf.h = 512;
|
||||
|
||||
// create program and generate BRDF LUT
|
||||
unsigned lut_fbo = fbo(tex, 0, 0), rbo=0;
|
||||
fbo_bind(lut_fbo);
|
||||
|
||||
static int program = -1, vao = -1;
|
||||
if( program < 0 ) {
|
||||
const char* vs = vfs_read("shaders/vs_0_2_fullscreen_quad_B_flipped.glsl");
|
||||
const char* fs = vfs_read("shaders/brdf.glsl");
|
||||
|
||||
program = shader(vs, fs, "", "fragcolor", NULL);
|
||||
glGenVertexArrays( 1, (GLuint*)&vao );
|
||||
}
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
handle old_shader = last_shader;
|
||||
glUseProgram( program );
|
||||
|
||||
glViewport(0, 0, 512, 512);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glBindVertexArray( vao );
|
||||
|
||||
glDrawArrays( GL_TRIANGLES, 0, 6 );
|
||||
profile_incstat("Render.num_drawcalls", +1);
|
||||
profile_incstat("Render.num_triangles", +2);
|
||||
|
||||
glBindVertexArray( 0 );
|
||||
|
||||
glUseProgram( last_shader );
|
||||
|
||||
fbo_unbind();
|
||||
fbo_destroy(lut_fbo);
|
||||
}
|
||||
|
||||
texture_t brdf_lut() {
|
||||
|
@ -2630,7 +2673,7 @@ bool colormap( colormap_t *cm, const char *texture_name, bool load_as_srgb ) {
|
|||
|
||||
int srgb = load_as_srgb ? TEXTURE_SRGB : 0;
|
||||
int hdr = strendi(texture_name, ".hdr") ? TEXTURE_FLOAT|TEXTURE_RGBA : 0;
|
||||
texture_t t = texture_compressed(texture_name, TEXTURE_LINEAR | TEXTURE_MIPMAPS | TEXTURE_REPEAT | hdr | srgb);
|
||||
texture_t t = texture_compressed(texture_name, TEXTURE_LINEAR | TEXTURE_ANISOTROPY | TEXTURE_MIPMAPS | TEXTURE_REPEAT | hdr | srgb);
|
||||
|
||||
if( t.id == texture_checker().id ) {
|
||||
cm->texture = NULL;
|
||||
|
@ -3009,7 +3052,7 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view,
|
|||
shader_bool( "has_tex_skysphere", has_tex_skysphere );
|
||||
shader_bool( "has_tex_skyenv", has_tex_skyenv );
|
||||
if( has_tex_skysphere ) {
|
||||
float mipCount = floor( log2( m.sky_refl.h ) );
|
||||
float mipCount = floor( log2( max(m.sky_refl.w, m.sky_refl.h) ) );
|
||||
shader_texture("tex_skysphere", m.sky_refl);
|
||||
shader_float( "skysphere_mip_count", mipCount );
|
||||
}
|
||||
|
|
66
engine/v4k.c
66
engine/v4k.c
|
@ -18352,6 +18352,9 @@ texture_t texture_compressed_from_mem(const void *data, int len, unsigned flags)
|
|||
if( dimensions > 0 ) glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
if( dimensions > 1 ) glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
if( dimensions > 2 ) glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
|
||||
if( flags&TEXTURE_CLAMP && dimensions > 0 ) glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
if( flags&TEXTURE_CLAMP && dimensions > 1 ) glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
if( flags&TEXTURE_CLAMP && dimensions > 2 ) glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
|
||||
if( target == GL_TEXTURE_CUBE_MAP ) target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
|
||||
|
@ -19773,15 +19776,55 @@ int ui_fxs() {
|
|||
static texture_t brdf = {0};
|
||||
|
||||
static void brdf_load() {
|
||||
const char *filename;
|
||||
filename = "Skyboxes/brdf_lut1k_256x256_32F.ktx";
|
||||
filename = "Skyboxes/brdf_lut2k_512x512_32F.ktx";
|
||||
// generate texture
|
||||
unsigned tex;
|
||||
glGenTextures(1, &tex);
|
||||
|
||||
brdf = texture_compressed( filename,
|
||||
TEXTURE_CLAMP | TEXTURE_NEAREST | TEXTURE_RG | TEXTURE_FLOAT
|
||||
);
|
||||
unsigned texchecker = texture_checker().id;
|
||||
ASSERT(brdf.id != texchecker, "!Couldn't load BRDF lookup table '%s'!", filename );
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16F, 512, 512, 0, GL_RG, GL_FLOAT, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
brdf.id = tex;
|
||||
brdf.w = 512;
|
||||
brdf.h = 512;
|
||||
|
||||
// create program and generate BRDF LUT
|
||||
unsigned lut_fbo = fbo(tex, 0, 0), rbo=0;
|
||||
fbo_bind(lut_fbo);
|
||||
|
||||
static int program = -1, vao = -1;
|
||||
if( program < 0 ) {
|
||||
const char* vs = vfs_read("shaders/vs_0_2_fullscreen_quad_B_flipped.glsl");
|
||||
const char* fs = vfs_read("shaders/brdf.glsl");
|
||||
|
||||
program = shader(vs, fs, "", "fragcolor", NULL);
|
||||
glGenVertexArrays( 1, (GLuint*)&vao );
|
||||
}
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
handle old_shader = last_shader;
|
||||
glUseProgram( program );
|
||||
|
||||
glViewport(0, 0, 512, 512);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glBindVertexArray( vao );
|
||||
|
||||
glDrawArrays( GL_TRIANGLES, 0, 6 );
|
||||
profile_incstat("Render.num_drawcalls", +1);
|
||||
profile_incstat("Render.num_triangles", +2);
|
||||
|
||||
glBindVertexArray( 0 );
|
||||
|
||||
glUseProgram( last_shader );
|
||||
|
||||
fbo_unbind();
|
||||
fbo_destroy(lut_fbo);
|
||||
}
|
||||
|
||||
texture_t brdf_lut() {
|
||||
|
@ -19802,7 +19845,7 @@ bool colormap( colormap_t *cm, const char *texture_name, bool load_as_srgb ) {
|
|||
|
||||
int srgb = load_as_srgb ? TEXTURE_SRGB : 0;
|
||||
int hdr = strendi(texture_name, ".hdr") ? TEXTURE_FLOAT|TEXTURE_RGBA : 0;
|
||||
texture_t t = texture_compressed(texture_name, TEXTURE_LINEAR | TEXTURE_MIPMAPS | TEXTURE_REPEAT | hdr | srgb);
|
||||
texture_t t = texture_compressed(texture_name, TEXTURE_LINEAR | TEXTURE_ANISOTROPY | TEXTURE_MIPMAPS | TEXTURE_REPEAT | hdr | srgb);
|
||||
|
||||
if( t.id == texture_checker().id ) {
|
||||
cm->texture = NULL;
|
||||
|
@ -20181,7 +20224,7 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view,
|
|||
shader_bool( "has_tex_skysphere", has_tex_skysphere );
|
||||
shader_bool( "has_tex_skyenv", has_tex_skyenv );
|
||||
if( has_tex_skysphere ) {
|
||||
float mipCount = floor( log2( m.sky_refl.h ) );
|
||||
float mipCount = floor( log2( max(m.sky_refl.w, m.sky_refl.h) ) );
|
||||
shader_texture("tex_skysphere", m.sky_refl);
|
||||
shader_float( "skysphere_mip_count", mipCount );
|
||||
}
|
||||
|
@ -29807,6 +29850,9 @@ static void v4k_post_init(float refresh_rate) {
|
|||
|
||||
hz = refresh_rate;
|
||||
// t = glfwGetTime();
|
||||
|
||||
// preload brdf LUT early
|
||||
(void)brdf_lut();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue