Files
nunuhara_xsystem4/shaders/reign.f.glsl
T
kichikuou 2de5132803 ReignEngine: Support (sprite) mesh attribute
It has the same effect as the (sprite) material attribute.

Also, now sprite objects are rendered in the DRAW_OPAQUE phase.
2022-12-24 16:54:40 +09:00

163 lines
4.4 KiB
GLSL

/* Copyright (C) 2022 kichikuou <KichikuouChrome@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#define NR_DIR_LIGHTS 3
#define DIFFUSE_EMISSIVE 0
#define DIFFUSE_NORMAL 1
#define DIFFUSE_LIGHT_MAP 2
#define DIFFUSE_ENV_MAP 3
#define FOG_LINEAR 1
#define FOG_LIGHT_SCATTERING 2
#define ALPHA_BLEND 0
#define ALPHA_TEST 1
#define ALPHA_MAP_BLEND 2
struct dir_light {
vec3 dir;
vec3 diffuse;
vec3 globe_diffuse;
};
uniform sampler2D tex;
uniform sampler2D specular_texture;
uniform sampler2D alpha_texture;
uniform sampler2D light_texture;
uniform sampler2D shadow_texture;
uniform float alpha_mod;
uniform bool use_normal_map;
uniform sampler2D normal_texture;
uniform vec3 ambient;
uniform dir_light dir_lights[NR_DIR_LIGHTS];
uniform float specular_strength;
uniform float specular_shininess;
uniform bool use_specular_map;
uniform float rim_exponent;
uniform vec3 rim_color;
uniform int diffuse_type;
uniform float shadow_darkness;
uniform float shadow_bias;
uniform int fog_type;
uniform float fog_near;
uniform float fog_far;
uniform vec3 fog_color;
uniform int alpha_mode;
in vec2 tex_coord;
in vec2 light_tex_coord;
in vec3 frag_pos;
in vec4 shadow_frag_pos;
in float dist;
in vec3 eye;
in vec3 normal;
in vec3 light_dir[NR_DIR_LIGHTS];
in vec3 specular_dir;
in vec3 ls_ex;
in vec3 ls_in;
out vec4 frag_color;
void main() {
vec3 norm;
if (use_normal_map) {
// NOTE: TT3's shader doesn't normalize this vector.
norm = texture(normal_texture, tex_coord).rgb * 2.0 - 1.0;
} else {
norm = normalize(normal);
}
vec3 view_dir = normalize(eye - frag_pos);
vec3 frag_rgb = ambient;
// Diffuse lighting
vec4 texel;
if (diffuse_type == DIFFUSE_ENV_MAP) {
texel = texture(tex, (vec2(normal.x, -normal.y) + 1.0) / 2.0);
frag_rgb = texel.rgb;
} else {
texel = texture(tex, tex_coord);
if (diffuse_type == DIFFUSE_EMISSIVE) {
frag_rgb = texel.rgb;
} else {
vec3 diffuse = vec3(0.0);
for (int i = 0; i < NR_DIR_LIGHTS; i++) {
float half_lambert = dot(norm, -light_dir[i]) * 0.5 + 0.5;
diffuse += mix(dir_lights[i].globe_diffuse, dir_lights[i].diffuse, half_lambert);
}
if (diffuse_type == DIFFUSE_LIGHT_MAP) {
diffuse *= texture(light_texture, light_tex_coord).rgb;
}
frag_rgb += texel.rgb * diffuse;
}
}
// Specular lighting
if (specular_strength > 0.0) {
vec3 reflect_dir = reflect(specular_dir, norm);
float specular = pow(max(dot(view_dir, reflect_dir), 0.0), specular_shininess) * specular_strength;
if (use_specular_map) {
specular *= texture(specular_texture, tex_coord).r;
}
frag_rgb += vec3(specular);
}
// Rim lighting
if (rim_exponent > 0.0) {
// Normal map is not used here.
vec3 n = use_normal_map ? vec3(0.0, 0.0, 1.0) : normalize(normal);
frag_rgb += pow(1.0 - max(dot(n, view_dir), 0.0), rim_exponent) * rim_color;
}
// Fog
if (fog_type == FOG_LINEAR) {
float fog_factor = clamp((dist - fog_near) / (fog_far - fog_near), 0.0, 1.0);
frag_rgb = mix(frag_rgb, fog_color, fog_factor);
} else if (fog_type == FOG_LIGHT_SCATTERING) {
frag_rgb = frag_rgb * ls_ex + ls_in;
}
// Shadow mapping
if (shadow_darkness > 0.0) {
vec3 shadow_coords = shadow_frag_pos.xyz / shadow_frag_pos.w * 0.5 + 0.5;
shadow_coords.z = min(1.0, shadow_coords.z - shadow_bias);
// PCF with 9 samples.
float brightness = 1.0;
vec2 texel_size = 1.0 / vec2(textureSize(shadow_texture, 0));
for (int x = -1; x <= 1; ++x) {
for (int y = -1; y <= 1; ++y) {
float depth = texture(shadow_texture, shadow_coords.xy + vec2(x, y) * texel_size).r;
if (depth < shadow_coords.z)
brightness -= 0.05 * shadow_darkness;
}
}
frag_rgb *= brightness;
}
// Alpha mapping
float alpha = texel.a * alpha_mod;
if (alpha_mode == ALPHA_TEST) {
if (alpha < 0.8)
discard;
} else if (alpha_mode == ALPHA_MAP_BLEND) {
alpha *= texture(alpha_texture, tex_coord).r;
}
frag_color = vec4(frag_rgb, alpha);
}