mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 21:51:22 +00:00 
			
		
		
		
	Use C++11 raw literals for shader code to improve readability
In files that have lots of branching, `\t` was replaced with a tab character instead.
This commit is contained in:
		
							parent
							
								
									b76dfde329
								
							
						
					
					
						commit
						abc38b8d66
					
				
					 17 changed files with 1146 additions and 1040 deletions
				
			
		|  | @ -1733,27 +1733,27 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay | ||||||
| 	onion.capture.material = Ref<ShaderMaterial>(memnew(ShaderMaterial)); | 	onion.capture.material = Ref<ShaderMaterial>(memnew(ShaderMaterial)); | ||||||
| 
 | 
 | ||||||
| 	onion.capture.shader = Ref<Shader>(memnew(Shader)); | 	onion.capture.shader = Ref<Shader>(memnew(Shader)); | ||||||
| 	onion.capture.shader->set_code(" \
 | 	onion.capture.shader->set_code(R"( | ||||||
| 		shader_type canvas_item; \ | shader_type canvas_item; | ||||||
| 		\ | 
 | ||||||
|         uniform vec4 bkg_color; \ | uniform vec4 bkg_color; | ||||||
| 		uniform vec4 dir_color; \ | uniform vec4 dir_color; | ||||||
| 		uniform bool differences_only; \ | uniform bool differences_only; | ||||||
| 		uniform sampler2D present; \ | uniform sampler2D present; | ||||||
| 		\ | 
 | ||||||
| 		float zero_if_equal(vec4 a, vec4 b) { \ | float zero_if_equal(vec4 a, vec4 b) { | ||||||
| 			return smoothstep(0.0, 0.005, length(a.rgb - b.rgb) / sqrt(3.0)); \ | 	return smoothstep(0.0, 0.005, length(a.rgb - b.rgb) / sqrt(3.0)); | ||||||
| 		} \ | } | ||||||
| 		\ | 
 | ||||||
| 		void fragment() { \ | void fragment() { | ||||||
| 			vec4 capture_samp = texture(TEXTURE, UV); \ | 	vec4 capture_samp = texture(TEXTURE, UV); | ||||||
| 			vec4 present_samp = texture(present, UV); \ | 	vec4 present_samp = texture(present, UV); | ||||||
| 			float bkg_mask = zero_if_equal(capture_samp, bkg_color); \ | 	float bkg_mask = zero_if_equal(capture_samp, bkg_color); | ||||||
| 			float diff_mask = 1.0 - zero_if_equal(present_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)); \ | 	diff_mask = min(1.0, diff_mask + float(!differences_only)); | ||||||
| 			COLOR = vec4(capture_samp.rgb * dir_color.rgb, bkg_mask * diff_mask); \ | 	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()); | 	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); | 		Ref<Shader> grid_shader = memnew(Shader); | ||||||
| 		grid_shader->set_code( | 		grid_shader->set_code(R"( | ||||||
| 				"\n" | shader_type spatial; | ||||||
| 				"shader_type spatial; \n" | 
 | ||||||
| 				"render_mode unshaded; \n" | render_mode unshaded; | ||||||
| 				"uniform bool orthogonal; \n" | 
 | ||||||
| 				"uniform float grid_size; \n" | uniform bool orthogonal; | ||||||
| 				"\n" | uniform float grid_size; | ||||||
| 				"void vertex() { \n" | 
 | ||||||
| 				"	// From FLAG_SRGB_VERTEX_COLOR \n" | void vertex() { | ||||||
| 				"	if (!OUTPUT_IS_SRGB) { \n" | 	// From FLAG_SRGB_VERTEX_COLOR.
 | ||||||
| 				"		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" | 	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" | } | ||||||
| 				"void fragment() { \n" | 
 | ||||||
| 				"	ALBEDO = COLOR.rgb; \n" | void fragment() { | ||||||
| 				"	vec3 dir = orthogonal ? -vec3(0, 0, 1) : VIEW; \n" | 	ALBEDO = COLOR.rgb; | ||||||
| 				"	float angle_fade = abs(dot(dir, NORMAL)); \n" | 	vec3 dir = orthogonal ? -vec3(0, 0, 1) : VIEW; | ||||||
| 				"	angle_fade = smoothstep(0.05, 0.2, angle_fade); \n" | 	float angle_fade = abs(dot(dir, NORMAL)); | ||||||
| 				"	\n" | 	angle_fade = smoothstep(0.05, 0.2, angle_fade); | ||||||
| 				"	vec3 world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz; \n" | 
 | ||||||
| 				"	vec3 world_normal = (CAMERA_MATRIX * vec4(NORMAL, 0.0)).xyz; \n" | 	vec3 world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz; | ||||||
| 				"	vec3 camera_world_pos = CAMERA_MATRIX[3].xyz; \n" | 	vec3 world_normal = (CAMERA_MATRIX * vec4(NORMAL, 0.0)).xyz; | ||||||
| 				"	vec3 camera_world_pos_on_plane = camera_world_pos * (1.0 - world_normal); \n" | 	vec3 camera_world_pos = CAMERA_MATRIX[3].xyz; | ||||||
| 				"	float dist_fade = 1.0 - (distance(world_pos, camera_world_pos_on_plane) / grid_size); \n" | 	vec3 camera_world_pos_on_plane = camera_world_pos * (1.0 - world_normal); | ||||||
| 				"	dist_fade = smoothstep(0.02, 0.3, dist_fade); \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); | ||||||
| 				"	ALPHA = COLOR.a * dist_fade * angle_fade; \n" | 
 | ||||||
| 				"}"); | 	ALPHA = COLOR.a * dist_fade * angle_fade; | ||||||
|  | } | ||||||
|  | )"); | ||||||
| 
 | 
 | ||||||
| 		for (int i = 0; i < 3; i++) { | 		for (int i = 0; i < 3; i++) { | ||||||
| 			grid_mat[i].instantiate(); | 			grid_mat[i].instantiate(); | ||||||
|  | @ -5621,33 +5623,35 @@ void Node3DEditor::_init_indicators() { | ||||||
| 
 | 
 | ||||||
| 				Ref<Shader> rotate_shader = memnew(Shader); | 				Ref<Shader> rotate_shader = memnew(Shader); | ||||||
| 
 | 
 | ||||||
| 				rotate_shader->set_code( | 				rotate_shader->set_code(R"( | ||||||
| 						"\n" | shader_type spatial; | ||||||
| 						"shader_type spatial; \n" | 
 | ||||||
| 						"render_mode unshaded, depth_test_disabled; \n" | render_mode unshaded, depth_test_disabled; | ||||||
| 						"uniform vec4 albedo; \n" | 
 | ||||||
| 						"\n" | uniform vec4 albedo; | ||||||
| 						"mat3 orthonormalize(mat3 m) { \n" | 
 | ||||||
| 						"	vec3 x = normalize(m[0]); \n" | mat3 orthonormalize(mat3 m) { | ||||||
| 						"	vec3 y = normalize(m[1] - x * dot(x, m[1])); \n" | 	vec3 x = normalize(m[0]); | ||||||
| 						"	vec3 z = m[2] - x * dot(x, m[2]); \n" | 	vec3 y = normalize(m[1] - x * dot(x, m[1])); | ||||||
| 						"	z = normalize(z - y * (dot(y,m[2]))); \n" | 	vec3 z = m[2] - x * dot(x, m[2]); | ||||||
| 						"	return mat3(x,y,z); \n" | 	z = normalize(z - y * (dot(y,m[2]))); | ||||||
| 						"} \n" | 	return mat3(x,y,z); | ||||||
| 						"\n" | } | ||||||
| 						"void vertex() { \n" | 
 | ||||||
| 						"	mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n" | void vertex() { | ||||||
| 						"	vec3 n = mv * VERTEX; \n" | 	mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); | ||||||
| 						"	float orientation = dot(vec3(0,0,-1),n); \n" | 	vec3 n = mv * VERTEX; | ||||||
| 						"	if (orientation <= 0.005) { \n" | 	float orientation = dot(vec3(0, 0, -1), n); | ||||||
| 						"		VERTEX += NORMAL*0.02; \n" | 	if (orientation <= 0.005) { | ||||||
| 						"	} \n" | 		VERTEX += NORMAL * 0.02; | ||||||
| 						"} \n" | 	} | ||||||
| 						"\n" | } | ||||||
| 						"void fragment() { \n" | 
 | ||||||
| 						"	ALBEDO = albedo.rgb; \n" | void fragment() { | ||||||
| 						"	ALPHA = albedo.a; \n" | 	ALBEDO = albedo.rgb; | ||||||
| 						"}"); | 	ALPHA = albedo.a; | ||||||
|  | } | ||||||
|  | )"); | ||||||
| 
 | 
 | ||||||
| 				Ref<ShaderMaterial> rotate_mat = memnew(ShaderMaterial); | 				Ref<ShaderMaterial> rotate_mat = memnew(ShaderMaterial); | ||||||
| 				rotate_mat->set_render_priority(Material::RENDER_PRIORITY_MAX); | 				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<ShaderMaterial> border_mat = rotate_mat->duplicate(); | ||||||
| 
 | 
 | ||||||
| 					Ref<Shader> border_shader = memnew(Shader); | 					Ref<Shader> border_shader = memnew(Shader); | ||||||
| 					border_shader->set_code( | 					border_shader->set_code(R"( | ||||||
| 							"\n" | shader_type spatial; | ||||||
| 							"shader_type spatial; \n" | 
 | ||||||
| 							"render_mode unshaded, depth_test_disabled; \n" | render_mode unshaded, depth_test_disabled; | ||||||
| 							"uniform vec4 albedo; \n" | 
 | ||||||
| 							"\n" | uniform vec4 albedo; | ||||||
| 							"mat3 orthonormalize(mat3 m) { \n" | 
 | ||||||
| 							"	vec3 x = normalize(m[0]); \n" | mat3 orthonormalize(mat3 m) { | ||||||
| 							"	vec3 y = normalize(m[1] - x * dot(x, m[1])); \n" | 	vec3 x = normalize(m[0]); | ||||||
| 							"	vec3 z = m[2] - x * dot(x, m[2]); \n" | 	vec3 y = normalize(m[1] - x * dot(x, m[1])); | ||||||
| 							"	z = normalize(z - y * (dot(y,m[2]))); \n" | 	vec3 z = m[2] - x * dot(x, m[2]); | ||||||
| 							"	return mat3(x,y,z); \n" | 	z = normalize(z - y * (dot(y,m[2]))); | ||||||
| 							"} \n" | 	return mat3(x,y,z); | ||||||
| 							"\n" | } | ||||||
| 							"void vertex() { \n" | 
 | ||||||
| 							"	mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n" | void vertex() { | ||||||
| 							"	mv = inverse(mv); \n" | 	mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); | ||||||
| 							"	VERTEX += NORMAL*0.008; \n" | 	mv = inverse(mv); | ||||||
| 							"	vec3 camera_dir_local = mv * vec3(0,0,1); \n" | 	VERTEX += NORMAL*0.008; | ||||||
| 							"	vec3 camera_up_local = mv * vec3(0,1,0); \n" | 	vec3 camera_dir_local = mv * vec3(0,0,1); | ||||||
| 							"	mat3 rotation_matrix = mat3(cross(camera_dir_local, camera_up_local), camera_up_local, camera_dir_local); \n" | 	vec3 camera_up_local = mv * vec3(0,1,0); | ||||||
| 							"	VERTEX = rotation_matrix * VERTEX; \n" | 	mat3 rotation_matrix = mat3(cross(camera_dir_local, camera_up_local), camera_up_local, camera_dir_local); | ||||||
| 							"} \n" | 	VERTEX = rotation_matrix * VERTEX; | ||||||
| 							"\n" | } | ||||||
| 							"void fragment() { \n" | 
 | ||||||
| 							"	ALBEDO = albedo.rgb; \n" | void fragment() { | ||||||
| 							"	ALPHA = albedo.a; \n" | 	ALBEDO = albedo.rgb; | ||||||
| 							"}"); | 	ALPHA = albedo.a; | ||||||
|  | } | ||||||
|  | )"); | ||||||
| 
 | 
 | ||||||
| 					border_mat->set_shader(border_shader); | 					border_mat->set_shader(border_shader); | ||||||
| 					border_mat->set_shader_param("albedo", Color(0.75, 0.75, 0.75, col.a / 3.0)); | 					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->connect("draw", callable_mp(this, &Node3DEditor::_sun_direction_draw)); | ||||||
| 		sun_direction->set_default_cursor_shape(CURSOR_MOVE); | 		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.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.instantiate(); | ||||||
| 		sun_direction_material->set_shader(sun_direction_shader); | 		sun_direction_material->set_shader(sun_direction_shader); | ||||||
| 		sun_direction_material->set_shader_param("sun_direction", Vector3(0, 0, 1)); | 		sun_direction_material->set_shader_param("sun_direction", Vector3(0, 0, 1)); | ||||||
|  |  | ||||||
|  | @ -77,16 +77,17 @@ void Texture3DEditor::_update_material() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Texture3DEditor::_make_shaders() { | 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.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.instantiate(); | ||||||
| 	material->set_shader(shader); | 	material->set_shader(shader); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -104,43 +104,46 @@ void TextureLayeredEditor::_update_material() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void TextureLayeredEditor::_make_shaders() { | 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].instantiate(); | ||||||
| 	shaders[0]->set_code(shader_2d_array); | 	shaders[0]->set_code(R"( | ||||||
|  | shader_type canvas_item; | ||||||
| 
 | 
 | ||||||
| 	String shader_cube = "" | uniform sampler2DArray tex; | ||||||
| 						 "shader_type canvas_item;\n" | uniform float layer; | ||||||
| 						 "uniform samplerCube tex;\n" | 
 | ||||||
| 						 "uniform vec3 normal;\n" | void fragment() { | ||||||
| 						 "uniform mat3 rot;\n" | 	COLOR = textureLod(tex, vec3(UV, layer), 0.0); | ||||||
| 						 "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" |  | ||||||
| 						 "}"; |  | ||||||
| 
 | 
 | ||||||
| 	shaders[1].instantiate(); | 	shaders[1].instantiate(); | ||||||
| 	shaders[1]->set_code(shader_cube); | 	shaders[1]->set_code(R"( | ||||||
|  | shader_type canvas_item; | ||||||
| 
 | 
 | ||||||
| 	String shader_cube_array = "" | uniform samplerCube tex; | ||||||
| 							   "shader_type canvas_item;\n" | uniform vec3 normal; | ||||||
| 							   "uniform samplerCubeArray tex;\n" | uniform mat3 rot; | ||||||
| 							   "uniform vec3 normal;\n" | 
 | ||||||
| 							   "uniform mat3 rot;\n" | void fragment() { | ||||||
| 							   "uniform float layer;\n" | 	vec3 n = rot * normalize(vec3(normal.xy * (UV * 2.0 - 1.0), normal.z)); | ||||||
| 							   "void fragment() {\n" | 	COLOR = textureLod(tex, n, 0.0); | ||||||
| 							   "  vec3 n = rot * normalize(vec3(normal.xy*(UV * 2.0 - 1.0),normal.z));\n" | } | ||||||
| 							   "  COLOR = textureLod(tex,vec4(n,layer),0.0);\n" | )"); | ||||||
| 							   "}"; |  | ||||||
| 
 | 
 | ||||||
| 	shaders[2].instantiate(); | 	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++) { | 	for (int i = 0; i < 3; i++) { | ||||||
| 		materials[i].instantiate(); | 		materials[i].instantiate(); | ||||||
|  |  | ||||||
|  | @ -97,43 +97,49 @@ Ref<Shader> ColorPicker::circle_shader; | ||||||
| 
 | 
 | ||||||
| void ColorPicker::init_shaders() { | void ColorPicker::init_shaders() { | ||||||
| 	wheel_shader.instantiate(); | 	wheel_shader.instantiate(); | ||||||
| 	wheel_shader->set_code( | 	wheel_shader->set_code(R"( | ||||||
| 			"shader_type canvas_item;" | shader_type canvas_item; | ||||||
| 			"void fragment() {" | 
 | ||||||
| 			"	float x = UV.x - 0.5;" | void fragment() { | ||||||
| 			"	float y = UV.y - 0.5;" | 	float x = UV.x - 0.5; | ||||||
| 			"	float a = atan(y, x);" | 	float y = UV.y - 0.5; | ||||||
| 			"	x += 0.001;" | 	float a = atan(y, x); | ||||||
| 			"	y += 0.001;" | 	x += 0.001; | ||||||
| 			"	float b = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42);" | 	y += 0.001; | ||||||
| 			"	x -= 0.002;" | 	float b = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42); | ||||||
| 			"	float b2 = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42);" | 	x -= 0.002; | ||||||
| 			"	y -= 0.002;" | 	float b2 = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42); | ||||||
| 			"	float b3 = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42);" | 	y -= 0.002; | ||||||
| 			"	x += 0.002;" | 	float b3 = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42); | ||||||
| 			"	float b4 = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42);" | 	x += 0.002; | ||||||
| 			"	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);" | 	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.instantiate(); | ||||||
| 	circle_shader->set_code( | 	circle_shader->set_code(R"( | ||||||
| 			"shader_type canvas_item;" | shader_type canvas_item; | ||||||
| 			"uniform float v = 1.0;" | 
 | ||||||
| 			"void fragment() {" | uniform float v = 1.0; | ||||||
| 			"	float x = UV.x - 0.5;" | 
 | ||||||
| 			"	float y = UV.y - 0.5;" | void fragment() { | ||||||
| 			"	float a = atan(y, x);" | 	float x = UV.x - 0.5; | ||||||
| 			"	x += 0.001;" | 	float y = UV.y - 0.5; | ||||||
| 			"	y += 0.001;" | 	float a = atan(y, x); | ||||||
| 			"	float b = float(sqrt(x * x + y * y) < 0.5);" | 	x += 0.001; | ||||||
| 			"	x -= 0.002;" | 	y += 0.001; | ||||||
| 			"	float b2 = float(sqrt(x * x + y * y) < 0.5);" | 	float b = float(sqrt(x * x + y * y) < 0.5); | ||||||
| 			"	y -= 0.002;" | 	x -= 0.002; | ||||||
| 			"	float b3 = float(sqrt(x * x + y * y) < 0.5);" | 	float b2 = float(sqrt(x * x + y * y) < 0.5); | ||||||
| 			"	x += 0.002;" | 	y -= 0.002; | ||||||
| 			"	float b4 = float(sqrt(x * x + y * y) < 0.5);" | 	float b3 = 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);" | 	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() { | void ColorPicker::finish_shaders() { | ||||||
|  |  | ||||||
|  | @ -128,24 +128,21 @@ void CanvasItemMaterial::_update_shader() { | ||||||
| 	if (particles_animation) { | 	if (particles_animation) { | ||||||
| 		code += "uniform int particles_anim_h_frames;\n"; | 		code += "uniform int particles_anim_h_frames;\n"; | ||||||
| 		code += "uniform int particles_anim_v_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 += "void vertex() {\n"; | ||||||
| 
 | 		code += "	float h_frames = float(particles_anim_h_frames);\n"; | ||||||
| 		code += "\tfloat h_frames = float(particles_anim_h_frames);\n"; | 		code += "	float v_frames = float(particles_anim_v_frames);\n"; | ||||||
| 		code += "\tfloat 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 += "\tVERTEX.xy /= vec2(h_frames, v_frames);\n"; | 		code += "	float particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n"; | ||||||
| 
 | 		code += "	if (!particles_anim_loop) {\n"; | ||||||
| 		code += "\tfloat particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);\n"; | 		code += "		particle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);\n"; | ||||||
| 		code += "\tfloat particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n"; | 		code += "	} else {\n"; | ||||||
| 		code += "\tif (!particles_anim_loop) {\n"; | 		code += "		particle_frame = mod(particle_frame, particle_total_frames);\n"; | ||||||
| 		code += "\t\tparticle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);\n"; | 		code += "	}"; | ||||||
| 		code += "\t} else {\n"; | 		code += "	UV /= vec2(h_frames, v_frames);\n"; | ||||||
| 		code += "\t\tparticle_frame = mod(particle_frame, particle_total_frames);\n"; | 		code += "	UV += vec2(mod(particle_frame, h_frames) / h_frames, floor(particle_frame / h_frames) / v_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 += "}\n"; | 		code += "}\n"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -757,148 +757,148 @@ void BaseMaterial3D::_update_shader() { | ||||||
| 	code += "void vertex() {\n"; | 	code += "void vertex() {\n"; | ||||||
| 
 | 
 | ||||||
| 	if (flags[FLAG_SRGB_VERTEX_COLOR]) { | 	if (flags[FLAG_SRGB_VERTEX_COLOR]) { | ||||||
| 		code += "\tif (!OUTPUT_IS_SRGB) {\n"; | 		code += "	if (!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 += "		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 += "\t}\n"; | 		code += "	}\n"; | ||||||
| 	} | 	} | ||||||
| 	if (flags[FLAG_USE_POINT_SIZE]) { | 	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) { | 	if (shading_mode == SHADING_MODE_PER_VERTEX) { | ||||||
| 		code += "\tROUGHNESS=roughness;\n"; | 		code += "	ROUGHNESS=roughness;\n"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (!flags[FLAG_UV1_USE_TRIPLANAR]) { | 	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) { | 	switch (billboard_mode) { | ||||||
| 		case BILLBOARD_DISABLED: { | 		case BILLBOARD_DISABLED: { | ||||||
| 		} break; | 		} break; | ||||||
| 		case BILLBOARD_ENABLED: { | 		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]) { | 			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; | 		} break; | ||||||
| 		case BILLBOARD_FIXED_Y: { | 		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]) { | 			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 { | 			} 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; | 		} break; | ||||||
| 		case BILLBOARD_PARTICLES: { | 		case BILLBOARD_PARTICLES: { | ||||||
| 			//make billboard
 | 			//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
 | 			//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
 | 			//set modelview
 | ||||||
| 			code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat_world;\n"; | 			code += "	MODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat_world;\n"; | ||||||
| 
 | 
 | ||||||
| 			//handle animation
 | 			//handle animation
 | ||||||
| 			code += "\tfloat h_frames = float(particles_anim_h_frames);\n"; | 			code += "	float h_frames = float(particles_anim_h_frames);\n"; | ||||||
| 			code += "\tfloat v_frames = float(particles_anim_v_frames);\n"; | 			code += "	float v_frames = float(particles_anim_v_frames);\n"; | ||||||
| 			code += "\tfloat particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);\n"; | 			code += "	float 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 += "	float particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n"; | ||||||
| 			code += "\tif (!particles_anim_loop) {\n"; | 			code += "	if (!particles_anim_loop) {\n"; | ||||||
| 			code += "\t\tparticle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);\n"; | 			code += "		particle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);\n"; | ||||||
| 			code += "\t} else {\n"; | 			code += "	} else {\n"; | ||||||
| 			code += "\t\tparticle_frame = mod(particle_frame, particle_total_frames);\n"; | 			code += "		particle_frame = mod(particle_frame, particle_total_frames);\n"; | ||||||
| 			code += "\t}"; | 			code += "	}"; | ||||||
| 			code += "\tUV /= vec2(h_frames, v_frames);\n"; | 			code += "	UV /= 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 += "	UV += vec2(mod(particle_frame, h_frames) / h_frames, floor(particle_frame / h_frames) / v_frames);\n"; | ||||||
| 		} break; | 		} break; | ||||||
| 		case BILLBOARD_MAX: | 		case BILLBOARD_MAX: | ||||||
| 			break; // Internal value, skip.
 | 			break; // Internal value, skip.
 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (flags[FLAG_FIXED_SIZE]) { | 	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
 | 		//orthogonal matrix, try to do about the same
 | ||||||
| 		//with viewport size
 | 		//with viewport size
 | ||||||
| 		code += "\t\tfloat h = abs(1.0 / (2.0 * PROJECTION_MATRIX[1][1]));\n"; | 		code += "		float h = abs(1.0 / (2.0 * PROJECTION_MATRIX[1][1]));\n"; | ||||||
| 		code += "\t\tfloat sc = (h * 2.0); //consistent with Y-fov\n"; | 		code += "		float sc = (h * 2.0); //consistent with Y-fov\n"; | ||||||
| 		code += "\t\tMODELVIEW_MATRIX[0]*=sc;\n"; | 		code += "		MODELVIEW_MATRIX[0]*=sc;\n"; | ||||||
| 		code += "\t\tMODELVIEW_MATRIX[1]*=sc;\n"; | 		code += "		MODELVIEW_MATRIX[1]*=sc;\n"; | ||||||
| 		code += "\t\tMODELVIEW_MATRIX[2]*=sc;\n"; | 		code += "		MODELVIEW_MATRIX[2]*=sc;\n"; | ||||||
| 		code += "\t} else {\n"; | 		code += "	} else {\n"; | ||||||
| 		//just scale by depth
 | 		//just scale by depth
 | ||||||
| 		code += "\t\tfloat sc = -(MODELVIEW_MATRIX)[3].z;\n"; | 		code += "		float sc = -(MODELVIEW_MATRIX)[3].z;\n"; | ||||||
| 		code += "\t\tMODELVIEW_MATRIX[0]*=sc;\n"; | 		code += "		MODELVIEW_MATRIX[0]*=sc;\n"; | ||||||
| 		code += "\t\tMODELVIEW_MATRIX[1]*=sc;\n"; | 		code += "		MODELVIEW_MATRIX[1]*=sc;\n"; | ||||||
| 		code += "\t\tMODELVIEW_MATRIX[2]*=sc;\n"; | 		code += "		MODELVIEW_MATRIX[2]*=sc;\n"; | ||||||
| 		code += "\t}\n"; | 		code += "	}\n"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (detail_uv == DETAIL_UV_2 && !flags[FLAG_UV2_USE_TRIPLANAR]) { | 	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]) { | 	if (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR]) { | ||||||
| 		//generate tangent and binormal in world space
 | 		//generate tangent and binormal in world space
 | ||||||
| 		code += "\tTANGENT = vec3(0.0,0.0,-1.0) * abs(NORMAL.x);\n"; | 		code += "	TANGENT = 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 += "	TANGENT+= 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 += "	TANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.z);\n"; | ||||||
| 		code += "\tTANGENT = normalize(TANGENT);\n"; | 		code += "	TANGENT = normalize(TANGENT);\n"; | ||||||
| 
 | 
 | ||||||
| 		code += "\tBINORMAL = vec3(0.0,1.0,0.0) * abs(NORMAL.x);\n"; | 		code += "	BINORMAL = 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 += "	BINORMAL+= 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 += "	BINORMAL+= vec3(0.0,1.0,0.0) * abs(NORMAL.z);\n"; | ||||||
| 		code += "\tBINORMAL = normalize(BINORMAL);\n"; | 		code += "	BINORMAL = normalize(BINORMAL);\n"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (flags[FLAG_UV1_USE_TRIPLANAR]) { | 	if (flags[FLAG_UV1_USE_TRIPLANAR]) { | ||||||
| 		if (flags[FLAG_UV1_USE_WORLD_TRIPLANAR]) { | 		if (flags[FLAG_UV1_USE_WORLD_TRIPLANAR]) { | ||||||
| 			code += "\tuv1_power_normal=pow(abs(mat3(WORLD_MATRIX) * NORMAL),vec3(uv1_blend_sharpness));\n"; | 			code += "	uv1_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_triplanar_pos = (WORLD_MATRIX * vec4(VERTEX, 1.0f)).xyz * uv1_scale + uv1_offset;\n"; | ||||||
| 		} else { | 		} else { | ||||||
| 			code += "\tuv1_power_normal=pow(abs(NORMAL),vec3(uv1_blend_sharpness));\n"; | 			code += "	uv1_power_normal=pow(abs(NORMAL),vec3(uv1_blend_sharpness));\n"; | ||||||
| 			code += "\tuv1_triplanar_pos = VERTEX * uv1_scale + uv1_offset;\n"; | 			code += "	uv1_triplanar_pos = VERTEX * uv1_scale + uv1_offset;\n"; | ||||||
| 		} | 		} | ||||||
| 		code += "\tuv1_power_normal/=dot(uv1_power_normal,vec3(1.0));\n"; | 		code += "	uv1_power_normal/=dot(uv1_power_normal,vec3(1.0));\n"; | ||||||
| 		code += "\tuv1_triplanar_pos *= vec3(1.0,-1.0, 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_TRIPLANAR]) { | ||||||
| 		if (flags[FLAG_UV2_USE_WORLD_TRIPLANAR]) { | 		if (flags[FLAG_UV2_USE_WORLD_TRIPLANAR]) { | ||||||
| 			code += "\tuv2_power_normal=pow(abs(mat3(WORLD_MATRIX) * NORMAL), vec3(uv2_blend_sharpness));\n"; | 			code += "	uv2_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_triplanar_pos = (WORLD_MATRIX * vec4(VERTEX, 1.0f)).xyz * uv2_scale + uv2_offset;\n"; | ||||||
| 		} else { | 		} else { | ||||||
| 			code += "\tuv2_power_normal=pow(abs(NORMAL), vec3(uv2_blend_sharpness));\n"; | 			code += "	uv2_power_normal=pow(abs(NORMAL), vec3(uv2_blend_sharpness));\n"; | ||||||
| 			code += "\tuv2_triplanar_pos = VERTEX * uv2_scale + uv2_offset;\n"; | 			code += "	uv2_triplanar_pos = VERTEX * uv2_scale + uv2_offset;\n"; | ||||||
| 		} | 		} | ||||||
| 		code += "\tuv2_power_normal/=dot(uv2_power_normal,vec3(1.0));\n"; | 		code += "	uv2_power_normal/=dot(uv2_power_normal,vec3(1.0));\n"; | ||||||
| 		code += "\tuv2_triplanar_pos *= vec3(1.0,-1.0, 1.0);\n"; | 		code += "	uv2_triplanar_pos *= vec3(1.0,-1.0, 1.0);\n"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (grow_enabled) { | 	if (grow_enabled) { | ||||||
| 		code += "\tVERTEX+=NORMAL*grow;\n"; | 		code += "	VERTEX+=NORMAL*grow;\n"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	code += "}\n"; | 	code += "}\n"; | ||||||
| 	code += "\n\n"; | 	code += "\n\n"; | ||||||
| 	if (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR]) { | 	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 += "vec4 triplanar_texture(sampler2D p_sampler,vec3 p_weights,vec3 p_triplanar_pos) {\n"; | ||||||
| 		code += "\tvec4 samp=vec4(0.0);\n"; | 		code += "	vec4 samp=vec4(0.0);\n"; | ||||||
| 		code += "\tsamp+= texture(p_sampler,p_triplanar_pos.xy) * p_weights.z;\n"; | 		code += "	samp+= 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 += "	samp+= 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 += "	samp+= texture(p_sampler,p_triplanar_pos.zy * vec2(-1.0,1.0)) * p_weights.x;\n"; | ||||||
| 		code += "\treturn samp;\n"; | 		code += "	return samp;\n"; | ||||||
| 		code += "}\n"; | 		code += "}\n"; | ||||||
| 	} | 	} | ||||||
| 	code += "\n\n"; | 	code += "\n\n"; | ||||||
| 	code += "void fragment() {\n"; | 	code += "void fragment() {\n"; | ||||||
| 
 | 
 | ||||||
| 	if (!flags[FLAG_UV1_USE_TRIPLANAR]) { | 	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])) { | 	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]) { | 	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
 | 	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 += "	{\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 += "		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) { | 		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 += "		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 += "\t\tfloat layer_depth = 1.0 / num_layers;\n"; | 			code += "		float layer_depth = 1.0 / num_layers;\n"; | ||||||
| 			code += "\t\tfloat current_layer_depth = 0.0;\n"; | 			code += "		float current_layer_depth = 0.0;\n"; | ||||||
| 			code += "\t\tvec2 P = view_dir.xy * heightmap_scale;\n"; | 			code += "		vec2 P = view_dir.xy * heightmap_scale;\n"; | ||||||
| 			code += "\t\tvec2 delta = P / num_layers;\n"; | 			code += "		vec2 delta = P / num_layers;\n"; | ||||||
| 			code += "\t\tvec2 ofs = base_uv;\n"; | 			code += "		vec2 ofs = base_uv;\n"; | ||||||
| 			if (flags[FLAG_INVERT_HEIGHTMAP]) { | 			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 { | 			} 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 += "		float current_depth = 0.0;\n"; | ||||||
| 			code += "\t\twhile(current_depth < depth) {\n"; | 			code += "		while(current_depth < depth) {\n"; | ||||||
| 			code += "\t\t\tofs -= delta;\n"; | 			code += "			ofs -= delta;\n"; | ||||||
| 			if (flags[FLAG_INVERT_HEIGHTMAP]) { | 			if (flags[FLAG_INVERT_HEIGHTMAP]) { | ||||||
| 				code += "\t\t\tdepth = texture(texture_heightmap, ofs).r;\n"; | 				code += "			depth = texture(texture_heightmap, ofs).r;\n"; | ||||||
| 			} else { | 			} 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 += "			current_depth += layer_depth;\n"; | ||||||
| 			code += "\t\t}\n"; | 			code += "		}\n"; | ||||||
| 			code += "\t\tvec2 prev_ofs = ofs + delta;\n"; | 			code += "		vec2 prev_ofs = ofs + delta;\n"; | ||||||
| 			code += "\t\tfloat after_depth  = depth - current_depth;\n"; | 			code += "		float after_depth  = depth - current_depth;\n"; | ||||||
| 			if (flags[FLAG_INVERT_HEIGHTMAP]) { | 			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 { | 			} 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 += "		float weight = after_depth / (after_depth - before_depth);\n"; | ||||||
| 			code += "\t\tofs = mix(ofs,prev_ofs,weight);\n"; | 			code += "		ofs = mix(ofs,prev_ofs,weight);\n"; | ||||||
| 
 | 
 | ||||||
| 		} else { | 		} else { | ||||||
| 			if (flags[FLAG_INVERT_HEIGHTMAP]) { | 			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 { | 			} 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) { | 		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]) { | 	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 { | 	} else { | ||||||
| 		if (flags[FLAG_UV1_USE_TRIPLANAR]) { | 		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 { | 		} 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]) { | 	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]) { | 	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 (!orm) { | ||||||
| 		if (flags[FLAG_UV1_USE_TRIPLANAR]) { | 		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 { | 		} 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) { | 		switch (roughness_texture_channel) { | ||||||
| 			case TEXTURE_CHANNEL_RED: { | 			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; | 			} break; | ||||||
| 			case TEXTURE_CHANNEL_GREEN: { | 			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; | 			} break; | ||||||
| 			case TEXTURE_CHANNEL_BLUE: { | 			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; | 			} break; | ||||||
| 			case TEXTURE_CHANNEL_ALPHA: { | 			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; | 			} break; | ||||||
| 			case TEXTURE_CHANNEL_GRAYSCALE: { | 			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; | 			} break; | ||||||
| 			case TEXTURE_CHANNEL_MAX: | 			case TEXTURE_CHANNEL_MAX: | ||||||
| 				break; // Internal value, skip.
 | 				break; // Internal value, skip.
 | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (flags[FLAG_UV1_USE_TRIPLANAR]) { | 		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 { | 		} 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 += "	ROUGHNESS = roughness_tex * roughness;\n"; | ||||||
| 		code += "\tSPECULAR = specular;\n"; | 		code += "	SPECULAR = specular;\n"; | ||||||
| 	} else { | 	} else { | ||||||
| 		if (flags[FLAG_UV1_USE_TRIPLANAR]) { | 		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 { | 		} 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 += "	ROUGHNESS = orm_tex.g;\n"; | ||||||
| 		code += "\tMETALLIC = orm_tex.b;\n"; | 		code += "	METALLIC = orm_tex.b;\n"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (features[FEATURE_NORMAL_MAPPING]) { | 	if (features[FEATURE_NORMAL_MAPPING]) { | ||||||
| 		if (flags[FLAG_UV1_USE_TRIPLANAR]) { | 		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 { | 		} 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 (features[FEATURE_EMISSION]) { | ||||||
| 		if (flags[FLAG_EMISSION_ON_UV2]) { | 		if (flags[FLAG_EMISSION_ON_UV2]) { | ||||||
| 			if (flags[FLAG_UV2_USE_TRIPLANAR]) { | 			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 { | 			} else { | ||||||
| 				code += "\tvec3 emission_tex = texture(texture_emission,base_uv2).rgb;\n"; | 				code += "	vec3 emission_tex = texture(texture_emission,base_uv2).rgb;\n"; | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			if (flags[FLAG_UV1_USE_TRIPLANAR]) { | 			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 { | 			} 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) { | 		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 { | 		} 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_REFRACTION]) { | ||||||
| 		if (features[FEATURE_NORMAL_MAPPING]) { | 		if (features[FEATURE_NORMAL_MAPPING]) { | ||||||
| 			code += "\tvec3 unpacked_normal = NORMAL_MAP;\n"; | 			code += "	vec3 unpacked_normal = NORMAL_MAP;\n"; | ||||||
| 			code += "\tunpacked_normal.xy = unpacked_normal.xy * 2.0 - 1.0;\n"; | 			code += "	unpacked_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 += "	unpacked_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 ref_normal = normalize( mix(NORMAL,TANGENT * unpacked_normal.x + BINORMAL * unpacked_normal.y + NORMAL * unpacked_normal.z,NORMAL_MAP_DEPTH) );\n"; | ||||||
| 		} else { | 		} else { | ||||||
| 			code += "\tvec3 ref_normal = NORMAL;\n"; | 			code += "	vec3 ref_normal = NORMAL;\n"; | ||||||
| 		} | 		} | ||||||
| 		if (flags[FLAG_UV1_USE_TRIPLANAR]) { | 		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 { | 		} 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 += "	float 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 += "	EMISSION += textureLod(SCREEN_TEXTURE,ref_ofs,ROUGHNESS * 8.0).rgb * ref_amount;\n"; | ||||||
| 		code += "\tALBEDO *= 1.0 - ref_amount;\n"; | 		code += "	ALBEDO *= 1.0 - ref_amount;\n"; | ||||||
| 		code += "\tALPHA = 1.0;\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) { | 	} 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) { | 	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) { | 	} 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)) { | 	if (alpha_antialiasing_mode != ALPHA_ANTIALIASING_OFF && (transparency == TRANSPARENCY_ALPHA_HASH || transparency == TRANSPARENCY_ALPHA_SCISSOR)) { | ||||||
| 		code += "\tALPHA_ANTIALIASING_EDGE = alpha_antialiasing_edge;\n"; | 		code += "	ALPHA_ANTIALIASING_EDGE = alpha_antialiasing_edge;\n"; | ||||||
| 		code += "\tALPHA_TEXTURE_COORDINATE = UV * vec2(albedo_texture_size);\n"; | 		code += "	ALPHA_TEXTURE_COORDINATE = UV * vec2(albedo_texture_size);\n"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (proximity_fade_enabled) { | 	if (proximity_fade_enabled) { | ||||||
| 		code += "\tfloat depth_tex = textureLod(DEPTH_TEXTURE,SCREEN_UV,0.0).r;\n"; | 		code += "	float 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 += "	vec4 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 += "	world_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 += "	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_DISABLED) { | ||||||
| 		if ((distance_fade == DISTANCE_FADE_OBJECT_DITHER || distance_fade == DISTANCE_FADE_PIXEL_DITHER)) { | 		if ((distance_fade == DISTANCE_FADE_OBJECT_DITHER || distance_fade == DISTANCE_FADE_PIXEL_DITHER)) { | ||||||
| 			if (!RenderingServer::get_singleton()->is_low_end()) { | 			if (!RenderingServer::get_singleton()->is_low_end()) { | ||||||
| 				code += "\t{\n"; | 				code += "	{\n"; | ||||||
| 				if (distance_fade == DISTANCE_FADE_OBJECT_DITHER) { | 				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 { | 				} 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 += "		float 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 += "		int x = int(FRAGCOORD.x) % 4;\n"; | ||||||
| 				code += "\t\tint y = int(FRAGCOORD.y) % 4;\n"; | 				code += "		int y = int(FRAGCOORD.y) % 4;\n"; | ||||||
| 				code += "\t\tint index = x + y * 4;\n"; | 				code += "		int index = x + y * 4;\n"; | ||||||
| 				code += "\t\tfloat limit = 0.0;\n\n"; | 				code += "		float limit = 0.0;\n\n"; | ||||||
| 				code += "\t\tif (x < 8) {\n"; | 				code += "		if (x < 8) {\n"; | ||||||
| 				code += "\t\t\tif (index == 0) limit = 0.0625;\n"; | 				code += "			if (index == 0) limit = 0.0625;\n"; | ||||||
| 				code += "\t\t\tif (index == 1) limit = 0.5625;\n"; | 				code += "			if (index == 1) limit = 0.5625;\n"; | ||||||
| 				code += "\t\t\tif (index == 2) limit = 0.1875;\n"; | 				code += "			if (index == 2) limit = 0.1875;\n"; | ||||||
| 				code += "\t\t\tif (index == 3) limit = 0.6875;\n"; | 				code += "			if (index == 3) limit = 0.6875;\n"; | ||||||
| 				code += "\t\t\tif (index == 4) limit = 0.8125;\n"; | 				code += "			if (index == 4) limit = 0.8125;\n"; | ||||||
| 				code += "\t\t\tif (index == 5) limit = 0.3125;\n"; | 				code += "			if (index == 5) limit = 0.3125;\n"; | ||||||
| 				code += "\t\t\tif (index == 6) limit = 0.9375;\n"; | 				code += "			if (index == 6) limit = 0.9375;\n"; | ||||||
| 				code += "\t\t\tif (index == 7) limit = 0.4375;\n"; | 				code += "			if (index == 7) limit = 0.4375;\n"; | ||||||
| 				code += "\t\t\tif (index == 8) limit = 0.25;\n"; | 				code += "			if (index == 8) limit = 0.25;\n"; | ||||||
| 				code += "\t\t\tif (index == 9) limit = 0.75;\n"; | 				code += "			if (index == 9) limit = 0.75;\n"; | ||||||
| 				code += "\t\t\tif (index == 10) limit = 0.125;\n"; | 				code += "			if (index == 10) limit = 0.125;\n"; | ||||||
| 				code += "\t\t\tif (index == 11) limit = 0.625;\n"; | 				code += "			if (index == 11) limit = 0.625;\n"; | ||||||
| 				code += "\t\t\tif (index == 12) limit = 1.0;\n"; | 				code += "			if (index == 12) limit = 1.0;\n"; | ||||||
| 				code += "\t\t\tif (index == 13) limit = 0.5;\n"; | 				code += "			if (index == 13) limit = 0.5;\n"; | ||||||
| 				code += "\t\t\tif (index == 14) limit = 0.875;\n"; | 				code += "			if (index == 14) limit = 0.875;\n"; | ||||||
| 				code += "\t\t\tif (index == 15) limit = 0.375;\n"; | 				code += "			if (index == 15) limit = 0.375;\n"; | ||||||
| 				code += "\t\t}\n\n"; | 				code += "		}\n\n"; | ||||||
| 				code += "\tif (fade < limit)\n"; | 				code += "	if (fade < limit)\n"; | ||||||
| 				code += "\t\tdiscard;\n"; | 				code += "		discard;\n"; | ||||||
| 				code += "\t}\n\n"; | 				code += "	}\n\n"; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 		} else { | 		} 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 (features[FEATURE_RIM]) { | ||||||
| 		if (flags[FLAG_UV1_USE_TRIPLANAR]) { | 		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 { | 		} 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 += "	RIM = rim*rim_tex.x;"; | ||||||
| 		code += "\tRIM_TINT = rim_tint*rim_tex.y;\n"; | 		code += "	RIM_TINT = rim_tint*rim_tex.y;\n"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (features[FEATURE_CLEARCOAT]) { | 	if (features[FEATURE_CLEARCOAT]) { | ||||||
| 		if (flags[FLAG_UV1_USE_TRIPLANAR]) { | 		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 { | 		} 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 += "	CLEARCOAT = clearcoat*clearcoat_tex.x;"; | ||||||
| 		code += "\tCLEARCOAT_GLOSS = clearcoat_gloss*clearcoat_tex.y;\n"; | 		code += "	CLEARCOAT_GLOSS = clearcoat_gloss*clearcoat_tex.y;\n"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (features[FEATURE_ANISOTROPY]) { | 	if (features[FEATURE_ANISOTROPY]) { | ||||||
| 		if (flags[FLAG_UV1_USE_TRIPLANAR]) { | 		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 { | 		} 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 += "	ANISOTROPY = anisotropy_ratio*anisotropy_tex.b;\n"; | ||||||
| 		code += "\tANISOTROPY_FLOW = anisotropy_tex.rg*2.0-1.0;\n"; | 		code += "	ANISOTROPY_FLOW = anisotropy_tex.rg*2.0-1.0;\n"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (features[FEATURE_AMBIENT_OCCLUSION]) { | 	if (features[FEATURE_AMBIENT_OCCLUSION]) { | ||||||
| 		if (!orm) { | 		if (!orm) { | ||||||
| 			if (flags[FLAG_AO_ON_UV2]) { | 			if (flags[FLAG_AO_ON_UV2]) { | ||||||
| 				if (flags[FLAG_UV2_USE_TRIPLANAR]) { | 				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 { | 				} 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 { | 			} else { | ||||||
| 				if (flags[FLAG_UV1_USE_TRIPLANAR]) { | 				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 { | 				} 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 { | 		} 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 (features[FEATURE_SUBSURFACE_SCATTERING]) { | ||||||
| 		if (flags[FLAG_UV1_USE_TRIPLANAR]) { | 		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 { | 		} 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 (features[FEATURE_SUBSURFACE_TRANSMITTANCE]) { | ||||||
| 		if (flags[FLAG_UV1_USE_TRIPLANAR]) { | 		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 { | 		} 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 += "	SSS_TRANSMITTANCE_DEPTH=transmittance_depth;\n"; | ||||||
| 		code += "\tSSS_TRANSMITTANCE_BOOST=transmittance_boost;\n"; | 		code += "	SSS_TRANSMITTANCE_BOOST=transmittance_boost;\n"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (features[FEATURE_BACKLIGHT]) { | 	if (features[FEATURE_BACKLIGHT]) { | ||||||
| 		if (flags[FLAG_UV1_USE_TRIPLANAR]) { | 		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 { | 		} 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]) { | 	if (features[FEATURE_DETAIL]) { | ||||||
|  | @ -1234,41 +1234,41 @@ void BaseMaterial3D::_update_shader() { | ||||||
| 
 | 
 | ||||||
| 		if (triplanar) { | 		if (triplanar) { | ||||||
| 			String tp_uv = detail_uv == DETAIL_UV_1 ? "uv1" : "uv2"; | 			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 += "	vec4 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_norm_tex = triplanar_texture(texture_detail_normal," + tp_uv + "_power_normal," + tp_uv + "_triplanar_pos);\n"; | ||||||
| 
 | 
 | ||||||
| 		} else { | 		} else { | ||||||
| 			String det_uv = detail_uv == DETAIL_UV_1 ? "base_uv" : "base_uv2"; | 			String det_uv = detail_uv == DETAIL_UV_1 ? "base_uv" : "base_uv2"; | ||||||
| 			code += "\tvec4 detail_tex = texture(texture_detail_albedo," + det_uv + ");\n"; | 			code += "	vec4 detail_tex = texture(texture_detail_albedo," + det_uv + ");\n"; | ||||||
| 			code += "\tvec4 detail_norm_tex = texture(texture_detail_normal," + det_uv + ");\n"; | 			code += "	vec4 detail_norm_tex = texture(texture_detail_normal," + det_uv + ");\n"; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (flags[FLAG_UV1_USE_TRIPLANAR]) { | 		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 { | 		} 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) { | 		switch (detail_blend_mode) { | ||||||
| 			case BLEND_MODE_MIX: { | 			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; | 			} break; | ||||||
| 			case BLEND_MODE_ADD: { | 			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; | 			} break; | ||||||
| 			case BLEND_MODE_SUB: { | 			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; | 			} break; | ||||||
| 			case BLEND_MODE_MUL: { | 			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; | 			} break; | ||||||
| 			case BLEND_MODE_MAX: | 			case BLEND_MODE_MAX: | ||||||
| 				break; // Internal value, skip.
 | 				break; // Internal value, skip.
 | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		code += "\tvec3 detail_norm = mix(NORMAL_MAP,detail_norm_tex.rgb,detail_tex.a);\n"; | 		code += "	vec3 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 += "	NORMAL_MAP = mix(NORMAL_MAP,detail_norm,detail_mask_tex.r);\n"; | ||||||
| 		code += "\tALBEDO.rgb = mix(ALBEDO.rgb,detail,detail_mask_tex.r);\n"; | 		code += "	ALBEDO.rgb = mix(ALBEDO.rgb,detail,detail_mask_tex.r);\n"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	code += "}\n"; | 	code += "}\n"; | ||||||
|  |  | ||||||
|  | @ -181,68 +181,75 @@ void ProceduralSkyMaterial::_bind_methods() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ProceduralSkyMaterial::ProceduralSkyMaterial() { | 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(); | 	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); | 	RS::get_singleton()->material_set_shader(_get_material(), shader); | ||||||
| 
 | 
 | ||||||
|  | @ -298,16 +305,17 @@ void PanoramaSkyMaterial::_bind_methods() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PanoramaSkyMaterial::PanoramaSkyMaterial() { | 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(); | 	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); | 	RS::get_singleton()->material_set_shader(_get_material(), shader); | ||||||
| } | } | ||||||
|  | @ -484,102 +492,102 @@ void PhysicalSkyMaterial::_bind_methods() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PhysicalSkyMaterial::PhysicalSkyMaterial() { | 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(); | 	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); | 	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++) { | 	for (int i = 0; i < get_output_port_count(); i++) { | ||||||
| 		output_vars.push_back(p_output_vars[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); | 	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"); | 	bool nend = _code.ends_with("\n"); | ||||||
| 	_code = _code.insert(0, "\t\t"); | 	_code = _code.insert(0, "		"); | ||||||
| 	_code = _code.replace("\n", "\n\t\t"); | 	_code = _code.replace("\n", "\n		"); | ||||||
| 	code += _code; | 	code += _code; | ||||||
| 	if (!nend) { | 	if (!nend) { | ||||||
| 		code += "\n\t}"; | 		code += "\n	}"; | ||||||
| 	} else { | 	} else { | ||||||
| 		code.remove(code.size() - 1); | 		code.remove(code.size() - 1); | ||||||
| 		code += "}"; | 		code += "}"; | ||||||
|  | @ -900,7 +900,7 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port | ||||||
| 				String expr = ""; | 				String expr = ""; | ||||||
| 				expr += "// " + global_expression->get_caption() + ":" + itos(index++) + "\n"; | 				expr += "// " + global_expression->get_caption() + ":" + itos(index++) + "\n"; | ||||||
| 				expr += global_expression->generate_global(get_mode(), Type(i), -1); | 				expr += global_expression->generate_global(get_mode(), Type(i), -1); | ||||||
| 				expr = expr.replace("\n", "\n\t"); | 				expr = expr.replace("\n", "\n	"); | ||||||
| 				expr += "\n"; | 				expr += "\n"; | ||||||
| 				global_expressions += expr; | 				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()); | 	ERR_FAIL_COND_V(err != OK, String()); | ||||||
| 
 | 
 | ||||||
| 	if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_SCALAR) { | 	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) { | 	} 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) { | 	} 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 { | 	} 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"; | 	code += "}\n"; | ||||||
| 
 | 
 | ||||||
|  | @ -1302,7 +1302,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui | ||||||
| 
 | 
 | ||||||
| 	if (vsnode->is_disabled()) { | 	if (vsnode->is_disabled()) { | ||||||
| 		code += "// " + vsnode->get_caption() + ":" + itos(node) + "\n"; | 		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; | 		return OK; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -1432,19 +1432,19 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui | ||||||
| 			if (defval.get_type() == Variant::FLOAT) { | 			if (defval.get_type() == Variant::FLOAT) { | ||||||
| 				float val = defval; | 				float val = defval; | ||||||
| 				inputs[i] = "n_in" + itos(node) + "p" + itos(i); | 				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) { | 			} else if (defval.get_type() == Variant::INT) { | ||||||
| 				int val = defval; | 				int val = defval; | ||||||
| 				inputs[i] = "n_in" + itos(node) + "p" + itos(i); | 				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) { | 			} else if (defval.get_type() == Variant::BOOL) { | ||||||
| 				bool val = defval; | 				bool val = defval; | ||||||
| 				inputs[i] = "n_in" + itos(node) + "p" + itos(i); | 				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) { | 			} else if (defval.get_type() == Variant::VECTOR3) { | ||||||
| 				Vector3 val = defval; | 				Vector3 val = defval; | ||||||
| 				inputs[i] = "n_in" + itos(node) + "p" + itos(i); | 				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) { | 			} else if (defval.get_type() == Variant::TRANSFORM3D) { | ||||||
| 				Transform3D val = defval; | 				Transform3D val = defval; | ||||||
| 				val.basis.transpose(); | 				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.y); | ||||||
| 				values.push_back(val.origin.z); | 				values.push_back(val.origin.z); | ||||||
| 				bool err = false; | 				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 { | 			} else { | ||||||
| 				//will go empty, node is expected to know what it is doing at this point and handle it
 | 				//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); | 			outputs[i] = "n_out" + itos(node) + "p" + itos(j); | ||||||
| 			switch (vsnode->get_output_port_type(i)) { | 			switch (vsnode->get_output_port_type(i)) { | ||||||
| 				case VisualShaderNode::PORT_TYPE_SCALAR: | 				case VisualShaderNode::PORT_TYPE_SCALAR: | ||||||
| 					code += "\tfloat " + outputs[i] + ";\n"; | 					code += "	float " + outputs[i] + ";\n"; | ||||||
| 					break; | 					break; | ||||||
| 				case VisualShaderNode::PORT_TYPE_SCALAR_INT: | 				case VisualShaderNode::PORT_TYPE_SCALAR_INT: | ||||||
| 					code += "\tint " + outputs[i] + ";\n"; | 					code += "	int " + outputs[i] + ";\n"; | ||||||
| 					break; | 					break; | ||||||
| 				case VisualShaderNode::PORT_TYPE_VECTOR: | 				case VisualShaderNode::PORT_TYPE_VECTOR: | ||||||
| 					code += "\tvec3 " + outputs[i] + ";\n"; | 					code += "	vec3 " + outputs[i] + ";\n"; | ||||||
| 					break; | 					break; | ||||||
| 				case VisualShaderNode::PORT_TYPE_BOOLEAN: | 				case VisualShaderNode::PORT_TYPE_BOOLEAN: | ||||||
| 					code += "\tbool " + outputs[i] + ";\n"; | 					code += "	bool " + outputs[i] + ";\n"; | ||||||
| 					break; | 					break; | ||||||
| 				case VisualShaderNode::PORT_TYPE_TRANSFORM: | 				case VisualShaderNode::PORT_TYPE_TRANSFORM: | ||||||
| 					code += "\tmat4 " + outputs[i] + ";\n"; | 					code += "	mat4 " + outputs[i] + ";\n"; | ||||||
| 					break; | 					break; | ||||||
| 				default: { | 				default: { | ||||||
| 				} | 				} | ||||||
|  | @ -1564,7 +1564,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui | ||||||
| 						new_line_inserted = true; | 						new_line_inserted = true; | ||||||
| 					} | 					} | ||||||
| 					String r = "n_out" + itos(node) + "p" + itos(i + 1); | 					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; | 					outputs[i + 1] = r; | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
|  | @ -1574,7 +1574,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui | ||||||
| 						new_line_inserted = true; | 						new_line_inserted = true; | ||||||
| 					} | 					} | ||||||
| 					String g = "n_out" + itos(node) + "p" + itos(i + 2); | 					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; | 					outputs[i + 2] = g; | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
|  | @ -1584,7 +1584,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui | ||||||
| 						new_line_inserted = true; | 						new_line_inserted = true; | ||||||
| 					} | 					} | ||||||
| 					String b = "n_out" + itos(node) + "p" + itos(i + 3); | 					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; | 					outputs[i + 3] = b; | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
|  | @ -1701,7 +1701,7 @@ void VisualShader::_update_shader() const { | ||||||
| 				String expr = ""; | 				String expr = ""; | ||||||
| 				expr += "// " + global_expression->get_caption() + ":" + itos(index++) + "\n"; | 				expr += "// " + global_expression->get_caption() + ":" + itos(index++) + "\n"; | ||||||
| 				expr += global_expression->generate_global(get_mode(), Type(i), -1); | 				expr += global_expression->generate_global(get_mode(), Type(i), -1); | ||||||
| 				expr = expr.replace("\n", "\n\t"); | 				expr = expr.replace("\n", "\n	"); | ||||||
| 				expr += "\n"; | 				expr += "\n"; | ||||||
| 				global_expressions += expr; | 				global_expressions += expr; | ||||||
| 			} | 			} | ||||||
|  | @ -1814,112 +1814,112 @@ void VisualShader::_update_shader() const { | ||||||
| 
 | 
 | ||||||
| 		code += "void start() {\n"; | 		code += "void start() {\n"; | ||||||
| 		if (has_start || has_start_custom) { | 		if (has_start || has_start_custom) { | ||||||
| 			code += "\tuint __seed = __hash(NUMBER + uint(1) + RANDOM_SEED);\n"; | 			code += "	uint __seed = __hash(NUMBER + uint(1) + RANDOM_SEED);\n"; | ||||||
| 			code += "\tvec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz;\n"; | 			code += "	vec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz;\n"; | ||||||
| 			code += "\tfloat __radians;\n"; | 			code += "	float __radians;\n"; | ||||||
| 			code += "\tvec3 __vec3_buff1;\n"; | 			code += "	vec3 __vec3_buff1;\n"; | ||||||
| 			code += "\tvec3 __vec3_buff2;\n"; | 			code += "	vec3 __vec3_buff2;\n"; | ||||||
| 			code += "\tfloat __scalar_buff1;\n"; | 			code += "	float __scalar_buff1;\n"; | ||||||
| 			code += "\tfloat __scalar_buff2;\n"; | 			code += "	float __scalar_buff2;\n"; | ||||||
| 			code += "\tvec3 __ndiff = normalize(__diff);\n\n"; | 			code += "	vec3 __ndiff = normalize(__diff);\n\n"; | ||||||
| 		} | 		} | ||||||
| 		if (has_start) { | 		if (has_start) { | ||||||
| 			code += "\t{\n"; | 			code += "	{\n"; | ||||||
| 			code += code_map[TYPE_START].replace("\n\t", "\n\t\t"); | 			code += code_map[TYPE_START].replace("\n	", "\n		"); | ||||||
| 			code += "\t}\n"; | 			code += "	}\n"; | ||||||
| 			if (has_start_custom) { | 			if (has_start_custom) { | ||||||
| 				code += "\t\n"; | 				code += "	\n"; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		if (has_start_custom) { | 		if (has_start_custom) { | ||||||
| 			code += "\t{\n"; | 			code += "	{\n"; | ||||||
| 			code += code_map[TYPE_START_CUSTOM].replace("\n\t", "\n\t\t"); | 			code += code_map[TYPE_START_CUSTOM].replace("\n	", "\n		"); | ||||||
| 			code += "\t}\n"; | 			code += "	}\n"; | ||||||
| 		} | 		} | ||||||
| 		code += "}\n\n"; | 		code += "}\n\n"; | ||||||
| 		code += "void process() {\n"; | 		code += "void process() {\n"; | ||||||
| 		if (has_process || has_process_custom || has_collide) { | 		if (has_process || has_process_custom || has_collide) { | ||||||
| 			code += "\tuint __seed = __hash(NUMBER + uint(1) + RANDOM_SEED);\n"; | 			code += "	uint __seed = __hash(NUMBER + uint(1) + RANDOM_SEED);\n"; | ||||||
| 			code += "\tvec3 __vec3_buff1;\n"; | 			code += "	vec3 __vec3_buff1;\n"; | ||||||
| 			code += "\tvec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz;\n"; | 			code += "	vec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz;\n"; | ||||||
| 			code += "\tvec3 __ndiff = normalize(__diff);\n\n"; | 			code += "	vec3 __ndiff = normalize(__diff);\n\n"; | ||||||
| 		} | 		} | ||||||
| 		code += "\t{\n"; | 		code += "	{\n"; | ||||||
| 		String tab = "\t"; | 		String tab = "	"; | ||||||
| 		if (has_collide) { | 		if (has_collide) { | ||||||
| 			code += "\t\tif (COLLIDED) {\n\n"; | 			code += "		if (COLLIDED) {\n\n"; | ||||||
| 			code += code_map[TYPE_COLLIDE].replace("\n\t", "\n\t\t\t"); | 			code += code_map[TYPE_COLLIDE].replace("\n	", "\n			"); | ||||||
| 			if (has_process) { | 			if (has_process) { | ||||||
| 				code += "\t\t} else {\n\n"; | 				code += "		} else {\n\n"; | ||||||
| 				tab += "\t"; | 				tab += "	"; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		if (has_process) { | 		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) { | 		if (has_collide) { | ||||||
| 			code += "\t\t}\n"; | 			code += "		}\n"; | ||||||
| 		} | 		} | ||||||
| 		code += "\t}\n"; | 		code += "	}\n"; | ||||||
| 
 | 
 | ||||||
| 		if (has_process_custom) { | 		if (has_process_custom) { | ||||||
| 			code += "\t{\n\n"; | 			code += "	{\n\n"; | ||||||
| 			code += code_map[TYPE_PROCESS_CUSTOM].replace("\n\t", "\n\t\t"); | 			code += code_map[TYPE_PROCESS_CUSTOM].replace("\n	", "\n		"); | ||||||
| 			code += "\t}\n"; | 			code += "	}\n"; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		code += "}\n\n"; | 		code += "}\n\n"; | ||||||
| 
 | 
 | ||||||
| 		global_compute_code += "float __rand_from_seed(inout uint seed) {\n"; | 		global_compute_code += "float __rand_from_seed(inout uint seed) {\n"; | ||||||
| 		global_compute_code += "\tint k;\n"; | 		global_compute_code += "	int k;\n"; | ||||||
| 		global_compute_code += "\tint s = int(seed);\n"; | 		global_compute_code += "	int s = int(seed);\n"; | ||||||
| 		global_compute_code += "\tif (s == 0)\n"; | 		global_compute_code += "	if (s == 0)\n"; | ||||||
| 		global_compute_code += "\ts = 305420679;\n"; | 		global_compute_code += "	s = 305420679;\n"; | ||||||
| 		global_compute_code += "\tk = s / 127773;\n"; | 		global_compute_code += "	k = s / 127773;\n"; | ||||||
| 		global_compute_code += "\ts = 16807 * (s - k * 127773) - 2836 * k;\n"; | 		global_compute_code += "	s = 16807 * (s - k * 127773) - 2836 * k;\n"; | ||||||
| 		global_compute_code += "\tif (s < 0)\n"; | 		global_compute_code += "	if (s < 0)\n"; | ||||||
| 		global_compute_code += "\t\ts += 2147483647;\n"; | 		global_compute_code += "		s += 2147483647;\n"; | ||||||
| 		global_compute_code += "\tseed = uint(s);\n"; | 		global_compute_code += "	seed = uint(s);\n"; | ||||||
| 		global_compute_code += "\treturn float(seed % uint(65536)) / 65535.0;\n"; | 		global_compute_code += "	return float(seed % uint(65536)) / 65535.0;\n"; | ||||||
| 		global_compute_code += "}\n\n"; | 		global_compute_code += "}\n\n"; | ||||||
| 
 | 
 | ||||||
| 		global_compute_code += "float __rand_from_seed_m1_p1(inout uint seed) {\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 += "}\n\n"; | ||||||
| 
 | 
 | ||||||
| 		global_compute_code += "float __randf_range(inout uint seed, float from, float to) {\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 += "}\n\n"; | ||||||
| 
 | 
 | ||||||
| 		global_compute_code += "vec3 __randv_range(inout uint seed, vec3 from, vec3 to) {\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 += "}\n\n"; | ||||||
| 
 | 
 | ||||||
| 		global_compute_code += "uint __hash(uint x) {\n"; | 		global_compute_code += "uint __hash(uint x) {\n"; | ||||||
| 		global_compute_code += "\tx = ((x >> uint(16)) ^ x) * uint(73244475);\n"; | 		global_compute_code += "	x = ((x >> uint(16)) ^ x) * uint(73244475);\n"; | ||||||
| 		global_compute_code += "\tx = ((x >> uint(16)) ^ x) * uint(73244475);\n"; | 		global_compute_code += "	x = ((x >> uint(16)) ^ x) * uint(73244475);\n"; | ||||||
| 		global_compute_code += "\tx = (x >> uint(16)) ^ x;\n"; | 		global_compute_code += "	x = (x >> uint(16)) ^ x;\n"; | ||||||
| 		global_compute_code += "\treturn x;\n"; | 		global_compute_code += "	return x;\n"; | ||||||
| 		global_compute_code += "}\n\n"; | 		global_compute_code += "}\n\n"; | ||||||
| 
 | 
 | ||||||
| 		global_compute_code += "mat3 __build_rotation_mat3(vec3 axis, float angle) {\n"; | 		global_compute_code += "mat3 __build_rotation_mat3(vec3 axis, float angle) {\n"; | ||||||
| 		global_compute_code += "\taxis = normalize(axis);\n"; | 		global_compute_code += "	axis = normalize(axis);\n"; | ||||||
| 		global_compute_code += "\tfloat s = sin(angle);\n"; | 		global_compute_code += "	float s = sin(angle);\n"; | ||||||
| 		global_compute_code += "\tfloat c = cos(angle);\n"; | 		global_compute_code += "	float c = cos(angle);\n"; | ||||||
| 		global_compute_code += "\tfloat oc = 1.0 - c;\n"; | 		global_compute_code += "	float 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 += "	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 += "}\n\n"; | ||||||
| 
 | 
 | ||||||
| 		global_compute_code += "mat4 __build_rotation_mat4(vec3 axis, float angle) {\n"; | 		global_compute_code += "mat4 __build_rotation_mat4(vec3 axis, float angle) {\n"; | ||||||
| 		global_compute_code += "\taxis = normalize(axis);\n"; | 		global_compute_code += "	axis = normalize(axis);\n"; | ||||||
| 		global_compute_code += "\tfloat s = sin(angle);\n"; | 		global_compute_code += "	float s = sin(angle);\n"; | ||||||
| 		global_compute_code += "\tfloat c = cos(angle);\n"; | 		global_compute_code += "	float c = cos(angle);\n"; | ||||||
| 		global_compute_code += "\tfloat oc = 1.0 - c;\n"; | 		global_compute_code += "	float 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 += "	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 += "}\n\n"; | ||||||
| 
 | 
 | ||||||
| 		global_compute_code += "vec3 __get_random_unit_vec3(inout uint seed) {\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"; | 		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) { | 		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) { | 			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; | 				break; | ||||||
| 			} | 			} | ||||||
| 			idx++; | 			idx++; | ||||||
|  | @ -2389,19 +2389,19 @@ String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::T | ||||||
| 		if (code == String()) { | 		if (code == String()) { | ||||||
| 			switch (get_output_port_type(0)) { | 			switch (get_output_port_type(0)) { | ||||||
| 				case PORT_TYPE_SCALAR: { | 				case PORT_TYPE_SCALAR: { | ||||||
| 					code = "\t" + p_output_vars[0] + " = 0.0;\n"; | 					code = "	" + p_output_vars[0] + " = 0.0;\n"; | ||||||
| 				} break; | 				} break; | ||||||
| 				case PORT_TYPE_SCALAR_INT: { | 				case PORT_TYPE_SCALAR_INT: { | ||||||
| 					code = "\t" + p_output_vars[0] + " = 0;\n"; | 					code = "	" + p_output_vars[0] + " = 0;\n"; | ||||||
| 				} break; | 				} break; | ||||||
| 				case PORT_TYPE_VECTOR: { | 				case PORT_TYPE_VECTOR: { | ||||||
| 					code = "\t" + p_output_vars[0] + " = vec3(0.0);\n"; | 					code = "	" + p_output_vars[0] + " = vec3(0.0);\n"; | ||||||
| 				} break; | 				} break; | ||||||
| 				case PORT_TYPE_TRANSFORM: { | 				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; | 				} break; | ||||||
| 				case PORT_TYPE_BOOLEAN: { | 				case PORT_TYPE_BOOLEAN: { | ||||||
| 					code = "\t" + p_output_vars[0] + " = false;\n"; | 					code = "	" + p_output_vars[0] + " = false;\n"; | ||||||
| 				} break; | 				} break; | ||||||
| 				default: //default (none found) is scalar
 | 				default: //default (none found) is scalar
 | ||||||
| 					break; | 					break; | ||||||
|  | @ -2417,14 +2417,14 @@ String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::T | ||||||
| 
 | 
 | ||||||
| 		while (ports[idx].mode != Shader::MODE_MAX) { | 		while (ports[idx].mode != Shader::MODE_MAX) { | ||||||
| 			if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type && ports[idx].name == input_name) { | 			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; | 				break; | ||||||
| 			} | 			} | ||||||
| 			idx++; | 			idx++; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (code == String()) { | 		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; | 		return code; | ||||||
|  | @ -2748,20 +2748,20 @@ String VisualShaderNodeUniformRef::generate_code(Shader::Mode p_mode, VisualShad | ||||||
| 	switch (uniform_type) { | 	switch (uniform_type) { | ||||||
| 		case UniformType::UNIFORM_TYPE_FLOAT: | 		case UniformType::UNIFORM_TYPE_FLOAT: | ||||||
| 			if (uniform_name == "[None]") { | 			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: | 		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: | 		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: | 		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: | 		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: { | 		case UniformType::UNIFORM_TYPE_COLOR: { | ||||||
| 			String code = "\t" + p_output_vars[0] + " = " + get_uniform_name() + ".rgb;\n"; | 			String code = "	" + p_output_vars[0] + " = " + get_uniform_name() + ".rgb;\n"; | ||||||
| 			code += "\t" + p_output_vars[1] + " = " + get_uniform_name() + ".a;\n"; | 			code += "	" + p_output_vars[1] + " = " + get_uniform_name() + ".a;\n"; | ||||||
| 			return code; | 			return code; | ||||||
| 		} break; | 		} break; | ||||||
| 		case UniformType::UNIFORM_TYPE_SAMPLER: | 		case UniformType::UNIFORM_TYPE_SAMPLER: | ||||||
|  | @ -2957,9 +2957,9 @@ String VisualShaderNodeOutput::generate_code(Shader::Mode p_mode, VisualShader:: | ||||||
| 			if (p_input_vars[count] != String()) { | 			if (p_input_vars[count] != String()) { | ||||||
| 				String s = ports[idx].string; | 				String s = ports[idx].string; | ||||||
| 				if (s.find(":") != -1) { | 				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 { | 				} else { | ||||||
| 					code += "\t" + s + " = " + p_input_vars[count] + ";\n"; | 					code += "	" + s + " = " + p_input_vars[count] + ";\n"; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			count++; | 			count++; | ||||||
|  | @ -3634,11 +3634,11 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad | ||||||
| 	String _expression = expression; | 	String _expression = expression; | ||||||
| 
 | 
 | ||||||
| 	_expression = _expression.insert(0, "\n"); | 	_expression = _expression.insert(0, "\n"); | ||||||
| 	_expression = _expression.replace("\n", "\n\t\t"); | 	_expression = _expression.replace("\n", "\n		"); | ||||||
| 
 | 
 | ||||||
| 	static Vector<String> pre_symbols; | 	static Vector<String> pre_symbols; | ||||||
| 	if (pre_symbols.is_empty()) { | 	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(";"); | 		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; | 	static Vector<String> post_symbols; | ||||||
| 	if (post_symbols.is_empty()) { | 	if (post_symbols.is_empty()) { | ||||||
| 		post_symbols.push_back("\t"); | 		post_symbols.push_back("	"); | ||||||
| 		post_symbols.push_back("\n"); | 		post_symbols.push_back("\n"); | ||||||
| 		post_symbols.push_back(","); | 		post_symbols.push_back(","); | ||||||
| 		post_symbols.push_back(";"); | 		post_symbols.push_back(";"); | ||||||
|  | @ -3717,14 +3717,14 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad | ||||||
| 			default: | 			default: | ||||||
| 				continue; | 				continue; | ||||||
| 		} | 		} | ||||||
| 		output_initializer += "\t" + p_output_vars[i] + " = " + tk + ";\n"; | 		output_initializer += "	" + p_output_vars[i] + " = " + tk + ";\n"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	String code; | 	String code; | ||||||
| 	code += output_initializer; | 	code += output_initializer; | ||||||
| 	code += "\t{"; | 	code += "	{"; | ||||||
| 	code += _expression; | 	code += _expression; | ||||||
| 	code += "\n\t}\n"; | 	code += "\n	}\n"; | ||||||
| 
 | 
 | ||||||
| 	return code; | 	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 VisualShaderNodeParticleSphereEmitter::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { | ||||||
| 	String code; | 	String code; | ||||||
| 	code += "vec3 __get_random_point_in_sphere(inout uint seed, float radius, float inner_radius) {\n"; | 	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"; | 	code += "}\n\n"; | ||||||
| 	return code; | 	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 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; | 	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; | 	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 VisualShaderNodeParticleBoxEmitter::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { | ||||||
| 	String code; | 	String code; | ||||||
| 	code += "vec3 __get_random_point_in_box(inout uint seed, vec3 extents) {\n"; | 	code += "vec3 __get_random_point_in_box(inout uint seed, vec3 extents) {\n"; | ||||||
| 	code += "\tvec3 half_extents = extents / 2.0;\n"; | 	code += "	vec3 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 += "	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"; | 	code += "}\n\n"; | ||||||
| 	return code; | 	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 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; | 	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; | 	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 VisualShaderNodeParticleRingEmitter::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { | ||||||
| 	String code; | 	String code; | ||||||
| 	code += "vec3 __get_random_point_on_ring(inout uint seed, float radius, float inner_radius, float height) {\n"; | 	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 += "	float 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 += "	vec2 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 += "	return vec3(ring.x, __randf_range(seed, min(0.0, height), max(0.0, height)), ring.y);\n"; | ||||||
| 	code += "}\n\n"; | 	code += "}\n\n"; | ||||||
| 	return code; | 	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 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; | 	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; | 	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 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; | 	String code; | ||||||
| 	if (degrees_mode) { | 	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 { | 	} 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; | 	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 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; | 	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 += "	__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 += "	__scalar_buff1 = __rand_from_seed_m1_p1(__seed) * __radians;\n"; | ||||||
| 	code += "\t__scalar_buff2 = __rand_from_seed_m1_p1(__seed) * __radians;\n"; | 	code += "	__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 += "	__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 += "	__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 += "	__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 += "	__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 += "	__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 += "	__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 += "	" + p_output_vars[0] + " = normalize(vec3(__vec3_buff1.x * __vec3_buff2.z, __vec3_buff2.y, __vec3_buff1.z * __vec3_buff2.z));\n"; | ||||||
| 	return code; | 	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 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; | 	String code; | ||||||
| 	if (op_type == OP_TYPE_SCALAR) { | 	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) { | 	} 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; | 	return code; | ||||||
| } | } | ||||||
|  | @ -491,14 +491,14 @@ String VisualShaderNodeParticleAccelerator::generate_code(Shader::Mode p_mode, V | ||||||
| 	String code; | 	String code; | ||||||
| 	switch (mode) { | 	switch (mode) { | ||||||
| 		case MODE_LINEAR: | 		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; | 			break; | ||||||
| 		case MODE_RADIAL: | 		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; | 			break; | ||||||
| 		case MODE_TANGENTIAL: | 		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 += "	__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 += "	" + 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; | 			break; | ||||||
| 		case MODE_MAX: | 		case MODE_MAX: | ||||||
| 			break; | 			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 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 code; | ||||||
| 	String tab = "\t"; | 	String tab = "	"; | ||||||
| 
 | 
 | ||||||
| 	if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) { | 	if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) { | ||||||
| 		if (!p_input_vars[0].is_empty()) { // custom.rgb
 | 		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)
 | 		if (!p_input_vars[0].is_empty()) { // active (begin)
 | ||||||
| 			code += tab + "ACTIVE = " + p_input_vars[0] + ";\n"; | 			code += tab + "ACTIVE = " + p_input_vars[0] + ";\n"; | ||||||
| 			code += tab + "if(ACTIVE) {\n"; | 			code += tab + "if(ACTIVE) {\n"; | ||||||
| 			tab += "\t"; | 			tab += "	"; | ||||||
| 		} | 		} | ||||||
| 		if (!p_input_vars[1].is_empty()) { // velocity
 | 		if (!p_input_vars[1].is_empty()) { // velocity
 | ||||||
| 			code += tab + "VELOCITY = " + p_input_vars[1] + ";\n"; | 			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) { | 		if (shader_type == VisualShader::TYPE_START) { | ||||||
| 			code += tab + "if (RESTART_POSITION) {\n"; | 			code += tab + "if (RESTART_POSITION) {\n"; | ||||||
| 			if (!p_input_vars[4].is_empty()) { | 			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 { | 			} 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 + "	if (RESTART_VELOCITY) {\n"; | ||||||
| 			code += tab + "\t\tVELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n"; | 			code += tab + "		VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n"; | ||||||
| 			code += tab + "\t}\n"; | 			code += tab + "	}\n"; | ||||||
| 			code += tab + "\tTRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n"; | 			code += tab + "	TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n"; | ||||||
| 			code += tab + "}\n"; | 			code += tab + "}\n"; | ||||||
| 		} else if (shader_type == VisualShader::TYPE_COLLIDE) { // position
 | 		} else if (shader_type == VisualShader::TYPE_COLLIDE) { // position
 | ||||||
| 			if (!p_input_vars[4].is_empty()) { | 			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)
 | 		if (!p_input_vars[0].is_empty()) { // active (end)
 | ||||||
| 			code += "\t}\n"; | 			code += "	}\n"; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return code; | 	return code; | ||||||
|  | @ -926,12 +926,12 @@ String VisualShaderNodeParticleEmit::generate_code(Shader::Mode p_mode, VisualSh | ||||||
| 	if (!is_input_port_connected(0)) { | 	if (!is_input_port_connected(0)) { | ||||||
| 		default_condition = true; | 		default_condition = true; | ||||||
| 		if (get_input_port_default_value(0)) { | 		if (get_input_port_default_value(0)) { | ||||||
| 			tab = "\t"; | 			tab = "	"; | ||||||
| 		} else { | 		} else { | ||||||
| 			return code; | 			return code; | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		tab = "\t\t"; | 		tab = "		"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	String transform; | 	String transform; | ||||||
|  | @ -1008,13 +1008,13 @@ String VisualShaderNodeParticleEmit::generate_code(Shader::Mode p_mode, VisualSh | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (!default_condition) { | 	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"; | 	code += tab + "emit_subparticle(" + transform + ", " + velocity + ", vec4(" + color + ", " + alpha + "), vec4(" + custom + ", " + custom_alpha + "), " + flags + ");\n"; | ||||||
| 
 | 
 | ||||||
| 	if (!default_condition) { | 	if (!default_condition) { | ||||||
| 		code += "\t}\n"; | 		code += "	}\n"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return code; | 	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 { | 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() { | 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 { | 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() { | 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 { | 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() { | 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 { | 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() { | 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 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; | 	String code; | ||||||
| 
 | 
 | ||||||
| 	code += "\t{\n"; | 	code += "		{\n"; | ||||||
| 
 | 
 | ||||||
| 	if (p_input_vars[0] == String()) { | 	if (p_input_vars[0] == String()) { | ||||||
| 		code += "\t\tvec2 __from_pos = vec2(0.0f);\n"; | 		code += "				vec2 __from_pos = vec2(0.0f);\n"; | ||||||
| 	} else { | 	} 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()) { | 	if (p_input_vars[1] == String()) { | ||||||
| 		code += "\t\tvec2 __to_pos = vec2(0.0f);\n"; | 		code += "				vec2 __to_pos = vec2(0.0f);\n"; | ||||||
| 	} else { | 	} 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 += "\n				vec2 __at = __from_pos;\n"; | ||||||
| 	code += "\t\tfloat __max_dist = distance(__from_pos, __to_pos);\n"; | 	code += "				float __max_dist = distance(__from_pos, __to_pos);\n"; | ||||||
| 	code += "\t\tvec2 __dir = normalize(__to_pos - __from_pos);\n\n"; | 	code += "				vec2 __dir = normalize(__to_pos - __from_pos);\n\n"; | ||||||
| 
 | 
 | ||||||
| 	code += "\t\tfloat __accum = 0.0f;\n"; | 	code += "				float __accum = 0.0f;\n"; | ||||||
| 	code += "\t\twhile(__accum < __max_dist) {\n"; | 	code += "				while(__accum < __max_dist) {\n"; | ||||||
| 	code += "\t\t\tfloat __d = texture_sdf(__at);\n"; | 	code += "						float __d = texture_sdf(__at);\n"; | ||||||
| 	code += "\t\t\t__accum += __d;\n"; | 	code += "						__accum += __d;\n"; | ||||||
| 	code += "\t\t\tif (__d < 0.01f) {\n"; | 	code += "						if (__d < 0.01f) {\n"; | ||||||
| 	code += "\t\t\t\tbreak;\n"; | 	code += "								break;\n"; | ||||||
| 	code += "\t\t\t}\n"; | 	code += "						}\n"; | ||||||
| 	code += "\t\t\t__at += __d * __dir;\n"; | 	code += "						__at += __d * __dir;\n"; | ||||||
| 	code += "\t\t}\n"; | 	code += "				}\n"; | ||||||
| 
 | 
 | ||||||
| 	code += "\t\tfloat __dist = min(__max_dist, __accum);\n"; | 	code += "				float __dist = min(__max_dist, __accum);\n"; | ||||||
| 	code += "\t\t" + p_output_vars[0] + " = __dist;\n"; | 	code += "				" + p_output_vars[0] + " = __dist;\n"; | ||||||
| 	code += "\t\t" + p_output_vars[1] + " = __accum < __max_dist;\n"; | 	code += "				" + p_output_vars[1] + " = __accum < __max_dist;\n"; | ||||||
| 	code += "\t\t" + p_output_vars[2] + " = vec3(__from_pos + __dir * __dist, 0.0f);\n"; | 	code += "				" + p_output_vars[2] + " = vec3(__from_pos + __dir * __dist, 0.0f);\n"; | ||||||
| 
 | 
 | ||||||
| 	code += "\t}\n"; | 	code += "		}\n"; | ||||||
| 
 | 
 | ||||||
| 	return code; | 	return code; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -681,7 +681,19 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin | ||||||
| 		//default material and shader
 | 		//default material and shader
 | ||||||
| 		default_shader = storage->shader_allocate(); | 		default_shader = storage->shader_allocate(); | ||||||
| 		storage->shader_initialize(default_shader); | 		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(); | 		default_material = storage->material_allocate(); | ||||||
| 		storage->material_initialize(default_material); | 		storage->material_initialize(default_material); | ||||||
| 		storage->material_set_shader(default_material, default_shader); | 		storage->material_set_shader(default_material, default_shader); | ||||||
|  | @ -698,7 +710,16 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin | ||||||
| 		overdraw_material_shader = storage->shader_allocate(); | 		overdraw_material_shader = storage->shader_allocate(); | ||||||
| 		storage->shader_initialize(overdraw_material_shader); | 		storage->shader_initialize(overdraw_material_shader); | ||||||
| 		// Use relatively low opacity so that more "layers" of overlapping objects can be distinguished.
 | 		// 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(); | 		overdraw_material = storage->material_allocate(); | ||||||
| 		storage->material_initialize(overdraw_material); | 		storage->material_initialize(overdraw_material); | ||||||
| 		storage->material_set_shader(overdraw_material, overdraw_material_shader); | 		storage->material_set_shader(overdraw_material, overdraw_material_shader); | ||||||
|  |  | ||||||
|  | @ -671,7 +671,19 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p | ||||||
| 		//default material and shader
 | 		//default material and shader
 | ||||||
| 		default_shader = storage->shader_allocate(); | 		default_shader = storage->shader_allocate(); | ||||||
| 		storage->shader_initialize(default_shader); | 		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(); | 		default_material = storage->material_allocate(); | ||||||
| 		storage->material_initialize(default_material); | 		storage->material_initialize(default_material); | ||||||
| 		storage->material_set_shader(default_material, default_shader); | 		storage->material_set_shader(default_material, default_shader); | ||||||
|  | @ -687,7 +699,16 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p | ||||||
| 		overdraw_material_shader = storage->shader_allocate(); | 		overdraw_material_shader = storage->shader_allocate(); | ||||||
| 		storage->shader_initialize(overdraw_material_shader); | 		storage->shader_initialize(overdraw_material_shader); | ||||||
| 		// Use relatively low opacity so that more "layers" of overlapping objects can be distinguished.
 | 		// 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(); | 		overdraw_material = storage->material_allocate(); | ||||||
| 		storage->material_initialize(overdraw_material); | 		storage->material_initialize(overdraw_material); | ||||||
| 		storage->material_set_shader(overdraw_material, overdraw_material_shader); | 		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(); | 		default_canvas_group_shader = storage->shader_allocate(); | ||||||
| 		storage->shader_initialize(default_canvas_group_shader); | 		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(); | 		default_canvas_group_material = storage->material_allocate(); | ||||||
| 		storage->material_initialize(default_canvas_group_material); | 		storage->material_initialize(default_canvas_group_material); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -757,7 +757,13 @@ void RendererSceneSkyRD::init(RendererStorageRD *p_storage) { | ||||||
| 		sky_shader.default_shader = storage->shader_allocate(); | 		sky_shader.default_shader = storage->shader_allocate(); | ||||||
| 		storage->shader_initialize(sky_shader.default_shader); | 		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(); | 		sky_shader.default_material = storage->material_allocate(); | ||||||
| 		storage->material_initialize(sky_shader.default_material); | 		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(); | 		sky_scene_state.fog_shader = storage->shader_allocate(); | ||||||
| 		storage->shader_initialize(sky_scene_state.fog_shader); | 		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(); | 		sky_scene_state.fog_material = storage->material_allocate(); | ||||||
| 		storage->material_initialize(sky_scene_state.fog_material); | 		storage->material_initialize(sky_scene_state.fog_material); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -9388,7 +9388,13 @@ RendererStorageRD::RendererStorageRD() { | ||||||
| 		// default material and shader for particles shader
 | 		// default material and shader for particles shader
 | ||||||
| 		particles_shader.default_shader = shader_allocate(); | 		particles_shader.default_shader = shader_allocate(); | ||||||
| 		shader_initialize(particles_shader.default_shader); | 		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(); | 		particles_shader.default_material = material_allocate(); | ||||||
| 		material_initialize(particles_shader.default_material); | 		material_initialize(particles_shader.default_material); | ||||||
| 		material_set_shader(particles_shader.default_material, particles_shader.default_shader); | 		material_set_shader(particles_shader.default_material, particles_shader.default_shader); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Hugo Locurcio
						Hugo Locurcio