mirror of
https://github.com/godotengine/godot.git
synced 2024-11-22 12:12:28 +00:00
Merge pull request #50605 from Calinou/tweak-shader-code-style
Use C++11 raw literals for shader code to improve readability
This commit is contained in:
commit
394191c02f
@ -1733,27 +1733,27 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
|
||||
onion.capture.material = Ref<ShaderMaterial>(memnew(ShaderMaterial));
|
||||
|
||||
onion.capture.shader = Ref<Shader>(memnew(Shader));
|
||||
onion.capture.shader->set_code(" \
|
||||
shader_type canvas_item; \
|
||||
\
|
||||
uniform vec4 bkg_color; \
|
||||
uniform vec4 dir_color; \
|
||||
uniform bool differences_only; \
|
||||
uniform sampler2D present; \
|
||||
\
|
||||
float zero_if_equal(vec4 a, vec4 b) { \
|
||||
return smoothstep(0.0, 0.005, length(a.rgb - b.rgb) / sqrt(3.0)); \
|
||||
} \
|
||||
\
|
||||
void fragment() { \
|
||||
vec4 capture_samp = texture(TEXTURE, UV); \
|
||||
vec4 present_samp = texture(present, UV); \
|
||||
float bkg_mask = zero_if_equal(capture_samp, bkg_color); \
|
||||
float diff_mask = 1.0 - zero_if_equal(present_samp, bkg_color); \
|
||||
diff_mask = min(1.0, diff_mask + float(!differences_only)); \
|
||||
COLOR = vec4(capture_samp.rgb * dir_color.rgb, bkg_mask * diff_mask); \
|
||||
} \
|
||||
");
|
||||
onion.capture.shader->set_code(R"(
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform vec4 bkg_color;
|
||||
uniform vec4 dir_color;
|
||||
uniform bool differences_only;
|
||||
uniform sampler2D present;
|
||||
|
||||
float zero_if_equal(vec4 a, vec4 b) {
|
||||
return smoothstep(0.0, 0.005, length(a.rgb - b.rgb) / sqrt(3.0));
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
vec4 capture_samp = texture(TEXTURE, UV);
|
||||
vec4 present_samp = texture(present, UV);
|
||||
float bkg_mask = zero_if_equal(capture_samp, bkg_color);
|
||||
float diff_mask = 1.0 - zero_if_equal(present_samp, bkg_color);
|
||||
diff_mask = min(1.0, diff_mask + float(!differences_only));
|
||||
COLOR = vec4(capture_samp.rgb * dir_color.rgb, bkg_mask * diff_mask);
|
||||
}
|
||||
)");
|
||||
RS::get_singleton()->material_set_shader(onion.capture.material->get_rid(), onion.capture.shader->get_rid());
|
||||
}
|
||||
|
||||
|
@ -5381,35 +5381,37 @@ void Node3DEditor::_init_indicators() {
|
||||
}
|
||||
|
||||
Ref<Shader> grid_shader = memnew(Shader);
|
||||
grid_shader->set_code(
|
||||
"\n"
|
||||
"shader_type spatial; \n"
|
||||
"render_mode unshaded; \n"
|
||||
"uniform bool orthogonal; \n"
|
||||
"uniform float grid_size; \n"
|
||||
"\n"
|
||||
"void vertex() { \n"
|
||||
" // From FLAG_SRGB_VERTEX_COLOR \n"
|
||||
" if (!OUTPUT_IS_SRGB) { \n"
|
||||
" COLOR.rgb = mix(pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb * (1.0 / 12.92), lessThan(COLOR.rgb, vec3(0.04045))); \n"
|
||||
" } \n"
|
||||
"} \n"
|
||||
"\n"
|
||||
"void fragment() { \n"
|
||||
" ALBEDO = COLOR.rgb; \n"
|
||||
" vec3 dir = orthogonal ? -vec3(0, 0, 1) : VIEW; \n"
|
||||
" float angle_fade = abs(dot(dir, NORMAL)); \n"
|
||||
" angle_fade = smoothstep(0.05, 0.2, angle_fade); \n"
|
||||
" \n"
|
||||
" vec3 world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz; \n"
|
||||
" vec3 world_normal = (CAMERA_MATRIX * vec4(NORMAL, 0.0)).xyz; \n"
|
||||
" vec3 camera_world_pos = CAMERA_MATRIX[3].xyz; \n"
|
||||
" vec3 camera_world_pos_on_plane = camera_world_pos * (1.0 - world_normal); \n"
|
||||
" float dist_fade = 1.0 - (distance(world_pos, camera_world_pos_on_plane) / grid_size); \n"
|
||||
" dist_fade = smoothstep(0.02, 0.3, dist_fade); \n"
|
||||
" \n"
|
||||
" ALPHA = COLOR.a * dist_fade * angle_fade; \n"
|
||||
"}");
|
||||
grid_shader->set_code(R"(
|
||||
shader_type spatial;
|
||||
|
||||
render_mode unshaded;
|
||||
|
||||
uniform bool orthogonal;
|
||||
uniform float grid_size;
|
||||
|
||||
void vertex() {
|
||||
// From FLAG_SRGB_VERTEX_COLOR.
|
||||
if (!OUTPUT_IS_SRGB) {
|
||||
COLOR.rgb = mix(pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb * (1.0 / 12.92), lessThan(COLOR.rgb, vec3(0.04045)));
|
||||
}
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
ALBEDO = COLOR.rgb;
|
||||
vec3 dir = orthogonal ? -vec3(0, 0, 1) : VIEW;
|
||||
float angle_fade = abs(dot(dir, NORMAL));
|
||||
angle_fade = smoothstep(0.05, 0.2, angle_fade);
|
||||
|
||||
vec3 world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz;
|
||||
vec3 world_normal = (CAMERA_MATRIX * vec4(NORMAL, 0.0)).xyz;
|
||||
vec3 camera_world_pos = CAMERA_MATRIX[3].xyz;
|
||||
vec3 camera_world_pos_on_plane = camera_world_pos * (1.0 - world_normal);
|
||||
float dist_fade = 1.0 - (distance(world_pos, camera_world_pos_on_plane) / grid_size);
|
||||
dist_fade = smoothstep(0.02, 0.3, dist_fade);
|
||||
|
||||
ALPHA = COLOR.a * dist_fade * angle_fade;
|
||||
}
|
||||
)");
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
grid_mat[i].instantiate();
|
||||
@ -5621,33 +5623,35 @@ void Node3DEditor::_init_indicators() {
|
||||
|
||||
Ref<Shader> rotate_shader = memnew(Shader);
|
||||
|
||||
rotate_shader->set_code(
|
||||
"\n"
|
||||
"shader_type spatial; \n"
|
||||
"render_mode unshaded, depth_test_disabled; \n"
|
||||
"uniform vec4 albedo; \n"
|
||||
"\n"
|
||||
"mat3 orthonormalize(mat3 m) { \n"
|
||||
" vec3 x = normalize(m[0]); \n"
|
||||
" vec3 y = normalize(m[1] - x * dot(x, m[1])); \n"
|
||||
" vec3 z = m[2] - x * dot(x, m[2]); \n"
|
||||
" z = normalize(z - y * (dot(y,m[2]))); \n"
|
||||
" return mat3(x,y,z); \n"
|
||||
"} \n"
|
||||
"\n"
|
||||
"void vertex() { \n"
|
||||
" mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n"
|
||||
" vec3 n = mv * VERTEX; \n"
|
||||
" float orientation = dot(vec3(0,0,-1),n); \n"
|
||||
" if (orientation <= 0.005) { \n"
|
||||
" VERTEX += NORMAL*0.02; \n"
|
||||
" } \n"
|
||||
"} \n"
|
||||
"\n"
|
||||
"void fragment() { \n"
|
||||
" ALBEDO = albedo.rgb; \n"
|
||||
" ALPHA = albedo.a; \n"
|
||||
"}");
|
||||
rotate_shader->set_code(R"(
|
||||
shader_type spatial;
|
||||
|
||||
render_mode unshaded, depth_test_disabled;
|
||||
|
||||
uniform vec4 albedo;
|
||||
|
||||
mat3 orthonormalize(mat3 m) {
|
||||
vec3 x = normalize(m[0]);
|
||||
vec3 y = normalize(m[1] - x * dot(x, m[1]));
|
||||
vec3 z = m[2] - x * dot(x, m[2]);
|
||||
z = normalize(z - y * (dot(y,m[2])));
|
||||
return mat3(x,y,z);
|
||||
}
|
||||
|
||||
void vertex() {
|
||||
mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX));
|
||||
vec3 n = mv * VERTEX;
|
||||
float orientation = dot(vec3(0, 0, -1), n);
|
||||
if (orientation <= 0.005) {
|
||||
VERTEX += NORMAL * 0.02;
|
||||
}
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
ALBEDO = albedo.rgb;
|
||||
ALPHA = albedo.a;
|
||||
}
|
||||
)");
|
||||
|
||||
Ref<ShaderMaterial> rotate_mat = memnew(ShaderMaterial);
|
||||
rotate_mat->set_render_priority(Material::RENDER_PRIORITY_MAX);
|
||||
@ -5667,34 +5671,36 @@ void Node3DEditor::_init_indicators() {
|
||||
Ref<ShaderMaterial> border_mat = rotate_mat->duplicate();
|
||||
|
||||
Ref<Shader> border_shader = memnew(Shader);
|
||||
border_shader->set_code(
|
||||
"\n"
|
||||
"shader_type spatial; \n"
|
||||
"render_mode unshaded, depth_test_disabled; \n"
|
||||
"uniform vec4 albedo; \n"
|
||||
"\n"
|
||||
"mat3 orthonormalize(mat3 m) { \n"
|
||||
" vec3 x = normalize(m[0]); \n"
|
||||
" vec3 y = normalize(m[1] - x * dot(x, m[1])); \n"
|
||||
" vec3 z = m[2] - x * dot(x, m[2]); \n"
|
||||
" z = normalize(z - y * (dot(y,m[2]))); \n"
|
||||
" return mat3(x,y,z); \n"
|
||||
"} \n"
|
||||
"\n"
|
||||
"void vertex() { \n"
|
||||
" mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n"
|
||||
" mv = inverse(mv); \n"
|
||||
" VERTEX += NORMAL*0.008; \n"
|
||||
" vec3 camera_dir_local = mv * vec3(0,0,1); \n"
|
||||
" vec3 camera_up_local = mv * vec3(0,1,0); \n"
|
||||
" mat3 rotation_matrix = mat3(cross(camera_dir_local, camera_up_local), camera_up_local, camera_dir_local); \n"
|
||||
" VERTEX = rotation_matrix * VERTEX; \n"
|
||||
"} \n"
|
||||
"\n"
|
||||
"void fragment() { \n"
|
||||
" ALBEDO = albedo.rgb; \n"
|
||||
" ALPHA = albedo.a; \n"
|
||||
"}");
|
||||
border_shader->set_code(R"(
|
||||
shader_type spatial;
|
||||
|
||||
render_mode unshaded, depth_test_disabled;
|
||||
|
||||
uniform vec4 albedo;
|
||||
|
||||
mat3 orthonormalize(mat3 m) {
|
||||
vec3 x = normalize(m[0]);
|
||||
vec3 y = normalize(m[1] - x * dot(x, m[1]));
|
||||
vec3 z = m[2] - x * dot(x, m[2]);
|
||||
z = normalize(z - y * (dot(y,m[2])));
|
||||
return mat3(x,y,z);
|
||||
}
|
||||
|
||||
void vertex() {
|
||||
mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX));
|
||||
mv = inverse(mv);
|
||||
VERTEX += NORMAL*0.008;
|
||||
vec3 camera_dir_local = mv * vec3(0,0,1);
|
||||
vec3 camera_up_local = mv * vec3(0,1,0);
|
||||
mat3 rotation_matrix = mat3(cross(camera_dir_local, camera_up_local), camera_up_local, camera_dir_local);
|
||||
VERTEX = rotation_matrix * VERTEX;
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
ALBEDO = albedo.rgb;
|
||||
ALPHA = albedo.a;
|
||||
}
|
||||
)");
|
||||
|
||||
border_mat->set_shader(border_shader);
|
||||
border_mat->set_shader_param("albedo", Color(0.75, 0.75, 0.75, col.a / 3.0));
|
||||
@ -7155,9 +7161,21 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) {
|
||||
sun_direction->connect("draw", callable_mp(this, &Node3DEditor::_sun_direction_draw));
|
||||
sun_direction->set_default_cursor_shape(CURSOR_MOVE);
|
||||
|
||||
String sun_dir_shader_code = "shader_type canvas_item; uniform vec3 sun_direction; uniform vec3 sun_color; void fragment() { vec3 n; n.xy = UV * 2.0 - 1.0; n.z = sqrt(max(0.0, 1.0 - dot(n.xy, n.xy))); COLOR.rgb = dot(n,sun_direction) * sun_color; COLOR.a = 1.0 - smoothstep(0.99,1.0,length(n.xy)); }";
|
||||
sun_direction_shader.instantiate();
|
||||
sun_direction_shader->set_code(sun_dir_shader_code);
|
||||
sun_direction_shader->set_code(R"(
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform vec3 sun_direction;
|
||||
uniform vec3 sun_color;
|
||||
|
||||
void fragment() {
|
||||
vec3 n;
|
||||
n.xy = UV * 2.0 - 1.0;
|
||||
n.z = sqrt(max(0.0, 1.0 - dot(n.xy, n.xy)));
|
||||
COLOR.rgb = dot(n, sun_direction) * sun_color;
|
||||
COLOR.a = 1.0 - smoothstep(0.99, 1.0, length(n.xy));
|
||||
}
|
||||
)");
|
||||
sun_direction_material.instantiate();
|
||||
sun_direction_material->set_shader(sun_direction_shader);
|
||||
sun_direction_material->set_shader_param("sun_direction", Vector3(0, 0, 1));
|
||||
|
@ -77,16 +77,17 @@ void Texture3DEditor::_update_material() {
|
||||
}
|
||||
|
||||
void Texture3DEditor::_make_shaders() {
|
||||
String shader_3d = ""
|
||||
"shader_type canvas_item;\n"
|
||||
"uniform sampler3D tex;\n"
|
||||
"uniform float layer;\n"
|
||||
"void fragment() {\n"
|
||||
" COLOR = textureLod(tex,vec3(UV,layer),0.0);\n"
|
||||
"}";
|
||||
|
||||
shader.instantiate();
|
||||
shader->set_code(shader_3d);
|
||||
shader->set_code(R"(
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform sampler3D tex;
|
||||
uniform float layer;
|
||||
|
||||
void fragment() {
|
||||
COLOR = textureLod(tex, vec3(UV, layer), 0.0);
|
||||
}
|
||||
)");
|
||||
material.instantiate();
|
||||
material->set_shader(shader);
|
||||
}
|
||||
|
@ -104,43 +104,46 @@ void TextureLayeredEditor::_update_material() {
|
||||
}
|
||||
|
||||
void TextureLayeredEditor::_make_shaders() {
|
||||
String shader_2d_array = ""
|
||||
"shader_type canvas_item;\n"
|
||||
"uniform sampler2DArray tex;\n"
|
||||
"uniform float layer;\n"
|
||||
"void fragment() {\n"
|
||||
" COLOR = textureLod(tex,vec3(UV,layer),0.0);\n"
|
||||
"}";
|
||||
|
||||
shaders[0].instantiate();
|
||||
shaders[0]->set_code(shader_2d_array);
|
||||
shaders[0]->set_code(R"(
|
||||
shader_type canvas_item;
|
||||
|
||||
String shader_cube = ""
|
||||
"shader_type canvas_item;\n"
|
||||
"uniform samplerCube tex;\n"
|
||||
"uniform vec3 normal;\n"
|
||||
"uniform mat3 rot;\n"
|
||||
"void fragment() {\n"
|
||||
" vec3 n = rot * normalize(vec3(normal.xy*(UV * 2.0 - 1.0),normal.z));\n"
|
||||
" COLOR = textureLod(tex,n,0.0);\n"
|
||||
"}";
|
||||
uniform sampler2DArray tex;
|
||||
uniform float layer;
|
||||
|
||||
void fragment() {
|
||||
COLOR = textureLod(tex, vec3(UV, layer), 0.0);
|
||||
}
|
||||
)");
|
||||
|
||||
shaders[1].instantiate();
|
||||
shaders[1]->set_code(shader_cube);
|
||||
shaders[1]->set_code(R"(
|
||||
shader_type canvas_item;
|
||||
|
||||
String shader_cube_array = ""
|
||||
"shader_type canvas_item;\n"
|
||||
"uniform samplerCubeArray tex;\n"
|
||||
"uniform vec3 normal;\n"
|
||||
"uniform mat3 rot;\n"
|
||||
"uniform float layer;\n"
|
||||
"void fragment() {\n"
|
||||
" vec3 n = rot * normalize(vec3(normal.xy*(UV * 2.0 - 1.0),normal.z));\n"
|
||||
" COLOR = textureLod(tex,vec4(n,layer),0.0);\n"
|
||||
"}";
|
||||
uniform samplerCube tex;
|
||||
uniform vec3 normal;
|
||||
uniform mat3 rot;
|
||||
|
||||
void fragment() {
|
||||
vec3 n = rot * normalize(vec3(normal.xy * (UV * 2.0 - 1.0), normal.z));
|
||||
COLOR = textureLod(tex, n, 0.0);
|
||||
}
|
||||
)");
|
||||
|
||||
shaders[2].instantiate();
|
||||
shaders[2]->set_code(shader_cube_array);
|
||||
shaders[2]->set_code(R"(
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform samplerCubeArray tex;
|
||||
uniform vec3 normal;
|
||||
uniform mat3 rot;
|
||||
uniform float layer;
|
||||
|
||||
void fragment() {
|
||||
vec3 n = rot * normalize(vec3(normal.xy * (UV * 2.0 - 1.0), normal.z));
|
||||
COLOR = textureLod(tex, vec4(n, layer), 0.0);
|
||||
}
|
||||
)");
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
materials[i].instantiate();
|
||||
|
@ -97,43 +97,49 @@ Ref<Shader> ColorPicker::circle_shader;
|
||||
|
||||
void ColorPicker::init_shaders() {
|
||||
wheel_shader.instantiate();
|
||||
wheel_shader->set_code(
|
||||
"shader_type canvas_item;"
|
||||
"void fragment() {"
|
||||
" float x = UV.x - 0.5;"
|
||||
" float y = UV.y - 0.5;"
|
||||
" float a = atan(y, x);"
|
||||
" x += 0.001;"
|
||||
" y += 0.001;"
|
||||
" float b = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42);"
|
||||
" x -= 0.002;"
|
||||
" float b2 = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42);"
|
||||
" y -= 0.002;"
|
||||
" float b3 = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42);"
|
||||
" x += 0.002;"
|
||||
" float b4 = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42);"
|
||||
" COLOR = vec4(clamp((abs(fract(((a - TAU) / TAU) + vec3(3.0, 2.0, 1.0) / 3.0) * 6.0 - 3.0) - 1.0), 0.0, 1.0), (b + b2 + b3 + b4) / 4.00);"
|
||||
"}");
|
||||
wheel_shader->set_code(R"(
|
||||
shader_type canvas_item;
|
||||
|
||||
void fragment() {
|
||||
float x = UV.x - 0.5;
|
||||
float y = UV.y - 0.5;
|
||||
float a = atan(y, x);
|
||||
x += 0.001;
|
||||
y += 0.001;
|
||||
float b = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42);
|
||||
x -= 0.002;
|
||||
float b2 = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42);
|
||||
y -= 0.002;
|
||||
float b3 = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42);
|
||||
x += 0.002;
|
||||
float b4 = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42);
|
||||
|
||||
COLOR = vec4(clamp((abs(fract(((a - TAU) / TAU) + vec3(3.0, 2.0, 1.0) / 3.0) * 6.0 - 3.0) - 1.0), 0.0, 1.0), (b + b2 + b3 + b4) / 4.00);
|
||||
}
|
||||
)");
|
||||
|
||||
circle_shader.instantiate();
|
||||
circle_shader->set_code(
|
||||
"shader_type canvas_item;"
|
||||
"uniform float v = 1.0;"
|
||||
"void fragment() {"
|
||||
" float x = UV.x - 0.5;"
|
||||
" float y = UV.y - 0.5;"
|
||||
" float a = atan(y, x);"
|
||||
" x += 0.001;"
|
||||
" y += 0.001;"
|
||||
" float b = float(sqrt(x * x + y * y) < 0.5);"
|
||||
" x -= 0.002;"
|
||||
" float b2 = float(sqrt(x * x + y * y) < 0.5);"
|
||||
" y -= 0.002;"
|
||||
" float b3 = float(sqrt(x * x + y * y) < 0.5);"
|
||||
" x += 0.002;"
|
||||
" float b4 = float(sqrt(x * x + y * y) < 0.5);"
|
||||
" COLOR = vec4(mix(vec3(1.0), clamp(abs(fract(vec3((a - TAU) / TAU) + vec3(1.0, 2.0 / 3.0, 1.0 / 3.0)) * 6.0 - vec3(3.0)) - vec3(1.0), 0.0, 1.0), ((float(sqrt(x * x + y * y)) * 2.0)) / 1.0) * vec3(v), (b + b2 + b3 + b4) / 4.00);"
|
||||
"}");
|
||||
circle_shader->set_code(R"(
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform float v = 1.0;
|
||||
|
||||
void fragment() {
|
||||
float x = UV.x - 0.5;
|
||||
float y = UV.y - 0.5;
|
||||
float a = atan(y, x);
|
||||
x += 0.001;
|
||||
y += 0.001;
|
||||
float b = float(sqrt(x * x + y * y) < 0.5);
|
||||
x -= 0.002;
|
||||
float b2 = float(sqrt(x * x + y * y) < 0.5);
|
||||
y -= 0.002;
|
||||
float b3 = float(sqrt(x * x + y * y) < 0.5);
|
||||
x += 0.002;
|
||||
float b4 = float(sqrt(x * x + y * y) < 0.5);
|
||||
|
||||
COLOR = vec4(mix(vec3(1.0), clamp(abs(fract(vec3((a - TAU) / TAU) + vec3(1.0, 2.0 / 3.0, 1.0 / 3.0)) * 6.0 - vec3(3.0)) - vec3(1.0), 0.0, 1.0), ((float(sqrt(x * x + y * y)) * 2.0)) / 1.0) * vec3(v), (b + b2 + b3 + b4) / 4.00);
|
||||
})");
|
||||
}
|
||||
|
||||
void ColorPicker::finish_shaders() {
|
||||
|
@ -128,24 +128,21 @@ void CanvasItemMaterial::_update_shader() {
|
||||
if (particles_animation) {
|
||||
code += "uniform int particles_anim_h_frames;\n";
|
||||
code += "uniform int particles_anim_v_frames;\n";
|
||||
code += "uniform bool particles_anim_loop;\n";
|
||||
code += "uniform bool particles_anim_loop;\n\n";
|
||||
|
||||
code += "void vertex() {\n";
|
||||
|
||||
code += "\tfloat h_frames = float(particles_anim_h_frames);\n";
|
||||
code += "\tfloat v_frames = float(particles_anim_v_frames);\n";
|
||||
|
||||
code += "\tVERTEX.xy /= vec2(h_frames, v_frames);\n";
|
||||
|
||||
code += "\tfloat particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);\n";
|
||||
code += "\tfloat particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n";
|
||||
code += "\tif (!particles_anim_loop) {\n";
|
||||
code += "\t\tparticle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);\n";
|
||||
code += "\t} else {\n";
|
||||
code += "\t\tparticle_frame = mod(particle_frame, particle_total_frames);\n";
|
||||
code += "\t}";
|
||||
code += "\tUV /= vec2(h_frames, v_frames);\n";
|
||||
code += "\tUV += vec2(mod(particle_frame, h_frames) / h_frames, floor(particle_frame / h_frames) / v_frames);\n";
|
||||
code += " float h_frames = float(particles_anim_h_frames);\n";
|
||||
code += " float v_frames = float(particles_anim_v_frames);\n";
|
||||
code += " VERTEX.xy /= vec2(h_frames, v_frames);\n";
|
||||
code += " float particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);\n";
|
||||
code += " float particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n";
|
||||
code += " if (!particles_anim_loop) {\n";
|
||||
code += " particle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);\n";
|
||||
code += " } else {\n";
|
||||
code += " particle_frame = mod(particle_frame, particle_total_frames);\n";
|
||||
code += " }";
|
||||
code += " UV /= vec2(h_frames, v_frames);\n";
|
||||
code += " UV += vec2(mod(particle_frame, h_frames) / h_frames, floor(particle_frame / h_frames) / v_frames);\n";
|
||||
code += "}\n";
|
||||
}
|
||||
|
||||
|
@ -757,148 +757,148 @@ void BaseMaterial3D::_update_shader() {
|
||||
code += "void vertex() {\n";
|
||||
|
||||
if (flags[FLAG_SRGB_VERTEX_COLOR]) {
|
||||
code += "\tif (!OUTPUT_IS_SRGB) {\n";
|
||||
code += "\t\tCOLOR.rgb = mix(pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb * (1.0 / 12.92), lessThan(COLOR.rgb, vec3(0.04045)));\n";
|
||||
code += "\t}\n";
|
||||
code += " if (!OUTPUT_IS_SRGB) {\n";
|
||||
code += " COLOR.rgb = mix(pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb * (1.0 / 12.92), lessThan(COLOR.rgb, vec3(0.04045)));\n";
|
||||
code += " }\n";
|
||||
}
|
||||
if (flags[FLAG_USE_POINT_SIZE]) {
|
||||
code += "\tPOINT_SIZE=point_size;\n";
|
||||
code += " POINT_SIZE=point_size;\n";
|
||||
}
|
||||
|
||||
if (shading_mode == SHADING_MODE_PER_VERTEX) {
|
||||
code += "\tROUGHNESS=roughness;\n";
|
||||
code += " ROUGHNESS=roughness;\n";
|
||||
}
|
||||
|
||||
if (!flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tUV=UV*uv1_scale.xy+uv1_offset.xy;\n";
|
||||
code += " UV=UV*uv1_scale.xy+uv1_offset.xy;\n";
|
||||
}
|
||||
|
||||
switch (billboard_mode) {
|
||||
case BILLBOARD_DISABLED: {
|
||||
} break;
|
||||
case BILLBOARD_ENABLED: {
|
||||
code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],CAMERA_MATRIX[1],CAMERA_MATRIX[2],WORLD_MATRIX[3]);\n";
|
||||
code += " MODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],CAMERA_MATRIX[1],CAMERA_MATRIX[2],WORLD_MATRIX[3]);\n";
|
||||
|
||||
if (flags[FLAG_BILLBOARD_KEEP_SCALE]) {
|
||||
code += "\tMODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(WORLD_MATRIX[0].xyz), 0.0, 0.0, 0.0),vec4(0.0, length(WORLD_MATRIX[1].xyz), 0.0, 0.0),vec4(0.0, 0.0, length(WORLD_MATRIX[2].xyz), 0.0),vec4(0.0, 0.0, 0.0, 1.0));\n";
|
||||
code += " MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(WORLD_MATRIX[0].xyz), 0.0, 0.0, 0.0),vec4(0.0, length(WORLD_MATRIX[1].xyz), 0.0, 0.0),vec4(0.0, 0.0, length(WORLD_MATRIX[2].xyz), 0.0),vec4(0.0, 0.0, 0.0, 1.0));\n";
|
||||
}
|
||||
} break;
|
||||
case BILLBOARD_FIXED_Y: {
|
||||
code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],WORLD_MATRIX[1],vec4(normalize(cross(CAMERA_MATRIX[0].xyz,WORLD_MATRIX[1].xyz)), 0.0),WORLD_MATRIX[3]);\n";
|
||||
code += " MODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],WORLD_MATRIX[1],vec4(normalize(cross(CAMERA_MATRIX[0].xyz,WORLD_MATRIX[1].xyz)), 0.0),WORLD_MATRIX[3]);\n";
|
||||
|
||||
if (flags[FLAG_BILLBOARD_KEEP_SCALE]) {
|
||||
code += "\tMODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(WORLD_MATRIX[0].xyz), 0.0, 0.0, 0.0),vec4(0.0, 1.0, 0.0, 0.0),vec4(0.0, 0.0, length(WORLD_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
|
||||
code += " MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(WORLD_MATRIX[0].xyz), 0.0, 0.0, 0.0),vec4(0.0, 1.0, 0.0, 0.0),vec4(0.0, 0.0, length(WORLD_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
|
||||
} else {
|
||||
code += "\tMODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(1.0, 0.0, 0.0, 0.0),vec4(0.0, 1.0/length(WORLD_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0),vec4(0.0, 0.0, 0.0 ,1.0));\n";
|
||||
code += " MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(1.0, 0.0, 0.0, 0.0),vec4(0.0, 1.0/length(WORLD_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0),vec4(0.0, 0.0, 0.0 ,1.0));\n";
|
||||
}
|
||||
} break;
|
||||
case BILLBOARD_PARTICLES: {
|
||||
//make billboard
|
||||
code += "\tmat4 mat_world = mat4(normalize(CAMERA_MATRIX[0])*length(WORLD_MATRIX[0]),normalize(CAMERA_MATRIX[1])*length(WORLD_MATRIX[0]),normalize(CAMERA_MATRIX[2])*length(WORLD_MATRIX[2]),WORLD_MATRIX[3]);\n";
|
||||
code += " mat4 mat_world = mat4(normalize(CAMERA_MATRIX[0])*length(WORLD_MATRIX[0]),normalize(CAMERA_MATRIX[1])*length(WORLD_MATRIX[0]),normalize(CAMERA_MATRIX[2])*length(WORLD_MATRIX[2]),WORLD_MATRIX[3]);\n";
|
||||
//rotate by rotation
|
||||
code += "\tmat_world = mat_world * mat4( vec4(cos(INSTANCE_CUSTOM.x),-sin(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(sin(INSTANCE_CUSTOM.x), cos(INSTANCE_CUSTOM.x), 0.0, 0.0),vec4(0.0, 0.0, 1.0, 0.0),vec4(0.0, 0.0, 0.0, 1.0));\n";
|
||||
code += " mat_world = mat_world * mat4( vec4(cos(INSTANCE_CUSTOM.x),-sin(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(sin(INSTANCE_CUSTOM.x), cos(INSTANCE_CUSTOM.x), 0.0, 0.0),vec4(0.0, 0.0, 1.0, 0.0),vec4(0.0, 0.0, 0.0, 1.0));\n";
|
||||
//set modelview
|
||||
code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat_world;\n";
|
||||
code += " MODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat_world;\n";
|
||||
|
||||
//handle animation
|
||||
code += "\tfloat h_frames = float(particles_anim_h_frames);\n";
|
||||
code += "\tfloat v_frames = float(particles_anim_v_frames);\n";
|
||||
code += "\tfloat particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);\n";
|
||||
code += "\tfloat particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n";
|
||||
code += "\tif (!particles_anim_loop) {\n";
|
||||
code += "\t\tparticle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);\n";
|
||||
code += "\t} else {\n";
|
||||
code += "\t\tparticle_frame = mod(particle_frame, particle_total_frames);\n";
|
||||
code += "\t}";
|
||||
code += "\tUV /= vec2(h_frames, v_frames);\n";
|
||||
code += "\tUV += vec2(mod(particle_frame, h_frames) / h_frames, floor(particle_frame / h_frames) / v_frames);\n";
|
||||
code += " float h_frames = float(particles_anim_h_frames);\n";
|
||||
code += " float v_frames = float(particles_anim_v_frames);\n";
|
||||
code += " float particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);\n";
|
||||
code += " float particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n";
|
||||
code += " if (!particles_anim_loop) {\n";
|
||||
code += " particle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);\n";
|
||||
code += " } else {\n";
|
||||
code += " particle_frame = mod(particle_frame, particle_total_frames);\n";
|
||||
code += " }";
|
||||
code += " UV /= vec2(h_frames, v_frames);\n";
|
||||
code += " UV += vec2(mod(particle_frame, h_frames) / h_frames, floor(particle_frame / h_frames) / v_frames);\n";
|
||||
} break;
|
||||
case BILLBOARD_MAX:
|
||||
break; // Internal value, skip.
|
||||
}
|
||||
|
||||
if (flags[FLAG_FIXED_SIZE]) {
|
||||
code += "\tif (PROJECTION_MATRIX[3][3] != 0.0) {\n";
|
||||
code += " if (PROJECTION_MATRIX[3][3] != 0.0) {\n";
|
||||
//orthogonal matrix, try to do about the same
|
||||
//with viewport size
|
||||
code += "\t\tfloat h = abs(1.0 / (2.0 * PROJECTION_MATRIX[1][1]));\n";
|
||||
code += "\t\tfloat sc = (h * 2.0); //consistent with Y-fov\n";
|
||||
code += "\t\tMODELVIEW_MATRIX[0]*=sc;\n";
|
||||
code += "\t\tMODELVIEW_MATRIX[1]*=sc;\n";
|
||||
code += "\t\tMODELVIEW_MATRIX[2]*=sc;\n";
|
||||
code += "\t} else {\n";
|
||||
code += " float h = abs(1.0 / (2.0 * PROJECTION_MATRIX[1][1]));\n";
|
||||
code += " float sc = (h * 2.0); //consistent with Y-fov\n";
|
||||
code += " MODELVIEW_MATRIX[0]*=sc;\n";
|
||||
code += " MODELVIEW_MATRIX[1]*=sc;\n";
|
||||
code += " MODELVIEW_MATRIX[2]*=sc;\n";
|
||||
code += " } else {\n";
|
||||
//just scale by depth
|
||||
code += "\t\tfloat sc = -(MODELVIEW_MATRIX)[3].z;\n";
|
||||
code += "\t\tMODELVIEW_MATRIX[0]*=sc;\n";
|
||||
code += "\t\tMODELVIEW_MATRIX[1]*=sc;\n";
|
||||
code += "\t\tMODELVIEW_MATRIX[2]*=sc;\n";
|
||||
code += "\t}\n";
|
||||
code += " float sc = -(MODELVIEW_MATRIX)[3].z;\n";
|
||||
code += " MODELVIEW_MATRIX[0]*=sc;\n";
|
||||
code += " MODELVIEW_MATRIX[1]*=sc;\n";
|
||||
code += " MODELVIEW_MATRIX[2]*=sc;\n";
|
||||
code += " }\n";
|
||||
}
|
||||
|
||||
if (detail_uv == DETAIL_UV_2 && !flags[FLAG_UV2_USE_TRIPLANAR]) {
|
||||
code += "\tUV2=UV2*uv2_scale.xy+uv2_offset.xy;\n";
|
||||
code += " UV2=UV2*uv2_scale.xy+uv2_offset.xy;\n";
|
||||
}
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR]) {
|
||||
//generate tangent and binormal in world space
|
||||
code += "\tTANGENT = vec3(0.0,0.0,-1.0) * abs(NORMAL.x);\n";
|
||||
code += "\tTANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.y);\n";
|
||||
code += "\tTANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.z);\n";
|
||||
code += "\tTANGENT = normalize(TANGENT);\n";
|
||||
code += " TANGENT = vec3(0.0,0.0,-1.0) * abs(NORMAL.x);\n";
|
||||
code += " TANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.y);\n";
|
||||
code += " TANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.z);\n";
|
||||
code += " TANGENT = normalize(TANGENT);\n";
|
||||
|
||||
code += "\tBINORMAL = vec3(0.0,1.0,0.0) * abs(NORMAL.x);\n";
|
||||
code += "\tBINORMAL+= vec3(0.0,0.0,-1.0) * abs(NORMAL.y);\n";
|
||||
code += "\tBINORMAL+= vec3(0.0,1.0,0.0) * abs(NORMAL.z);\n";
|
||||
code += "\tBINORMAL = normalize(BINORMAL);\n";
|
||||
code += " BINORMAL = vec3(0.0,1.0,0.0) * abs(NORMAL.x);\n";
|
||||
code += " BINORMAL+= vec3(0.0,0.0,-1.0) * abs(NORMAL.y);\n";
|
||||
code += " BINORMAL+= vec3(0.0,1.0,0.0) * abs(NORMAL.z);\n";
|
||||
code += " BINORMAL = normalize(BINORMAL);\n";
|
||||
}
|
||||
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
if (flags[FLAG_UV1_USE_WORLD_TRIPLANAR]) {
|
||||
code += "\tuv1_power_normal=pow(abs(mat3(WORLD_MATRIX) * NORMAL),vec3(uv1_blend_sharpness));\n";
|
||||
code += "\tuv1_triplanar_pos = (WORLD_MATRIX * vec4(VERTEX, 1.0f)).xyz * uv1_scale + uv1_offset;\n";
|
||||
code += " uv1_power_normal=pow(abs(mat3(WORLD_MATRIX) * NORMAL),vec3(uv1_blend_sharpness));\n";
|
||||
code += " uv1_triplanar_pos = (WORLD_MATRIX * vec4(VERTEX, 1.0f)).xyz * uv1_scale + uv1_offset;\n";
|
||||
} else {
|
||||
code += "\tuv1_power_normal=pow(abs(NORMAL),vec3(uv1_blend_sharpness));\n";
|
||||
code += "\tuv1_triplanar_pos = VERTEX * uv1_scale + uv1_offset;\n";
|
||||
code += " uv1_power_normal=pow(abs(NORMAL),vec3(uv1_blend_sharpness));\n";
|
||||
code += " uv1_triplanar_pos = VERTEX * uv1_scale + uv1_offset;\n";
|
||||
}
|
||||
code += "\tuv1_power_normal/=dot(uv1_power_normal,vec3(1.0));\n";
|
||||
code += "\tuv1_triplanar_pos *= vec3(1.0,-1.0, 1.0);\n";
|
||||
code += " uv1_power_normal/=dot(uv1_power_normal,vec3(1.0));\n";
|
||||
code += " uv1_triplanar_pos *= vec3(1.0,-1.0, 1.0);\n";
|
||||
}
|
||||
|
||||
if (flags[FLAG_UV2_USE_TRIPLANAR]) {
|
||||
if (flags[FLAG_UV2_USE_WORLD_TRIPLANAR]) {
|
||||
code += "\tuv2_power_normal=pow(abs(mat3(WORLD_MATRIX) * NORMAL), vec3(uv2_blend_sharpness));\n";
|
||||
code += "\tuv2_triplanar_pos = (WORLD_MATRIX * vec4(VERTEX, 1.0f)).xyz * uv2_scale + uv2_offset;\n";
|
||||
code += " uv2_power_normal=pow(abs(mat3(WORLD_MATRIX) * NORMAL), vec3(uv2_blend_sharpness));\n";
|
||||
code += " uv2_triplanar_pos = (WORLD_MATRIX * vec4(VERTEX, 1.0f)).xyz * uv2_scale + uv2_offset;\n";
|
||||
} else {
|
||||
code += "\tuv2_power_normal=pow(abs(NORMAL), vec3(uv2_blend_sharpness));\n";
|
||||
code += "\tuv2_triplanar_pos = VERTEX * uv2_scale + uv2_offset;\n";
|
||||
code += " uv2_power_normal=pow(abs(NORMAL), vec3(uv2_blend_sharpness));\n";
|
||||
code += " uv2_triplanar_pos = VERTEX * uv2_scale + uv2_offset;\n";
|
||||
}
|
||||
code += "\tuv2_power_normal/=dot(uv2_power_normal,vec3(1.0));\n";
|
||||
code += "\tuv2_triplanar_pos *= vec3(1.0,-1.0, 1.0);\n";
|
||||
code += " uv2_power_normal/=dot(uv2_power_normal,vec3(1.0));\n";
|
||||
code += " uv2_triplanar_pos *= vec3(1.0,-1.0, 1.0);\n";
|
||||
}
|
||||
|
||||
if (grow_enabled) {
|
||||
code += "\tVERTEX+=NORMAL*grow;\n";
|
||||
code += " VERTEX+=NORMAL*grow;\n";
|
||||
}
|
||||
|
||||
code += "}\n";
|
||||
code += "\n\n";
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR]) {
|
||||
code += "vec4 triplanar_texture(sampler2D p_sampler,vec3 p_weights,vec3 p_triplanar_pos) {\n";
|
||||
code += "\tvec4 samp=vec4(0.0);\n";
|
||||
code += "\tsamp+= texture(p_sampler,p_triplanar_pos.xy) * p_weights.z;\n";
|
||||
code += "\tsamp+= texture(p_sampler,p_triplanar_pos.xz) * p_weights.y;\n";
|
||||
code += "\tsamp+= texture(p_sampler,p_triplanar_pos.zy * vec2(-1.0,1.0)) * p_weights.x;\n";
|
||||
code += "\treturn samp;\n";
|
||||
code += " vec4 samp=vec4(0.0);\n";
|
||||
code += " samp+= texture(p_sampler,p_triplanar_pos.xy) * p_weights.z;\n";
|
||||
code += " samp+= texture(p_sampler,p_triplanar_pos.xz) * p_weights.y;\n";
|
||||
code += " samp+= texture(p_sampler,p_triplanar_pos.zy * vec2(-1.0,1.0)) * p_weights.x;\n";
|
||||
code += " return samp;\n";
|
||||
code += "}\n";
|
||||
}
|
||||
code += "\n\n";
|
||||
code += "void fragment() {\n";
|
||||
|
||||
if (!flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tvec2 base_uv = UV;\n";
|
||||
code += " vec2 base_uv = UV;\n";
|
||||
}
|
||||
|
||||
if ((features[FEATURE_DETAIL] && detail_uv == DETAIL_UV_2) || (features[FEATURE_AMBIENT_OCCLUSION] && flags[FLAG_AO_ON_UV2]) || (features[FEATURE_EMISSION] && flags[FLAG_EMISSION_ON_UV2])) {
|
||||
code += "\tvec2 base_uv2 = UV2;\n";
|
||||
code += " vec2 base_uv2 = UV2;\n";
|
||||
}
|
||||
|
||||
if (features[FEATURE_HEIGHT_MAPPING] && flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
@ -916,317 +916,317 @@ void BaseMaterial3D::_update_shader() {
|
||||
}
|
||||
|
||||
if (!RenderingServer::get_singleton()->is_low_end() && features[FEATURE_HEIGHT_MAPPING] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //heightmap not supported with triplanar
|
||||
code += "\t{\n";
|
||||
code += "\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*heightmap_flip.x,-BINORMAL*heightmap_flip.y,NORMAL));\n"; // binormal is negative due to mikktspace, flip 'unflips' it ;-)
|
||||
code += " {\n";
|
||||
code += " vec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*heightmap_flip.x,-BINORMAL*heightmap_flip.y,NORMAL));\n"; // binormal is negative due to mikktspace, flip 'unflips' it ;-)
|
||||
|
||||
if (deep_parallax) {
|
||||
code += "\t\tfloat num_layers = mix(float(heightmap_max_layers),float(heightmap_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n";
|
||||
code += "\t\tfloat layer_depth = 1.0 / num_layers;\n";
|
||||
code += "\t\tfloat current_layer_depth = 0.0;\n";
|
||||
code += "\t\tvec2 P = view_dir.xy * heightmap_scale;\n";
|
||||
code += "\t\tvec2 delta = P / num_layers;\n";
|
||||
code += "\t\tvec2 ofs = base_uv;\n";
|
||||
code += " float num_layers = mix(float(heightmap_max_layers),float(heightmap_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n";
|
||||
code += " float layer_depth = 1.0 / num_layers;\n";
|
||||
code += " float current_layer_depth = 0.0;\n";
|
||||
code += " vec2 P = view_dir.xy * heightmap_scale;\n";
|
||||
code += " vec2 delta = P / num_layers;\n";
|
||||
code += " vec2 ofs = base_uv;\n";
|
||||
if (flags[FLAG_INVERT_HEIGHTMAP]) {
|
||||
code += "\t\tfloat depth = texture(texture_heightmap, ofs).r;\n";
|
||||
code += " float depth = texture(texture_heightmap, ofs).r;\n";
|
||||
} else {
|
||||
code += "\t\tfloat depth = 1.0 - texture(texture_heightmap, ofs).r;\n";
|
||||
code += " float depth = 1.0 - texture(texture_heightmap, ofs).r;\n";
|
||||
}
|
||||
code += "\t\tfloat current_depth = 0.0;\n";
|
||||
code += "\t\twhile(current_depth < depth) {\n";
|
||||
code += "\t\t\tofs -= delta;\n";
|
||||
code += " float current_depth = 0.0;\n";
|
||||
code += " while(current_depth < depth) {\n";
|
||||
code += " ofs -= delta;\n";
|
||||
if (flags[FLAG_INVERT_HEIGHTMAP]) {
|
||||
code += "\t\t\tdepth = texture(texture_heightmap, ofs).r;\n";
|
||||
code += " depth = texture(texture_heightmap, ofs).r;\n";
|
||||
} else {
|
||||
code += "\t\t\tdepth = 1.0 - texture(texture_heightmap, ofs).r;\n";
|
||||
code += " depth = 1.0 - texture(texture_heightmap, ofs).r;\n";
|
||||
}
|
||||
code += "\t\t\tcurrent_depth += layer_depth;\n";
|
||||
code += "\t\t}\n";
|
||||
code += "\t\tvec2 prev_ofs = ofs + delta;\n";
|
||||
code += "\t\tfloat after_depth = depth - current_depth;\n";
|
||||
code += " current_depth += layer_depth;\n";
|
||||
code += " }\n";
|
||||
code += " vec2 prev_ofs = ofs + delta;\n";
|
||||
code += " float after_depth = depth - current_depth;\n";
|
||||
if (flags[FLAG_INVERT_HEIGHTMAP]) {
|
||||
code += "\t\tfloat before_depth = texture(texture_heightmap, prev_ofs).r - current_depth + layer_depth;\n";
|
||||
code += " float before_depth = texture(texture_heightmap, prev_ofs).r - current_depth + layer_depth;\n";
|
||||
} else {
|
||||
code += "\t\tfloat before_depth = ( 1.0 - texture(texture_heightmap, prev_ofs).r ) - current_depth + layer_depth;\n";
|
||||
code += " float before_depth = ( 1.0 - texture(texture_heightmap, prev_ofs).r ) - current_depth + layer_depth;\n";
|
||||
}
|
||||
code += "\t\tfloat weight = after_depth / (after_depth - before_depth);\n";
|
||||
code += "\t\tofs = mix(ofs,prev_ofs,weight);\n";
|
||||
code += " float weight = after_depth / (after_depth - before_depth);\n";
|
||||
code += " ofs = mix(ofs,prev_ofs,weight);\n";
|
||||
|
||||
} else {
|
||||
if (flags[FLAG_INVERT_HEIGHTMAP]) {
|
||||
code += "\t\tfloat depth = texture(texture_heightmap, base_uv).r;\n";
|
||||
code += " float depth = texture(texture_heightmap, base_uv).r;\n";
|
||||
} else {
|
||||
code += "\t\tfloat depth = 1.0 - texture(texture_heightmap, base_uv).r;\n";
|
||||
code += " float depth = 1.0 - texture(texture_heightmap, base_uv).r;\n";
|
||||
}
|
||||
code += "\t\tvec2 ofs = base_uv - view_dir.xy / view_dir.z * (depth * heightmap_scale);\n";
|
||||
code += " vec2 ofs = base_uv - view_dir.xy / view_dir.z * (depth * heightmap_scale);\n";
|
||||
}
|
||||
|
||||
code += "\t\tbase_uv=ofs;\n";
|
||||
code += " base_uv=ofs;\n";
|
||||
if (features[FEATURE_DETAIL] && detail_uv == DETAIL_UV_2) {
|
||||
code += "\t\tbase_uv2-=ofs;\n";
|
||||
code += " base_uv2-=ofs;\n";
|
||||
}
|
||||
|
||||
code += "\t}\n";
|
||||
code += " }\n";
|
||||
}
|
||||
|
||||
if (flags[FLAG_USE_POINT_SIZE]) {
|
||||
code += "\tvec4 albedo_tex = texture(texture_albedo,POINT_COORD);\n";
|
||||
code += " vec4 albedo_tex = texture(texture_albedo,POINT_COORD);\n";
|
||||
} else {
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tvec4 albedo_tex = triplanar_texture(texture_albedo,uv1_power_normal,uv1_triplanar_pos);\n";
|
||||
code += " vec4 albedo_tex = triplanar_texture(texture_albedo,uv1_power_normal,uv1_triplanar_pos);\n";
|
||||
} else {
|
||||
code += "\tvec4 albedo_tex = texture(texture_albedo,base_uv);\n";
|
||||
code += " vec4 albedo_tex = texture(texture_albedo,base_uv);\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (flags[FLAG_ALBEDO_TEXTURE_FORCE_SRGB]) {
|
||||
code += "\talbedo_tex.rgb = mix(pow((albedo_tex.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)),vec3(2.4)),albedo_tex.rgb.rgb * (1.0 / 12.92),lessThan(albedo_tex.rgb,vec3(0.04045)));\n";
|
||||
code += " albedo_tex.rgb = mix(pow((albedo_tex.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)),vec3(2.4)),albedo_tex.rgb.rgb * (1.0 / 12.92),lessThan(albedo_tex.rgb,vec3(0.04045)));\n";
|
||||
}
|
||||
|
||||
if (flags[FLAG_ALBEDO_FROM_VERTEX_COLOR]) {
|
||||
code += "\talbedo_tex *= COLOR;\n";
|
||||
code += " albedo_tex *= COLOR;\n";
|
||||
}
|
||||
code += "\tALBEDO = albedo.rgb * albedo_tex.rgb;\n";
|
||||
code += " ALBEDO = albedo.rgb * albedo_tex.rgb;\n";
|
||||
|
||||
if (!orm) {
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tfloat metallic_tex = dot(triplanar_texture(texture_metallic,uv1_power_normal,uv1_triplanar_pos),metallic_texture_channel);\n";
|
||||
code += " float metallic_tex = dot(triplanar_texture(texture_metallic,uv1_power_normal,uv1_triplanar_pos),metallic_texture_channel);\n";
|
||||
} else {
|
||||
code += "\tfloat metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);\n";
|
||||
code += " float metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);\n";
|
||||
}
|
||||
code += "\tMETALLIC = metallic_tex * metallic;\n";
|
||||
code += " METALLIC = metallic_tex * metallic;\n";
|
||||
|
||||
switch (roughness_texture_channel) {
|
||||
case TEXTURE_CHANNEL_RED: {
|
||||
code += "\tvec4 roughness_texture_channel = vec4(1.0,0.0,0.0,0.0);\n";
|
||||
code += " vec4 roughness_texture_channel = vec4(1.0,0.0,0.0,0.0);\n";
|
||||
} break;
|
||||
case TEXTURE_CHANNEL_GREEN: {
|
||||
code += "\tvec4 roughness_texture_channel = vec4(0.0,1.0,0.0,0.0);\n";
|
||||
code += " vec4 roughness_texture_channel = vec4(0.0,1.0,0.0,0.0);\n";
|
||||
} break;
|
||||
case TEXTURE_CHANNEL_BLUE: {
|
||||
code += "\tvec4 roughness_texture_channel = vec4(0.0,0.0,1.0,0.0);\n";
|
||||
code += " vec4 roughness_texture_channel = vec4(0.0,0.0,1.0,0.0);\n";
|
||||
} break;
|
||||
case TEXTURE_CHANNEL_ALPHA: {
|
||||
code += "\tvec4 roughness_texture_channel = vec4(0.0,0.0,0.0,1.0);\n";
|
||||
code += " vec4 roughness_texture_channel = vec4(0.0,0.0,0.0,1.0);\n";
|
||||
} break;
|
||||
case TEXTURE_CHANNEL_GRAYSCALE: {
|
||||
code += "\tvec4 roughness_texture_channel = vec4(0.333333,0.333333,0.333333,0.0);\n";
|
||||
code += " vec4 roughness_texture_channel = vec4(0.333333,0.333333,0.333333,0.0);\n";
|
||||
} break;
|
||||
case TEXTURE_CHANNEL_MAX:
|
||||
break; // Internal value, skip.
|
||||
}
|
||||
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tfloat roughness_tex = dot(triplanar_texture(texture_roughness,uv1_power_normal,uv1_triplanar_pos),roughness_texture_channel);\n";
|
||||
code += " float roughness_tex = dot(triplanar_texture(texture_roughness,uv1_power_normal,uv1_triplanar_pos),roughness_texture_channel);\n";
|
||||
} else {
|
||||
code += "\tfloat roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);\n";
|
||||
code += " float roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);\n";
|
||||
}
|
||||
code += "\tROUGHNESS = roughness_tex * roughness;\n";
|
||||
code += "\tSPECULAR = specular;\n";
|
||||
code += " ROUGHNESS = roughness_tex * roughness;\n";
|
||||
code += " SPECULAR = specular;\n";
|
||||
} else {
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tvec4 orm_tex = triplanar_texture(texture_orm,uv1_power_normal,uv1_triplanar_pos);\n";
|
||||
code += " vec4 orm_tex = triplanar_texture(texture_orm,uv1_power_normal,uv1_triplanar_pos);\n";
|
||||
} else {
|
||||
code += "\tvec4 orm_tex = texture(texture_orm,base_uv);\n";
|
||||
code += " vec4 orm_tex = texture(texture_orm,base_uv);\n";
|
||||
}
|
||||
|
||||
code += "\tROUGHNESS = orm_tex.g;\n";
|
||||
code += "\tMETALLIC = orm_tex.b;\n";
|
||||
code += " ROUGHNESS = orm_tex.g;\n";
|
||||
code += " METALLIC = orm_tex.b;\n";
|
||||
}
|
||||
|
||||
if (features[FEATURE_NORMAL_MAPPING]) {
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tNORMAL_MAP = triplanar_texture(texture_normal,uv1_power_normal,uv1_triplanar_pos).rgb;\n";
|
||||
code += " NORMAL_MAP = triplanar_texture(texture_normal,uv1_power_normal,uv1_triplanar_pos).rgb;\n";
|
||||
} else {
|
||||
code += "\tNORMAL_MAP = texture(texture_normal,base_uv).rgb;\n";
|
||||
code += " NORMAL_MAP = texture(texture_normal,base_uv).rgb;\n";
|
||||
}
|
||||
code += "\tNORMAL_MAP_DEPTH = normal_scale;\n";
|
||||
code += " NORMAL_MAP_DEPTH = normal_scale;\n";
|
||||
}
|
||||
|
||||
if (features[FEATURE_EMISSION]) {
|
||||
if (flags[FLAG_EMISSION_ON_UV2]) {
|
||||
if (flags[FLAG_UV2_USE_TRIPLANAR]) {
|
||||
code += "\tvec3 emission_tex = triplanar_texture(texture_emission,uv2_power_normal,uv2_triplanar_pos).rgb;\n";
|
||||
code += " vec3 emission_tex = triplanar_texture(texture_emission,uv2_power_normal,uv2_triplanar_pos).rgb;\n";
|
||||
} else {
|
||||
code += "\tvec3 emission_tex = texture(texture_emission,base_uv2).rgb;\n";
|
||||
code += " vec3 emission_tex = texture(texture_emission,base_uv2).rgb;\n";
|
||||
}
|
||||
} else {
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tvec3 emission_tex = triplanar_texture(texture_emission,uv1_power_normal,uv1_triplanar_pos).rgb;\n";
|
||||
code += " vec3 emission_tex = triplanar_texture(texture_emission,uv1_power_normal,uv1_triplanar_pos).rgb;\n";
|
||||
} else {
|
||||
code += "\tvec3 emission_tex = texture(texture_emission,base_uv).rgb;\n";
|
||||
code += " vec3 emission_tex = texture(texture_emission,base_uv).rgb;\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (emission_op == EMISSION_OP_ADD) {
|
||||
code += "\tEMISSION = (emission.rgb+emission_tex)*emission_energy;\n";
|
||||
code += " EMISSION = (emission.rgb+emission_tex)*emission_energy;\n";
|
||||
} else {
|
||||
code += "\tEMISSION = (emission.rgb*emission_tex)*emission_energy;\n";
|
||||
code += " EMISSION = (emission.rgb*emission_tex)*emission_energy;\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (features[FEATURE_REFRACTION]) {
|
||||
if (features[FEATURE_NORMAL_MAPPING]) {
|
||||
code += "\tvec3 unpacked_normal = NORMAL_MAP;\n";
|
||||
code += "\tunpacked_normal.xy = unpacked_normal.xy * 2.0 - 1.0;\n";
|
||||
code += "\tunpacked_normal.z = sqrt(max(0.0, 1.0 - dot(unpacked_normal.xy, unpacked_normal.xy)));\n";
|
||||
code += "\tvec3 ref_normal = normalize( mix(NORMAL,TANGENT * unpacked_normal.x + BINORMAL * unpacked_normal.y + NORMAL * unpacked_normal.z,NORMAL_MAP_DEPTH) );\n";
|
||||
code += " vec3 unpacked_normal = NORMAL_MAP;\n";
|
||||
code += " unpacked_normal.xy = unpacked_normal.xy * 2.0 - 1.0;\n";
|
||||
code += " unpacked_normal.z = sqrt(max(0.0, 1.0 - dot(unpacked_normal.xy, unpacked_normal.xy)));\n";
|
||||
code += " vec3 ref_normal = normalize( mix(NORMAL,TANGENT * unpacked_normal.x + BINORMAL * unpacked_normal.y + NORMAL * unpacked_normal.z,NORMAL_MAP_DEPTH) );\n";
|
||||
} else {
|
||||
code += "\tvec3 ref_normal = NORMAL;\n";
|
||||
code += " vec3 ref_normal = NORMAL;\n";
|
||||
}
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tvec2 ref_ofs = SCREEN_UV - ref_normal.xy * dot(triplanar_texture(texture_refraction,uv1_power_normal,uv1_triplanar_pos),refraction_texture_channel) * refraction;\n";
|
||||
code += " vec2 ref_ofs = SCREEN_UV - ref_normal.xy * dot(triplanar_texture(texture_refraction,uv1_power_normal,uv1_triplanar_pos),refraction_texture_channel) * refraction;\n";
|
||||
} else {
|
||||
code += "\tvec2 ref_ofs = SCREEN_UV - ref_normal.xy * dot(texture(texture_refraction,base_uv),refraction_texture_channel) * refraction;\n";
|
||||
code += " vec2 ref_ofs = SCREEN_UV - ref_normal.xy * dot(texture(texture_refraction,base_uv),refraction_texture_channel) * refraction;\n";
|
||||
}
|
||||
code += "\tfloat ref_amount = 1.0 - albedo.a * albedo_tex.a;\n";
|
||||
code += "\tEMISSION += textureLod(SCREEN_TEXTURE,ref_ofs,ROUGHNESS * 8.0).rgb * ref_amount;\n";
|
||||
code += "\tALBEDO *= 1.0 - ref_amount;\n";
|
||||
code += "\tALPHA = 1.0;\n";
|
||||
code += " float ref_amount = 1.0 - albedo.a * albedo_tex.a;\n";
|
||||
code += " EMISSION += textureLod(SCREEN_TEXTURE,ref_ofs,ROUGHNESS * 8.0).rgb * ref_amount;\n";
|
||||
code += " ALBEDO *= 1.0 - ref_amount;\n";
|
||||
code += " ALPHA = 1.0;\n";
|
||||
|
||||
} else if (transparency != TRANSPARENCY_DISABLED || flags[FLAG_USE_SHADOW_TO_OPACITY] || (distance_fade == DISTANCE_FADE_PIXEL_ALPHA) || proximity_fade_enabled) {
|
||||
code += "\tALPHA = albedo.a * albedo_tex.a;\n";
|
||||
code += " ALPHA = albedo.a * albedo_tex.a;\n";
|
||||
}
|
||||
if (transparency == TRANSPARENCY_ALPHA_HASH) {
|
||||
code += "\tALPHA_HASH_SCALE = alpha_hash_scale;\n";
|
||||
code += " ALPHA_HASH_SCALE = alpha_hash_scale;\n";
|
||||
} else if (transparency == TRANSPARENCY_ALPHA_SCISSOR) {
|
||||
code += "\tALPHA_SCISSOR_THRESHOLD = alpha_scissor_threshold;\n";
|
||||
code += " ALPHA_SCISSOR_THRESHOLD = alpha_scissor_threshold;\n";
|
||||
}
|
||||
if (alpha_antialiasing_mode != ALPHA_ANTIALIASING_OFF && (transparency == TRANSPARENCY_ALPHA_HASH || transparency == TRANSPARENCY_ALPHA_SCISSOR)) {
|
||||
code += "\tALPHA_ANTIALIASING_EDGE = alpha_antialiasing_edge;\n";
|
||||
code += "\tALPHA_TEXTURE_COORDINATE = UV * vec2(albedo_texture_size);\n";
|
||||
code += " ALPHA_ANTIALIASING_EDGE = alpha_antialiasing_edge;\n";
|
||||
code += " ALPHA_TEXTURE_COORDINATE = UV * vec2(albedo_texture_size);\n";
|
||||
}
|
||||
|
||||
if (proximity_fade_enabled) {
|
||||
code += "\tfloat depth_tex = textureLod(DEPTH_TEXTURE,SCREEN_UV,0.0).r;\n";
|
||||
code += "\tvec4 world_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV*2.0-1.0,depth_tex*2.0-1.0,1.0);\n";
|
||||
code += "\tworld_pos.xyz/=world_pos.w;\n";
|
||||
code += "\tALPHA*=clamp(1.0-smoothstep(world_pos.z+proximity_fade_distance,world_pos.z,VERTEX.z),0.0,1.0);\n";
|
||||
code += " float depth_tex = textureLod(DEPTH_TEXTURE,SCREEN_UV,0.0).r;\n";
|
||||
code += " vec4 world_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV*2.0-1.0,depth_tex*2.0-1.0,1.0);\n";
|
||||
code += " world_pos.xyz/=world_pos.w;\n";
|
||||
code += " ALPHA*=clamp(1.0-smoothstep(world_pos.z+proximity_fade_distance,world_pos.z,VERTEX.z),0.0,1.0);\n";
|
||||
}
|
||||
|
||||
if (distance_fade != DISTANCE_FADE_DISABLED) {
|
||||
if ((distance_fade == DISTANCE_FADE_OBJECT_DITHER || distance_fade == DISTANCE_FADE_PIXEL_DITHER)) {
|
||||
if (!RenderingServer::get_singleton()->is_low_end()) {
|
||||
code += "\t{\n";
|
||||
code += " {\n";
|
||||
if (distance_fade == DISTANCE_FADE_OBJECT_DITHER) {
|
||||
code += "\t\tfloat fade_distance = abs((INV_CAMERA_MATRIX * WORLD_MATRIX[3]).z);\n";
|
||||
code += " float fade_distance = abs((INV_CAMERA_MATRIX * WORLD_MATRIX[3]).z);\n";
|
||||
|
||||
} else {
|
||||
code += "\t\tfloat fade_distance=-VERTEX.z;\n";
|
||||
code += " float fade_distance=-VERTEX.z;\n";
|
||||
}
|
||||
|
||||
code += "\t\tfloat fade=clamp(smoothstep(distance_fade_min,distance_fade_max,fade_distance),0.0,1.0);\n";
|
||||
code += "\t\tint x = int(FRAGCOORD.x) % 4;\n";
|
||||
code += "\t\tint y = int(FRAGCOORD.y) % 4;\n";
|
||||
code += "\t\tint index = x + y * 4;\n";
|
||||
code += "\t\tfloat limit = 0.0;\n\n";
|
||||
code += "\t\tif (x < 8) {\n";
|
||||
code += "\t\t\tif (index == 0) limit = 0.0625;\n";
|
||||
code += "\t\t\tif (index == 1) limit = 0.5625;\n";
|
||||
code += "\t\t\tif (index == 2) limit = 0.1875;\n";
|
||||
code += "\t\t\tif (index == 3) limit = 0.6875;\n";
|
||||
code += "\t\t\tif (index == 4) limit = 0.8125;\n";
|
||||
code += "\t\t\tif (index == 5) limit = 0.3125;\n";
|
||||
code += "\t\t\tif (index == 6) limit = 0.9375;\n";
|
||||
code += "\t\t\tif (index == 7) limit = 0.4375;\n";
|
||||
code += "\t\t\tif (index == 8) limit = 0.25;\n";
|
||||
code += "\t\t\tif (index == 9) limit = 0.75;\n";
|
||||
code += "\t\t\tif (index == 10) limit = 0.125;\n";
|
||||
code += "\t\t\tif (index == 11) limit = 0.625;\n";
|
||||
code += "\t\t\tif (index == 12) limit = 1.0;\n";
|
||||
code += "\t\t\tif (index == 13) limit = 0.5;\n";
|
||||
code += "\t\t\tif (index == 14) limit = 0.875;\n";
|
||||
code += "\t\t\tif (index == 15) limit = 0.375;\n";
|
||||
code += "\t\t}\n\n";
|
||||
code += "\tif (fade < limit)\n";
|
||||
code += "\t\tdiscard;\n";
|
||||
code += "\t}\n\n";
|
||||
code += " float fade=clamp(smoothstep(distance_fade_min,distance_fade_max,fade_distance),0.0,1.0);\n";
|
||||
code += " int x = int(FRAGCOORD.x) % 4;\n";
|
||||
code += " int y = int(FRAGCOORD.y) % 4;\n";
|
||||
code += " int index = x + y * 4;\n";
|
||||
code += " float limit = 0.0;\n\n";
|
||||
code += " if (x < 8) {\n";
|
||||
code += " if (index == 0) limit = 0.0625;\n";
|
||||
code += " if (index == 1) limit = 0.5625;\n";
|
||||
code += " if (index == 2) limit = 0.1875;\n";
|
||||
code += " if (index == 3) limit = 0.6875;\n";
|
||||
code += " if (index == 4) limit = 0.8125;\n";
|
||||
code += " if (index == 5) limit = 0.3125;\n";
|
||||
code += " if (index == 6) limit = 0.9375;\n";
|
||||
code += " if (index == 7) limit = 0.4375;\n";
|
||||
code += " if (index == 8) limit = 0.25;\n";
|
||||
code += " if (index == 9) limit = 0.75;\n";
|
||||
code += " if (index == 10) limit = 0.125;\n";
|
||||
code += " if (index == 11) limit = 0.625;\n";
|
||||
code += " if (index == 12) limit = 1.0;\n";
|
||||
code += " if (index == 13) limit = 0.5;\n";
|
||||
code += " if (index == 14) limit = 0.875;\n";
|
||||
code += " if (index == 15) limit = 0.375;\n";
|
||||
code += " }\n\n";
|
||||
code += " if (fade < limit)\n";
|
||||
code += " discard;\n";
|
||||
code += " }\n\n";
|
||||
}
|
||||
|
||||
} else {
|
||||
code += "\tALPHA*=clamp(smoothstep(distance_fade_min,distance_fade_max,-VERTEX.z),0.0,1.0);\n";
|
||||
code += " ALPHA*=clamp(smoothstep(distance_fade_min,distance_fade_max,-VERTEX.z),0.0,1.0);\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (features[FEATURE_RIM]) {
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tvec2 rim_tex = triplanar_texture(texture_rim,uv1_power_normal,uv1_triplanar_pos).xy;\n";
|
||||
code += " vec2 rim_tex = triplanar_texture(texture_rim,uv1_power_normal,uv1_triplanar_pos).xy;\n";
|
||||
} else {
|
||||
code += "\tvec2 rim_tex = texture(texture_rim,base_uv).xy;\n";
|
||||
code += " vec2 rim_tex = texture(texture_rim,base_uv).xy;\n";
|
||||
}
|
||||
code += "\tRIM = rim*rim_tex.x;";
|
||||
code += "\tRIM_TINT = rim_tint*rim_tex.y;\n";
|
||||
code += " RIM = rim*rim_tex.x;";
|
||||
code += " RIM_TINT = rim_tint*rim_tex.y;\n";
|
||||
}
|
||||
|
||||
if (features[FEATURE_CLEARCOAT]) {
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tvec2 clearcoat_tex = triplanar_texture(texture_clearcoat,uv1_power_normal,uv1_triplanar_pos).xy;\n";
|
||||
code += " vec2 clearcoat_tex = triplanar_texture(texture_clearcoat,uv1_power_normal,uv1_triplanar_pos).xy;\n";
|
||||
} else {
|
||||
code += "\tvec2 clearcoat_tex = texture(texture_clearcoat,base_uv).xy;\n";
|
||||
code += " vec2 clearcoat_tex = texture(texture_clearcoat,base_uv).xy;\n";
|
||||
}
|
||||
code += "\tCLEARCOAT = clearcoat*clearcoat_tex.x;";
|
||||
code += "\tCLEARCOAT_GLOSS = clearcoat_gloss*clearcoat_tex.y;\n";
|
||||
code += " CLEARCOAT = clearcoat*clearcoat_tex.x;";
|
||||
code += " CLEARCOAT_GLOSS = clearcoat_gloss*clearcoat_tex.y;\n";
|
||||
}
|
||||
|
||||
if (features[FEATURE_ANISOTROPY]) {
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tvec3 anisotropy_tex = triplanar_texture(texture_flowmap,uv1_power_normal,uv1_triplanar_pos).rga;\n";
|
||||
code += " vec3 anisotropy_tex = triplanar_texture(texture_flowmap,uv1_power_normal,uv1_triplanar_pos).rga;\n";
|
||||
} else {
|
||||
code += "\tvec3 anisotropy_tex = texture(texture_flowmap,base_uv).rga;\n";
|
||||
code += " vec3 anisotropy_tex = texture(texture_flowmap,base_uv).rga;\n";
|
||||
}
|
||||
code += "\tANISOTROPY = anisotropy_ratio*anisotropy_tex.b;\n";
|
||||
code += "\tANISOTROPY_FLOW = anisotropy_tex.rg*2.0-1.0;\n";
|
||||
code += " ANISOTROPY = anisotropy_ratio*anisotropy_tex.b;\n";
|
||||
code += " ANISOTROPY_FLOW = anisotropy_tex.rg*2.0-1.0;\n";
|
||||
}
|
||||
|
||||
if (features[FEATURE_AMBIENT_OCCLUSION]) {
|
||||
if (!orm) {
|
||||
if (flags[FLAG_AO_ON_UV2]) {
|
||||
if (flags[FLAG_UV2_USE_TRIPLANAR]) {
|
||||
code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv2_power_normal,uv2_triplanar_pos),ao_texture_channel);\n";
|
||||
code += " AO = dot(triplanar_texture(texture_ambient_occlusion,uv2_power_normal,uv2_triplanar_pos),ao_texture_channel);\n";
|
||||
} else {
|
||||
code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv2),ao_texture_channel);\n";
|
||||
code += " AO = dot(texture(texture_ambient_occlusion,base_uv2),ao_texture_channel);\n";
|
||||
}
|
||||
} else {
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv1_power_normal,uv1_triplanar_pos),ao_texture_channel);\n";
|
||||
code += " AO = dot(triplanar_texture(texture_ambient_occlusion,uv1_power_normal,uv1_triplanar_pos),ao_texture_channel);\n";
|
||||
} else {
|
||||
code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv),ao_texture_channel);\n";
|
||||
code += " AO = dot(texture(texture_ambient_occlusion,base_uv),ao_texture_channel);\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
code += "\tAO = orm_tex.r;\n";
|
||||
code += " AO = orm_tex.r;\n";
|
||||
}
|
||||
|
||||
code += "\tAO_LIGHT_AFFECT = ao_light_affect;\n";
|
||||
code += " AO_LIGHT_AFFECT = ao_light_affect;\n";
|
||||
}
|
||||
|
||||
if (features[FEATURE_SUBSURFACE_SCATTERING]) {
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tfloat sss_tex = triplanar_texture(texture_subsurface_scattering,uv1_power_normal,uv1_triplanar_pos).r;\n";
|
||||
code += " float sss_tex = triplanar_texture(texture_subsurface_scattering,uv1_power_normal,uv1_triplanar_pos).r;\n";
|
||||
} else {
|
||||
code += "\tfloat sss_tex = texture(texture_subsurface_scattering,base_uv).r;\n";
|
||||
code += " float sss_tex = texture(texture_subsurface_scattering,base_uv).r;\n";
|
||||
}
|
||||
code += "\tSSS_STRENGTH=subsurface_scattering_strength*sss_tex;\n";
|
||||
code += " SSS_STRENGTH=subsurface_scattering_strength*sss_tex;\n";
|
||||
}
|
||||
|
||||
if (features[FEATURE_SUBSURFACE_TRANSMITTANCE]) {
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tvec4 trans_color_tex = triplanar_texture(texture_subsurface_transmittance,uv1_power_normal,uv1_triplanar_pos);\n";
|
||||
code += " vec4 trans_color_tex = triplanar_texture(texture_subsurface_transmittance,uv1_power_normal,uv1_triplanar_pos);\n";
|
||||
} else {
|
||||
code += "\tvec4 trans_color_tex = texture(texture_subsurface_transmittance,base_uv);\n";
|
||||
code += " vec4 trans_color_tex = texture(texture_subsurface_transmittance,base_uv);\n";
|
||||
}
|
||||
code += "\tSSS_TRANSMITTANCE_COLOR=transmittance_color*trans_color_tex;\n";
|
||||
code += " SSS_TRANSMITTANCE_COLOR=transmittance_color*trans_color_tex;\n";
|
||||
|
||||
code += "\tSSS_TRANSMITTANCE_DEPTH=transmittance_depth;\n";
|
||||
code += "\tSSS_TRANSMITTANCE_BOOST=transmittance_boost;\n";
|
||||
code += " SSS_TRANSMITTANCE_DEPTH=transmittance_depth;\n";
|
||||
code += " SSS_TRANSMITTANCE_BOOST=transmittance_boost;\n";
|
||||
}
|
||||
|
||||
if (features[FEATURE_BACKLIGHT]) {
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tvec3 backlight_tex = triplanar_texture(texture_backlight,uv1_power_normal,uv1_triplanar_pos).rgb;\n";
|
||||
code += " vec3 backlight_tex = triplanar_texture(texture_backlight,uv1_power_normal,uv1_triplanar_pos).rgb;\n";
|
||||
} else {
|
||||
code += "\tvec3 backlight_tex = texture(texture_backlight,base_uv).rgb;\n";
|
||||
code += " vec3 backlight_tex = texture(texture_backlight,base_uv).rgb;\n";
|
||||
}
|
||||
code += "\tBACKLIGHT = (backlight.rgb+backlight_tex);\n";
|
||||
code += " BACKLIGHT = (backlight.rgb+backlight_tex);\n";
|
||||
}
|
||||
|
||||
if (features[FEATURE_DETAIL]) {
|
||||
@ -1234,41 +1234,41 @@ void BaseMaterial3D::_update_shader() {
|
||||
|
||||
if (triplanar) {
|
||||
String tp_uv = detail_uv == DETAIL_UV_1 ? "uv1" : "uv2";
|
||||
code += "\tvec4 detail_tex = triplanar_texture(texture_detail_albedo," + tp_uv + "_power_normal," + tp_uv + "_triplanar_pos);\n";
|
||||
code += "\tvec4 detail_norm_tex = triplanar_texture(texture_detail_normal," + tp_uv + "_power_normal," + tp_uv + "_triplanar_pos);\n";
|
||||
code += " vec4 detail_tex = triplanar_texture(texture_detail_albedo," + tp_uv + "_power_normal," + tp_uv + "_triplanar_pos);\n";
|
||||
code += " vec4 detail_norm_tex = triplanar_texture(texture_detail_normal," + tp_uv + "_power_normal," + tp_uv + "_triplanar_pos);\n";
|
||||
|
||||
} else {
|
||||
String det_uv = detail_uv == DETAIL_UV_1 ? "base_uv" : "base_uv2";
|
||||
code += "\tvec4 detail_tex = texture(texture_detail_albedo," + det_uv + ");\n";
|
||||
code += "\tvec4 detail_norm_tex = texture(texture_detail_normal," + det_uv + ");\n";
|
||||
code += " vec4 detail_tex = texture(texture_detail_albedo," + det_uv + ");\n";
|
||||
code += " vec4 detail_norm_tex = texture(texture_detail_normal," + det_uv + ");\n";
|
||||
}
|
||||
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tvec4 detail_mask_tex = triplanar_texture(texture_detail_mask,uv1_power_normal,uv1_triplanar_pos);\n";
|
||||
code += " vec4 detail_mask_tex = triplanar_texture(texture_detail_mask,uv1_power_normal,uv1_triplanar_pos);\n";
|
||||
} else {
|
||||
code += "\tvec4 detail_mask_tex = texture(texture_detail_mask,base_uv);\n";
|
||||
code += " vec4 detail_mask_tex = texture(texture_detail_mask,base_uv);\n";
|
||||
}
|
||||
|
||||
switch (detail_blend_mode) {
|
||||
case BLEND_MODE_MIX: {
|
||||
code += "\tvec3 detail = mix(ALBEDO.rgb,detail_tex.rgb,detail_tex.a);\n";
|
||||
code += " vec3 detail = mix(ALBEDO.rgb,detail_tex.rgb,detail_tex.a);\n";
|
||||
} break;
|
||||
case BLEND_MODE_ADD: {
|
||||
code += "\tvec3 detail = mix(ALBEDO.rgb,ALBEDO.rgb+detail_tex.rgb,detail_tex.a);\n";
|
||||
code += " vec3 detail = mix(ALBEDO.rgb,ALBEDO.rgb+detail_tex.rgb,detail_tex.a);\n";
|
||||
} break;
|
||||
case BLEND_MODE_SUB: {
|
||||
code += "\tvec3 detail = mix(ALBEDO.rgb,ALBEDO.rgb-detail_tex.rgb,detail_tex.a);\n";
|
||||
code += " vec3 detail = mix(ALBEDO.rgb,ALBEDO.rgb-detail_tex.rgb,detail_tex.a);\n";
|
||||
} break;
|
||||
case BLEND_MODE_MUL: {
|
||||
code += "\tvec3 detail = mix(ALBEDO.rgb,ALBEDO.rgb*detail_tex.rgb,detail_tex.a);\n";
|
||||
code += " vec3 detail = mix(ALBEDO.rgb,ALBEDO.rgb*detail_tex.rgb,detail_tex.a);\n";
|
||||
} break;
|
||||
case BLEND_MODE_MAX:
|
||||
break; // Internal value, skip.
|
||||
}
|
||||
|
||||
code += "\tvec3 detail_norm = mix(NORMAL_MAP,detail_norm_tex.rgb,detail_tex.a);\n";
|
||||
code += "\tNORMAL_MAP = mix(NORMAL_MAP,detail_norm,detail_mask_tex.r);\n";
|
||||
code += "\tALBEDO.rgb = mix(ALBEDO.rgb,detail,detail_mask_tex.r);\n";
|
||||
code += " vec3 detail_norm = mix(NORMAL_MAP,detail_norm_tex.rgb,detail_tex.a);\n";
|
||||
code += " NORMAL_MAP = mix(NORMAL_MAP,detail_norm,detail_mask_tex.r);\n";
|
||||
code += " ALBEDO.rgb = mix(ALBEDO.rgb,detail,detail_mask_tex.r);\n";
|
||||
}
|
||||
|
||||
code += "}\n";
|
||||
|
@ -181,68 +181,75 @@ void ProceduralSkyMaterial::_bind_methods() {
|
||||
}
|
||||
|
||||
ProceduralSkyMaterial::ProceduralSkyMaterial() {
|
||||
String code = "shader_type sky;\n\n";
|
||||
|
||||
code += "uniform vec4 sky_top_color : hint_color = vec4(0.35, 0.46, 0.71, 1.0);\n";
|
||||
code += "uniform vec4 sky_horizon_color : hint_color = vec4(0.55, 0.69, 0.81, 1.0);\n";
|
||||
code += "uniform float sky_curve : hint_range(0, 1) = 0.09;\n";
|
||||
code += "uniform float sky_energy = 1.0;\n\n";
|
||||
code += "uniform vec4 ground_bottom_color : hint_color = vec4(0.12, 0.12, 0.13, 1.0);\n";
|
||||
code += "uniform vec4 ground_horizon_color : hint_color = vec4(0.37, 0.33, 0.31, 1.0);\n";
|
||||
code += "uniform float ground_curve : hint_range(0, 1) = 0.02;\n";
|
||||
code += "uniform float ground_energy = 1.0;\n\n";
|
||||
code += "uniform float sun_angle_max = 1.74;\n";
|
||||
code += "uniform float sun_curve : hint_range(0, 1) = 0.05;\n\n";
|
||||
code += "void sky() {\n";
|
||||
code += "\tfloat v_angle = acos(clamp(EYEDIR.y, -1.0, 1.0));\n";
|
||||
code += "\tfloat c = (1.0 - v_angle / (PI * 0.5));\n";
|
||||
code += "\tvec3 sky = mix(sky_horizon_color.rgb, sky_top_color.rgb, clamp(1.0 - pow(1.0 - c, 1.0 / sky_curve), 0.0, 1.0));\n";
|
||||
code += "\tsky *= sky_energy;\n";
|
||||
code += "\tif (LIGHT0_ENABLED) {\n";
|
||||
code += "\t\tfloat sun_angle = acos(dot(LIGHT0_DIRECTION, EYEDIR));\n";
|
||||
code += "\t\tif (sun_angle < LIGHT0_SIZE) {\n";
|
||||
code += "\t\t\tsky = LIGHT0_COLOR * LIGHT0_ENERGY;\n";
|
||||
code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
|
||||
code += "\t\t\tfloat c2 = (sun_angle - LIGHT0_SIZE) / (sun_angle_max - LIGHT0_SIZE);\n";
|
||||
code += "\t\t\tsky = mix(LIGHT0_COLOR * LIGHT0_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
|
||||
code += "\t\t}\n";
|
||||
code += "\t}\n";
|
||||
code += "\tif (LIGHT1_ENABLED) {\n";
|
||||
code += "\t\tfloat sun_angle = acos(dot(LIGHT1_DIRECTION, EYEDIR));\n";
|
||||
code += "\t\tif (sun_angle < LIGHT1_SIZE) {\n";
|
||||
code += "\t\t\tsky = LIGHT1_COLOR * LIGHT1_ENERGY;\n";
|
||||
code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
|
||||
code += "\t\t\tfloat c2 = (sun_angle - LIGHT1_SIZE) / (sun_angle_max - LIGHT1_SIZE);\n";
|
||||
code += "\t\t\tsky = mix(LIGHT1_COLOR * LIGHT1_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
|
||||
code += "\t\t}\n";
|
||||
code += "\t}\n";
|
||||
code += "\tif (LIGHT2_ENABLED) {\n";
|
||||
code += "\t\tfloat sun_angle = acos(dot(LIGHT2_DIRECTION, EYEDIR));\n";
|
||||
code += "\t\tif (sun_angle < LIGHT2_SIZE) {\n";
|
||||
code += "\t\t\tsky = LIGHT2_COLOR * LIGHT2_ENERGY;\n";
|
||||
code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
|
||||
code += "\t\t\tfloat c2 = (sun_angle - LIGHT2_SIZE) / (sun_angle_max - LIGHT2_SIZE);\n";
|
||||
code += "\t\t\tsky = mix(LIGHT2_COLOR * LIGHT2_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
|
||||
code += "\t\t}\n";
|
||||
code += "\t}\n";
|
||||
code += "\tif (LIGHT3_ENABLED) {\n";
|
||||
code += "\t\tfloat sun_angle = acos(dot(LIGHT3_DIRECTION, EYEDIR));\n";
|
||||
code += "\t\tif (sun_angle < LIGHT3_SIZE) {\n";
|
||||
code += "\t\t\tsky = LIGHT3_COLOR * LIGHT3_ENERGY;\n";
|
||||
code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
|
||||
code += "\t\t\tfloat c2 = (sun_angle - LIGHT3_SIZE) / (sun_angle_max - LIGHT3_SIZE);\n";
|
||||
code += "\t\t\tsky = mix(LIGHT3_COLOR * LIGHT3_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
|
||||
code += "\t\t}\n";
|
||||
code += "\t}\n";
|
||||
code += "\tc = (v_angle - (PI * 0.5)) / (PI * 0.5);\n";
|
||||
code += "\tvec3 ground = mix(ground_horizon_color.rgb, ground_bottom_color.rgb, clamp(1.0 - pow(1.0 - c, 1.0 / ground_curve), 0.0, 1.0));\n";
|
||||
code += "\tground *= ground_energy;\n";
|
||||
code += "\tCOLOR = mix(ground, sky, step(0.0, EYEDIR.y));\n";
|
||||
code += "}\n";
|
||||
|
||||
shader = RS::get_singleton()->shader_create();
|
||||
|
||||
RS::get_singleton()->shader_set_code(shader, code);
|
||||
RS::get_singleton()->shader_set_code(shader, R"(
|
||||
shader_type sky;
|
||||
|
||||
uniform vec4 sky_top_color : hint_color = vec4(0.35, 0.46, 0.71, 1.0);
|
||||
uniform vec4 sky_horizon_color : hint_color = vec4(0.55, 0.69, 0.81, 1.0);
|
||||
uniform float sky_curve : hint_range(0, 1) = 0.09;
|
||||
uniform float sky_energy = 1.0;
|
||||
uniform vec4 ground_bottom_color : hint_color = vec4(0.12, 0.12, 0.13, 1.0);
|
||||
uniform vec4 ground_horizon_color : hint_color = vec4(0.37, 0.33, 0.31, 1.0);
|
||||
uniform float ground_curve : hint_range(0, 1) = 0.02;
|
||||
uniform float ground_energy = 1.0;
|
||||
uniform float sun_angle_max = 1.74;
|
||||
uniform float sun_curve : hint_range(0, 1) = 0.05;
|
||||
|
||||
void sky() {
|
||||
float v_angle = acos(clamp(EYEDIR.y, -1.0, 1.0));
|
||||
float c = (1.0 - v_angle / (PI * 0.5));
|
||||
vec3 sky = mix(sky_horizon_color.rgb, sky_top_color.rgb, clamp(1.0 - pow(1.0 - c, 1.0 / sky_curve), 0.0, 1.0));
|
||||
sky *= sky_energy;
|
||||
|
||||
if (LIGHT0_ENABLED) {
|
||||
float sun_angle = acos(dot(LIGHT0_DIRECTION, EYEDIR));
|
||||
if (sun_angle < LIGHT0_SIZE) {
|
||||
sky = LIGHT0_COLOR * LIGHT0_ENERGY;
|
||||
} else if (sun_angle < sun_angle_max) {
|
||||
float c2 = (sun_angle - LIGHT0_SIZE) / (sun_angle_max - LIGHT0_SIZE);
|
||||
sky = mix(LIGHT0_COLOR * LIGHT0_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));
|
||||
}
|
||||
}
|
||||
|
||||
if (LIGHT1_ENABLED) {
|
||||
float sun_angle = acos(dot(LIGHT1_DIRECTION, EYEDIR));
|
||||
if (sun_angle < LIGHT1_SIZE) {
|
||||
sky = LIGHT1_COLOR * LIGHT1_ENERGY;
|
||||
} else if (sun_angle < sun_angle_max) {
|
||||
float c2 = (sun_angle - LIGHT1_SIZE) / (sun_angle_max - LIGHT1_SIZE);
|
||||
sky = mix(LIGHT1_COLOR * LIGHT1_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));
|
||||
}
|
||||
}
|
||||
|
||||
if (LIGHT2_ENABLED) {
|
||||
float sun_angle = acos(dot(LIGHT2_DIRECTION, EYEDIR));
|
||||
if (sun_angle < LIGHT2_SIZE) {
|
||||
sky = LIGHT2_COLOR * LIGHT2_ENERGY;
|
||||
} else if (sun_angle < sun_angle_max) {
|
||||
float c2 = (sun_angle - LIGHT2_SIZE) / (sun_angle_max - LIGHT2_SIZE);
|
||||
sky = mix(LIGHT2_COLOR * LIGHT2_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));
|
||||
}
|
||||
}
|
||||
|
||||
if (LIGHT3_ENABLED) {
|
||||
float sun_angle = acos(dot(LIGHT3_DIRECTION, EYEDIR));
|
||||
if (sun_angle < LIGHT3_SIZE) {
|
||||
sky = LIGHT3_COLOR * LIGHT3_ENERGY;
|
||||
} else if (sun_angle < sun_angle_max) {
|
||||
float c2 = (sun_angle - LIGHT3_SIZE) / (sun_angle_max - LIGHT3_SIZE);
|
||||
sky = mix(LIGHT3_COLOR * LIGHT3_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));
|
||||
}
|
||||
}
|
||||
|
||||
c = (v_angle - (PI * 0.5)) / (PI * 0.5);
|
||||
vec3 ground = mix(ground_horizon_color.rgb, ground_bottom_color.rgb, clamp(1.0 - pow(1.0 - c, 1.0 / ground_curve), 0.0, 1.0));
|
||||
ground *= ground_energy;
|
||||
|
||||
COLOR = mix(ground, sky, step(0.0, EYEDIR.y));
|
||||
}
|
||||
)");
|
||||
|
||||
RS::get_singleton()->material_set_shader(_get_material(), shader);
|
||||
|
||||
@ -298,16 +305,17 @@ void PanoramaSkyMaterial::_bind_methods() {
|
||||
}
|
||||
|
||||
PanoramaSkyMaterial::PanoramaSkyMaterial() {
|
||||
String code = "shader_type sky;\n\n";
|
||||
|
||||
code += "uniform sampler2D source_panorama : filter_linear;\n";
|
||||
code += "void sky() {\n";
|
||||
code += "\tCOLOR = texture(source_panorama, SKY_COORDS).rgb;\n";
|
||||
code += "}";
|
||||
|
||||
shader = RS::get_singleton()->shader_create();
|
||||
|
||||
RS::get_singleton()->shader_set_code(shader, code);
|
||||
RS::get_singleton()->shader_set_code(shader, R"(
|
||||
shader_type sky;
|
||||
|
||||
uniform sampler2D source_panorama : filter_linear;
|
||||
|
||||
void sky() {
|
||||
COLOR = texture(source_panorama, SKY_COORDS).rgb;
|
||||
}
|
||||
)");
|
||||
|
||||
RS::get_singleton()->material_set_shader(_get_material(), shader);
|
||||
}
|
||||
@ -484,102 +492,102 @@ void PhysicalSkyMaterial::_bind_methods() {
|
||||
}
|
||||
|
||||
PhysicalSkyMaterial::PhysicalSkyMaterial() {
|
||||
String code = "shader_type sky;\n\n";
|
||||
|
||||
code += "uniform float rayleigh : hint_range(0, 64) = 2.0;\n";
|
||||
code += "uniform vec4 rayleigh_color : hint_color = vec4(0.056, 0.14, 0.3, 1.0);\n";
|
||||
code += "uniform float mie : hint_range(0, 1) = 0.005;\n";
|
||||
code += "uniform float mie_eccentricity : hint_range(-1, 1) = 0.8;\n";
|
||||
code += "uniform vec4 mie_color : hint_color = vec4(0.36, 0.56, 0.82, 1.0);\n\n";
|
||||
|
||||
code += "uniform float turbidity : hint_range(0, 1000) = 10.0;\n";
|
||||
code += "uniform float sun_disk_scale : hint_range(0, 360) = 1.0;\n";
|
||||
code += "uniform vec4 ground_color : hint_color = vec4(1.0);\n";
|
||||
code += "uniform float exposure : hint_range(0, 128) = 0.1;\n";
|
||||
code += "uniform float dither_strength : hint_range(0, 10) = 1.0;\n\n";
|
||||
|
||||
code += "uniform sampler2D night_sky : hint_black;";
|
||||
|
||||
code += "const vec3 UP = vec3( 0.0, 1.0, 0.0 );\n\n";
|
||||
|
||||
code += "// Sun constants\n";
|
||||
code += "const float SUN_ENERGY = 1000.0;\n\n";
|
||||
|
||||
code += "// optical length at zenith for molecules\n";
|
||||
code += "const float rayleigh_zenith_size = 8.4e3;\n";
|
||||
code += "const float mie_zenith_size = 1.25e3;\n\n";
|
||||
|
||||
code += "float henyey_greenstein(float cos_theta, float g) {\n";
|
||||
code += "\tconst float k = 0.0795774715459;\n";
|
||||
code += "\treturn k * (1.0 - g * g) / (pow(1.0 + g * g - 2.0 * g * cos_theta, 1.5));\n";
|
||||
code += "}\n\n";
|
||||
|
||||
code += "// From: https://www.shadertoy.com/view/4sfGzS credit to iq\n";
|
||||
code += "float hash(vec3 p) {\n";
|
||||
code += "\tp = fract( p * 0.3183099 + 0.1 );\n";
|
||||
code += "\tp *= 17.0;\n";
|
||||
code += "\treturn fract(p.x * p.y * p.z * (p.x + p.y + p.z));\n";
|
||||
code += "}\n\n";
|
||||
|
||||
code += "void sky() {\n";
|
||||
code += "\tif (LIGHT0_ENABLED) {\n";
|
||||
code += "\t\tfloat zenith_angle = clamp( dot(UP, normalize(LIGHT0_DIRECTION)), -1.0, 1.0 );\n";
|
||||
code += "\t\tfloat sun_energy = max(0.0, 1.0 - exp(-((PI * 0.5) - acos(zenith_angle)))) * SUN_ENERGY * LIGHT0_ENERGY;\n";
|
||||
code += "\t\tfloat sun_fade = 1.0 - clamp(1.0 - exp(LIGHT0_DIRECTION.y), 0.0, 1.0);\n\n";
|
||||
|
||||
code += "\t\t// rayleigh coefficients\n";
|
||||
code += "\t\tfloat rayleigh_coefficient = rayleigh - ( 1.0 * ( 1.0 - sun_fade ) );\n";
|
||||
code += "\t\tvec3 rayleigh_beta = rayleigh_coefficient * rayleigh_color.rgb * 0.0001;\n";
|
||||
code += "\t\t// mie coefficients from Preetham\n";
|
||||
code += "\t\tvec3 mie_beta = turbidity * mie * mie_color.rgb * 0.000434;\n\n";
|
||||
|
||||
code += "\t\t// optical length\n";
|
||||
code += "\t\tfloat zenith = acos(max(0.0, dot(UP, EYEDIR)));\n";
|
||||
code += "\t\tfloat optical_mass = 1.0 / (cos(zenith) + 0.15 * pow(93.885 - degrees(zenith), -1.253));\n";
|
||||
code += "\t\tfloat rayleigh_scatter = rayleigh_zenith_size * optical_mass;\n";
|
||||
code += "\t\tfloat mie_scatter = mie_zenith_size * optical_mass;\n\n";
|
||||
|
||||
code += "\t\t// light extinction based on thickness of atmosphere\n";
|
||||
code += "\t\tvec3 extinction = exp(-(rayleigh_beta * rayleigh_scatter + mie_beta * mie_scatter));\n\n";
|
||||
|
||||
code += "\t\t// in scattering\n";
|
||||
code += "\t\tfloat cos_theta = dot(EYEDIR, normalize(LIGHT0_DIRECTION));\n\n";
|
||||
|
||||
code += "\t\tfloat rayleigh_phase = (3.0 / (16.0 * PI)) * (1.0 + pow(cos_theta * 0.5 + 0.5, 2.0));\n";
|
||||
code += "\t\tvec3 betaRTheta = rayleigh_beta * rayleigh_phase;\n\n";
|
||||
|
||||
code += "\t\tfloat mie_phase = henyey_greenstein(cos_theta, mie_eccentricity);\n";
|
||||
code += "\t\tvec3 betaMTheta = mie_beta * mie_phase;\n\n";
|
||||
|
||||
code += "\t\tvec3 Lin = pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * (1.0 - extinction), vec3(1.5));\n";
|
||||
code += "\t\t// Hack from https://github.com/mrdoob/three.js/blob/master/examples/jsm/objects/Sky.js\n";
|
||||
code += "\t\tLin *= mix(vec3(1.0), pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * extinction, vec3(0.5)), clamp(pow(1.0 - zenith_angle, 5.0), 0.0, 1.0));\n\n";
|
||||
|
||||
code += "\t\t// Hack in the ground color\n";
|
||||
code += "\t\tLin *= mix(ground_color.rgb, vec3(1.0), smoothstep(-0.1, 0.1, dot(UP, EYEDIR)));\n\n";
|
||||
|
||||
code += "\t\t// Solar disk and out-scattering\n";
|
||||
code += "\t\tfloat sunAngularDiameterCos = cos(LIGHT0_SIZE * sun_disk_scale);\n";
|
||||
code += "\t\tfloat sunAngularDiameterCos2 = cos(LIGHT0_SIZE * sun_disk_scale*0.5);\n";
|
||||
code += "\t\tfloat sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos2, cos_theta);\n";
|
||||
code += "\t\tvec3 L0 = (sun_energy * 1900.0 * extinction) * sundisk * LIGHT0_COLOR;\n";
|
||||
code += "\t\tL0 += texture(night_sky, SKY_COORDS).xyz * extinction;\n\n";
|
||||
|
||||
code += "\t\tvec3 color = (Lin + L0) * 0.04;\n";
|
||||
code += "\t\tCOLOR = pow(color, vec3(1.0 / (1.2 + (1.2 * sun_fade))));\n";
|
||||
code += "\t\tCOLOR *= exposure;\n";
|
||||
code += "\t\t// Make optional, eliminates banding\n";
|
||||
code += "\t\tCOLOR += (hash(EYEDIR * 1741.9782) * 0.08 - 0.04) * 0.016 * dither_strength;\n";
|
||||
code += "\t} else {\n";
|
||||
code += "\t\t// There is no sun, so display night_sky and nothing else\n";
|
||||
code += "\t\tCOLOR = texture(night_sky, SKY_COORDS).xyz * 0.04;\n";
|
||||
code += "\t\tCOLOR *= exposure;\n";
|
||||
code += "\t}\n";
|
||||
code += "}\n";
|
||||
|
||||
shader = RS::get_singleton()->shader_create();
|
||||
|
||||
RS::get_singleton()->shader_set_code(shader, code);
|
||||
RS::get_singleton()->shader_set_code(shader, R"(
|
||||
shader_type sky;
|
||||
|
||||
uniform float rayleigh : hint_range(0, 64) = 2.0;
|
||||
uniform vec4 rayleigh_color : hint_color = vec4(0.056, 0.14, 0.3, 1.0);
|
||||
uniform float mie : hint_range(0, 1) = 0.005;
|
||||
uniform float mie_eccentricity : hint_range(-1, 1) = 0.8;
|
||||
uniform vec4 mie_color : hint_color = vec4(0.36, 0.56, 0.82, 1.0);
|
||||
|
||||
uniform float turbidity : hint_range(0, 1000) = 10.0;
|
||||
uniform float sun_disk_scale : hint_range(0, 360) = 1.0;
|
||||
uniform vec4 ground_color : hint_color = vec4(1.0);
|
||||
uniform float exposure : hint_range(0, 128) = 0.1;
|
||||
uniform float dither_strength : hint_range(0, 10) = 1.0;
|
||||
|
||||
uniform sampler2D night_sky : hint_black;
|
||||
|
||||
const vec3 UP = vec3( 0.0, 1.0, 0.0 );
|
||||
|
||||
// Sun constants
|
||||
const float SUN_ENERGY = 1000.0;
|
||||
|
||||
// Optical length at zenith for molecules.
|
||||
const float rayleigh_zenith_size = 8.4e3;
|
||||
const float mie_zenith_size = 1.25e3;
|
||||
|
||||
float henyey_greenstein(float cos_theta, float g) {
|
||||
const float k = 0.0795774715459;
|
||||
return k * (1.0 - g * g) / (pow(1.0 + g * g - 2.0 * g * cos_theta, 1.5));
|
||||
}
|
||||
|
||||
// From: https://www.shadertoy.com/view/4sfGzS credit to iq
|
||||
float hash(vec3 p) {
|
||||
p = fract( p * 0.3183099 + 0.1 );
|
||||
p *= 17.0;
|
||||
return fract(p.x * p.y * p.z * (p.x + p.y + p.z));
|
||||
}
|
||||
|
||||
void sky() {
|
||||
if (LIGHT0_ENABLED) {
|
||||
float zenith_angle = clamp( dot(UP, normalize(LIGHT0_DIRECTION)), -1.0, 1.0 );
|
||||
float sun_energy = max(0.0, 1.0 - exp(-((PI * 0.5) - acos(zenith_angle)))) * SUN_ENERGY * LIGHT0_ENERGY;
|
||||
float sun_fade = 1.0 - clamp(1.0 - exp(LIGHT0_DIRECTION.y), 0.0, 1.0);
|
||||
|
||||
// Rayleigh coefficients.
|
||||
float rayleigh_coefficient = rayleigh - ( 1.0 * ( 1.0 - sun_fade ) );
|
||||
vec3 rayleigh_beta = rayleigh_coefficient * rayleigh_color.rgb * 0.0001;
|
||||
// mie coefficients from Preetham
|
||||
vec3 mie_beta = turbidity * mie * mie_color.rgb * 0.000434;
|
||||
|
||||
// Optical length.
|
||||
float zenith = acos(max(0.0, dot(UP, EYEDIR)));
|
||||
float optical_mass = 1.0 / (cos(zenith) + 0.15 * pow(93.885 - degrees(zenith), -1.253));
|
||||
float rayleigh_scatter = rayleigh_zenith_size * optical_mass;
|
||||
float mie_scatter = mie_zenith_size * optical_mass;
|
||||
|
||||
// Light extinction based on thickness of atmosphere.
|
||||
vec3 extinction = exp(-(rayleigh_beta * rayleigh_scatter + mie_beta * mie_scatter));
|
||||
|
||||
// In scattering.
|
||||
float cos_theta = dot(EYEDIR, normalize(LIGHT0_DIRECTION));
|
||||
|
||||
float rayleigh_phase = (3.0 / (16.0 * PI)) * (1.0 + pow(cos_theta * 0.5 + 0.5, 2.0));
|
||||
vec3 betaRTheta = rayleigh_beta * rayleigh_phase;
|
||||
|
||||
float mie_phase = henyey_greenstein(cos_theta, mie_eccentricity);
|
||||
vec3 betaMTheta = mie_beta * mie_phase;
|
||||
|
||||
vec3 Lin = pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * (1.0 - extinction), vec3(1.5));
|
||||
// Hack from https://github.com/mrdoob/three.js/blob/master/examples/jsm/objects/Sky.js
|
||||
Lin *= mix(vec3(1.0), pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * extinction, vec3(0.5)), clamp(pow(1.0 - zenith_angle, 5.0), 0.0, 1.0));
|
||||
|
||||
// Hack in the ground color.
|
||||
Lin *= mix(ground_color.rgb, vec3(1.0), smoothstep(-0.1, 0.1, dot(UP, EYEDIR)));
|
||||
|
||||
// Solar disk and out-scattering.
|
||||
float sunAngularDiameterCos = cos(LIGHT0_SIZE * sun_disk_scale);
|
||||
float sunAngularDiameterCos2 = cos(LIGHT0_SIZE * sun_disk_scale*0.5);
|
||||
float sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos2, cos_theta);
|
||||
vec3 L0 = (sun_energy * 1900.0 * extinction) * sundisk * LIGHT0_COLOR;
|
||||
L0 += texture(night_sky, SKY_COORDS).xyz * extinction;
|
||||
|
||||
vec3 color = (Lin + L0) * 0.04;
|
||||
COLOR = pow(color, vec3(1.0 / (1.2 + (1.2 * sun_fade))));
|
||||
COLOR *= exposure;
|
||||
// Make optional, eliminates banding.
|
||||
COLOR += (hash(EYEDIR * 1741.9782) * 0.08 - 0.04) * 0.016 * dither_strength;
|
||||
} else {
|
||||
// There is no sun, so display night_sky and nothing else.
|
||||
COLOR = texture(night_sky, SKY_COORDS).xyz * 0.04;
|
||||
COLOR *= exposure;
|
||||
}
|
||||
}
|
||||
)");
|
||||
|
||||
RS::get_singleton()->material_set_shader(_get_material(), shader);
|
||||
|
||||
|
@ -352,14 +352,14 @@ String VisualShaderNodeCustom::generate_code(Shader::Mode p_mode, VisualShader::
|
||||
for (int i = 0; i < get_output_port_count(); i++) {
|
||||
output_vars.push_back(p_output_vars[i]);
|
||||
}
|
||||
String code = "\t{\n";
|
||||
String code = " {\n";
|
||||
String _code = (String)get_script_instance()->call("_get_code", input_vars, output_vars, (int)p_mode, (int)p_type);
|
||||
bool nend = _code.ends_with("\n");
|
||||
_code = _code.insert(0, "\t\t");
|
||||
_code = _code.replace("\n", "\n\t\t");
|
||||
_code = _code.insert(0, " ");
|
||||
_code = _code.replace("\n", "\n ");
|
||||
code += _code;
|
||||
if (!nend) {
|
||||
code += "\n\t}";
|
||||
code += "\n }";
|
||||
} else {
|
||||
code.remove(code.size() - 1);
|
||||
code += "}";
|
||||
@ -900,7 +900,7 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port
|
||||
String expr = "";
|
||||
expr += "// " + global_expression->get_caption() + ":" + itos(index++) + "\n";
|
||||
expr += global_expression->generate_global(get_mode(), Type(i), -1);
|
||||
expr = expr.replace("\n", "\n\t");
|
||||
expr = expr.replace("\n", "\n ");
|
||||
expr += "\n";
|
||||
global_expressions += expr;
|
||||
}
|
||||
@ -935,13 +935,13 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port
|
||||
ERR_FAIL_COND_V(err != OK, String());
|
||||
|
||||
if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_SCALAR) {
|
||||
code += "\tCOLOR.rgb = vec3(n_out" + itos(p_node) + "p" + itos(p_port) + " );\n";
|
||||
code += " COLOR.rgb = vec3(n_out" + itos(p_node) + "p" + itos(p_port) + " );\n";
|
||||
} else if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_SCALAR_INT) {
|
||||
code += "\tCOLOR.rgb = vec3(float(n_out" + itos(p_node) + "p" + itos(p_port) + "));\n";
|
||||
code += " COLOR.rgb = vec3(float(n_out" + itos(p_node) + "p" + itos(p_port) + "));\n";
|
||||
} else if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_BOOLEAN) {
|
||||
code += "\tCOLOR.rgb = vec3(n_out" + itos(p_node) + "p" + itos(p_port) + " ? 1.0 : 0.0);\n";
|
||||
code += " COLOR.rgb = vec3(n_out" + itos(p_node) + "p" + itos(p_port) + " ? 1.0 : 0.0);\n";
|
||||
} else {
|
||||
code += "\tCOLOR.rgb = n_out" + itos(p_node) + "p" + itos(p_port) + ";\n";
|
||||
code += " COLOR.rgb = n_out" + itos(p_node) + "p" + itos(p_port) + ";\n";
|
||||
}
|
||||
code += "}\n";
|
||||
|
||||
@ -1302,7 +1302,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
|
||||
|
||||
if (vsnode->is_disabled()) {
|
||||
code += "// " + vsnode->get_caption() + ":" + itos(node) + "\n";
|
||||
code += "\t// Node is disabled and code is not generated.\n";
|
||||
code += " // Node is disabled and code is not generated.\n";
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -1432,19 +1432,19 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
|
||||
if (defval.get_type() == Variant::FLOAT) {
|
||||
float val = defval;
|
||||
inputs[i] = "n_in" + itos(node) + "p" + itos(i);
|
||||
node_code += "\tfloat " + inputs[i] + " = " + vformat("%.5f", val) + ";\n";
|
||||
node_code += " float " + inputs[i] + " = " + vformat("%.5f", val) + ";\n";
|
||||
} else if (defval.get_type() == Variant::INT) {
|
||||
int val = defval;
|
||||
inputs[i] = "n_in" + itos(node) + "p" + itos(i);
|
||||
node_code += "\tint " + inputs[i] + " = " + itos(val) + ";\n";
|
||||
node_code += " int " + inputs[i] + " = " + itos(val) + ";\n";
|
||||
} else if (defval.get_type() == Variant::BOOL) {
|
||||
bool val = defval;
|
||||
inputs[i] = "n_in" + itos(node) + "p" + itos(i);
|
||||
node_code += "\tbool " + inputs[i] + " = " + (val ? "true" : "false") + ";\n";
|
||||
node_code += " bool " + inputs[i] + " = " + (val ? "true" : "false") + ";\n";
|
||||
} else if (defval.get_type() == Variant::VECTOR3) {
|
||||
Vector3 val = defval;
|
||||
inputs[i] = "n_in" + itos(node) + "p" + itos(i);
|
||||
node_code += "\tvec3 " + inputs[i] + " = " + vformat("vec3(%.5f, %.5f, %.5f);\n", val.x, val.y, val.z);
|
||||
node_code += " vec3 " + inputs[i] + " = " + vformat("vec3(%.5f, %.5f, %.5f);\n", val.x, val.y, val.z);
|
||||
} else if (defval.get_type() == Variant::TRANSFORM3D) {
|
||||
Transform3D val = defval;
|
||||
val.basis.transpose();
|
||||
@ -1459,7 +1459,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
|
||||
values.push_back(val.origin.y);
|
||||
values.push_back(val.origin.z);
|
||||
bool err = false;
|
||||
node_code += "\tmat4 " + inputs[i] + " = " + String("mat4(vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 1.0));\n").sprintf(values, &err);
|
||||
node_code += " mat4 " + inputs[i] + " = " + String("mat4(vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 1.0));\n").sprintf(values, &err);
|
||||
} else {
|
||||
//will go empty, node is expected to know what it is doing at this point and handle it
|
||||
}
|
||||
@ -1522,19 +1522,19 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
|
||||
outputs[i] = "n_out" + itos(node) + "p" + itos(j);
|
||||
switch (vsnode->get_output_port_type(i)) {
|
||||
case VisualShaderNode::PORT_TYPE_SCALAR:
|
||||
code += "\tfloat " + outputs[i] + ";\n";
|
||||
code += " float " + outputs[i] + ";\n";
|
||||
break;
|
||||
case VisualShaderNode::PORT_TYPE_SCALAR_INT:
|
||||
code += "\tint " + outputs[i] + ";\n";
|
||||
code += " int " + outputs[i] + ";\n";
|
||||
break;
|
||||
case VisualShaderNode::PORT_TYPE_VECTOR:
|
||||
code += "\tvec3 " + outputs[i] + ";\n";
|
||||
code += " vec3 " + outputs[i] + ";\n";
|
||||
break;
|
||||
case VisualShaderNode::PORT_TYPE_BOOLEAN:
|
||||
code += "\tbool " + outputs[i] + ";\n";
|
||||
code += " bool " + outputs[i] + ";\n";
|
||||
break;
|
||||
case VisualShaderNode::PORT_TYPE_TRANSFORM:
|
||||
code += "\tmat4 " + outputs[i] + ";\n";
|
||||
code += " mat4 " + outputs[i] + ";\n";
|
||||
break;
|
||||
default: {
|
||||
}
|
||||
@ -1564,7 +1564,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
|
||||
new_line_inserted = true;
|
||||
}
|
||||
String r = "n_out" + itos(node) + "p" + itos(i + 1);
|
||||
code += "\tfloat " + r + " = n_out" + itos(node) + "p" + itos(i) + ".r;\n";
|
||||
code += " float " + r + " = n_out" + itos(node) + "p" + itos(i) + ".r;\n";
|
||||
outputs[i + 1] = r;
|
||||
}
|
||||
|
||||
@ -1574,7 +1574,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
|
||||
new_line_inserted = true;
|
||||
}
|
||||
String g = "n_out" + itos(node) + "p" + itos(i + 2);
|
||||
code += "\tfloat " + g + " = n_out" + itos(node) + "p" + itos(i) + ".g;\n";
|
||||
code += " float " + g + " = n_out" + itos(node) + "p" + itos(i) + ".g;\n";
|
||||
outputs[i + 2] = g;
|
||||
}
|
||||
|
||||
@ -1584,7 +1584,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
|
||||
new_line_inserted = true;
|
||||
}
|
||||
String b = "n_out" + itos(node) + "p" + itos(i + 3);
|
||||
code += "\tfloat " + b + " = n_out" + itos(node) + "p" + itos(i) + ".b;\n";
|
||||
code += " float " + b + " = n_out" + itos(node) + "p" + itos(i) + ".b;\n";
|
||||
outputs[i + 3] = b;
|
||||
}
|
||||
|
||||
@ -1701,7 +1701,7 @@ void VisualShader::_update_shader() const {
|
||||
String expr = "";
|
||||
expr += "// " + global_expression->get_caption() + ":" + itos(index++) + "\n";
|
||||
expr += global_expression->generate_global(get_mode(), Type(i), -1);
|
||||
expr = expr.replace("\n", "\n\t");
|
||||
expr = expr.replace("\n", "\n ");
|
||||
expr += "\n";
|
||||
global_expressions += expr;
|
||||
}
|
||||
@ -1814,112 +1814,112 @@ void VisualShader::_update_shader() const {
|
||||
|
||||
code += "void start() {\n";
|
||||
if (has_start || has_start_custom) {
|
||||
code += "\tuint __seed = __hash(NUMBER + uint(1) + RANDOM_SEED);\n";
|
||||
code += "\tvec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz;\n";
|
||||
code += "\tfloat __radians;\n";
|
||||
code += "\tvec3 __vec3_buff1;\n";
|
||||
code += "\tvec3 __vec3_buff2;\n";
|
||||
code += "\tfloat __scalar_buff1;\n";
|
||||
code += "\tfloat __scalar_buff2;\n";
|
||||
code += "\tvec3 __ndiff = normalize(__diff);\n\n";
|
||||
code += " uint __seed = __hash(NUMBER + uint(1) + RANDOM_SEED);\n";
|
||||
code += " vec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz;\n";
|
||||
code += " float __radians;\n";
|
||||
code += " vec3 __vec3_buff1;\n";
|
||||
code += " vec3 __vec3_buff2;\n";
|
||||
code += " float __scalar_buff1;\n";
|
||||
code += " float __scalar_buff2;\n";
|
||||
code += " vec3 __ndiff = normalize(__diff);\n\n";
|
||||
}
|
||||
if (has_start) {
|
||||
code += "\t{\n";
|
||||
code += code_map[TYPE_START].replace("\n\t", "\n\t\t");
|
||||
code += "\t}\n";
|
||||
code += " {\n";
|
||||
code += code_map[TYPE_START].replace("\n ", "\n ");
|
||||
code += " }\n";
|
||||
if (has_start_custom) {
|
||||
code += "\t\n";
|
||||
code += " \n";
|
||||
}
|
||||
}
|
||||
if (has_start_custom) {
|
||||
code += "\t{\n";
|
||||
code += code_map[TYPE_START_CUSTOM].replace("\n\t", "\n\t\t");
|
||||
code += "\t}\n";
|
||||
code += " {\n";
|
||||
code += code_map[TYPE_START_CUSTOM].replace("\n ", "\n ");
|
||||
code += " }\n";
|
||||
}
|
||||
code += "}\n\n";
|
||||
code += "void process() {\n";
|
||||
if (has_process || has_process_custom || has_collide) {
|
||||
code += "\tuint __seed = __hash(NUMBER + uint(1) + RANDOM_SEED);\n";
|
||||
code += "\tvec3 __vec3_buff1;\n";
|
||||
code += "\tvec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz;\n";
|
||||
code += "\tvec3 __ndiff = normalize(__diff);\n\n";
|
||||
code += " uint __seed = __hash(NUMBER + uint(1) + RANDOM_SEED);\n";
|
||||
code += " vec3 __vec3_buff1;\n";
|
||||
code += " vec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz;\n";
|
||||
code += " vec3 __ndiff = normalize(__diff);\n\n";
|
||||
}
|
||||
code += "\t{\n";
|
||||
String tab = "\t";
|
||||
code += " {\n";
|
||||
String tab = " ";
|
||||
if (has_collide) {
|
||||
code += "\t\tif (COLLIDED) {\n\n";
|
||||
code += code_map[TYPE_COLLIDE].replace("\n\t", "\n\t\t\t");
|
||||
code += " if (COLLIDED) {\n\n";
|
||||
code += code_map[TYPE_COLLIDE].replace("\n ", "\n ");
|
||||
if (has_process) {
|
||||
code += "\t\t} else {\n\n";
|
||||
tab += "\t";
|
||||
code += " } else {\n\n";
|
||||
tab += " ";
|
||||
}
|
||||
}
|
||||
if (has_process) {
|
||||
code += code_map[TYPE_PROCESS].replace("\n\t", "\n\t" + tab);
|
||||
code += code_map[TYPE_PROCESS].replace("\n ", "\n " + tab);
|
||||
}
|
||||
if (has_collide) {
|
||||
code += "\t\t}\n";
|
||||
code += " }\n";
|
||||
}
|
||||
code += "\t}\n";
|
||||
code += " }\n";
|
||||
|
||||
if (has_process_custom) {
|
||||
code += "\t{\n\n";
|
||||
code += code_map[TYPE_PROCESS_CUSTOM].replace("\n\t", "\n\t\t");
|
||||
code += "\t}\n";
|
||||
code += " {\n\n";
|
||||
code += code_map[TYPE_PROCESS_CUSTOM].replace("\n ", "\n ");
|
||||
code += " }\n";
|
||||
}
|
||||
|
||||
code += "}\n\n";
|
||||
|
||||
global_compute_code += "float __rand_from_seed(inout uint seed) {\n";
|
||||
global_compute_code += "\tint k;\n";
|
||||
global_compute_code += "\tint s = int(seed);\n";
|
||||
global_compute_code += "\tif (s == 0)\n";
|
||||
global_compute_code += "\ts = 305420679;\n";
|
||||
global_compute_code += "\tk = s / 127773;\n";
|
||||
global_compute_code += "\ts = 16807 * (s - k * 127773) - 2836 * k;\n";
|
||||
global_compute_code += "\tif (s < 0)\n";
|
||||
global_compute_code += "\t\ts += 2147483647;\n";
|
||||
global_compute_code += "\tseed = uint(s);\n";
|
||||
global_compute_code += "\treturn float(seed % uint(65536)) / 65535.0;\n";
|
||||
global_compute_code += " int k;\n";
|
||||
global_compute_code += " int s = int(seed);\n";
|
||||
global_compute_code += " if (s == 0)\n";
|
||||
global_compute_code += " s = 305420679;\n";
|
||||
global_compute_code += " k = s / 127773;\n";
|
||||
global_compute_code += " s = 16807 * (s - k * 127773) - 2836 * k;\n";
|
||||
global_compute_code += " if (s < 0)\n";
|
||||
global_compute_code += " s += 2147483647;\n";
|
||||
global_compute_code += " seed = uint(s);\n";
|
||||
global_compute_code += " return float(seed % uint(65536)) / 65535.0;\n";
|
||||
global_compute_code += "}\n\n";
|
||||
|
||||
global_compute_code += "float __rand_from_seed_m1_p1(inout uint seed) {\n";
|
||||
global_compute_code += "\treturn __rand_from_seed(seed) * 2.0 - 1.0;\n";
|
||||
global_compute_code += " return __rand_from_seed(seed) * 2.0 - 1.0;\n";
|
||||
global_compute_code += "}\n\n";
|
||||
|
||||
global_compute_code += "float __randf_range(inout uint seed, float from, float to) {\n";
|
||||
global_compute_code += "\treturn __rand_from_seed(seed) * (to - from) + from;\n";
|
||||
global_compute_code += " return __rand_from_seed(seed) * (to - from) + from;\n";
|
||||
global_compute_code += "}\n\n";
|
||||
|
||||
global_compute_code += "vec3 __randv_range(inout uint seed, vec3 from, vec3 to) {\n";
|
||||
global_compute_code += "\treturn vec3(__randf_range(seed, from.x, to.x), __randf_range(seed, from.y, to.y), __randf_range(seed, from.z, to.z));\n";
|
||||
global_compute_code += " return vec3(__randf_range(seed, from.x, to.x), __randf_range(seed, from.y, to.y), __randf_range(seed, from.z, to.z));\n";
|
||||
global_compute_code += "}\n\n";
|
||||
|
||||
global_compute_code += "uint __hash(uint x) {\n";
|
||||
global_compute_code += "\tx = ((x >> uint(16)) ^ x) * uint(73244475);\n";
|
||||
global_compute_code += "\tx = ((x >> uint(16)) ^ x) * uint(73244475);\n";
|
||||
global_compute_code += "\tx = (x >> uint(16)) ^ x;\n";
|
||||
global_compute_code += "\treturn x;\n";
|
||||
global_compute_code += " x = ((x >> uint(16)) ^ x) * uint(73244475);\n";
|
||||
global_compute_code += " x = ((x >> uint(16)) ^ x) * uint(73244475);\n";
|
||||
global_compute_code += " x = (x >> uint(16)) ^ x;\n";
|
||||
global_compute_code += " return x;\n";
|
||||
global_compute_code += "}\n\n";
|
||||
|
||||
global_compute_code += "mat3 __build_rotation_mat3(vec3 axis, float angle) {\n";
|
||||
global_compute_code += "\taxis = normalize(axis);\n";
|
||||
global_compute_code += "\tfloat s = sin(angle);\n";
|
||||
global_compute_code += "\tfloat c = cos(angle);\n";
|
||||
global_compute_code += "\tfloat oc = 1.0 - c;\n";
|
||||
global_compute_code += "\treturn mat3(vec3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s), vec3(oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s), vec3(oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c));\n";
|
||||
global_compute_code += " axis = normalize(axis);\n";
|
||||
global_compute_code += " float s = sin(angle);\n";
|
||||
global_compute_code += " float c = cos(angle);\n";
|
||||
global_compute_code += " float oc = 1.0 - c;\n";
|
||||
global_compute_code += " return mat3(vec3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s), vec3(oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s), vec3(oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c));\n";
|
||||
global_compute_code += "}\n\n";
|
||||
|
||||
global_compute_code += "mat4 __build_rotation_mat4(vec3 axis, float angle) {\n";
|
||||
global_compute_code += "\taxis = normalize(axis);\n";
|
||||
global_compute_code += "\tfloat s = sin(angle);\n";
|
||||
global_compute_code += "\tfloat c = cos(angle);\n";
|
||||
global_compute_code += "\tfloat oc = 1.0 - c;\n";
|
||||
global_compute_code += "\treturn mat4(vec4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0), vec4(oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0), vec4(oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0), vec4(0, 0, 0, 1));\n";
|
||||
global_compute_code += " axis = normalize(axis);\n";
|
||||
global_compute_code += " float s = sin(angle);\n";
|
||||
global_compute_code += " float c = cos(angle);\n";
|
||||
global_compute_code += " float oc = 1.0 - c;\n";
|
||||
global_compute_code += " return mat4(vec4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0), vec4(oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0), vec4(oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0), vec4(0, 0, 0, 1));\n";
|
||||
global_compute_code += "}\n\n";
|
||||
|
||||
global_compute_code += "vec3 __get_random_unit_vec3(inout uint seed) {\n";
|
||||
global_compute_code += "\treturn normalize(vec3(__rand_from_seed_m1_p1(seed), __rand_from_seed_m1_p1(seed), __rand_from_seed_m1_p1(seed)));\n";
|
||||
global_compute_code += " return normalize(vec3(__rand_from_seed_m1_p1(seed), __rand_from_seed_m1_p1(seed), __rand_from_seed_m1_p1(seed)));\n";
|
||||
global_compute_code += "}\n\n";
|
||||
}
|
||||
|
||||
@ -2380,7 +2380,7 @@ String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::T
|
||||
|
||||
while (preview_ports[idx].mode != Shader::MODE_MAX) {
|
||||
if (preview_ports[idx].mode == shader_mode && preview_ports[idx].shader_type == shader_type && preview_ports[idx].name == input_name) {
|
||||
code = "\t" + p_output_vars[0] + " = " + preview_ports[idx].string + ";\n";
|
||||
code = " " + p_output_vars[0] + " = " + preview_ports[idx].string + ";\n";
|
||||
break;
|
||||
}
|
||||
idx++;
|
||||
@ -2389,19 +2389,19 @@ String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::T
|
||||
if (code == String()) {
|
||||
switch (get_output_port_type(0)) {
|
||||
case PORT_TYPE_SCALAR: {
|
||||
code = "\t" + p_output_vars[0] + " = 0.0;\n";
|
||||
code = " " + p_output_vars[0] + " = 0.0;\n";
|
||||
} break;
|
||||
case PORT_TYPE_SCALAR_INT: {
|
||||
code = "\t" + p_output_vars[0] + " = 0;\n";
|
||||
code = " " + p_output_vars[0] + " = 0;\n";
|
||||
} break;
|
||||
case PORT_TYPE_VECTOR: {
|
||||
code = "\t" + p_output_vars[0] + " = vec3(0.0);\n";
|
||||
code = " " + p_output_vars[0] + " = vec3(0.0);\n";
|
||||
} break;
|
||||
case PORT_TYPE_TRANSFORM: {
|
||||
code = "\t" + p_output_vars[0] + " = mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
|
||||
code = " " + p_output_vars[0] + " = mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
|
||||
} break;
|
||||
case PORT_TYPE_BOOLEAN: {
|
||||
code = "\t" + p_output_vars[0] + " = false;\n";
|
||||
code = " " + p_output_vars[0] + " = false;\n";
|
||||
} break;
|
||||
default: //default (none found) is scalar
|
||||
break;
|
||||
@ -2417,14 +2417,14 @@ String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::T
|
||||
|
||||
while (ports[idx].mode != Shader::MODE_MAX) {
|
||||
if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type && ports[idx].name == input_name) {
|
||||
code = "\t" + p_output_vars[0] + " = " + ports[idx].string + ";\n";
|
||||
code = " " + p_output_vars[0] + " = " + ports[idx].string + ";\n";
|
||||
break;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
||||
if (code == String()) {
|
||||
code = "\t" + p_output_vars[0] + " = 0.0;\n"; //default (none found) is scalar
|
||||
code = " " + p_output_vars[0] + " = 0.0;\n"; //default (none found) is scalar
|
||||
}
|
||||
|
||||
return code;
|
||||
@ -2748,20 +2748,20 @@ String VisualShaderNodeUniformRef::generate_code(Shader::Mode p_mode, VisualShad
|
||||
switch (uniform_type) {
|
||||
case UniformType::UNIFORM_TYPE_FLOAT:
|
||||
if (uniform_name == "[None]") {
|
||||
return "\t" + p_output_vars[0] + " = 0.0;\n";
|
||||
return " " + p_output_vars[0] + " = 0.0;\n";
|
||||
}
|
||||
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
|
||||
return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
|
||||
case UniformType::UNIFORM_TYPE_INT:
|
||||
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
|
||||
return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
|
||||
case UniformType::UNIFORM_TYPE_BOOLEAN:
|
||||
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
|
||||
return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
|
||||
case UniformType::UNIFORM_TYPE_VECTOR:
|
||||
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
|
||||
return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
|
||||
case UniformType::UNIFORM_TYPE_TRANSFORM:
|
||||
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
|
||||
return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
|
||||
case UniformType::UNIFORM_TYPE_COLOR: {
|
||||
String code = "\t" + p_output_vars[0] + " = " + get_uniform_name() + ".rgb;\n";
|
||||
code += "\t" + p_output_vars[1] + " = " + get_uniform_name() + ".a;\n";
|
||||
String code = " " + p_output_vars[0] + " = " + get_uniform_name() + ".rgb;\n";
|
||||
code += " " + p_output_vars[1] + " = " + get_uniform_name() + ".a;\n";
|
||||
return code;
|
||||
} break;
|
||||
case UniformType::UNIFORM_TYPE_SAMPLER:
|
||||
@ -2957,9 +2957,9 @@ String VisualShaderNodeOutput::generate_code(Shader::Mode p_mode, VisualShader::
|
||||
if (p_input_vars[count] != String()) {
|
||||
String s = ports[idx].string;
|
||||
if (s.find(":") != -1) {
|
||||
code += "\t" + s.get_slicec(':', 0) + " = " + p_input_vars[count] + "." + s.get_slicec(':', 1) + ";\n";
|
||||
code += " " + s.get_slicec(':', 0) + " = " + p_input_vars[count] + "." + s.get_slicec(':', 1) + ";\n";
|
||||
} else {
|
||||
code += "\t" + s + " = " + p_input_vars[count] + ";\n";
|
||||
code += " " + s + " = " + p_input_vars[count] + ";\n";
|
||||
}
|
||||
}
|
||||
count++;
|
||||
@ -3634,11 +3634,11 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad
|
||||
String _expression = expression;
|
||||
|
||||
_expression = _expression.insert(0, "\n");
|
||||
_expression = _expression.replace("\n", "\n\t\t");
|
||||
_expression = _expression.replace("\n", "\n ");
|
||||
|
||||
static Vector<String> pre_symbols;
|
||||
if (pre_symbols.is_empty()) {
|
||||
pre_symbols.push_back("\t");
|
||||
pre_symbols.push_back(" ");
|
||||
pre_symbols.push_back(",");
|
||||
pre_symbols.push_back(";");
|
||||
pre_symbols.push_back("{");
|
||||
@ -3658,7 +3658,7 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad
|
||||
|
||||
static Vector<String> post_symbols;
|
||||
if (post_symbols.is_empty()) {
|
||||
post_symbols.push_back("\t");
|
||||
post_symbols.push_back(" ");
|
||||
post_symbols.push_back("\n");
|
||||
post_symbols.push_back(",");
|
||||
post_symbols.push_back(";");
|
||||
@ -3717,14 +3717,14 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
output_initializer += "\t" + p_output_vars[i] + " = " + tk + ";\n";
|
||||
output_initializer += " " + p_output_vars[i] + " = " + tk + ";\n";
|
||||
}
|
||||
|
||||
String code;
|
||||
code += output_initializer;
|
||||
code += "\t{";
|
||||
code += " {";
|
||||
code += _expression;
|
||||
code += "\n\t}\n";
|
||||
code += "\n }\n";
|
||||
|
||||
return code;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -76,14 +76,14 @@ String VisualShaderNodeParticleSphereEmitter::get_input_port_name(int p_port) co
|
||||
String VisualShaderNodeParticleSphereEmitter::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
|
||||
String code;
|
||||
code += "vec3 __get_random_point_in_sphere(inout uint seed, float radius, float inner_radius) {\n";
|
||||
code += "\treturn __get_random_unit_vec3(seed) * __randf_range(seed, inner_radius, radius);\n";
|
||||
code += " return __get_random_unit_vec3(seed) * __randf_range(seed, inner_radius, radius);\n";
|
||||
code += "}\n\n";
|
||||
return code;
|
||||
}
|
||||
|
||||
String VisualShaderNodeParticleSphereEmitter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
|
||||
String code;
|
||||
code += "\t" + p_output_vars[0] + " = __get_random_point_in_sphere(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ");\n";
|
||||
code += " " + p_output_vars[0] + " = __get_random_point_in_sphere(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ");\n";
|
||||
return code;
|
||||
}
|
||||
|
||||
@ -119,15 +119,15 @@ String VisualShaderNodeParticleBoxEmitter::get_input_port_name(int p_port) const
|
||||
String VisualShaderNodeParticleBoxEmitter::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
|
||||
String code;
|
||||
code += "vec3 __get_random_point_in_box(inout uint seed, vec3 extents) {\n";
|
||||
code += "\tvec3 half_extents = extents / 2.0;\n";
|
||||
code += "\treturn vec3(__randf_range(seed, -half_extents.x, half_extents.x), __randf_range(seed, -half_extents.y, half_extents.y), __randf_range(seed, -half_extents.z, half_extents.z));\n";
|
||||
code += " vec3 half_extents = extents / 2.0;\n";
|
||||
code += " return vec3(__randf_range(seed, -half_extents.x, half_extents.x), __randf_range(seed, -half_extents.y, half_extents.y), __randf_range(seed, -half_extents.z, half_extents.z));\n";
|
||||
code += "}\n\n";
|
||||
return code;
|
||||
}
|
||||
|
||||
String VisualShaderNodeParticleBoxEmitter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
|
||||
String code;
|
||||
code += "\t" + p_output_vars[0] + " = __get_random_point_in_box(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ");\n";
|
||||
code += " " + p_output_vars[0] + " = __get_random_point_in_box(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ");\n";
|
||||
return code;
|
||||
}
|
||||
|
||||
@ -163,16 +163,16 @@ String VisualShaderNodeParticleRingEmitter::get_input_port_name(int p_port) cons
|
||||
String VisualShaderNodeParticleRingEmitter::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
|
||||
String code;
|
||||
code += "vec3 __get_random_point_on_ring(inout uint seed, float radius, float inner_radius, float height) {\n";
|
||||
code += "\tfloat angle = __rand_from_seed(seed) * PI * 2.0;\n";
|
||||
code += "\tvec2 ring = vec2(sin(angle), cos(angle)) * __randf_range(seed, inner_radius, radius);\n";
|
||||
code += "\treturn vec3(ring.x, __randf_range(seed, min(0.0, height), max(0.0, height)), ring.y);\n";
|
||||
code += " float angle = __rand_from_seed(seed) * PI * 2.0;\n";
|
||||
code += " vec2 ring = vec2(sin(angle), cos(angle)) * __randf_range(seed, inner_radius, radius);\n";
|
||||
code += " return vec3(ring.x, __randf_range(seed, min(0.0, height), max(0.0, height)), ring.y);\n";
|
||||
code += "}\n\n";
|
||||
return code;
|
||||
}
|
||||
|
||||
String VisualShaderNodeParticleRingEmitter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
|
||||
String code;
|
||||
code = "\t" + p_output_vars[0] + " = __get_random_point_on_ring(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ", " + (p_input_vars[2].is_empty() ? (String)get_input_port_default_value(2) : p_input_vars[2]) + ");\n";
|
||||
code = " " + p_output_vars[0] + " = __get_random_point_on_ring(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ", " + (p_input_vars[2].is_empty() ? (String)get_input_port_default_value(2) : p_input_vars[2]) + ");\n";
|
||||
return code;
|
||||
}
|
||||
|
||||
@ -242,9 +242,9 @@ String VisualShaderNodeParticleMultiplyByAxisAngle::get_output_port_name(int p_p
|
||||
String VisualShaderNodeParticleMultiplyByAxisAngle::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
|
||||
String code;
|
||||
if (degrees_mode) {
|
||||
code += "\t" + p_output_vars[0] + " = __build_rotation_mat3(" + (p_input_vars[1].is_empty() ? ("vec3" + (String)get_input_port_default_value(1)) : p_input_vars[1]) + ", radians(" + (p_input_vars[2].is_empty() ? (String)get_input_port_default_value(2) : p_input_vars[2]) + ")) * " + (p_input_vars[0].is_empty() ? "vec3(0.0)" : p_input_vars[0]) + ";\n";
|
||||
code += " " + p_output_vars[0] + " = __build_rotation_mat3(" + (p_input_vars[1].is_empty() ? ("vec3" + (String)get_input_port_default_value(1)) : p_input_vars[1]) + ", radians(" + (p_input_vars[2].is_empty() ? (String)get_input_port_default_value(2) : p_input_vars[2]) + ")) * " + (p_input_vars[0].is_empty() ? "vec3(0.0)" : p_input_vars[0]) + ";\n";
|
||||
} else {
|
||||
code += "\t" + p_output_vars[0] + " = __build_rotation_mat3(" + (p_input_vars[1].is_empty() ? ("vec3" + (String)get_input_port_default_value(1)) : p_input_vars[1]) + ", " + (p_input_vars[2].is_empty() ? (String)get_input_port_default_value(2) : p_input_vars[2]) + ") * " + (p_input_vars[0].is_empty() ? "vec3(0.0)" : p_input_vars[0]) + ";\n";
|
||||
code += " " + p_output_vars[0] + " = __build_rotation_mat3(" + (p_input_vars[1].is_empty() ? ("vec3" + (String)get_input_port_default_value(1)) : p_input_vars[1]) + ", " + (p_input_vars[2].is_empty() ? (String)get_input_port_default_value(2) : p_input_vars[2]) + ") * " + (p_input_vars[0].is_empty() ? "vec3(0.0)" : p_input_vars[0]) + ";\n";
|
||||
}
|
||||
return code;
|
||||
}
|
||||
@ -315,16 +315,16 @@ String VisualShaderNodeParticleConeVelocity::get_output_port_name(int p_port) co
|
||||
|
||||
String VisualShaderNodeParticleConeVelocity::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
|
||||
String code;
|
||||
code += "\t__radians = radians(" + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ");\n";
|
||||
code += "\t__scalar_buff1 = __rand_from_seed_m1_p1(__seed) * __radians;\n";
|
||||
code += "\t__scalar_buff2 = __rand_from_seed_m1_p1(__seed) * __radians;\n";
|
||||
code += "\t__vec3_buff1 = " + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + ";\n";
|
||||
code += "\t__scalar_buff1 += __vec3_buff1.z != 0.0 ? atan(__vec3_buff1.x, __vec3_buff1.z) : sign(__vec3_buff1.x) * (PI / 2.0);\n";
|
||||
code += "\t__scalar_buff2 += __vec3_buff1.z != 0.0 ? atan(__vec3_buff1.y, abs(__vec3_buff1.z)) : (__vec3_buff1.x != 0.0 ? atan(__vec3_buff1.y, abs(__vec3_buff1.x)) : sign(__vec3_buff1.y) * (PI / 2.0));\n";
|
||||
code += "\t__vec3_buff1 = vec3(sin(__scalar_buff1), 0.0, cos(__scalar_buff1));\n";
|
||||
code += "\t__vec3_buff2 = vec3(0.0, sin(__scalar_buff2), cos(__scalar_buff2));\n";
|
||||
code += "\t__vec3_buff2.z = __vec3_buff2.z / max(0.0001, sqrt(abs(__vec3_buff2.z)));\n";
|
||||
code += "\t" + p_output_vars[0] + " = normalize(vec3(__vec3_buff1.x * __vec3_buff2.z, __vec3_buff2.y, __vec3_buff1.z * __vec3_buff2.z));\n";
|
||||
code += " __radians = radians(" + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ");\n";
|
||||
code += " __scalar_buff1 = __rand_from_seed_m1_p1(__seed) * __radians;\n";
|
||||
code += " __scalar_buff2 = __rand_from_seed_m1_p1(__seed) * __radians;\n";
|
||||
code += " __vec3_buff1 = " + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + ";\n";
|
||||
code += " __scalar_buff1 += __vec3_buff1.z != 0.0 ? atan(__vec3_buff1.x, __vec3_buff1.z) : sign(__vec3_buff1.x) * (PI / 2.0);\n";
|
||||
code += " __scalar_buff2 += __vec3_buff1.z != 0.0 ? atan(__vec3_buff1.y, abs(__vec3_buff1.z)) : (__vec3_buff1.x != 0.0 ? atan(__vec3_buff1.y, abs(__vec3_buff1.x)) : sign(__vec3_buff1.y) * (PI / 2.0));\n";
|
||||
code += " __vec3_buff1 = vec3(sin(__scalar_buff1), 0.0, cos(__scalar_buff1));\n";
|
||||
code += " __vec3_buff2 = vec3(0.0, sin(__scalar_buff2), cos(__scalar_buff2));\n";
|
||||
code += " __vec3_buff2.z = __vec3_buff2.z / max(0.0001, sqrt(abs(__vec3_buff2.z)));\n";
|
||||
code += " " + p_output_vars[0] + " = normalize(vec3(__vec3_buff1.x * __vec3_buff2.z, __vec3_buff2.y, __vec3_buff1.z * __vec3_buff2.z));\n";
|
||||
return code;
|
||||
}
|
||||
|
||||
@ -394,9 +394,9 @@ String VisualShaderNodeParticleRandomness::get_input_port_name(int p_port) const
|
||||
String VisualShaderNodeParticleRandomness::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
|
||||
String code;
|
||||
if (op_type == OP_TYPE_SCALAR) {
|
||||
code += vformat("\t%s = __randf_range(__seed, %s, %s);\n", p_output_vars[0], p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0], p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]);
|
||||
code += vformat(" %s = __randf_range(__seed, %s, %s);\n", p_output_vars[0], p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0], p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]);
|
||||
} else if (op_type == OP_TYPE_VECTOR) {
|
||||
code += vformat("\t%s = __randv_range(__seed, %s, %s);\n", p_output_vars[0], p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0], p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]);
|
||||
code += vformat(" %s = __randv_range(__seed, %s, %s);\n", p_output_vars[0], p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0], p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
@ -491,14 +491,14 @@ String VisualShaderNodeParticleAccelerator::generate_code(Shader::Mode p_mode, V
|
||||
String code;
|
||||
switch (mode) {
|
||||
case MODE_LINEAR:
|
||||
code += "\t" + p_output_vars[0] + " = length(VELOCITY) > 0.0 ? " + "normalize(VELOCITY) * " + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + " * mix(1.0, __rand_from_seed(__seed), " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ") : vec3(0.0);\n";
|
||||
code += " " + p_output_vars[0] + " = length(VELOCITY) > 0.0 ? " + "normalize(VELOCITY) * " + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + " * mix(1.0, __rand_from_seed(__seed), " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ") : vec3(0.0);\n";
|
||||
break;
|
||||
case MODE_RADIAL:
|
||||
code += "\t" + p_output_vars[0] + " = length(__diff) > 0.0 ? __ndiff * " + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + " * mix(1.0, __rand_from_seed(__seed), " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ") : vec3(0.0);\n";
|
||||
code += " " + p_output_vars[0] + " = length(__diff) > 0.0 ? __ndiff * " + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + " * mix(1.0, __rand_from_seed(__seed), " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ") : vec3(0.0);\n";
|
||||
break;
|
||||
case MODE_TANGENTIAL:
|
||||
code += "\t__vec3_buff1 = cross(__ndiff, normalize(" + (p_input_vars[2].is_empty() ? "vec3" + (String)get_input_port_default_value(2) : p_input_vars[2]) + "));\n";
|
||||
code += "\t" + p_output_vars[0] + " = length(__vec3_buff1) > 0.0 ? normalize(__vec3_buff1) * (" + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + " * mix(1.0, __rand_from_seed(__seed), " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ")) : vec3(0.0);\n";
|
||||
code += " __vec3_buff1 = cross(__ndiff, normalize(" + (p_input_vars[2].is_empty() ? "vec3" + (String)get_input_port_default_value(2) : p_input_vars[2]) + "));\n";
|
||||
code += " " + p_output_vars[0] + " = length(__vec3_buff1) > 0.0 ? normalize(__vec3_buff1) * (" + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + " * mix(1.0, __rand_from_seed(__seed), " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ")) : vec3(0.0);\n";
|
||||
break;
|
||||
case MODE_MAX:
|
||||
break;
|
||||
@ -693,7 +693,7 @@ bool VisualShaderNodeParticleOutput::is_port_separator(int p_index) const {
|
||||
|
||||
String VisualShaderNodeParticleOutput::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
|
||||
String code;
|
||||
String tab = "\t";
|
||||
String tab = " ";
|
||||
|
||||
if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) {
|
||||
if (!p_input_vars[0].is_empty()) { // custom.rgb
|
||||
@ -718,7 +718,7 @@ String VisualShaderNodeParticleOutput::generate_code(Shader::Mode p_mode, Visual
|
||||
if (!p_input_vars[0].is_empty()) { // active (begin)
|
||||
code += tab + "ACTIVE = " + p_input_vars[0] + ";\n";
|
||||
code += tab + "if(ACTIVE) {\n";
|
||||
tab += "\t";
|
||||
tab += " ";
|
||||
}
|
||||
if (!p_input_vars[1].is_empty()) { // velocity
|
||||
code += tab + "VELOCITY = " + p_input_vars[1] + ";\n";
|
||||
@ -734,14 +734,14 @@ String VisualShaderNodeParticleOutput::generate_code(Shader::Mode p_mode, Visual
|
||||
if (shader_type == VisualShader::TYPE_START) {
|
||||
code += tab + "if (RESTART_POSITION) {\n";
|
||||
if (!p_input_vars[4].is_empty()) {
|
||||
code += tab + "\tTRANSFORM = mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(" + p_input_vars[4] + ", 1.0));\n";
|
||||
code += tab + " TRANSFORM = mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(" + p_input_vars[4] + ", 1.0));\n";
|
||||
} else {
|
||||
code += tab + "\tTRANSFORM = mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
|
||||
code += tab + " TRANSFORM = mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
|
||||
}
|
||||
code += tab + "\tif (RESTART_VELOCITY) {\n";
|
||||
code += tab + "\t\tVELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n";
|
||||
code += tab + "\t}\n";
|
||||
code += tab + "\tTRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n";
|
||||
code += tab + " if (RESTART_VELOCITY) {\n";
|
||||
code += tab + " VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n";
|
||||
code += tab + " }\n";
|
||||
code += tab + " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n";
|
||||
code += tab + "}\n";
|
||||
} else if (shader_type == VisualShader::TYPE_COLLIDE) { // position
|
||||
if (!p_input_vars[4].is_empty()) {
|
||||
@ -779,7 +779,7 @@ String VisualShaderNodeParticleOutput::generate_code(Shader::Mode p_mode, Visual
|
||||
}
|
||||
}
|
||||
if (!p_input_vars[0].is_empty()) { // active (end)
|
||||
code += "\t}\n";
|
||||
code += " }\n";
|
||||
}
|
||||
}
|
||||
return code;
|
||||
@ -926,12 +926,12 @@ String VisualShaderNodeParticleEmit::generate_code(Shader::Mode p_mode, VisualSh
|
||||
if (!is_input_port_connected(0)) {
|
||||
default_condition = true;
|
||||
if (get_input_port_default_value(0)) {
|
||||
tab = "\t";
|
||||
tab = " ";
|
||||
} else {
|
||||
return code;
|
||||
}
|
||||
} else {
|
||||
tab = "\t\t";
|
||||
tab = " ";
|
||||
}
|
||||
|
||||
String transform;
|
||||
@ -1008,13 +1008,13 @@ String VisualShaderNodeParticleEmit::generate_code(Shader::Mode p_mode, VisualSh
|
||||
}
|
||||
|
||||
if (!default_condition) {
|
||||
code += "\tif (" + p_input_vars[0] + ") {\n";
|
||||
code += " if (" + p_input_vars[0] + ") {\n";
|
||||
}
|
||||
|
||||
code += tab + "emit_subparticle(" + transform + ", " + velocity + ", vec4(" + color + ", " + alpha + "), vec4(" + custom + ", " + custom_alpha + "), " + flags + ");\n";
|
||||
|
||||
if (!default_condition) {
|
||||
code += "\t}\n";
|
||||
code += " }\n";
|
||||
}
|
||||
|
||||
return code;
|
||||
|
@ -61,7 +61,7 @@ String VisualShaderNodeSDFToScreenUV::get_output_port_name(int p_port) const {
|
||||
}
|
||||
|
||||
String VisualShaderNodeSDFToScreenUV::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
|
||||
return "\t" + p_output_vars[0] + " = vec3(sdf_to_screen_uv(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
|
||||
return " " + p_output_vars[0] + " = vec3(sdf_to_screen_uv(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
|
||||
}
|
||||
|
||||
VisualShaderNodeSDFToScreenUV::VisualShaderNodeSDFToScreenUV() {
|
||||
@ -105,7 +105,7 @@ String VisualShaderNodeScreenUVToSDF::get_input_port_default_hint(int p_port) co
|
||||
}
|
||||
|
||||
String VisualShaderNodeScreenUVToSDF::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
|
||||
return "\t" + p_output_vars[0] + " = vec3(screen_uv_to_sdf(" + (p_input_vars[0] == String() ? "SCREEN_UV" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
|
||||
return " " + p_output_vars[0] + " = vec3(screen_uv_to_sdf(" + (p_input_vars[0] == String() ? "SCREEN_UV" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
|
||||
}
|
||||
|
||||
VisualShaderNodeScreenUVToSDF::VisualShaderNodeScreenUVToSDF() {
|
||||
@ -142,7 +142,7 @@ String VisualShaderNodeTextureSDF::get_output_port_name(int p_port) const {
|
||||
}
|
||||
|
||||
String VisualShaderNodeTextureSDF::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
|
||||
return "\t" + p_output_vars[0] + " = texture_sdf(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + ");\n";
|
||||
return " " + p_output_vars[0] + " = texture_sdf(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + ");\n";
|
||||
}
|
||||
|
||||
VisualShaderNodeTextureSDF::VisualShaderNodeTextureSDF() {
|
||||
@ -179,7 +179,7 @@ String VisualShaderNodeTextureSDFNormal::get_output_port_name(int p_port) const
|
||||
}
|
||||
|
||||
String VisualShaderNodeTextureSDFNormal::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
|
||||
return "\t" + p_output_vars[0] + " = vec3(texture_sdf_normal(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
|
||||
return " " + p_output_vars[0] + " = vec3(texture_sdf_normal(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
|
||||
}
|
||||
|
||||
VisualShaderNodeTextureSDFNormal::VisualShaderNodeTextureSDFNormal() {
|
||||
@ -240,40 +240,40 @@ String VisualShaderNodeSDFRaymarch::get_output_port_name(int p_port) const {
|
||||
String VisualShaderNodeSDFRaymarch::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
|
||||
String code;
|
||||
|
||||
code += "\t{\n";
|
||||
code += " {\n";
|
||||
|
||||
if (p_input_vars[0] == String()) {
|
||||
code += "\t\tvec2 __from_pos = vec2(0.0f);\n";
|
||||
code += " vec2 __from_pos = vec2(0.0f);\n";
|
||||
} else {
|
||||
code += "\t\tvec2 __from_pos = " + p_input_vars[0] + ".xy;\n";
|
||||
code += " vec2 __from_pos = " + p_input_vars[0] + ".xy;\n";
|
||||
}
|
||||
|
||||
if (p_input_vars[1] == String()) {
|
||||
code += "\t\tvec2 __to_pos = vec2(0.0f);\n";
|
||||
code += " vec2 __to_pos = vec2(0.0f);\n";
|
||||
} else {
|
||||
code += "\t\tvec2 __to_pos = " + p_input_vars[1] + ".xy;\n";
|
||||
code += " vec2 __to_pos = " + p_input_vars[1] + ".xy;\n";
|
||||
}
|
||||
|
||||
code += "\n\t\tvec2 __at = __from_pos;\n";
|
||||
code += "\t\tfloat __max_dist = distance(__from_pos, __to_pos);\n";
|
||||
code += "\t\tvec2 __dir = normalize(__to_pos - __from_pos);\n\n";
|
||||
code += "\n vec2 __at = __from_pos;\n";
|
||||
code += " float __max_dist = distance(__from_pos, __to_pos);\n";
|
||||
code += " vec2 __dir = normalize(__to_pos - __from_pos);\n\n";
|
||||
|
||||
code += "\t\tfloat __accum = 0.0f;\n";
|
||||
code += "\t\twhile(__accum < __max_dist) {\n";
|
||||
code += "\t\t\tfloat __d = texture_sdf(__at);\n";
|
||||
code += "\t\t\t__accum += __d;\n";
|
||||
code += "\t\t\tif (__d < 0.01f) {\n";
|
||||
code += "\t\t\t\tbreak;\n";
|
||||
code += "\t\t\t}\n";
|
||||
code += "\t\t\t__at += __d * __dir;\n";
|
||||
code += "\t\t}\n";
|
||||
code += " float __accum = 0.0f;\n";
|
||||
code += " while(__accum < __max_dist) {\n";
|
||||
code += " float __d = texture_sdf(__at);\n";
|
||||
code += " __accum += __d;\n";
|
||||
code += " if (__d < 0.01f) {\n";
|
||||
code += " break;\n";
|
||||
code += " }\n";
|
||||
code += " __at += __d * __dir;\n";
|
||||
code += " }\n";
|
||||
|
||||
code += "\t\tfloat __dist = min(__max_dist, __accum);\n";
|
||||
code += "\t\t" + p_output_vars[0] + " = __dist;\n";
|
||||
code += "\t\t" + p_output_vars[1] + " = __accum < __max_dist;\n";
|
||||
code += "\t\t" + p_output_vars[2] + " = vec3(__from_pos + __dir * __dist, 0.0f);\n";
|
||||
code += " float __dist = min(__max_dist, __accum);\n";
|
||||
code += " " + p_output_vars[0] + " = __dist;\n";
|
||||
code += " " + p_output_vars[1] + " = __accum < __max_dist;\n";
|
||||
code += " " + p_output_vars[2] + " = vec3(__from_pos + __dir * __dist, 0.0f);\n";
|
||||
|
||||
code += "\t}\n";
|
||||
code += " }\n";
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -683,7 +683,19 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
|
||||
//default material and shader
|
||||
default_shader = storage->shader_allocate();
|
||||
storage->shader_initialize(default_shader);
|
||||
storage->shader_set_code(default_shader, "shader_type spatial; void vertex() { ROUGHNESS = 0.8; } void fragment() { ALBEDO=vec3(0.6); ROUGHNESS=0.8; METALLIC=0.2; } \n");
|
||||
storage->shader_set_code(default_shader, R"(
|
||||
shader_type spatial;
|
||||
|
||||
void vertex() {
|
||||
ROUGHNESS = 0.8;
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
ALBEDO = vec3(0.6);
|
||||
ROUGHNESS = 0.8;
|
||||
METALLIC = 0.2;
|
||||
}
|
||||
)");
|
||||
default_material = storage->material_allocate();
|
||||
storage->material_initialize(default_material);
|
||||
storage->material_set_shader(default_material, default_shader);
|
||||
@ -700,7 +712,16 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
|
||||
overdraw_material_shader = storage->shader_allocate();
|
||||
storage->shader_initialize(overdraw_material_shader);
|
||||
// Use relatively low opacity so that more "layers" of overlapping objects can be distinguished.
|
||||
storage->shader_set_code(overdraw_material_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.1; }");
|
||||
storage->shader_set_code(overdraw_material_shader, R"(
|
||||
shader_type spatial;
|
||||
|
||||
render_mode blend_add, unshaded;
|
||||
|
||||
void fragment() {
|
||||
ALBEDO = vec3(0.4, 0.8, 0.8);
|
||||
ALPHA = 0.1;
|
||||
}
|
||||
)");
|
||||
overdraw_material = storage->material_allocate();
|
||||
storage->material_initialize(overdraw_material);
|
||||
storage->material_set_shader(overdraw_material, overdraw_material_shader);
|
||||
|
@ -673,7 +673,19 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
|
||||
//default material and shader
|
||||
default_shader = storage->shader_allocate();
|
||||
storage->shader_initialize(default_shader);
|
||||
storage->shader_set_code(default_shader, "shader_type spatial; void vertex() { ROUGHNESS = 0.8; } void fragment() { ALBEDO=vec3(0.6); ROUGHNESS=0.8; METALLIC=0.2; } \n");
|
||||
storage->shader_set_code(default_shader, R"(
|
||||
shader_type spatial;
|
||||
|
||||
void vertex() {
|
||||
ROUGHNESS = 0.8;
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
ALBEDO = vec3(0.6);
|
||||
ROUGHNESS = 0.8;
|
||||
METALLIC = 0.2;
|
||||
}
|
||||
)");
|
||||
default_material = storage->material_allocate();
|
||||
storage->material_initialize(default_material);
|
||||
storage->material_set_shader(default_material, default_shader);
|
||||
@ -689,7 +701,16 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
|
||||
overdraw_material_shader = storage->shader_allocate();
|
||||
storage->shader_initialize(overdraw_material_shader);
|
||||
// Use relatively low opacity so that more "layers" of overlapping objects can be distinguished.
|
||||
storage->shader_set_code(overdraw_material_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.1; }");
|
||||
storage->shader_set_code(overdraw_material_shader, R"(
|
||||
shader_type spatial;
|
||||
|
||||
render_mode blend_add, unshaded;
|
||||
|
||||
void fragment() {
|
||||
ALBEDO = vec3(0.4, 0.8, 0.8);
|
||||
ALPHA = 0.1;
|
||||
}
|
||||
)");
|
||||
overdraw_material = storage->material_allocate();
|
||||
storage->material_initialize(overdraw_material);
|
||||
storage->material_set_shader(overdraw_material, overdraw_material_shader);
|
||||
|
@ -2570,8 +2570,19 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
|
||||
default_canvas_group_shader = storage->shader_allocate();
|
||||
storage->shader_initialize(default_canvas_group_shader);
|
||||
|
||||
storage->shader_set_code(default_canvas_group_shader, "shader_type canvas_item; \nvoid fragment() {\n\tvec4 c = textureLod(SCREEN_TEXTURE,SCREEN_UV,0.0); if (c.a > 0.0001) c.rgb/=c.a; COLOR *= c; \n}\n");
|
||||
storage->shader_set_code(default_canvas_group_shader, R"(
|
||||
shader_type canvas_item;
|
||||
|
||||
void fragment() {
|
||||
vec4 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0);
|
||||
|
||||
if (c.a > 0.0001) {
|
||||
c.rgb /= c.a;
|
||||
}
|
||||
|
||||
COLOR *= c;
|
||||
}
|
||||
)");
|
||||
default_canvas_group_material = storage->material_allocate();
|
||||
storage->material_initialize(default_canvas_group_material);
|
||||
|
||||
|
@ -757,7 +757,13 @@ void RendererSceneSkyRD::init(RendererStorageRD *p_storage) {
|
||||
sky_shader.default_shader = storage->shader_allocate();
|
||||
storage->shader_initialize(sky_shader.default_shader);
|
||||
|
||||
storage->shader_set_code(sky_shader.default_shader, "shader_type sky; void sky() { COLOR = vec3(0.0); } \n");
|
||||
storage->shader_set_code(sky_shader.default_shader, R"(
|
||||
shader_type sky;
|
||||
|
||||
void sky() {
|
||||
COLOR = vec3(0.0);
|
||||
}
|
||||
)");
|
||||
|
||||
sky_shader.default_material = storage->material_allocate();
|
||||
storage->material_initialize(sky_shader.default_material);
|
||||
@ -838,7 +844,15 @@ void RendererSceneSkyRD::init(RendererStorageRD *p_storage) {
|
||||
sky_scene_state.fog_shader = storage->shader_allocate();
|
||||
storage->shader_initialize(sky_scene_state.fog_shader);
|
||||
|
||||
storage->shader_set_code(sky_scene_state.fog_shader, "shader_type sky; uniform vec4 clear_color; void sky() { COLOR = clear_color.rgb; } \n");
|
||||
storage->shader_set_code(sky_scene_state.fog_shader, R"(
|
||||
shader_type sky;
|
||||
|
||||
uniform vec4 clear_color;
|
||||
|
||||
void sky() {
|
||||
COLOR = clear_color.rgb;
|
||||
}
|
||||
)");
|
||||
sky_scene_state.fog_material = storage->material_allocate();
|
||||
storage->material_initialize(sky_scene_state.fog_material);
|
||||
|
||||
|
@ -9388,7 +9388,13 @@ RendererStorageRD::RendererStorageRD() {
|
||||
// default material and shader for particles shader
|
||||
particles_shader.default_shader = shader_allocate();
|
||||
shader_initialize(particles_shader.default_shader);
|
||||
shader_set_code(particles_shader.default_shader, "shader_type particles; void process() { COLOR = vec4(1.0); } \n");
|
||||
shader_set_code(particles_shader.default_shader, R"(
|
||||
shader_type particles;
|
||||
|
||||
void process() {
|
||||
COLOR = vec4(1.0);
|
||||
}
|
||||
)");
|
||||
particles_shader.default_material = material_allocate();
|
||||
material_initialize(particles_shader.default_material);
|
||||
material_set_shader(particles_shader.default_material, particles_shader.default_shader);
|
||||
|
Loading…
Reference in New Issue
Block a user