Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emission not precomputed in ibl shader #1061

Merged
merged 3 commits into from
Aug 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/ysceneview/ysceneview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,10 @@ void draw_widgets(gui_window* win, app_states* apps, const gui_input& input) {
draw_combobox(win, "environments##2", app->selected_environment,
app->ioscene->environments);
if (draw_widgets(win, app->ioscene, app->selected_environment)) {
auto ioenvironment = app->selected_environment;
auto glenvironment = get_element(ioenvironment,
app->ioscene->environments, app->glscene->environments);
set_emission(glenvironment, ioenvironment->emission);
}
end_header(win);
}
Expand Down
106 changes: 59 additions & 47 deletions libs/yocto_gui/yocto_shade.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,12 @@ shade_scene::~shade_scene() {
delete instance_program;
}

static const char* shade_instance_vertex();
static const char* shade_instanced_vertex();
static const char* shade_instance_fragment();

static const char* shade_environment_fragment();

static const char* precompute_brdflut_vertex();
static const char* precompute_brdflut_fragment();

Expand All @@ -179,7 +185,7 @@ void init_scene(shade_scene* scene, bool instanced_drawing) {
// set_program(scene->envlight_program, shade_instance_vertex(),
// shade_instance_fragment(), true);
set_program(scene->environment_program, precompute_cubemap_vertex(),
shade_enivronment_fragment(), true);
shade_environment_fragment(), true);
}

