pbr: refactor material management and shader
Introduced a new PBRMaterial resource type. Materials are now fully described with .material files instead of being hardcoded. Added some functions to abstract away and simplify set up of PBR shaders.
This commit is contained in:
parent
507080c604
commit
78266ace3f
37 changed files with 707 additions and 232 deletions
5
resources/00-taisei.pkgdir/gfx/credits/tower.material
Normal file
5
resources/00-taisei.pkgdir/gfx/credits/tower.material
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
ambient_map = credits/tower_ambient
|
||||
diffuse_map = credits/tower_diffuse
|
||||
normal_map = credits/tower_normal
|
||||
roughness_map = credits/tower_roughness
|
6
resources/00-taisei.pkgdir/gfx/stage2/branch.material
Normal file
6
resources/00-taisei.pkgdir/gfx/stage2/branch.material
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
diffuse_map = stage2/branch_diffuse
|
||||
normal_map = stage2/branch_normal
|
||||
ambient_map = stage2/branch_ambient
|
||||
roughness_map = stage2/branch_roughness
|
||||
|
6
resources/00-taisei.pkgdir/gfx/stage2/grass.material
Normal file
6
resources/00-taisei.pkgdir/gfx/stage2/grass.material
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
diffuse_map = stage2/grass_diffuse
|
||||
normal_map = stage2/grass_normal
|
||||
ambient_map = stage2/grass_ambient
|
||||
roughness_map = stage2/grass_roughness
|
||||
|
6
resources/00-taisei.pkgdir/gfx/stage2/ground.material
Normal file
6
resources/00-taisei.pkgdir/gfx/stage2/ground.material
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
diffuse_map = stage2/ground_diffuse
|
||||
normal_map = stage2/ground_normal
|
||||
ambient_map = stage2/ground_ambient
|
||||
roughness_map = stage2/ground_roughness
|
||||
|
6
resources/00-taisei.pkgdir/gfx/stage2/leaves.material
Normal file
6
resources/00-taisei.pkgdir/gfx/stage2/leaves.material
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
diffuse_map = stage2/leaves_diffuse
|
||||
normal_map = stage2/leaves_normal
|
||||
ambient_map = stage2/leaves_ambient
|
||||
roughness_map = stage2/leaves_roughness
|
||||
|
6
resources/00-taisei.pkgdir/gfx/stage2/rocks.material
Normal file
6
resources/00-taisei.pkgdir/gfx/stage2/rocks.material
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
diffuse_map = stage2/rocks_diffuse
|
||||
normal_map = stage2/rocks_normal
|
||||
ambient_map = stage2/rocks_ambient
|
||||
roughness_map = stage2/rocks_roughness
|
||||
|
5
resources/00-taisei.pkgdir/gfx/stage3/ground.material
Normal file
5
resources/00-taisei.pkgdir/gfx/stage3/ground.material
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
ambient_map = stage3/ground_ambient
|
||||
diffuse_map = stage3/ground_diffuse
|
||||
normal_map = stage3/ground_normal
|
||||
roughness_map = stage3/ground_roughness
|
5
resources/00-taisei.pkgdir/gfx/stage3/leaves.material
Normal file
5
resources/00-taisei.pkgdir/gfx/stage3/leaves.material
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
ambient_map = stage3/leaves_ambient
|
||||
diffuse_map = stage3/leaves_diffuse
|
||||
normal_map = stage3/leaves_normal
|
||||
roughness_map = stage3/leaves_roughness
|
5
resources/00-taisei.pkgdir/gfx/stage3/rocks.material
Normal file
5
resources/00-taisei.pkgdir/gfx/stage3/rocks.material
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
ambient_map = stage3/rocks_ambient
|
||||
diffuse_map = stage3/rocks_diffuse
|
||||
normal_map = stage3/rocks_normal
|
||||
roughness_map = stage3/rocks_roughness
|
5
resources/00-taisei.pkgdir/gfx/stage3/trees.material
Normal file
5
resources/00-taisei.pkgdir/gfx/stage3/trees.material
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
ambient_map = stage3/trees_ambient
|
||||
diffuse_map = stage3/trees_diffuse
|
||||
normal_map = stage3/trees_normal
|
||||
roughness_map = stage3/trees_roughness
|
5
resources/00-taisei.pkgdir/gfx/stage4/corridor.material
Normal file
5
resources/00-taisei.pkgdir/gfx/stage4/corridor.material
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
ambient_map = stage4/corridor_ambient
|
||||
diffuse_map = stage4/corridor_diffuse
|
||||
normal_map = stage4/corridor_normal
|
||||
roughness_map = stage4/corridor_roughness
|
5
resources/00-taisei.pkgdir/gfx/stage4/ground.material
Normal file
5
resources/00-taisei.pkgdir/gfx/stage4/ground.material
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
ambient_map = stage4/ground_ambient
|
||||
diffuse_map = stage4/ground_diffuse
|
||||
normal_map = stage4/ground_normal
|
||||
roughness_map = stage4/ground_roughness
|
5
resources/00-taisei.pkgdir/gfx/stage4/mansion.material
Normal file
5
resources/00-taisei.pkgdir/gfx/stage4/mansion.material
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
ambient_map = stage4/mansion_ambient
|
||||
diffuse_map = stage4/mansion_diffuse
|
||||
normal_map = stage4/mansion_normal
|
||||
roughness_map = stage4/mansion_roughness
|
|
@ -4,14 +4,29 @@
|
|||
#include "standard.glslh"
|
||||
#include "../lib/pbr.glslh"
|
||||
|
||||
UNIFORM(1) sampler2D roughness_map;
|
||||
UNIFORM(2) sampler2D normal_map;
|
||||
UNIFORM(3) sampler2D ambient_map;
|
||||
UNIFORM(4) float metallic;
|
||||
UNIFORM(5) vec3 ambient_color; // modulates ambient map
|
||||
UNIFORM(6) int light_count;
|
||||
UNIFORM(7) vec3 light_positions[PBR_MAX_LIGHTS];
|
||||
UNIFORM(13) vec3 light_colors[PBR_MAX_LIGHTS]; // layout-id also depends on PBR_MAX_LIGHTS
|
||||
#define PBR_FEATURE_DIFFUSE_MAP 1
|
||||
#define PBR_FEATURE_NORMAL_MAP 2
|
||||
#define PBR_FEATURE_AMBIENT_MAP 4
|
||||
#define PBR_FEATURE_ROUGHNESS_MAP 8
|
||||
#define PBR_FEATURE_ENVIRONMENT_MAP 16
|
||||
|
||||
UNIFORM(1) int features_mask;
|
||||
|
||||
UNIFORM(2) sampler2D diffuse_map;
|
||||
UNIFORM(3) sampler2D normal_map;
|
||||
UNIFORM(4) sampler2D ambient_map;
|
||||
UNIFORM(5) sampler2D roughness_map;
|
||||
UNIFORM(6) samplerCube environment_map;
|
||||
|
||||
// These either modulate their respective maps, or are used instead of them
|
||||
UNIFORM(7) vec4 diffuseRGB_metallicA;
|
||||
UNIFORM(8) vec4 ambientRGB_roughnessA;
|
||||
|
||||
UNIFORM(11) mat4 inv_camera_transform; // only used if PBR_FEATURE_ENVIRONMENT_MAP is set
|
||||
|
||||
UNIFORM(12) int light_count;
|
||||
UNIFORM(13) vec3 light_positions[PBR_MAX_LIGHTS];
|
||||
UNIFORM(19) vec3 light_colors[PBR_MAX_LIGHTS]; // layout-id also depends on PBR_MAX_LIGHTS
|
||||
|
||||
VARYING(3) vec3 pos;
|
||||
VARYING(4) vec3 tangent;
|
||||
|
|
|
@ -4,23 +4,51 @@
|
|||
#include "interface/pbr.glslh"
|
||||
|
||||
void main(void) {
|
||||
vec4 roughness_sample = texture(roughness_map, texCoord);
|
||||
float alpha = roughness_sample.a;
|
||||
float roughness = ambientRGB_roughnessA.a;
|
||||
float alpha;
|
||||
|
||||
if(alpha < 0.3) {
|
||||
discard;
|
||||
if(bool(features_mask & PBR_FEATURE_ROUGHNESS_MAP)) {
|
||||
vec4 roughness_sample = texture(roughness_map, texCoord);
|
||||
roughness *= roughness_sample.r;
|
||||
alpha = roughness_sample.a;
|
||||
|
||||
// TODO: a way to opt out of this, since it hurts performance.
|
||||
if(alpha < 0.3) {
|
||||
discard;
|
||||
}
|
||||
} else {
|
||||
alpha = 1.0;
|
||||
}
|
||||
|
||||
float metallic = diffuseRGB_metallicA.a;
|
||||
vec3 diffuse = diffuseRGB_metallicA.rgb;
|
||||
|
||||
if(bool(features_mask & PBR_FEATURE_DIFFUSE_MAP)) {
|
||||
diffuse *= texture(diffuse_map, texCoord).rgb;
|
||||
}
|
||||
|
||||
vec3 ambient = ambientRGB_roughnessA.rgb;
|
||||
|
||||
if(bool(features_mask & PBR_FEATURE_AMBIENT_MAP)) {
|
||||
ambient *= texture(ambient_map, texCoord).rgb;
|
||||
}
|
||||
|
||||
vec3 tbn_normal;
|
||||
|
||||
if(bool(features_mask & PBR_FEATURE_NORMAL_MAP)) {
|
||||
tbn_normal = sample_normalmap(normal_map, texCoord);
|
||||
} else {
|
||||
tbn_normal = vec3(0, 0, 1);
|
||||
}
|
||||
|
||||
vec3 ambient = texture(ambient_map, texCoord).rgb;
|
||||
vec3 tbn_normal = sample_normalmap(normal_map, texCoord);
|
||||
mat3 tbn = mat3(normalize(tangent), normalize(bitangent), normalize(normal));
|
||||
|
||||
PBRParams p;
|
||||
p.fragPos = pos;
|
||||
p.albedo = r_color.rgb * texture(tex, texCoord).rgb;
|
||||
p.roughness = roughness_sample.r;
|
||||
p.albedo = diffuse;
|
||||
p.roughness = roughness;
|
||||
p.metallic = metallic;
|
||||
p.normal = normalize(tbn * tbn_normal);
|
||||
p.normal = tbn * tbn_normal;
|
||||
|
||||
PBRState pbr = PBR(p);
|
||||
|
||||
|
@ -29,9 +57,17 @@ void main(void) {
|
|||
Lo += PBR_PointLight(pbr, PointLight(light_positions[i], light_colors[i]));
|
||||
}
|
||||
|
||||
vec3 color = ambient * ambient_color + Lo;
|
||||
vec3 color = ambient + Lo;
|
||||
|
||||
if(bool(features_mask & PBR_FEATURE_ENVIRONMENT_MAP)) {
|
||||
vec3 reflected_ray = mat3(inv_camera_transform) * reflect(pos, p.normal);
|
||||
vec3 reflection = texture(environment_map, fixCubeCoord(reflected_ray)).rgb;
|
||||
float r = (1 - p.roughness);
|
||||
color += (r * r) * reflection * mix(vec3(0.5), p.albedo, p.metallic);
|
||||
}
|
||||
|
||||
color = PBR_TonemapReinhard(color);
|
||||
color = PBR_GammaCorrect(color);
|
||||
|
||||
fragColor = vec4(color, 1) * alpha;
|
||||
fragColor = vec4(color * alpha, alpha);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ if host_machine.system() == 'emscripten'
|
|||
'gfx/*.ani',
|
||||
'gfx/*.spr',
|
||||
'gfx/*.tex',
|
||||
'gfx/*.material',
|
||||
'fonts/*.font',
|
||||
'models/*.iqm',
|
||||
|
||||
|
|
67
scripts/automaterials.py
Executable file
67
scripts/automaterials.py
Executable file
|
@ -0,0 +1,67 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
from collections import defaultdict
|
||||
|
||||
from taiseilib.common import (
|
||||
run_main,
|
||||
)
|
||||
|
||||
|
||||
mat_re = re.compile(r'(.*)_(diffuse|normal|ambient|roughness)\.(?:tex|basis|png|webp)$')
|
||||
|
||||
|
||||
def main(args):
|
||||
resdir = Path(__file__).parent.parent / 'resources'
|
||||
|
||||
materials = defaultdict(set)
|
||||
gfxdirs = []
|
||||
|
||||
for pkgdir in resdir.glob('*.pkgdir'):
|
||||
gfx = pkgdir / 'gfx'
|
||||
|
||||
if not gfx.is_dir():
|
||||
continue
|
||||
|
||||
gfxdirs.append(gfx)
|
||||
print(gfx)
|
||||
|
||||
for p in gfx.glob('**/*'):
|
||||
rel = p.relative_to(gfx)
|
||||
m = mat_re.match(str(rel))
|
||||
|
||||
if m is None:
|
||||
continue
|
||||
|
||||
matname, mapname = m.groups()
|
||||
materials[matname].add(mapname)
|
||||
|
||||
gfxmain = gfxdirs[0]
|
||||
|
||||
for mat, maps in materials.items():
|
||||
mat_filename = f'{mat}.material'
|
||||
|
||||
skip = False
|
||||
for gfx in gfxdirs:
|
||||
if (gfx / mat_filename).exists():
|
||||
print(' - Skip', mat_filename)
|
||||
skip = True
|
||||
break
|
||||
if skip:
|
||||
continue
|
||||
|
||||
outpath = (gfxmain / mat_filename).resolve()
|
||||
|
||||
lines = ['']
|
||||
|
||||
for mapname in sorted(maps):
|
||||
lines.append(f'{mapname}_map = {mat}_{mapname}')
|
||||
|
||||
lines.append('')
|
||||
print(' * Write', outpath)
|
||||
outpath.write_text('\n'.join(lines))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
run_main(main)
|
119
src/resource/material.c
Normal file
119
src/resource/material.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* This software is licensed under the terms of the MIT License.
|
||||
* See COPYING for further information.
|
||||
* ---
|
||||
* Copyright (c) 2011-2019, Lukas Weber <laochailan@web.de>.
|
||||
* Copyright (c) 2012-2019, Andrei Alexeyev <akari@taisei-project.org>.
|
||||
*/
|
||||
|
||||
#include "taisei.h"
|
||||
|
||||
#include "material.h"
|
||||
|
||||
static char *material_path(const char *basename);
|
||||
static bool material_check_path(const char *path);
|
||||
static void material_load_stage1(ResourceLoadState *st);
|
||||
|
||||
ResourceHandler material_res_handler = {
|
||||
.type = RES_MATERIAL,
|
||||
.typename = "material",
|
||||
.subdir = MATERIAL_PATH_PREFIX,
|
||||
|
||||
.procs = {
|
||||
.find = material_path,
|
||||
.check = material_check_path,
|
||||
.load = material_load_stage1,
|
||||
.unload = free,
|
||||
},
|
||||
};
|
||||
|
||||
static char *material_path(const char *basename) {
|
||||
return try_path(MATERIAL_PATH_PREFIX, basename, MATERIAL_EXTENSION);
|
||||
}
|
||||
|
||||
static bool material_check_path(const char *path) {
|
||||
return strendswith(path, MATERIAL_EXTENSION);
|
||||
}
|
||||
|
||||
struct mat_load_data {
|
||||
PBRMaterial *mat;
|
||||
|
||||
union {
|
||||
struct {
|
||||
char *diffuse_map;
|
||||
char *normal_map;
|
||||
char *ambient_map;
|
||||
char *roughness_map;
|
||||
};
|
||||
|
||||
char *maps[4];
|
||||
};
|
||||
};
|
||||
|
||||
static void free_mat_load_data(struct mat_load_data *ld) {
|
||||
for(int i = 0; i < ARRAY_SIZE(ld->maps); ++i) {
|
||||
free(ld->maps[i]);
|
||||
}
|
||||
|
||||
free(ld);
|
||||
}
|
||||
|
||||
static void material_load_stage2(ResourceLoadState *st);
|
||||
|
||||
static void material_load_stage1(ResourceLoadState *st) {
|
||||
struct mat_load_data *ld = calloc(1, sizeof(*ld));
|
||||
ld->mat = calloc(1, sizeof(*ld->mat));
|
||||
*ld->mat = (PBRMaterial) {
|
||||
.diffuse_color = { 1, 1, 1 },
|
||||
.ambient_color = { 1, 1, 1 },
|
||||
.roughness_value = 1,
|
||||
.metallic_value = 0,
|
||||
};
|
||||
|
||||
if(!parse_keyvalue_file_with_spec(st->path, (KVSpec[]) {
|
||||
{ "diffuse_map", .out_str = &ld->diffuse_map },
|
||||
{ "normal_map", .out_str = &ld->normal_map },
|
||||
{ "ambient_map", .out_str = &ld->ambient_map },
|
||||
{ "roughness_map", .out_str = &ld->roughness_map },
|
||||
{ "diffuse_color", .callback = kvparser_vec3, .callback_data = ld->mat->diffuse_color },
|
||||
{ "ambient_color", .callback = kvparser_vec3, .callback_data = ld->mat->ambient_color },
|
||||
{ "roughness", .out_float = &ld->mat->roughness_value },
|
||||
{ "metallic", .out_float = &ld->mat->metallic_value },
|
||||
})) {
|
||||
free_mat_load_data(ld);
|
||||
log_error("Failed to parse material file '%s'", st->path);
|
||||
res_load_failed(st);
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = 0; i < ARRAY_SIZE(ld->maps); ++i) {
|
||||
if(ld->maps[i]) {
|
||||
res_load_dependency(st, RES_TEXTURE, ld->maps[i]);
|
||||
}
|
||||
}
|
||||
|
||||
res_load_continue_after_dependencies(st, material_load_stage2, ld);
|
||||
}
|
||||
|
||||
#define LOADMAP(_map_) do { \
|
||||
if(ld->_map_##_map) { \
|
||||
ld->mat->_map_##_map = get_resource_data(RES_TEXTURE, ld->_map_##_map, st->flags); \
|
||||
if(UNLIKELY(ld->mat->_map_##_map == NULL)) { \
|
||||
log_fatal("%s: failed to load " #_map_ " map '%s'", st->name, ld->_map_##_map); \
|
||||
free_mat_load_data(ld); \
|
||||
res_load_failed(st); \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
static void material_load_stage2(ResourceLoadState *st) {
|
||||
struct mat_load_data *ld = st->opaque;
|
||||
|
||||
LOADMAP(diffuse);
|
||||
LOADMAP(normal);
|
||||
LOADMAP(ambient);
|
||||
LOADMAP(roughness);
|
||||
|
||||
res_load_finished(st, ld->mat);
|
||||
free_mat_load_data(ld);
|
||||
}
|
33
src/resource/material.h
Normal file
33
src/resource/material.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* This software is licensed under the terms of the MIT License.
|
||||
* See COPYING for further information.
|
||||
* ---
|
||||
* Copyright (c) 2011-2019, Lukas Weber <laochailan@web.de>.
|
||||
* Copyright (c) 2012-2019, Andrei Alexeyev <akari@taisei-project.org>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "taisei.h"
|
||||
|
||||
#include "resource.h"
|
||||
#include "texture.h"
|
||||
|
||||
typedef struct PBRMaterial {
|
||||
Texture *diffuse_map;
|
||||
Texture *normal_map;
|
||||
Texture *ambient_map;
|
||||
Texture *roughness_map;
|
||||
|
||||
vec3 diffuse_color;
|
||||
vec3 ambient_color;
|
||||
float roughness_value;
|
||||
float metallic_value;
|
||||
} PBRMaterial;
|
||||
|
||||
extern ResourceHandler material_res_handler;
|
||||
|
||||
#define MATERIAL_PATH_PREFIX "res/gfx/"
|
||||
#define MATERIAL_EXTENSION ".material"
|
||||
|
||||
DEFINE_RESOURCE_GETTER(PBRMaterial, res_material, RES_MATERIAL)
|
||||
DEFINE_OPTIONAL_RESOURCE_GETTER(PBRMaterial, res_material_optional, RES_MATERIAL)
|
|
@ -3,6 +3,7 @@ resource_src = files(
|
|||
'animation.c',
|
||||
'bgm.c',
|
||||
'font.c',
|
||||
'material.c',
|
||||
'model.c',
|
||||
'postprocess.c',
|
||||
'resource.c',
|
||||
|
|
|
@ -15,30 +15,32 @@
|
|||
#include "events.h"
|
||||
#include "taskmanager.h"
|
||||
|
||||
#include "texture.h"
|
||||
#include "animation.h"
|
||||
#include "sfx.h"
|
||||
#include "bgm.h"
|
||||
#include "shader_object.h"
|
||||
#include "shader_program.h"
|
||||
#include "font.h"
|
||||
#include "material.h"
|
||||
#include "model.h"
|
||||
#include "postprocess.h"
|
||||
#include "sfx.h"
|
||||
#include "shader_object.h"
|
||||
#include "shader_program.h"
|
||||
#include "sprite.h"
|
||||
#include "font.h"
|
||||
#include "texture.h"
|
||||
|
||||
#include "renderer/common/backend.h"
|
||||
|
||||
ResourceHandler *_handlers[] = {
|
||||
[RES_TEXTURE] = &texture_res_handler,
|
||||
[RES_ANIM] = &animation_res_handler,
|
||||
[RES_SFX] = &sfx_res_handler,
|
||||
[RES_BGM] = &bgm_res_handler,
|
||||
[RES_MODEL] = &model_res_handler,
|
||||
[RES_POSTPROCESS] = &postprocess_res_handler,
|
||||
[RES_SPRITE] = &sprite_res_handler,
|
||||
[RES_FONT] = &font_res_handler,
|
||||
[RES_SHADER_OBJECT] = &shader_object_res_handler,
|
||||
[RES_SHADER_PROGRAM] = &shader_program_res_handler,
|
||||
[RES_ANIM] = &animation_res_handler,
|
||||
[RES_BGM] = &bgm_res_handler,
|
||||
[RES_FONT] = &font_res_handler,
|
||||
[RES_MATERIAL] = &material_res_handler,
|
||||
[RES_MODEL] = &model_res_handler,
|
||||
[RES_POSTPROCESS] = &postprocess_res_handler,
|
||||
[RES_SFX] = &sfx_res_handler,
|
||||
[RES_SHADER_OBJECT] = &shader_object_res_handler,
|
||||
[RES_SHADER_PROGRAM] = &shader_program_res_handler,
|
||||
[RES_SPRITE] = &sprite_res_handler,
|
||||
[RES_TEXTURE] = &texture_res_handler,
|
||||
};
|
||||
|
||||
typedef enum ResourceStatus {
|
||||
|
|
|
@ -22,6 +22,7 @@ typedef enum ResourceType {
|
|||
RES_POSTPROCESS,
|
||||
RES_SPRITE,
|
||||
RES_FONT,
|
||||
RES_MATERIAL,
|
||||
RES_NUMTYPES,
|
||||
} ResourceType;
|
||||
|
||||
|
|
|
@ -22,11 +22,9 @@ Stage2DrawData *stage2_get_draw_data(void) {
|
|||
}
|
||||
|
||||
#define STAGE2_MAX_LIGHTS 4
|
||||
static void stage2_bg_setup_pbr_lighting(int max_lights) {
|
||||
|
||||
static void stage2_bg_setup_pbr_lighting(Camera3D *cam, int max_lights) {
|
||||
// FIXME: Instead of calling this for each segment, maybe set up the lighting once for the whole scene?
|
||||
|
||||
Camera3D *cam = &stage_3d_context.cam;
|
||||
|
||||
PointLight3D lights[STAGE2_MAX_LIGHTS] = {
|
||||
{ { 100, cam->pos[1] - 100, 100 }, { 50000, 50000, 50000 } },
|
||||
{ { 0, 0, 0 }, { 1, 0, 30 } },
|
||||
|
@ -59,7 +57,11 @@ static void stage2_bg_setup_pbr_lighting(int max_lights) {
|
|||
}
|
||||
|
||||
camera3d_set_point_light_uniforms(cam, imin(max_lights, ARRAY_SIZE(lights)), lights);
|
||||
r_uniform_vec3("ambient_color", 0.5, 0.5, 0.5);
|
||||
}
|
||||
|
||||
static void stage2_bg_setup_pbr_env(Camera3D *cam, int max_lights, PBREnvironment *env) {
|
||||
stage2_bg_setup_pbr_lighting(cam, max_lights);
|
||||
glm_vec3_broadcast(0.5f, env->ambient_color);
|
||||
}
|
||||
|
||||
static void stage2_branch_mv_transform(vec3 pos) {
|
||||
|
@ -78,16 +80,13 @@ static void stage2_bg_branch_draw(vec3 pos) {
|
|||
stage2_branch_mv_transform(pos);
|
||||
|
||||
r_shader("pbr");
|
||||
stage2_bg_setup_pbr_lighting(1);
|
||||
|
||||
r_uniform_float("metallic", 0);
|
||||
r_uniform_sampler("tex", "stage2/branch_diffuse");
|
||||
r_uniform_sampler("roughness_map", "stage2/branch_roughness");
|
||||
r_uniform_sampler("normal_map", "stage2/branch_normal");
|
||||
r_uniform_sampler("ambient_map", "stage2/branch_ambient");
|
||||
r_draw_model("stage2/branch");
|
||||
PBREnvironment env = { 0 };
|
||||
stage2_bg_setup_pbr_env(&stage_3d_context.cam, 1, &env);
|
||||
|
||||
pbr_draw_model(&stage2_draw_data->models.branch, &env);
|
||||
|
||||
r_mat_mv_pop();
|
||||
|
||||
r_state_pop();
|
||||
}
|
||||
|
||||
|
@ -100,16 +99,13 @@ static void stage2_bg_leaves_draw(vec3 pos) {
|
|||
stage2_branch_mv_transform(pos);
|
||||
|
||||
r_shader("pbr");
|
||||
stage2_bg_setup_pbr_lighting(1);
|
||||
|
||||
r_uniform_float("metallic", 0);
|
||||
r_uniform_sampler("tex", "stage2/leaves_diffuse");
|
||||
r_uniform_sampler("roughness_map", "stage2/leaves_roughness");
|
||||
r_uniform_sampler("normal_map", "stage2/leaves_normal");
|
||||
r_uniform_sampler("ambient_map", "stage2/leaves_ambient");
|
||||
r_draw_model("stage2/leaves");
|
||||
PBREnvironment env = { 0 };
|
||||
stage2_bg_setup_pbr_env(&stage_3d_context.cam, 1, &env);
|
||||
|
||||
pbr_draw_model(&stage2_draw_data->models.leaves, &env);
|
||||
|
||||
r_mat_mv_pop();
|
||||
|
||||
r_state_pop();
|
||||
}
|
||||
|
||||
|
@ -126,9 +122,10 @@ static void stage2_bg_grass_draw(vec3 pos) {
|
|||
r_mat_mv_scale(2, 2, 2);
|
||||
|
||||
ShaderProgram *sprite_shader = res_shader("sprite_pbr");
|
||||
|
||||
r_shader_ptr(sprite_shader);
|
||||
stage2_bg_setup_pbr_lighting(STAGE2_MAX_LIGHTS);
|
||||
|
||||
PBREnvironment env = { 0 };
|
||||
stage2_bg_setup_pbr_env(&stage_3d_context.cam, STAGE2_MAX_LIGHTS, &env);
|
||||
|
||||
r_disable(RCAP_CULL_FACE);
|
||||
// r_disable(RCAP_DEPTH_WRITE);
|
||||
|
@ -169,20 +166,11 @@ static void stage2_bg_ground_draw(vec3 pos) {
|
|||
r_mat_mv_translate(pos[0], pos[1], pos[2]);
|
||||
|
||||
r_shader("pbr");
|
||||
stage2_bg_setup_pbr_lighting(STAGE2_MAX_LIGHTS);
|
||||
PBREnvironment env = { 0 };
|
||||
stage2_bg_setup_pbr_env(&stage_3d_context.cam, STAGE2_MAX_LIGHTS, &env);
|
||||
|
||||
r_uniform_float("metallic", 0);
|
||||
r_uniform_sampler("tex", "stage2/rocks_diffuse");
|
||||
r_uniform_sampler("roughness_map", "stage2/rocks_roughness");
|
||||
r_uniform_sampler("normal_map", "stage2/rocks_normal");
|
||||
r_uniform_sampler("ambient_map", "stage2/rocks_ambient");
|
||||
r_draw_model("stage2/rocks");
|
||||
|
||||
r_uniform_sampler("tex", "stage2/ground_diffuse");
|
||||
r_uniform_sampler("roughness_map", "stage2/ground_roughness");
|
||||
r_uniform_sampler("normal_map", "stage2/ground_normal");
|
||||
r_uniform_sampler("ambient_map", "stage2/ground_ambient");
|
||||
r_draw_model("stage2/ground");
|
||||
pbr_draw_model(&stage2_draw_data->models.rocks, &env);
|
||||
pbr_draw_model(&stage2_draw_data->models.ground, &env);
|
||||
|
||||
r_mat_mv_pop();
|
||||
r_state_pop();
|
||||
|
@ -195,15 +183,11 @@ static void stage2_bg_ground_grass_draw(vec3 pos) {
|
|||
r_mat_mv_translate(pos[0], pos[1], pos[2]);
|
||||
|
||||
r_shader("pbr");
|
||||
stage2_bg_setup_pbr_lighting(STAGE2_MAX_LIGHTS);
|
||||
PBREnvironment env = { 0 };
|
||||
stage2_bg_setup_pbr_env(&stage_3d_context.cam, STAGE2_MAX_LIGHTS, &env);
|
||||
glm_vec3_broadcast(0.4f, env.ambient_color);
|
||||
|
||||
r_uniform_float("metallic", 0);
|
||||
r_uniform_sampler("tex", "stage2/grass_diffuse");
|
||||
r_uniform_sampler("roughness_map", "stage2/grass_roughness");
|
||||
r_uniform_sampler("normal_map", "stage2/grass_normal");
|
||||
r_uniform_sampler("ambient_map", "stage2/grass_ambient");
|
||||
r_uniform_vec3("ambient_color", 0.4, 0.4, 0.4);
|
||||
r_draw_model("stage2/grass");
|
||||
pbr_draw_model(&stage2_draw_data->models.grass, &env);
|
||||
|
||||
r_mat_mv_pop();
|
||||
r_state_pop();
|
||||
|
@ -296,6 +280,12 @@ void stage2_drawsys_init(void) {
|
|||
stage_3d_context.cam.near = 1;
|
||||
stage_3d_context.cam.far = 60;
|
||||
stage2_draw_data = calloc(1, sizeof(*stage2_draw_data));
|
||||
|
||||
pbr_load_model(&stage2_draw_data->models.branch, "stage2/branch", "stage2/branch");
|
||||
pbr_load_model(&stage2_draw_data->models.grass, "stage2/grass", "stage2/grass");
|
||||
pbr_load_model(&stage2_draw_data->models.ground, "stage2/ground", "stage2/ground");
|
||||
pbr_load_model(&stage2_draw_data->models.leaves, "stage2/leaves", "stage2/leaves");
|
||||
pbr_load_model(&stage2_draw_data->models.rocks, "stage2/rocks", "stage2/rocks");
|
||||
}
|
||||
|
||||
void stage2_drawsys_shutdown(void) {
|
||||
|
|
|
@ -10,12 +10,21 @@
|
|||
#include "taisei.h"
|
||||
|
||||
#include "stagedraw.h"
|
||||
#include "stageutils.h"
|
||||
|
||||
typedef struct Stage2DrawData {
|
||||
struct {
|
||||
Color color;
|
||||
} fog;
|
||||
|
||||
struct {
|
||||
PBRModel branch;
|
||||
PBRModel grass;
|
||||
PBRModel ground;
|
||||
PBRModel leaves;
|
||||
PBRModel rocks;
|
||||
} models;
|
||||
|
||||
real hina_lights;
|
||||
} Stage2DrawData;
|
||||
|
||||
|
|
|
@ -78,36 +78,23 @@ static void stage2_preload(void) {
|
|||
"part/blast_huge_rays",
|
||||
NULL);
|
||||
preload_resources(RES_TEXTURE, RESF_DEFAULT,
|
||||
"stage2/ground_diffuse",
|
||||
"stage2/ground_roughness",
|
||||
"stage2/ground_normal",
|
||||
"stage2/ground_ambient",
|
||||
"stage2/branch_diffuse",
|
||||
"stage2/branch_roughness",
|
||||
"stage2/branch_normal",
|
||||
"stage2/branch_ambient",
|
||||
"stage2/leaves_diffuse",
|
||||
"stage2/leaves_roughness",
|
||||
"stage2/leaves_normal",
|
||||
"stage2/leaves_ambient",
|
||||
"stage2/rocks_diffuse",
|
||||
"stage2/rocks_roughness",
|
||||
"stage2/rocks_normal",
|
||||
"stage2/rocks_ambient",
|
||||
"stage2/grass_diffuse",
|
||||
"stage2/grass_roughness",
|
||||
"stage2/grass_normal",
|
||||
"stage2/grass_ambient",
|
||||
"stage2/water_floor",
|
||||
"stage2/spellbg1",
|
||||
"stage2/spellbg2",
|
||||
NULL);
|
||||
preload_resources(RES_MODEL, RESF_DEFAULT,
|
||||
"stage2/ground",
|
||||
"stage2/rocks",
|
||||
preload_resources(RES_MATERIAL, RESF_DEFAULT,
|
||||
"stage2/branch",
|
||||
"stage2/leaves",
|
||||
"stage2/grass",
|
||||
"stage2/ground",
|
||||
"stage2/leaves",
|
||||
"stage2/rocks",
|
||||
NULL);
|
||||
preload_resources(RES_MODEL, RESF_DEFAULT,
|
||||
"stage2/branch",
|
||||
"stage2/grass",
|
||||
"stage2/ground",
|
||||
"stage2/leaves",
|
||||
"stage2/rocks",
|
||||
NULL);
|
||||
preload_resources(RES_SHADER_PROGRAM, RESF_DEFAULT,
|
||||
"stage1_water",
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
|
||||
MODERNIZE_THIS_FILE_AND_REMOVE_ME
|
||||
|
||||
static Stage3DrawData *stage3_draw_data;
|
||||
|
||||
Stage3DrawData *stage3_get_draw_data(void) {
|
||||
return NOT_NULL(stage3_draw_data);
|
||||
}
|
||||
|
||||
static uint stage3_bg_pos(Stage3D *s3d, vec3 pos, float maxrange) {
|
||||
vec3 p = {
|
||||
0,
|
||||
|
@ -29,8 +35,7 @@ static uint stage3_bg_pos(Stage3D *s3d, vec3 pos, float maxrange) {
|
|||
return linear3dpos(s3d, pos, maxrange, p, r);
|
||||
}
|
||||
|
||||
static void stage3_bg_setup_pbr_lighting(void) {
|
||||
Camera3D *cam = &stage_3d_context.cam;
|
||||
static void stage3_bg_setup_pbr_lighting(Camera3D *cam) {
|
||||
PointLight3D lights[] = {
|
||||
// TODO animate colors
|
||||
{ { 0, 0, 10000 }, { 10, 42, 30 } },
|
||||
|
@ -60,44 +65,29 @@ static void stage3_bg_setup_pbr_lighting(void) {
|
|||
}
|
||||
|
||||
camera3d_set_point_light_uniforms(cam, ARRAY_SIZE(lights), lights);
|
||||
}
|
||||
|
||||
real f = 1/(1+global.frames/1000.);
|
||||
r_uniform_vec3("ambient_color",f,f,sqrt(f));
|
||||
static void stage3_bg_setup_pbr_env(Camera3D *cam, PBREnvironment *env) {
|
||||
stage3_bg_setup_pbr_lighting(cam);
|
||||
|
||||
float f = 1.0f / (1.0f + global.frames / 1000.0f);
|
||||
glm_vec3_copy((vec3) { f, f, sqrtf(f) }, env->ambient_color);
|
||||
}
|
||||
|
||||
static void stage3_bg_ground_draw(vec3 pos) {
|
||||
r_state_push();
|
||||
r_mat_mv_push();
|
||||
r_mat_mv_translate(pos[0], pos[1], pos[2]);
|
||||
|
||||
r_mat_mv_translate_v(pos);
|
||||
|
||||
r_shader("pbr");
|
||||
//r_uniform_vec3_array("light_positions[0]", 0, 1, &stage_3d_context.cx);
|
||||
|
||||
stage3_bg_setup_pbr_lighting();
|
||||
PBREnvironment env = { 0 };
|
||||
stage3_bg_setup_pbr_env(&stage_3d_context.cam, &env);
|
||||
|
||||
r_uniform_float("metallic", 0);
|
||||
r_uniform_sampler("tex", "stage3/ground_diffuse");
|
||||
r_uniform_sampler("roughness_map", "stage3/ground_roughness");
|
||||
r_uniform_sampler("normal_map", "stage3/ground_normal");
|
||||
r_uniform_sampler("ambient_map", "stage3/ground_ambient");
|
||||
pbr_draw_model(&stage3_draw_data->models.ground, &env);
|
||||
pbr_draw_model(&stage3_draw_data->models.trees, &env);
|
||||
pbr_draw_model(&stage3_draw_data->models.rocks, &env);
|
||||
|
||||
|
||||
r_draw_model("stage3/ground");
|
||||
|
||||
r_uniform_sampler("tex", "stage3/trees_diffuse");
|
||||
r_uniform_sampler("roughness_map", "stage3/trees_roughness");
|
||||
r_uniform_sampler("normal_map", "stage3/trees_normal");
|
||||
r_uniform_sampler("ambient_map", "stage3/trees_ambient");
|
||||
|
||||
r_draw_model("stage3/trees");
|
||||
|
||||
r_uniform_sampler("tex", "stage3/rocks_diffuse");
|
||||
r_uniform_sampler("roughness_map", "stage3/rocks_roughness");
|
||||
r_uniform_sampler("normal_map", "stage3/rocks_normal");
|
||||
r_uniform_sampler("ambient_map", "stage3/rocks_ambient");
|
||||
|
||||
r_draw_model("stage3/rocks");
|
||||
r_mat_mv_pop();
|
||||
r_state_pop();
|
||||
}
|
||||
|
@ -105,22 +95,15 @@ static void stage3_bg_ground_draw(vec3 pos) {
|
|||
static void stage3_bg_leaves_draw(vec3 pos) {
|
||||
r_state_push();
|
||||
r_mat_mv_push();
|
||||
r_mat_mv_translate(pos[0], pos[1], pos[2]);
|
||||
r_mat_mv_translate(0,0,-0.0002);
|
||||
|
||||
r_mat_mv_translate_v(pos);
|
||||
r_mat_mv_translate(0, 0, -0.0002);
|
||||
|
||||
r_shader("pbr");
|
||||
|
||||
stage3_bg_setup_pbr_lighting();
|
||||
PBREnvironment env = { 0 };
|
||||
stage3_bg_setup_pbr_env(&stage_3d_context.cam, &env);
|
||||
|
||||
r_uniform_float("metallic", 0);
|
||||
r_uniform_sampler("tex", "stage3/leaves_diffuse");
|
||||
r_uniform_sampler("roughness_map", "stage3/leaves_roughness");
|
||||
r_uniform_sampler("normal_map", "stage3/leaves_normal");
|
||||
r_uniform_sampler("ambient_map", "stage3/leaves_ambient");
|
||||
|
||||
|
||||
r_draw_model("stage3/leaves");
|
||||
pbr_draw_model(&stage3_draw_data->models.leaves, &env);
|
||||
|
||||
r_mat_mv_pop();
|
||||
r_state_pop();
|
||||
|
@ -132,10 +115,17 @@ void stage3_drawsys_init(void) {
|
|||
stage_3d_context.cam.rot.v[0] = 80;
|
||||
stage_3d_context.cam.vel[1] = 0.1;
|
||||
stage_3d_context.cam.vel[2] = 0.05;
|
||||
|
||||
stage3_draw_data = calloc(1, sizeof(*stage3_draw_data));
|
||||
|
||||
pbr_load_model(&stage3_draw_data->models.ground, "stage3/ground", "stage3/ground"); pbr_load_model(&stage3_draw_data->models.leaves, "stage3/leaves", "stage3/leaves");
|
||||
pbr_load_model(&stage3_draw_data->models.rocks, "stage3/rocks", "stage3/rocks");
|
||||
pbr_load_model(&stage3_draw_data->models.trees, "stage3/trees", "stage3/trees");
|
||||
}
|
||||
|
||||
void stage3_drawsys_shutdown(void) {
|
||||
stage3d_shutdown(&stage_3d_context);
|
||||
free(stage3_draw_data);
|
||||
}
|
||||
|
||||
static bool stage3_fog(Framebuffer *fb) {
|
||||
|
|
|
@ -11,6 +11,19 @@
|
|||
|
||||
#include "util/fbpair.h"
|
||||
#include "stagedraw.h"
|
||||
#include "stageutils.h"
|
||||
|
||||
typedef struct Stage3DrawData {
|
||||
struct {
|
||||
PBRModel ground;
|
||||
PBRModel leaves;
|
||||
PBRModel rocks;
|
||||
PBRModel trees;
|
||||
} models;
|
||||
} Stage3DrawData;
|
||||
|
||||
Stage3DrawData *stage3_get_draw_data(void)
|
||||
attr_returns_nonnull attr_returns_max_aligned;
|
||||
|
||||
void stage3_drawsys_init(void);
|
||||
void stage3_drawsys_shutdown(void);
|
||||
|
|
|
@ -86,34 +86,24 @@ static void stage3_preload(void) {
|
|||
portrait_preload_base_sprite("scuttle", NULL, RESF_DEFAULT);
|
||||
portrait_preload_face_sprite("scuttle", "normal", RESF_DEFAULT);
|
||||
preload_resources(RES_BGM, RESF_OPTIONAL, "stage3", "stage3boss", NULL);
|
||||
preload_resources(RES_SPRITE, RESF_DEFAULT,
|
||||
"stage3/ground_ambient",
|
||||
"stage3/ground_normal",
|
||||
"stage3/ground_roughness",
|
||||
"stage3/ground_diffuse",
|
||||
"stage3/trees_ambient",
|
||||
"stage3/trees_normal",
|
||||
"stage3/trees_roughness",
|
||||
"stage3/trees_diffuse",
|
||||
"stage3/rocks_ambient",
|
||||
"stage3/rocks_normal",
|
||||
"stage3/rocks_roughness",
|
||||
"stage3/rocks_diffuse",
|
||||
"stage3/leaves_ambient",
|
||||
"stage3/leaves_normal",
|
||||
"stage3/leaves_roughness",
|
||||
"stage3/leaves_diffuse",
|
||||
preload_resources(RES_TEXTURE, RESF_DEFAULT,
|
||||
"stage3/spellbg1",
|
||||
"stage3/spellbg2",
|
||||
"stage3/wspellbg",
|
||||
"stage3/wspellclouds",
|
||||
"stage3/wspellswarm",
|
||||
NULL);
|
||||
preload_resources(RES_MODEL, RESF_DEFAULT,
|
||||
preload_resources(RES_MATERIAL, RESF_DEFAULT,
|
||||
"stage3/ground",
|
||||
"stage3/leaves",
|
||||
"stage3/rocks",
|
||||
"stage3/trees",
|
||||
NULL);
|
||||
preload_resources(RES_MODEL, RESF_DEFAULT,
|
||||
"stage3/ground",
|
||||
"stage3/leaves",
|
||||
"stage3/rocks",
|
||||
"stage3/trees",
|
||||
NULL);
|
||||
preload_resources(RES_SHADER_PROGRAM, RESF_DEFAULT,
|
||||
"zbuf_fog",
|
||||
|
|
|
@ -80,47 +80,81 @@ static bool stage4_water_composite(Framebuffer *reflections) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static uint stage4_lake_pos(Stage3D *s3d, vec3 pos, float maxrange) {
|
||||
vec3 p = {0, 0, 0};
|
||||
return single3dpos(s3d, pos, maxrange, p);
|
||||
}
|
||||
|
||||
static void stage4_lake_draw(vec3 pos) {
|
||||
static void stage4_bg_setup_pbr_lighting_outdoors(Camera3D *cam) {
|
||||
PointLight3D lights[] = {
|
||||
{ { 0, 0, 0 }, { 3, 4, 5 } },
|
||||
{ { 0, 25, 3 }, { 4, 20, 22 } },
|
||||
};
|
||||
|
||||
vec3 r;
|
||||
Camera3D *cam = &stage_3d_context.cam;
|
||||
camera3d_unprojected_ray(cam, global.plr.pos, r);
|
||||
glm_vec3_scale(r, 4, r);
|
||||
glm_vec3_add(cam->pos, r, lights[0].pos);
|
||||
|
||||
r_mat_mv_push();
|
||||
r_mat_mv_translate(pos[0], pos[1], pos[2]);
|
||||
r_shader("pbr");
|
||||
camera3d_set_point_light_uniforms(cam, ARRAY_SIZE(lights), lights);
|
||||
}
|
||||
|
||||
static void stage4_bg_setup_pbr_env_outdoors(Camera3D *cam, PBREnvironment *env) {
|
||||
stage4_bg_setup_pbr_lighting_outdoors(cam);
|
||||
glm_vec3_broadcast(1.0f, env->ambient_color);
|
||||
}
|
||||
|
||||
static void stage4_bg_setup_pbr_lighting_indoors(Camera3D *cam, vec3 pos) {
|
||||
float xoff = 3.0f;
|
||||
float zoff = 1.3f;
|
||||
|
||||
PointLight3D lights[] = {
|
||||
{ { -xoff, pos[1], pos[2]+zoff }, { 1, 20, 20 } },
|
||||
{ { xoff, pos[1], pos[2]+zoff }, { 1, 20, 20 } },
|
||||
{ { -xoff, pos[1]-10, pos[2]+zoff }, { 1, 20, 20 } },
|
||||
{ { xoff, pos[1]-10, pos[2]+zoff }, { 1, 20, 20 } },
|
||||
{ { -xoff, pos[1]+10, pos[2]+zoff }, { 1, 20, 20 } },
|
||||
{ { xoff, pos[1]+10, pos[2]+zoff }, { 1, 20, 20 } },
|
||||
};
|
||||
|
||||
for(int i = 0; i < ARRAY_SIZE(lights); i++) {
|
||||
float t = global.frames * 0.02f;
|
||||
float mod1 = cosf(13095434.0f * lights[i].pos[1]);
|
||||
float mod2 = sinf(1242435.0f * lights[i].pos[0] * lights[i].pos[1]);
|
||||
|
||||
float f = (
|
||||
sinf((1.0f + mod1) * t) +
|
||||
sinf((2.35f + mod2) * t + mod1) +
|
||||
sinf((3.1257f + mod1 * mod2) * t + mod2)
|
||||
) / 3.0f;
|
||||
|
||||
glm_vec3_scale(lights[i].radiance, 0.6f + 0.4f * f, lights[i].radiance);
|
||||
}
|
||||
|
||||
camera3d_set_point_light_uniforms(cam, ARRAY_SIZE(lights), lights);
|
||||
}
|
||||
|
||||
r_uniform_float("metallic", 0);
|
||||
r_uniform_sampler("tex", "stage4/ground_diffuse");
|
||||
r_uniform_sampler("roughness_map", "stage4/ground_roughness");
|
||||
r_uniform_sampler("normal_map", "stage4/ground_normal");
|
||||
r_uniform_sampler("ambient_map", "stage4/ground_ambient");
|
||||
r_uniform_vec3("ambient_color", 1, 1, 1);
|
||||
static void stage4_bg_setup_pbr_env_indoors(Camera3D *cam, vec3 pos, PBREnvironment *env) {
|
||||
stage4_bg_setup_pbr_lighting_indoors(cam, pos);
|
||||
glm_vec3_copy(&stage4_draw_data->ambient_color.r, env->ambient_color);
|
||||
log_debug("%0.2f %0.2f %0.2f", env->ambient_color[0], env->ambient_color[1], env->ambient_color[2]);
|
||||
}
|
||||
|
||||
r_draw_model("stage4/ground");
|
||||
static uint stage4_lake_pos(Stage3D *s3d, vec3 pos, float maxrange) {
|
||||
vec3 p = {0, 0, 0};
|
||||
return single3dpos(s3d, pos, maxrange, p);
|
||||
}
|
||||
|
||||
r_uniform_float("metallic", 0);
|
||||
r_uniform_sampler("tex", "stage4/mansion_diffuse");
|
||||
r_uniform_sampler("roughness_map", "stage4/mansion_roughness");
|
||||
r_uniform_sampler("normal_map", "stage4/mansion_normal");
|
||||
r_uniform_sampler("ambient_map", "stage4/mansion_ambient");
|
||||
static void stage4_lake_draw(vec3 pos) {
|
||||
r_state_push();
|
||||
r_mat_mv_push();
|
||||
r_mat_mv_translate_v(pos);
|
||||
|
||||
r_shader("pbr");
|
||||
|
||||
PBREnvironment env = { 0 };
|
||||
stage4_bg_setup_pbr_env_outdoors(&stage_3d_context.cam, &env);
|
||||
|
||||
pbr_draw_model(&stage4_draw_data->models.ground, &env);
|
||||
pbr_draw_model(&stage4_draw_data->models.mansion, &env);
|
||||
|
||||
r_draw_model("stage4/mansion");
|
||||
r_mat_mv_pop();
|
||||
r_shader_standard();
|
||||
r_state_pop();
|
||||
}
|
||||
|
||||
static uint stage4_corridor_pos(Stage3D *s3d, vec3 pos, float maxrange) {
|
||||
|
@ -139,42 +173,19 @@ static uint stage4_corridor_pos(Stage3D *s3d, vec3 pos, float maxrange) {
|
|||
}
|
||||
|
||||
static void stage4_corridor_draw(vec3 pos) {
|
||||
real xoff = 3;
|
||||
real zoff = 1.3;
|
||||
PointLight3D lights[] = {
|
||||
{ { -xoff, pos[1], pos[2]+zoff }, { 1, 20, 20 } },
|
||||
{ { xoff, pos[1], pos[2]+zoff }, { 1, 20, 20 } },
|
||||
{ { -xoff, pos[1]-10, pos[2]+zoff }, { 1, 20, 20 } },
|
||||
{ { xoff, pos[1]-10, pos[2]+zoff }, { 1, 20, 20 } },
|
||||
{ { -xoff, pos[1]+10, pos[2]+zoff }, { 1, 20, 20 } },
|
||||
{ { xoff, pos[1]+10, pos[2]+zoff }, { 1, 20, 20 } },
|
||||
};
|
||||
|
||||
for(int i = 0; i < ARRAY_SIZE(lights); i++) {
|
||||
real t = global.frames*0.02;
|
||||
real mod1 = cos(13095434*lights[i].pos[1]);
|
||||
real mod2 = sin(1242435*lights[i].pos[0]*lights[i].pos[1]);
|
||||
|
||||
double f = (sin((1+mod1)*t) + sin((2.35+mod2)*t+mod1) + sin((3.1257+mod1*mod2)*t+mod2))/3;
|
||||
glm_vec3_scale(lights[i].radiance,0.6+0.4*f, lights[i].radiance);
|
||||
}
|
||||
|
||||
r_state_push();
|
||||
r_mat_mv_push();
|
||||
r_mat_mv_translate(pos[0], pos[1], pos[2]);
|
||||
//r_mat_mv_rotate(pos[1]/2000, 0, 1, 0);
|
||||
r_mat_mv_translate_v(pos);
|
||||
|
||||
r_shader("pbr");
|
||||
|
||||
camera3d_set_point_light_uniforms(&stage_3d_context.cam, ARRAY_SIZE(lights), lights);
|
||||
PBREnvironment env = { 0 };
|
||||
stage4_bg_setup_pbr_env_indoors(&stage_3d_context.cam, pos, &env);
|
||||
|
||||
r_uniform_float("metallic", 0);
|
||||
r_uniform_sampler("tex", "stage4/corridor_diffuse");
|
||||
r_uniform_sampler("roughness_map", "stage4/corridor_roughness");
|
||||
r_uniform_sampler("normal_map", "stage4/corridor_normal");
|
||||
r_uniform_sampler("ambient_map", "stage4/corridor_ambient");
|
||||
r_uniform_vec3_rgb("ambient_color", &stage4_draw_data->ambient_color);
|
||||
pbr_draw_model(&stage4_draw_data->models.corridor, &env);
|
||||
|
||||
r_draw_model("stage4/corridor");
|
||||
r_mat_mv_pop();
|
||||
r_state_pop();
|
||||
}
|
||||
|
||||
void stage4_draw(void) {
|
||||
|
@ -189,6 +200,10 @@ void stage4_draw(void) {
|
|||
void stage4_drawsys_init(void) {
|
||||
stage4_draw_data = calloc(1, sizeof(*stage4_draw_data));
|
||||
stage3d_init(&stage_3d_context, 16);
|
||||
|
||||
pbr_load_model(&stage4_draw_data->models.corridor, "stage4/corridor", "stage4/corridor");
|
||||
pbr_load_model(&stage4_draw_data->models.ground, "stage4/ground", "stage4/ground");
|
||||
pbr_load_model(&stage4_draw_data->models.mansion, "stage4/mansion", "stage4/mansion");
|
||||
}
|
||||
|
||||
void stage4_drawsys_shutdown(void) {
|
||||
|
|
|
@ -11,10 +11,17 @@
|
|||
|
||||
#include "stagedraw.h"
|
||||
#include "color.h"
|
||||
#include "stageutils.h"
|
||||
|
||||
typedef struct Stage4DrawData {
|
||||
Color ambient_color;
|
||||
vec3 midboss_light_pos;
|
||||
|
||||
struct {
|
||||
PBRModel corridor;
|
||||
PBRModel ground;
|
||||
PBRModel mansion;
|
||||
} models;
|
||||
} Stage4DrawData;
|
||||
|
||||
void stage4_drawsys_init(void);
|
||||
|
|
|
@ -86,21 +86,9 @@ static void stage4_preload(void) {
|
|||
portrait_preload_base_sprite("kurumi", NULL, RESF_DEFAULT);
|
||||
portrait_preload_face_sprite("kurumi", "normal", RESF_DEFAULT);
|
||||
preload_resources(RES_BGM, RESF_OPTIONAL, "stage4", "stage4boss", NULL);
|
||||
preload_resources(RES_SPRITE, RESF_DEFAULT,
|
||||
preload_resources(RES_TEXTURE, RESF_DEFAULT,
|
||||
"stage4/kurumibg1",
|
||||
"stage4/kurumibg2",
|
||||
"stage4/ground_ambient",
|
||||
"stage4/ground_diffuse",
|
||||
"stage4/ground_roughness",
|
||||
"stage4/ground_normal",
|
||||
"stage4/mansion_ambient",
|
||||
"stage4/mansion_diffuse",
|
||||
"stage4/mansion_roughness",
|
||||
"stage4/mansion_normal",
|
||||
"stage4/corridor_ambient",
|
||||
"stage4/corridor_diffuse",
|
||||
"stage4/corridor_roughness",
|
||||
"stage4/corridor_normal",
|
||||
NULL);
|
||||
preload_resources(RES_SPRITE, RESF_DEFAULT,
|
||||
"stage6/scythe", // Stage 6 is intentional
|
||||
|
@ -115,10 +103,15 @@ static void stage4_preload(void) {
|
|||
preload_resources(RES_ANIM, RESF_DEFAULT,
|
||||
"boss/kurumi",
|
||||
NULL);
|
||||
preload_resources(RES_MODEL, RESF_DEFAULT,
|
||||
"stage4/mansion",
|
||||
"stage4/ground",
|
||||
preload_resources(RES_MATERIAL, RESF_DEFAULT,
|
||||
"stage4/corridor",
|
||||
"stage4/ground",
|
||||
"stage4/mansion",
|
||||
NULL);
|
||||
preload_resources(RES_MODEL, RESF_DEFAULT,
|
||||
"stage4/corridor",
|
||||
"stage4/ground",
|
||||
"stage4/mansion",
|
||||
NULL);
|
||||
preload_resources(RES_TEXTURE, RESF_OPTIONAL,
|
||||
"part/sinewave",
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "taisei.h"
|
||||
|
||||
#include "stagedraw.h"
|
||||
#include "stageutils.h"
|
||||
|
||||
typedef struct Stage5DrawData {
|
||||
|
||||
|
@ -33,6 +34,11 @@ typedef struct Stage5DrawData {
|
|||
float rad;
|
||||
} stairs;
|
||||
|
||||
struct {
|
||||
PBRModel metal;
|
||||
PBRModel stairs;
|
||||
PBRModel wall;
|
||||
} models;
|
||||
} Stage5DrawData;
|
||||
|
||||
void stage5_drawsys_init(void);
|
||||
|
|
|
@ -18,7 +18,6 @@ enum {
|
|||
};
|
||||
|
||||
typedef struct Stage6DrawData {
|
||||
|
||||
struct {
|
||||
float position[3*NUM_STARS];
|
||||
} stars;
|
||||
|
@ -32,6 +31,19 @@ typedef struct Stage6DrawData {
|
|||
FBPair fbpair;
|
||||
} baryon;
|
||||
|
||||
struct {
|
||||
PBRModel rim;
|
||||
PBRModel spires;
|
||||
PBRModel stairs;
|
||||
PBRModel tower;
|
||||
PBRModel tower_bottom;
|
||||
|
||||
// these don't use pbr materials
|
||||
Model *calabi_yau_quintic;
|
||||
Model *top_plate;
|
||||
} models;
|
||||
|
||||
Texture *envmap;
|
||||
} Stage6DrawData;
|
||||
|
||||
Stage6DrawData* stage6_get_draw_data(void);
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include "global.h"
|
||||
#include "util/glm.h"
|
||||
#include "video.h"
|
||||
#include "resource/model.h"
|
||||
#include "resource/material.h"
|
||||
|
||||
Stage3D stage_3d_context;
|
||||
|
||||
|
@ -52,6 +54,19 @@ void stage3d_apply_transforms(Stage3D *s, mat4 mat) {
|
|||
camera3d_apply_transforms(&s->cam, mat);
|
||||
}
|
||||
|
||||
void camera3d_apply_inverse_transforms(Camera3D *cam, mat4 mat) {
|
||||
// TODO optimize this
|
||||
mat4 temp;
|
||||
glm_mat4_identity(temp);
|
||||
camera3d_apply_transforms(cam, temp);
|
||||
glm_mat4_inv_fast(temp, mat);
|
||||
}
|
||||
|
||||
void stage3d_apply_inverse_transforms(Stage3D *s, mat4 mat) {
|
||||
camera3d_apply_inverse_transforms(&s->cam, mat);
|
||||
}
|
||||
|
||||
|
||||
// The author that brought you linear3dpos and that one function
|
||||
// that calculates the closest point to a line segment proudly presents:
|
||||
//
|
||||
|
@ -121,6 +136,58 @@ void camera3d_set_point_light_uniforms(
|
|||
r_uniform_int("light_count", num_lights);
|
||||
}
|
||||
|
||||
void pbr_set_material_uniforms(const PBRMaterial *m, const PBREnvironment *env) {
|
||||
int flags = 0;
|
||||
|
||||
if(m->diffuse_map) {
|
||||
r_uniform_sampler("diffuse_map", m->diffuse_map);
|
||||
flags |= PBR_FEATURE_DIFFUSE_MAP;
|
||||
}
|
||||
|
||||
if(m->normal_map) {
|
||||
r_uniform_sampler("normal_map", m->normal_map);
|
||||
flags |= PBR_FEATURE_NORMAL_MAP;
|
||||
}
|
||||
|
||||
if(m->roughness_map) {
|
||||
r_uniform_sampler("roughness_map", m->roughness_map);
|
||||
flags |= PBR_FEATURE_ROUGHNESS_MAP;
|
||||
}
|
||||
|
||||
if(m->ambient_map) {
|
||||
r_uniform_sampler("ambient_map", m->ambient_map);
|
||||
flags |= PBR_FEATURE_AMBIENT_MAP;
|
||||
}
|
||||
|
||||
if(env->environment_map) {
|
||||
r_uniform_sampler("environment_map", env->environment_map);
|
||||
r_uniform_mat4("inv_camera_transform", (vec4*)env->cam_inverse_transform);
|
||||
flags |= PBR_FEATURE_ENVIRONMENT_MAP;
|
||||
}
|
||||
|
||||
vec4 diffuseRGB_metallicA;
|
||||
glm_vec3_copy((float*)m->diffuse_color, diffuseRGB_metallicA);
|
||||
diffuseRGB_metallicA[3] = m->metallic_value;
|
||||
r_uniform_vec4_vec("diffuseRGB_metallicA", diffuseRGB_metallicA);
|
||||
|
||||
vec4 ambientRGB_roughnessA;
|
||||
glm_vec3_mul((float*)env->ambient_color, (float*)m->ambient_color, ambientRGB_roughnessA);
|
||||
ambientRGB_roughnessA[3] = m->roughness_value;
|
||||
r_uniform_vec4_vec("ambientRGB_roughnessA", ambientRGB_roughnessA);
|
||||
|
||||
r_uniform_int("features_mask", flags);
|
||||
}
|
||||
|
||||
void pbr_draw_model(const PBRModel *pmdl, const PBREnvironment *env) {
|
||||
pbr_set_material_uniforms(NOT_NULL(pmdl->mat), env);
|
||||
r_draw_model_ptr(NOT_NULL(pmdl->mdl), 0, 0);
|
||||
}
|
||||
|
||||