шейдеры билбордов
This commit is contained in:
@@ -87,6 +87,7 @@ static func build(
|
||||
mat.set_shader_parameter("effect_alpha_scale", combiner.get("effect_alpha_scale", 1.0))
|
||||
mat.set_shader_parameter("effect_alpha_power", combiner.get("effect_alpha_power", 1.0))
|
||||
mat.set_shader_parameter("uv_edge_fade_strength", combiner.get("uv_edge_fade_strength", 0.0))
|
||||
mat.set_shader_parameter("billboard_enabled", bool(combiner.get("billboard_enabled", false)))
|
||||
mat.set_meta("wow_flags", material_flags)
|
||||
mat.set_meta("wow_blend_mode", blend_mode)
|
||||
mat.set_meta("wow_priority_plane", int(combiner.get("priority_plane", 0)))
|
||||
@@ -94,6 +95,7 @@ static func build(
|
||||
mat.set_meta("wow_texture2_flags", texture2_flags)
|
||||
mat.set_meta("wow_texture3_flags", texture3_flags)
|
||||
mat.set_meta("wow_texture4_flags", texture4_flags)
|
||||
mat.set_meta("wow_m2_billboard_enabled", bool(combiner.get("billboard_enabled", false)))
|
||||
return mat
|
||||
|
||||
|
||||
@@ -228,6 +230,7 @@ uniform vec2 stage3_uv_scroll = vec2(0.0);
|
||||
uniform float effect_alpha_scale = 1.0;
|
||||
uniform float effect_alpha_power = 1.0;
|
||||
uniform float uv_edge_fade_strength = 0.0;
|
||||
uniform bool billboard_enabled = false;
|
||||
|
||||
global uniform vec4 wow_ambient_color;
|
||||
global uniform vec4 wow_light_color;
|
||||
@@ -244,8 +247,58 @@ varying vec2 uv_interp;
|
||||
varying vec2 uv2_interp;
|
||||
varying float edge_fade;
|
||||
|
||||
vec3 safe_normalize(vec3 value, vec3 fallback) {
|
||||
float len = length(value);
|
||||
if (len <= 0.00001) {
|
||||
return normalize(fallback);
|
||||
}
|
||||
return value / len;
|
||||
}
|
||||
|
||||
vec3 apply_m2_billboard(vec3 vertex, vec3 normal, vec4 custom0, mat4 model_matrix, mat3 model_normal_matrix, mat4 inv_view_matrix, out vec3 billboard_world_normal) {
|
||||
billboard_world_normal = safe_normalize(model_normal_matrix * normal, normal);
|
||||
if (!billboard_enabled) {
|
||||
return vertex;
|
||||
}
|
||||
|
||||
int mode = int(custom0.w + 0.5);
|
||||
if (mode <= 0) {
|
||||
return vertex;
|
||||
}
|
||||
|
||||
vec3 pivot = custom0.xyz;
|
||||
vec3 offset = vertex - pivot;
|
||||
vec3 camera_right = safe_normalize(inv_view_matrix[0].xyz, vec3(1.0, 0.0, 0.0));
|
||||
vec3 camera_up = safe_normalize(inv_view_matrix[1].xyz, vec3(0.0, 1.0, 0.0));
|
||||
vec3 camera_back = safe_normalize(inv_view_matrix[2].xyz, vec3(0.0, 0.0, 1.0));
|
||||
vec3 world_x = camera_right;
|
||||
vec3 world_y = camera_up;
|
||||
vec3 world_z = camera_back;
|
||||
|
||||
if (mode == 2) {
|
||||
world_x = safe_normalize((model_matrix * vec4(1.0, 0.0, 0.0, 0.0)).xyz, camera_right);
|
||||
world_y = safe_normalize(camera_up - world_x * dot(camera_up, world_x), (model_matrix * vec4(0.0, 1.0, 0.0, 0.0)).xyz);
|
||||
world_z = safe_normalize(cross(world_x, world_y), camera_back);
|
||||
} else if (mode == 3) {
|
||||
world_z = safe_normalize((model_matrix * vec4(0.0, 0.0, 1.0, 0.0)).xyz, camera_back);
|
||||
world_x = safe_normalize(camera_right - world_z * dot(camera_right, world_z), (model_matrix * vec4(1.0, 0.0, 0.0, 0.0)).xyz);
|
||||
world_y = safe_normalize(cross(world_z, world_x), camera_up);
|
||||
} else if (mode == 4) {
|
||||
world_y = safe_normalize((model_matrix * vec4(0.0, 1.0, 0.0, 0.0)).xyz, camera_up);
|
||||
world_x = safe_normalize(cross(world_y, camera_back), (model_matrix * vec4(1.0, 0.0, 0.0, 0.0)).xyz);
|
||||
world_z = safe_normalize(cross(world_x, world_y), camera_back);
|
||||
}
|
||||
|
||||
vec3 world_pivot = (model_matrix * vec4(pivot, 1.0)).xyz;
|
||||
vec3 billboard_world_pos = world_pivot + world_x * offset.x + world_y * offset.y + world_z * offset.z;
|
||||
billboard_world_normal = world_z;
|
||||
return (inverse(model_matrix) * vec4(billboard_world_pos, 1.0)).xyz;
|
||||
}
|
||||
|
||||
void vertex() {
|
||||
world_normal = normalize(MODEL_NORMAL_MATRIX * NORMAL);
|
||||
vec3 billboard_normal;
|
||||
VERTEX = apply_m2_billboard(VERTEX, NORMAL, CUSTOM0, MODEL_MATRIX, MODEL_NORMAL_MATRIX, INV_VIEW_MATRIX, billboard_normal);
|
||||
world_normal = billboard_normal;
|
||||
world_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
|
||||
view_pos = (MODELVIEW_MATRIX * vec4(VERTEX, 1.0)).xyz;
|
||||
uv_interp = UV;
|
||||
|
||||
Reference in New Issue
Block a user