bool is_initialized(shade_scene* scene) {
Expand Down Expand Up @@ -445,6 +451,12 @@ shade_environment* add_environment(shade_scene* scene, const frame3f& frame,
return environment;
}

struct shade_view {
frame3f camera_frame = {};
mat4f view_matrix = {};
mat4f projection_matrix = {};
};

void set_view_uniforms(ogl_program* program, const shade_view& view) {
set_uniform(program, "eye", view.camera_frame.o);
set_uniform(program, "view", view.view_matrix);
Expand Down Expand Up @@ -526,7 +538,8 @@ void draw_environments(
set_params_uniforms(program, params);
for (auto environment : scene->environments) {
if (!is_initialized(environment->cubemap)) continue;
set_uniform(program, "environment", environment->cubemap, 0);
set_uniform(program, "emission", environment->emission);
set_uniform(program, "emission_tex", environment->cubemap, 0);
draw_shape(environment->shape);
}
unbind_program();
Expand Down Expand Up @@ -559,6 +572,7 @@ void set_lighting_uniforms(ogl_program* program, const shade_scene* scene,
auto environment = scene->environments.front();
set_uniform(program, "lighting", 2);
set_uniform(program, "lights_num", 0);
set_uniform(program, "envlight_scale", environment->emission);
set_uniform(
program, "envlight_irradiance", environment->envlight_diffuse, 6);
set_uniform(
Expand Down Expand Up @@ -656,8 +670,7 @@ void draw_scene(shade_scene* scene, shade_camera* camera, const vec4i& viewport,
// environment. The input sampler can be either a cubemap or a latlong texture.
template <typename Sampler>
static void precompute_cubemap(ogl_cubemap* cubemap, const Sampler* environment,
ogl_program* program, int size, int num_mipmap_levels = 1,
const vec3f& emission = {1, 1, 1}) {
ogl_program* program, int size, int num_mipmap_levels = 1) {
// init cubemap with no data
set_cubemap(cubemap, size, 3,
array<float*, 6>{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
Expand Down Expand Up @@ -698,7 +711,6 @@ static void precompute_cubemap(ogl_cubemap* cubemap, const Sampler* environment,
set_uniform(program, "projection", camera_proj);
set_uniform(program, "eye", vec3f{0, 0, 0});
set_uniform(program, "mipmap_level", mipmap_level);
set_uniform(program, "emission", emission);
set_uniform(program, "environment", environment, 0);

draw_shape(cube);
Expand Down Expand Up @@ -750,7 +762,7 @@ static void init_environment(shade_environment* environment) {
set_program(program, precompute_cubemap_vertex(),
precompute_environment_fragment(), true);
precompute_cubemap(environment->cubemap, environment->emission_tex->texture,
program, size, 1, environment->emission);
program, size, 1);
}

void init_envlight(shade_environment* environment) {
Expand All @@ -774,7 +786,7 @@ void init_envlight(shade_environment* environment) {
precompute_brdflut(environment->envlight_brdflut);
}

const char* shade_instance_vertex() {
static const char* shade_instance_vertex() {
static const char* code =
R"(
#version 330
Expand Down Expand Up @@ -824,7 +836,7 @@ void main() {
return code;
}

const char* shade_instanced_vertex() {
static const char* shade_instanced_vertex() {
static const char* code = R"(
#version 330

Expand Down Expand Up @@ -893,7 +905,7 @@ void main() {
return code;
}

const char* shade_instance_fragment() {
static const char* shade_instance_fragment() {
static const char* code =
R"(
#version 330
Expand Down Expand Up @@ -937,6 +949,7 @@ uniform vec3 lights_position[16]; // light positions
uniform vec3 lights_emission[16]; // light intensities

// precomputed textures for image based lighting
uniform vec3 envlight_scale;
uniform samplerCube envlight_irradiance;
uniform samplerCube envlight_reflection;
uniform sampler2D envlight_brdflut;
Expand Down Expand Up @@ -1114,10 +1127,10 @@ void main() {
}
if (lighting == lighting_envlight) {
// diffuse
radiance += brdf.diffuse * textureLod(envlight_irradiance, n, 0).rgb;
radiance += brdf.diffuse * envlight_scale * textureLod(envlight_irradiance, n, 0).rgb;
// specular
vec3 incoming = normalize(reflect(-outgoing, n));
vec3 reflection = sample_prefiltered_refleciton(incoming, brdf.roughness);
vec3 reflection = envlight_scale * sample_prefiltered_refleciton(incoming, brdf.roughness);
vec2 env_brdf = texture(envlight_brdflut, vec2(max(dot(n, outgoing), 0.0), roughness)).rg;
radiance += reflection * (brdf.specular * env_brdf.x + env_brdf.y);
}
Expand All @@ -1139,7 +1152,8 @@ void main() {
return code;
}

const char* shade_envlight_fragment() {
#if 0
static const char* shade_envlight_fragment() {
static const char* code = R"(
#version 330

Expand Down Expand Up @@ -1315,6 +1329,8 @@ void main() {
return code;
}

#endif

static const char* precompute_brdflut_vertex() {
static const char* code = R"(
#version 330
Expand Down Expand Up @@ -1466,6 +1482,36 @@ void main() {
return code;
}

static const char* shade_environment_fragment() {
static const char* code = R"(
#version 330

out vec3 frag_color;

in vec3 position; // position in world space

uniform vec3 eye; // camera position
uniform mat4 view; // inverse of the camera frame (as a matrix)
uniform mat4 projection; // camera projection

uniform float exposure;
uniform float gamma;

uniform vec3 emission;
uniform samplerCube emission_tex;

void main() {
vec3 direction = normalize(position);
vec3 radiance = emission * texture(emission_tex, direction).rgb;

// final color correction
radiance = pow(radiance * pow(2, exposure), vec3(1 / gamma));
frag_color = radiance;
}
)";
return code;
}

static const char* precompute_environment_fragment() {
static const char* code = R"(
#version 330
Expand All @@ -1479,7 +1525,6 @@ uniform mat4 view; // inverse of the camera frame (as a matrix)
uniform mat4 projection; // camera projection

uniform sampler2D environment;
uniform vec3 emission = vec3(1);

vec2 sample_spherical_map(vec3 v) {
vec2 uv = vec2(atan(v.z, v.x), asin(v.y));
Expand All @@ -1493,10 +1538,7 @@ void main() {
vec3 normal = normalize(position);
vec2 uv = sample_spherical_map(normal);
vec3 color = texture(environment, uv).rgb;

// TODO(giacomo): We skip gamma correction, assuming the environment is stored
// in linear space. Is it always true? Probably not.
frag_color = emission * color;
frag_color = color;
}
)";
return code;
Expand Down Expand Up @@ -1637,34 +1679,4 @@ void main() {
return code;
}

const char* shade_enivronment_fragment() {
static const char* code = R"(
#version 330

out vec3 frag_color;

in vec3 position; // position in world space

uniform vec3 eye; // camera position
uniform mat4 view; // inverse of the camera frame (as a matrix)
uniform mat4 projection; // camera projection

uniform float exposure;
uniform float gamma;

uniform samplerCube environment;

void main() {
vec3 v = normalize(position);

vec3 radiance = texture(environment, v).rgb;

// final color correction
radiance = pow(radiance * pow(2, exposure), vec3(1 / gamma));
frag_color = radiance;
}
)";
return code;
}

} // namespace yocto
29 changes: 1 addition & 28 deletions libs/yocto_gui/yocto_shade.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,37 +317,10 @@ shade_instance* add_instance(shade_scene* scene, const frame3f& frame,
shade_environment* add_environment(shade_scene* scene, const frame3f& frame,
const vec3f& emission, shade_texture* emission_tex = nullptr);

// internal drawing functions
struct shade_view {
frame3f camera_frame = {};
mat4f view_matrix = {};
mat4f projection_matrix = {};
};

void set_view_uniforms(ogl_program* program, const shade_view& view);
void set_instance_uniforms(ogl_program* program, const frame3f& frame,
const shade_shape* shape, const shade_material* material,
const shade_params& params);
void set_camlight_uniforms(
ogl_program* program, const shade_scene* scene, const shade_view& view);
void set_envlight_uniforms(
ogl_program* program, const shade_scene* scene, const shade_view& view);

void draw_instances(
shade_scene* scene, const shade_view& view, const shade_params& params);
void draw_environments(
shade_scene* scene, const shade_view& view, const shade_params& params);

// draw scene
void draw_scene(shade_scene* scene, shade_camera* camera, const vec4i& viewport,
const shade_params& params);

// read-only access to defualt shader code
const char* shade_instance_vertex();
const char* shade_instanced_vertex();
const char* shade_instance_fragment();
const char* shade_envlight_fragment();
const char* shade_enivronment_fragment();

} // namespace yocto

#endif