Browse Source

PBR more or less working, still working on bringing gizmos back

Juan Linietsky 9 years ago
parent
commit
53d8f2b1ec
45 changed files with 3019 additions and 586 deletions
  1. 2 2
      doc/base/classes.xml
  2. 647 61
      drivers/gles3/rasterizer_scene_gles3.cpp
  3. 121 17
      drivers/gles3/rasterizer_scene_gles3.h
  4. 187 39
      drivers/gles3/rasterizer_storage_gles3.cpp
  5. 18 8
      drivers/gles3/rasterizer_storage_gles3.h
  6. 77 4
      drivers/gles3/shader_compiler_gles3.cpp
  7. 1 0
      drivers/gles3/shader_gles3.cpp
  8. 1 0
      drivers/gles3/shader_gles3.h
  9. 49 10
      drivers/gles3/shaders/cubemap_filter.glsl
  10. 241 41
      drivers/gles3/shaders/scene.glsl
  11. 2 2
      modules/gridmap/grid_map.cpp
  12. 8 8
      platform/iphone/rasterizer_iphone.cpp
  13. 10 10
      platform/iphone/rasterizer_iphone.h
  14. 146 10
      scene/3d/light.cpp
  15. 40 1
      scene/3d/light.h
  16. 5 5
      scene/3d/particles.cpp
  17. 37 15
      scene/main/scene_main_loop.cpp
  18. 12 0
      scene/main/scene_main_loop.h
  19. 1 1
      scene/main/viewport.cpp
  20. 8 3
      scene/register_scene_types.cpp
  21. 14 13
      scene/resources/environment.cpp
  22. 3 3
      scene/resources/environment.h
  23. 751 3
      scene/resources/material.cpp
  24. 286 5
      scene/resources/material.h
  25. 49 49
      servers/visual/rasterizer.cpp
  26. 31 29
      servers/visual/rasterizer.h
  27. 17 25
      servers/visual/shader_language.cpp
  28. 8 8
      servers/visual/shader_types.cpp
  29. 10 10
      servers/visual/visual_server_raster.cpp
  30. 2 2
      servers/visual/visual_server_raster.h
  31. 56 7
      servers/visual/visual_server_scene.cpp
  32. 0 7
      servers/visual_server.cpp
  33. 7 12
      servers/visual_server.h
  34. 13 13
      tools/editor/io_plugins/editor_import_collada.cpp
  35. 15 15
      tools/editor/io_plugins/editor_scene_import_plugin.cpp
  36. 12 12
      tools/editor/io_plugins/editor_scene_importer_fbxconv.cpp
  37. 5 5
      tools/editor/plugins/baked_light_baker.cpp
  38. 10 10
      tools/editor/plugins/collision_polygon_editor_plugin.cpp
  39. 2 2
      tools/editor/plugins/collision_polygon_editor_plugin.h
  40. 6 6
      tools/editor/plugins/path_editor_plugin.cpp
  41. 2 2
      tools/editor/plugins/path_editor_plugin.h
  42. 26 30
      tools/editor/plugins/spatial_editor_plugin.cpp
  43. 4 4
      tools/editor/plugins/spatial_editor_plugin.h
  44. 49 49
      tools/editor/spatial_editor_gizmos.cpp
  45. 28 28
      tools/editor/spatial_editor_gizmos.h

+ 2 - 2
doc/base/classes.xml

@@ -13434,12 +13434,12 @@
 		</theme_item>
 	</theme_items>
 </class>
-<class name="FixedMaterial" inherits="Material" category="Core">
+<class name="FixedSpatialMaterial" inherits="Material" category="Core">
 	<brief_description>
 		Simple Material with a fixed parameter set.
 	</brief_description>
 	<description>
-		FixedMaterial is a simple type of material [Resource], which contains a fixed amount of parameters. It is the only type of material supported in fixed-pipeline devices and APIs. It is also an often a better alternative to [ShaderMaterial] for most simple use cases.
+		FixedSpatialMaterial is a simple type of material [Resource], which contains a fixed amount of parameters. It is the only type of material supported in fixed-pipeline devices and APIs. It is also an often a better alternative to [ShaderMaterial] for most simple use cases.
 	</description>
 	<methods>
 		<method name="get_fixed_flag" qualifiers="const">

File diff suppressed because it is too large
+ 647 - 61
drivers/gles3/rasterizer_scene_gles3.cpp


+ 121 - 17
drivers/gles3/rasterizer_scene_gles3.h

@@ -32,12 +32,28 @@ public:
 			float camera_inverse_matrix[16];
 			float camera_matrix[16];
 			float time[4];
-			float ambient_light[4];
+			float ambient_light_color[4];
+			float bg_color[4];
+			float ambient_energy;
+			float bg_energy;
 
 		} ubo_data;
 
 		GLuint scene_ubo;
 
+		struct EnvironmentRadianceUBO {
+
+			float transform[16];
+			float box_min[4]; //unused for now
+			float box_max[4];
+			float ambient_contribution;
+
+		} env_radiance_data;
+
+		GLuint env_radiance_ubo;
+
+		GLuint brdf_texture;
+
 		GLuint skybox_verts;
 		GLuint skybox_array;
 
@@ -54,16 +70,15 @@ public:
 
 		RID skybox_color;
 		RID skybox_radiance;
-		RID skybox_irradiance;
 		float skybox_scale;
 
 		Color bg_color;
-		float energy;
+		float bg_energy;
 		float skybox_ambient;
 
 		Color ambient_color;
-		float ambient_anergy;
-		float ambient_skybox_energy;
+		float ambient_energy;
+		float ambient_skybox_contribution;
 
 		int canvas_max_layer;
 
@@ -71,10 +86,10 @@ public:
 		Environment() {
 			bg_mode=VS::ENV_BG_CLEAR_COLOR;
 			skybox_scale=1.0;
-			energy=1.0;
+			bg_energy=1.0;
 			skybox_ambient=0;
-			ambient_anergy=1.0;
-			ambient_skybox_energy=0.0;
+			ambient_energy=1.0;
+			ambient_skybox_contribution=0.0;
 			canvas_max_layer=0;
 		}
 	};
@@ -84,12 +99,12 @@ public:
 	virtual RID environment_create();
 
 	virtual void environment_set_background(RID p_env,VS::EnvironmentBG p_bg);
-	virtual void environment_set_skybox(RID p_env,RID p_skybox,int p_radiance_size,int p_irradiance_size);
+	virtual void environment_set_skybox(RID p_env,RID p_skybox,int p_radiance_size);
 	virtual void environment_set_skybox_scale(RID p_env,float p_scale);
 	virtual void environment_set_bg_color(RID p_env,const Color& p_color);
 	virtual void environment_set_bg_energy(RID p_env,float p_energy);
 	virtual void environment_set_canvas_max_layer(RID p_env,int p_max_layer);
-	virtual void environment_set_ambient_light(RID p_env,const Color& p_color,float p_energy=1.0,float p_skybox_energy=0.0);
+	virtual void environment_set_ambient_light(RID p_env,const Color& p_color,float p_energy=1.0,float p_skybox_contribution=0.0);
 
 	virtual void environment_set_glow(RID p_env,bool p_enable,int p_radius,float p_intensity,float p_strength,float p_bloom_treshold,VS::EnvironmentGlowBlendMode p_blend_mode);
 	virtual void environment_set_fog(RID p_env,bool p_enable,float p_begin,float p_end,RID p_gradient_texture);
@@ -100,19 +115,81 @@ public:
 	virtual void environment_set_saturation(RID p_env,bool p_enable,float p_saturation);
 	virtual void environment_set_color_correction(RID p_env,bool p_enable,RID p_ramp);
 
+
+	/* LIGHT INSTANCE */
+
+	struct LightInstance : public RID_Data {
+
+		struct SplitInfo {
+
+			CameraMatrix camera;
+			Transform transform;
+			float near;
+			float far;
+		};
+
+		struct LightDataUBO {
+
+			float light_pos_inv_radius[4];
+			float light_direction_attenuation[4];
+			float light_color_energy[4];
+			float light_params[4]; //cone attenuation, specular, shadow darkening,
+			float shadow_split_offsets[4];
+			float shadow_matrix1[16];
+			float shadow_matrix2[16];
+			float shadow_matrix3[16];
+			float shadow_matrix4[16];
+
+		} light_ubo_data;
+
+
+		SplitInfo split_info[4];
+
+		RID light;
+		RasterizerStorageGLES3::Light *light_ptr;
+
+		CameraMatrix shadow_matrix[4];
+
+		Transform transform;
+
+		Vector3 light_vector;
+		Vector3 spot_vector;
+		float linear_att;
+
+		GLuint light_ubo;
+
+		uint64_t shadow_pass;
+		uint64_t last_pass;
+		uint16_t light_index;
+
+		Vector2 dp;
+
+		CameraMatrix shadow_projection[4];
+
+
+		LightInstance() { }
+
+	};
+
+	mutable RID_Owner<LightInstance> light_instance_owner;
+
+	virtual RID light_instance_create(RID p_light);
+	virtual void light_instance_set_transform(RID p_light_instance,const Transform& p_transform);
+
 	/* RENDER LIST */
 
 	struct RenderList {
 
 		enum {
 			DEFAULT_MAX_ELEMENTS=65536,
-			MAX_LIGHTS=4,
 			SORT_FLAG_SKELETON=1,
 			SORT_FLAG_INSTANCING=2,
-
+			MAX_DIRECTIONAL_LIGHTS=16,
+			MAX_LIGHTS=4096,
 			SORT_KEY_DEPTH_LAYER_SHIFT=58,
 			SORT_KEY_LIGHT_TYPE_SHIFT=54, //type is most important
 			SORT_KEY_LIGHT_INDEX_SHIFT=38, //type is most important
+			SORT_KEY_LIGHT_INDEX_UNSHADED=uint64_t(0xF) << SORT_KEY_LIGHT_TYPE_SHIFT, //type is most important
 			SORT_KEY_MATERIAL_INDEX_SHIFT=22,
 			SORT_KEY_GEOMETRY_INDEX_SHIFT=6,
 			SORT_KEY_GEOMETRY_TYPE_SHIFT=2,
@@ -161,7 +238,24 @@ public:
 
 			SortArray<Element*,SortByKey> sorter;
 			if (p_alpha) {
-				sorter.sort(&elements[max_elements-alpha_element_count-1],alpha_element_count);
+				sorter.sort(&elements[max_elements-alpha_element_count],alpha_element_count);
+			} else {
+				sorter.sort(elements,element_count);
+			}
+		}
+
+		struct SortByDepth {
+
+			_FORCE_INLINE_ bool operator()(const Element* A,  const Element* B ) const {
+				return A->instance->depth > B->instance->depth;
+			}
+		};
+
+		void sort_by_depth(bool p_alpha) {
+
+			SortArray<Element*,SortByDepth> sorter;
+			if (p_alpha) {
+				sorter.sort(&elements[max_elements-alpha_element_count],alpha_element_count);
 			} else {
 				sorter.sort(elements,element_count);
 			}
@@ -197,6 +291,7 @@ public:
 
 		}
 
+
 		RenderList() {
 
 			max_elements=DEFAULT_MAX_ELEMENTS;
@@ -210,26 +305,35 @@ public:
 
 
 
+	LightInstance *directional_light_instances[RenderList::MAX_DIRECTIONAL_LIGHTS];
+	int directional_light_instance_count;
+
+	LightInstance *light_instances[RenderList::MAX_LIGHTS];
+	int light_instance_count;
+
 	RenderList render_list;
 
 	_FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES3::Material* p_material,bool p_alpha_pass);
 	_FORCE_INLINE_ void _setup_geometry(RenderList::Element *e);
 	_FORCE_INLINE_ void _render_geometry(RenderList::Element *e);
+	_FORCE_INLINE_ void _setup_light(LightInstance *p_light);
 
+	void _render_list(RenderList::Element **p_elements, int p_element_count, const Transform& p_view_transform, const CameraMatrix& p_projection, RasterizerStorageGLES3::Texture *p_base_env, bool p_reverse_cull, bool p_alpha_pass);
 
-	void _render_list(RenderList::Element **p_elements, int p_element_count, const Transform& p_view_transform, const CameraMatrix& p_projection, bool p_reverse_cull, bool p_alpha_pass);
-
-	virtual RID light_instance_create(RID p_light);
-	virtual void light_instance_set_transform(RID p_light_instance,const Transform& p_transform);
 
 	_FORCE_INLINE_ void _add_geometry(  RasterizerStorageGLES3::Geometry* p_geometry,  InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner,int p_material);
 
 	void _draw_skybox(RID p_skybox, CameraMatrix& p_projection, const Transform& p_transform, bool p_vflip, float p_scale);
 
+	void _setup_environment(Environment *env,CameraMatrix& p_cam_projection, const Transform& p_cam_transform);
+	void _setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform);
+
 	virtual void render_scene(const Transform& p_cam_transform,CameraMatrix& p_cam_projection,bool p_cam_ortogonal,InstanceBase** p_cull_result,int p_cull_count,RID* p_light_cull_result,int p_light_cull_count,RID* p_directional_lights,int p_directional_light_count,RID p_environment);
 
 	virtual bool free(RID p_rid);
 
+	void _generate_brdf();
+
 	void initialize();
 	void finalize();
 	RasterizerSceneGLES3();

+ 187 - 39
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -587,6 +587,7 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture,int p_width, int p_h
 	texture->height=p_height;
 	texture->format=p_format;
 	texture->flags=p_flags;
+	texture->stored_cube_sides=0;
 	texture->target = (p_flags & VS::TEXTURE_FLAG_CUBEMAP) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
 
 	_get_gl_image_and_format(Image(),texture->format,texture->flags,format,internal_format,type,compressed,srgb);
@@ -759,8 +760,9 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture,const Image& p_image
 
 	//printf("texture: %i x %i - size: %i - total: %i\n",texture->width,texture->height,tsize,_rinfo.texture_mem);
 
+	texture->stored_cube_sides|=(1<<p_cube_side);
 
-	if (texture->flags&VS::TEXTURE_FLAG_MIPMAPS && mipmaps==1 && !texture->ignore_mipmaps) {
+	if (texture->flags&VS::TEXTURE_FLAG_MIPMAPS && mipmaps==1 && !texture->ignore_mipmaps && (!(texture->flags&VS::TEXTURE_FLAG_CUBEMAP) || texture->stored_cube_sides==(1<<6)-1)) {
 		//generate mipmaps if they were requested and the image does not contain them
 		glGenerateMipmap(texture->target);
 	}
@@ -995,7 +997,7 @@ void RasterizerStorageGLES3::texture_set_shrink_all_x2_on_set_data(bool p_enable
 	config.shrink_textures_x2=p_enable;
 }
 
-RID RasterizerStorageGLES3::texture_create_pbr_cubemap(RID p_source,VS::PBRCubeMapMode p_mode,int p_resolution) const {
+RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source,int p_resolution) const {
 
 	Texture * texture = texture_owner.get(p_source);
 	ERR_FAIL_COND_V(!texture,RID());
@@ -1019,12 +1021,13 @@ RID RasterizerStorageGLES3::texture_create_pbr_cubemap(RID p_source,VS::PBRCubeM
 	glDisable(GL_BLEND);
 
 
-	glActiveTexture(GL_TEXTURE1);
+	glActiveTexture(GL_TEXTURE0);
 	glBindTexture(texture->target, texture->tex_id);
 
-	glActiveTexture(GL_TEXTURE0);
+	glActiveTexture(GL_TEXTURE1);
 	GLuint new_cubemap;
 	glGenTextures(1, &new_cubemap);
+	glBindTexture(GL_TEXTURE_CUBE_MAP, new_cubemap);
 
 
 	GLuint tmp_fb;
@@ -1033,8 +1036,7 @@ RID RasterizerStorageGLES3::texture_create_pbr_cubemap(RID p_source,VS::PBRCubeM
 	glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb);
 
 
-	int w = texture->width;
-	int h = texture->height;
+	int size = p_resolution;
 
 	int lod=0;
 
@@ -1044,19 +1046,42 @@ RID RasterizerStorageGLES3::texture_create_pbr_cubemap(RID p_source,VS::PBRCubeM
 
 	int mm_level=mipmaps;
 
+	GLenum internal_format = use_float?GL_RGBA16F:GL_RGB10_A2;
+	GLenum format = GL_RGBA;
+	GLenum type = use_float?GL_HALF_FLOAT:GL_UNSIGNED_INT_2_10_10_10_REV;
+
+
+	while(mm_level) {
+
+		for(int i=0;i<6;i++) {
+			glTexImage2D(_cube_side_enum[i], lod, internal_format,  size, size, 0, format, type, NULL);
+		}
+
+		lod++;
+		mm_level--;
+
+		if (size>1)
+			size>>=1;
+	}
+
+	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
+	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, lod-1);
+
+	lod=0;
+	mm_level=mipmaps;
+
+	size = p_resolution;
+
 	while(mm_level) {
 
 		for(int i=0;i<6;i++) {
-			glTexImage2D(_cube_side_enum[i], lod, use_float?GL_RGBA16F:GL_RGB10_A2,  w, h, 0, GL_RGBA, use_float?GL_HALF_FLOAT:GL_UNSIGNED_INT_2_10_10_10_REV, NULL);
-			glTexParameteri(_cube_side_enum[i], GL_TEXTURE_BASE_LEVEL, lod);
-			glTexParameteri(_cube_side_enum[i], GL_TEXTURE_MAX_LEVEL, lod);
-			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], new_cubemap, 0);
+			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], new_cubemap, lod);
 
-			glViewport(0,0,w,h);
+			glViewport(0,0,size,size);
 			glBindVertexArray(resources.quadie_array);
 
 			shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::FACE_ID,i);
-			shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::ROUGHNESS,lod/float(mipmaps));
+			shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::ROUGHNESS,lod/float(mipmaps-1));
 
 
 			glDrawArrays(GL_TRIANGLE_FAN,0,4);
@@ -1069,29 +1094,51 @@ RID RasterizerStorageGLES3::texture_create_pbr_cubemap(RID p_source,VS::PBRCubeM
 
 
 
-		if (w>1)
-			w>>=1;
-		if (h>1)
-			h>>=1;
-
+		if (size>1)
+			size>>=1;
 		lod++;
 		mm_level--;
 
 	}
 
 
-	for(int i=0;i<6;i++) {
-		//restore ranges
-		glTexParameteri(_cube_side_enum[i], GL_TEXTURE_BASE_LEVEL, 0);
-		glTexParameteri(_cube_side_enum[i], GL_TEXTURE_MAX_LEVEL, lod);
+	//restore ranges
+	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
+	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, lod-1);
 
-	}
+	glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+	glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+	glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+	glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+	glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
 
 	glBindFramebuffer(GL_FRAMEBUFFER, config.system_fbo);
 	glDeleteFramebuffers(1, &tmp_fb);
 
-
-	return RID();
+	Texture * ctex = memnew( Texture );
+
+	ctex->flags=VS::TEXTURE_FLAG_CUBEMAP|VS::TEXTURE_FLAG_MIPMAPS|VS::TEXTURE_FLAG_FILTER;
+	ctex->width=p_resolution;
+	ctex->height=p_resolution;
+	ctex->alloc_width=p_resolution;
+	ctex->alloc_height=p_resolution;
+	ctex->format=use_float?Image::FORMAT_RGBAH:Image::FORMAT_RGBA8;
+	ctex->target=GL_TEXTURE_CUBE_MAP;
+	ctex->gl_format_cache=format;
+	ctex->gl_internal_format_cache=internal_format;
+	ctex->gl_type_cache=type;
+	ctex->data_size=0;
+	ctex->compressed=false;
+	ctex->srgb=false;
+	ctex->total_data_size=0;
+	ctex->ignore_mipmaps=false;
+	ctex->mipmaps=mipmaps;
+	ctex->active=true;
+	ctex->tex_id=new_cubemap;
+	ctex->stored_cube_sides=(1<<6)-1;
+	ctex->render_target=NULL;
+
+	return texture_owner.make_rid(ctex);
 }
 
 
@@ -1137,9 +1184,9 @@ void RasterizerStorageGLES3::shader_set_mode(RID p_shader,VS::ShaderMode p_mode)
 	shader->mode=p_mode;
 
 	ShaderGLES3* shaders[VS::SHADER_MAX]={
-		&canvas->state.canvas_shader,
 		&scene->state.scene_shader,
 		&canvas->state.canvas_shader,
+		&canvas->state.canvas_shader,
 
 	};
 
@@ -1231,10 +1278,14 @@ void RasterizerStorageGLES3::_update_shader(Shader* p_shader) const {
 			shaders.actions_scene.render_mode_values["cull_back"]=Pair<int*,int>(&p_shader->spatial.cull_mode,Shader::Spatial::CULL_MODE_BACK);
 			shaders.actions_scene.render_mode_values["cull_disable"]=Pair<int*,int>(&p_shader->spatial.cull_mode,Shader::Spatial::CULL_MODE_DISABLED);
 
-			shaders.actions_canvas.render_mode_flags["unshaded"]=&p_shader->spatial.unshaded;
-			shaders.actions_canvas.render_mode_flags["ontop"]=&p_shader->spatial.ontop;
+			shaders.actions_scene.render_mode_flags["unshaded"]=&p_shader->spatial.unshaded;
+			shaders.actions_scene.render_mode_flags["ontop"]=&p_shader->spatial.ontop;
+
+			shaders.actions_scene.usage_flag_pointers["ALPHA"]=&p_shader->spatial.uses_alpha;
+
+			actions=&shaders.actions_scene;
+			actions->uniforms=&p_shader->uniforms;
 
-			shaders.actions_canvas.usage_flag_pointers["ALPHA"]=&p_shader->spatial.uses_alpha;
 
 		}
 
@@ -1243,6 +1294,7 @@ void RasterizerStorageGLES3::_update_shader(Shader* p_shader) const {
 
 	Error err = shaders.compiler.compile(p_shader->mode,p_shader->code,actions,p_shader->path,gen_code);
 
+
 	ERR_FAIL_COND(err!=OK);
 
 	p_shader->shader->set_custom_shader_code(p_shader->custom_code_id,gen_code.vertex,gen_code.vertex_global,gen_code.fragment,gen_code.light,gen_code.fragment_global,gen_code.uniforms,gen_code.texture_uniforms,gen_code.defines);
@@ -1633,29 +1685,29 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
 
 				gui[0]=v.r;
 				gui[1]=v.g;
-				gui[3]=v.b;
-				gui[4]=v.a;
+				gui[2]=v.b;
+				gui[3]=v.a;
 			} else if (value.get_type()==Variant::RECT2) {
 				Rect2 v=value;
 
 				gui[0]=v.pos.x;
 				gui[1]=v.pos.y;
-				gui[3]=v.size.x;
-				gui[4]=v.size.y;
+				gui[2]=v.size.x;
+				gui[3]=v.size.y;
 			} else if (value.get_type()==Variant::QUAT) {
 				Quat v=value;
 
 				gui[0]=v.x;
 				gui[1]=v.y;
-				gui[3]=v.z;
-				gui[4]=v.w;
+				gui[2]=v.z;
+				gui[3]=v.w;
 			} else {
 				Plane v=value;
 
 				gui[0]=v.normal.x;
 				gui[1]=v.normal.y;
-				gui[3]=v.normal.x;
-				gui[4]=v.d;
+				gui[2]=v.normal.x;
+				gui[3]=v.d;
 
 			}
 		} break;
@@ -2307,8 +2359,6 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
 	if (p_format&VS::ARRAY_FORMAT_INDEX) {
 
 		index_array_size=attribs[VS::ARRAY_INDEX].stride*p_index_count;
-
-		print_line("index count: "+itos(p_index_count)+" stride: "+itos(attribs[VS::ARRAY_INDEX].stride) );
 	}
 
 
@@ -2882,55 +2932,134 @@ Matrix32 RasterizerStorageGLES3::skeleton_bone_get_transform_2d(RID p_skeleton,i
 
 RID RasterizerStorageGLES3::light_create(VS::LightType p_type){
 
-	return RID();
+	Light *light = memnew( Light );
+	light->type=p_type;
+
+	light->param[VS::LIGHT_PARAM_ENERGY]=1.0;
+	light->param[VS::LIGHT_PARAM_SPECULAR]=1.0;
+	light->param[VS::LIGHT_PARAM_RANGE]=1.0;
+	light->param[VS::LIGHT_PARAM_SPOT_ANGLE]=45;
+	light->param[VS::LIGHT_PARAM_SHADOW_MAX_DISTANCE]=0;
+	light->param[VS::LIGHT_PARAM_SHADOW_DARKNESS]=0;
+	light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET]=0.1;
+	light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET]=0.3;
+	light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET]=0.6;
+	light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_4_OFFSET]=1.0;
+	light->param[VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS]=0.1;
+	light->param[VS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE]=0.1;
+
+
+	light->color=Color(1,1,1,1);
+	light->shadow=false;
+	light->negative=false;
+	light->cull_mask=0xFFFFFFFF;
+	light->directional_shadow_mode=VS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL;
+
+	return light_owner.make_rid(light);
 }
 
 void RasterizerStorageGLES3::light_set_color(RID p_light,const Color& p_color){
 
+	Light * light = light_owner.getornull(p_light);
+	ERR_FAIL_COND(!light);
 
+	light->color=p_color;
 }
 void RasterizerStorageGLES3::light_set_param(RID p_light,VS::LightParam p_param,float p_value){
 
+	Light * light = light_owner.getornull(p_light);
+	ERR_FAIL_COND(!light);
+	ERR_FAIL_INDEX(p_param,VS::LIGHT_PARAM_MAX);
 
+	if (p_param==VS::LIGHT_PARAM_RANGE || p_param==VS::LIGHT_PARAM_SPOT_ANGLE) {
+		light->instance_change_notify();
+	}
+	light->param[p_param]=p_value;
 }
 void RasterizerStorageGLES3::light_set_shadow(RID p_light,bool p_enabled){
 
+	Light * light = light_owner.getornull(p_light);
+	ERR_FAIL_COND(!light);
+	light->shadow=p_enabled;
 
 }
 void RasterizerStorageGLES3::light_set_projector(RID p_light,RID p_texture){
 
+	Light * light = light_owner.getornull(p_light);
+	ERR_FAIL_COND(!light);
+
 
 }
 void RasterizerStorageGLES3::light_set_attenuation_texure(RID p_light,RID p_texture){
 
+	Light * light = light_owner.getornull(p_light);
+	ERR_FAIL_COND(!light);
+
 
 }
 void RasterizerStorageGLES3::light_set_negative(RID p_light,bool p_enable){
 
+	Light * light = light_owner.getornull(p_light);
+	ERR_FAIL_COND(!light);
 
+	light->negative=p_enable;
 }
 void RasterizerStorageGLES3::light_set_cull_mask(RID p_light,uint32_t p_mask){
 
+	Light * light = light_owner.getornull(p_light);
+	ERR_FAIL_COND(!light);
 
+	light->cull_mask=p_mask;
 }
 void RasterizerStorageGLES3::light_set_shader(RID p_light,RID p_shader){
 
+	Light * light = light_owner.getornull(p_light);
+	ERR_FAIL_COND(!light);
 
 }
 
 
 void RasterizerStorageGLES3::light_directional_set_shadow_mode(RID p_light,VS::LightDirectionalShadowMode p_mode){
 
+	Light * light = light_owner.getornull(p_light);
+	ERR_FAIL_COND(!light);
 
 }
 
 VS::LightType RasterizerStorageGLES3::light_get_type(RID p_light) const {
 
+	const Light * light = light_owner.getornull(p_light);
+	ERR_FAIL_COND_V(!light,VS::LIGHT_DIRECTIONAL);
+
 	return VS::LIGHT_DIRECTIONAL;
 }
 
 AABB RasterizerStorageGLES3::light_get_aabb(RID p_light) const {
 
+	const Light * light = light_owner.getornull(p_light);
+	ERR_FAIL_COND_V(!light,AABB());
+
+	switch( light->type ) {
+
+		case VS::LIGHT_SPOT: {
+
+			float len=light->param[VS::LIGHT_PARAM_RANGE];
+			float size=Math::tan(Math::deg2rad(light->param[VS::LIGHT_PARAM_SPOT_ANGLE]))*len;
+			return AABB( Vector3( -size,-size,-len ), Vector3( size*2, size*2, len ) );
+		} break;
+		case VS::LIGHT_OMNI: {
+
+			float r = light->param[VS::LIGHT_PARAM_RANGE];
+			return AABB( -Vector3(r,r,r), Vector3(r,r,r)*2 );
+		} break;
+		case VS::LIGHT_DIRECTIONAL: {
+
+			return AABB();
+		} break;
+		default: {}
+	}
+
+	ERR_FAIL_V( AABB() );
 	return AABB();
 }
 
@@ -3028,6 +3157,10 @@ void RasterizerStorageGLES3::instance_add_dependency(RID p_base,RasterizerScene:
 			inst = mesh_owner.getornull(p_base);
 			ERR_FAIL_COND(!inst);
 		} break;
+		case VS::INSTANCE_LIGHT: {
+			inst = light_owner.getornull(p_base);
+			ERR_FAIL_COND(!inst);
+		} break;
 		default: {
 			ERR_FAIL();
 		}
@@ -3046,6 +3179,10 @@ void RasterizerStorageGLES3::instance_remove_dependency(RID p_base,RasterizerSce
 			ERR_FAIL_COND(!inst);
 
 		} break;
+		case VS::INSTANCE_LIGHT: {
+			inst = light_owner.getornull(p_base);
+			ERR_FAIL_COND(!inst);
+		} break;
 		default: {
 			ERR_FAIL();
 		}
@@ -3542,6 +3679,9 @@ VS::InstanceType RasterizerStorageGLES3::get_base_type(RID p_rid) const {
 	if (mesh_owner.owns(p_rid)) {
 		return VS::INSTANCE_MESH;
 	}
+	if (light_owner.owns(p_rid)) {
+		return VS::INSTANCE_LIGHT;
+	}
 
 	return VS::INSTANCE_NONE;
 }
@@ -3617,6 +3757,14 @@ bool RasterizerStorageGLES3::free(RID p_rid){
 		mesh_owner.free(p_rid);
 		memdelete(mesh);
 
+	} else if (light_owner.owns(p_rid)) {
+
+		// delete the texture
+		Light *light = light_owner.get(p_rid);
+
+		light_owner.free(p_rid);
+		memdelete(light);
+
 	} else if (canvas_occluder_owner.owns(p_rid)) {
 
 

+ 18 - 8
drivers/gles3/rasterizer_storage_gles3.h

@@ -135,10 +135,13 @@ public:
 		bool active;
 		GLuint tex_id;
 
+		uint16_t stored_cube_sides;
+
 		RenderTarget *render_target;
 
 		Texture() {
 
+			stored_cube_sides=0;
 			ignore_mipmaps=false;
 			render_target=NULL;
 			flags=width=height=0;
@@ -184,7 +187,7 @@ public:
 
 	virtual void texture_debug_usage(List<VS::TextureInfo> *r_info);
 
-	virtual RID texture_create_pbr_cubemap(RID p_source,VS::PBRCubeMapMode p_mode,int p_resolution=-1) const;
+	virtual RID texture_create_radiance_cubemap(RID p_source,int p_resolution=-1) const;
 
 
 	/* SHADER API */
@@ -351,13 +354,6 @@ public:
 
 	struct Instantiable : public RID_Data {
 
-		enum Type {
-			GEOMETRY_INVALID,
-			GEOMETRY_SURFACE,
-			GEOMETRY_IMMEDIATE,
-			GEOMETRY_MULTISURFACE,
-		};
-
 		SelfList<RasterizerScene::InstanceBase>::List instance_list;
 
 		_FORCE_INLINE_ void instance_change_notify() {
@@ -582,6 +578,20 @@ public:
 
 	/* Light API */
 
+
+	struct Light : Instantiable {
+
+		VS::LightType type;
+		float param[VS::LIGHT_PARAM_MAX];
+		Color color;
+		bool shadow;
+		bool negative;
+		uint32_t cull_mask;
+		VS::LightDirectionalShadowMode directional_shadow_mode;
+	};
+
+	mutable RID_Owner<Light> light_owner;
+
 	virtual RID light_create(VS::LightType p_type);
 
 	virtual void light_set_color(RID p_light,const Color& p_color);

+ 77 - 4
drivers/gles3/shader_compiler_gles3.cpp

@@ -48,7 +48,7 @@ static int _get_datatype_size(SL::DataType p_type) {
 		case SL::TYPE_SAMPLERCUBE: return 16;
 	}
 
-
+	ERR_FAIL_V(0);
 }
 
 
@@ -195,7 +195,12 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
 
 			for(Map<StringName,SL::ShaderNode::Uniform>::Element *E=pnode->uniforms.front();E;E=E->next()) {
 
-				String ucode="uniform ";
+				String ucode;
+
+				if (SL::is_sampler_type(E->get().type)) {
+					ucode="uniform ";
+				}
+
 				ucode+=_prestr(E->get().precission);
 				ucode+=_typestr(E->get().type);
 				ucode+=" "+_mkid(E->key());
@@ -228,7 +233,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
 			for(int i=0;i<uniform_sizes.size();i++) {
 
 				if (i>0)
-					r_gen_code.uniform_offsets[i]=uniform_sizes[i]-1;
+					r_gen_code.uniform_offsets[i]=uniform_sizes[i-1];
 				else
 					r_gen_code.uniform_offsets[i]=0;
 			}
@@ -320,7 +325,11 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
 			SL::VariableNode *vnode=(SL::VariableNode*)p_node;
 
 			if (p_default_actions.usage_defines.has(vnode->name) && !used_name_defines.has(vnode->name)) {
-				r_gen_code.defines.push_back(p_default_actions.usage_defines[vnode->name].utf8());
+				String define = p_default_actions.usage_defines[vnode->name];
+				if (define.begins_with("@")) {
+					define = p_default_actions.usage_defines[define.substr(1,define.length())];
+				}
+				r_gen_code.defines.push_back(define.utf8());
 				used_name_defines.insert(vnode->name);
 			}
 
@@ -451,6 +460,14 @@ Error ShaderCompilerGLES3::compile(VS::ShaderMode p_mode, const String& p_code,
 	Error err = parser.compile(p_code,ShaderTypes::get_singleton()->get_functions(p_mode),ShaderTypes::get_singleton()->get_modes(p_mode));
 
 	if (err!=OK) {
+#if 1
+
+		Vector<String> shader = p_code.split("\n");
+		for(int i=0;i<shader.size();i++) {
+			print_line(itos(i)+" "+shader[i]);
+		}
+#endif
+
 		_err_print_error(NULL,p_path.utf8().get_data(),parser.get_error_line(),parser.get_error_text().utf8().get_data(),ERR_HANDLER_SHADER);
 		return err;
 	}
@@ -469,6 +486,7 @@ Error ShaderCompilerGLES3::compile(VS::ShaderMode p_mode, const String& p_code,
 
 	_dump_node_code(parser.get_shader(),1,r_gen_code,*p_actions,actions[p_mode]);
 
+
 	return OK;
 
 }
@@ -518,6 +536,61 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
 
 	actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_transform"]="#define SKIP_TRANSFORM_USED\n";
 
+	/** SPATIAL SHADER **/
+
+
+	actions[VS::SHADER_SPATIAL].renames["WORLD_MATRIX"]="world_transform";
+	actions[VS::SHADER_SPATIAL].renames["INV_CAMERA_MATRIX"]="camera_inverse_matrix";
+	actions[VS::SHADER_SPATIAL].renames["PROJECTION_MATRIX"]="projection_matrix";
+
+
+	actions[VS::SHADER_SPATIAL].renames["VERTEX"]="vertex.xyz";
+	actions[VS::SHADER_SPATIAL].renames["NORMAL"]="normal";
+	actions[VS::SHADER_SPATIAL].renames["TANGENT"]="tangent";
+	actions[VS::SHADER_SPATIAL].renames["BINORMAL"]="binormal";
+	actions[VS::SHADER_SPATIAL].renames["UV"]="uv_interp";
+	actions[VS::SHADER_SPATIAL].renames["UV2"]="uv2_interp";
+	actions[VS::SHADER_SPATIAL].renames["COLOR"]="color_interp";
+	actions[VS::SHADER_SPATIAL].renames["POINT_SIZE"]="gl_PointSize";
+	//actions[VS::SHADER_SPATIAL].renames["INSTANCE_ID"]=ShaderLanguage::TYPE_INT;
+
+	//builtins
+
+	actions[VS::SHADER_SPATIAL].renames["TIME"]="time";
+	//actions[VS::SHADER_SPATIAL].renames["VIEWPORT_SIZE"]=ShaderLanguage::TYPE_VEC2;
+
+	actions[VS::SHADER_SPATIAL].renames["FRAGCOORD"]="gl_FragCoord";
+	actions[VS::SHADER_SPATIAL].renames["FRONT_FACING"]="gl_FrotFacing";
+	actions[VS::SHADER_SPATIAL].renames["NORMALMAP"]="normalmap";
+	actions[VS::SHADER_SPATIAL].renames["NORMALMAP_DEPTH"]="normaldepth";
+	actions[VS::SHADER_SPATIAL].renames["ALBEDO"]="albedo";
+	actions[VS::SHADER_SPATIAL].renames["ALPHA"]="alpha";
+	actions[VS::SHADER_SPATIAL].renames["SPECULAR"]="specular";
+	actions[VS::SHADER_SPATIAL].renames["ROUGHNESS"]="roughness";
+	actions[VS::SHADER_SPATIAL].renames["EMISSION"]="emission";
+	actions[VS::SHADER_SPATIAL].renames["SPECIAL"]="special";
+	actions[VS::SHADER_SPATIAL].renames["DISCARD"]="_discard";
+//	actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"]=ShaderLanguage::TYPE_VEC2;
+	actions[VS::SHADER_SPATIAL].renames["POINT_COORD"]="gl_PointCoord";
+
+
+	actions[VS::SHADER_SPATIAL].usage_defines["TANGENT"]="#define ENABLE_TANGENT_INTERP\n";
+	actions[VS::SHADER_SPATIAL].usage_defines["BINORMAL"]="@TANGENT";
+	actions[VS::SHADER_SPATIAL].usage_defines["UV"]="#define ENABLE_UV_INTERP\n";
+	actions[VS::SHADER_SPATIAL].usage_defines["UV2"]="#define ENABLE_UV2_INTERP\n";
+	actions[VS::SHADER_SPATIAL].usage_defines["NORMALMAP"]="#define ENABLE_NORMALMAP\n";
+	actions[VS::SHADER_SPATIAL].usage_defines["NORMALMAP_DEPTH"]="@NORMALMAP";
+	actions[VS::SHADER_SPATIAL].usage_defines["COLOR"]="#define ENABLE_COLOR_INTERP\n";
+
+	actions[VS::SHADER_SPATIAL].render_mode_defines["skip_transform"]="#define SKIP_TRANSFORM_USED\n";
+
+
+
+
+
+
+
+
 	List<String> func_list;
 
 	ShaderLanguage::get_builtin_funcs(&func_list);

+ 1 - 0
drivers/gles3/shader_gles3.cpp

@@ -751,6 +751,7 @@ void ShaderGLES3::set_custom_shader_code(uint32_t p_code_id, const String& p_ver
 	ERR_FAIL_COND(!custom_code_map.has(p_code_id));
 	CustomCode *cc=&custom_code_map[p_code_id];
 
+
 	cc->vertex=p_vertex;
 	cc->vertex_globals=p_vertex_globals;
 	cc->fragment=p_fragment;

+ 1 - 0
drivers/gles3/shader_gles3.h

@@ -29,6 +29,7 @@
 #ifndef SHADER_GLES3_H
 #define SHADER_GLES3_H
 
+#include <stdio.h>
 
 #include "platform_config.h"
 #ifndef GLES3_INCLUDE_H

+ 49 - 10
drivers/gles3/shaders/cubemap_filter.glsl

@@ -16,19 +16,26 @@ void main() {
 [fragment]
 
 
-uniform samplerCube source_cube; //texunit:1
+precision highp float;
+precision highp int;
+
+
+uniform samplerCube source_cube; //texunit:0
 uniform int face_id;
 uniform float roughness;
 in highp vec2 uv_interp;
 
 
-layout(location = 0) vec4 frag_color;
+layout(location = 0) out vec4 frag_color;
+
+
+#define M_PI 3.14159265359
 
 
 vec3 texelCoordToVec(vec2 uv, int faceID)
 {
     mat3 faceUvVectors[6];
-
+/*
     // -x
     faceUvVectors[1][0] = vec3(0.0, 0.0, 1.0);  // u -> +z
     faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y
@@ -58,6 +65,37 @@ vec3 texelCoordToVec(vec2 uv, int faceID)
     faceUvVectors[4][0] = vec3(1.0, 0.0, 0.0);  // u -> +x
     faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y
     faceUvVectors[4][2] = vec3(0.0, 0.0, 1.0);  // +z face
+*/
+
+    // -x
+    faceUvVectors[0][0] = vec3(0.0, 0.0, 1.0);  // u -> +z
+    faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y
+    faceUvVectors[0][2] = vec3(-1.0, 0.0, 0.0); // -x face
+
+    // +x
+    faceUvVectors[1][0] = vec3(0.0, 0.0, -1.0); // u -> -z
+    faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y
+    faceUvVectors[1][2] = vec3(1.0, 0.0, 0.0);  // +x face
+
+    // -y
+    faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0);  // u -> +x
+    faceUvVectors[2][1] = vec3(0.0, 0.0, -1.0); // v -> -z
+    faceUvVectors[2][2] = vec3(0.0, -1.0, 0.0); // -y face
+
+    // +y
+    faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0);  // u -> +x
+    faceUvVectors[3][1] = vec3(0.0, 0.0, 1.0);  // v -> +z
+    faceUvVectors[3][2] = vec3(0.0, 1.0, 0.0);  // +y face
+
+    // -z
+    faceUvVectors[4][0] = vec3(-1.0, 0.0, 0.0); // u -> -x
+    faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y
+    faceUvVectors[4][2] = vec3(0.0, 0.0, -1.0); // -z face
+
+    // +z
+    faceUvVectors[5][0] = vec3(1.0, 0.0, 0.0);  // u -> +x
+    faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y
+    faceUvVectors[5][2] = vec3(0.0, 0.0, 1.0);  // +z face
 
     // out = u * s_faceUv[0] + v * s_faceUv[1] + s_faceUv[2].
     vec3 result = (faceUvVectors[faceID][0] * uv.x) + (faceUvVectors[faceID][1] * uv.y) + faceUvVectors[faceID][2];
@@ -113,7 +151,7 @@ vec2 Hammersley(uint i, uint N) {
      return vec2(float(i)/float(N), radicalInverse_VdC(i));
 }
 
-#define SAMPLE_COUNT 1024
+#define SAMPLE_COUNT 1024u
 
 void main() {
 
@@ -123,20 +161,21 @@ void main() {
 	//vec4 color = color_interp;
 	vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
 
-	for(int sampleNum = 0; sampleNum < SAMPLE_COUNT; sampleNum++) {
+	for(uint sampleNum = 0u; sampleNum < SAMPLE_COUNT; sampleNum++) {
 		vec2 xi = Hammersley(sampleNum, SAMPLE_COUNT);
-		vec2 xi = texture2DLod(Texture0, vec2(float(sampleNum) / float(SAMPLE_COUNT), 0.5), 0.0).xy;
 
 		vec3 H  = ImportanceSampleGGX( xi, roughness, N );
 		vec3 V  = N;
 		vec3 L  = normalize(2.0 * dot( V, H ) * H - V);
 
-		float ndotl = max(0.0, dot(N, L));
-		vec3 s = textureCubeLod(u_skyCube, H, 0.0).rgb * ndotl;
+		float ndotl = clamp(dot(N, L),0.0,1.0);
 
-		sum += vec4(s, 1.0);
+		if (ndotl>0.0) {
+			sum.rgb += textureLod(source_cube, H, 0.0).rgb *ndotl;
+			sum.a += ndotl;
+		}
 	}
-	sum /= sum.w;
+	sum /= sum.a;
 
 	frag_color = vec4(sum.rgb, 1.0);
 }

+ 241 - 41
drivers/gles3/shaders/scene.glsl

@@ -1,7 +1,7 @@
 [vertex]
 
 
-
+#define ENABLE_UV_INTERP
 /*
 from VisualServer:
 
@@ -52,14 +52,47 @@ layout(std140) uniform SceneData { //ubo:0
 	highp mat4 camera_matrix;
 	highp vec4 time;
 
-	highp vec4 ambient_light;
+	highp vec4 ambient_light_color;
+	highp vec4 bg_color;
+	float ambient_energy;
+	float bg_energy;
 };
 
 uniform highp mat4 world_transform;
 
+#ifdef USE_FORWARD_LIGHTING
+
+layout(std140) uniform LightData { //ubo:3
+
+	highp vec4 light_pos_inv_radius;
+	mediump vec4 light_direction_attenuation;
+	mediump vec4 light_color_energy;
+	mediump vec4 light_params; //cone attenuation, specular, shadow darkening,
+	mediump vec4 shadow_split_offsets;
+	highp mat4 shadow_matrix1;
+	highp mat4 shadow_matrix2;
+	highp mat4 shadow_matrix3;
+	highp mat4 shadow_matrix4;
+};
+
+#ifdef USE_FORWARD_1_SHADOW_MAP
+out mediump vec4 forward_shadow_pos1;
+#endif
+
+#ifdef USE_FORWARD_2_SHADOW_MAP
+out mediump vec4 forward_shadow_pos2;
+#endif
+
+#ifdef USE_FORWARD_4_SHADOW_MAP
+out mediump vec4 forward_shadow_pos3;
+out mediump vec4 forward_shadow_pos4;
+#endif
+
+#endif
+
 /* Varyings */
 
-out vec3 vertex_interp;
+out highp vec3 vertex_interp;
 out vec3 normal_interp;
 
 #if defined(ENABLE_COLOR_INTERP)
@@ -74,13 +107,6 @@ out vec2 uv_interp;
 out vec2 uv2_interp;
 #endif
 
-#if defined(ENABLE_VAR1_INTERP)
-out vec4 var1_interp;
-#endif
-
-#if defined(ENABLE_VAR2_INTERP)
-out vec4 var2_interp;
-#endif
 
 #if defined(ENABLE_TANGENT_INTERP)
 out vec3 tangent_interp;
@@ -118,13 +144,13 @@ MATERIAL_UNIFORMS
 
 void main() {
 
-	highp vec4 vertex_in = vertex_attrib; // vec4(vertex_attrib.xyz * data_attrib.x,1.0);
+	highp vec4 vertex = vertex_attrib; // vec4(vertex_attrib.xyz * data_attrib.x,1.0);
 	highp mat4 modelview = camera_inverse_matrix * world_transform;
-	vec3 normal_in = normal_attrib;
-	normal_in*=normal_mult;
+	vec3 normal = normal_attrib * normal_mult;
+
 #if defined(ENABLE_TANGENT_INTERP)
-	vec3 tangent_in = tangent_attrib.xyz;
-	tangent_in*=normal_mult;
+	vec3 tangent = tangent_attrib.xyz;
+	tangent*=normal_mult;
 	float binormalf = tangent_attrib.a;
 #endif
 
@@ -137,23 +163,31 @@ void main() {
 		m+=mat4(texture2D(skeleton_matrices,vec2((bone_indices.z*3.0+0.0)*skeltex_pixel_size,0.0)),texture2D(skeleton_matrices,vec2((bone_indices.z*3.0+1.0)*skeltex_pixel_size,0.0)),texture2D(skeleton_matrices,vec2((bone_indices.z*3.0+2.0)*skeltex_pixel_size,0.0)),vec4(0.0,0.0,0.0,1.0))*bone_weights.z;
 		m+=mat4(texture2D(skeleton_matrices,vec2((bone_indices.w*3.0+0.0)*skeltex_pixel_size,0.0)),texture2D(skeleton_matrices,vec2((bone_indices.w*3.0+1.0)*skeltex_pixel_size,0.0)),texture2D(skeleton_matrices,vec2((bone_indices.w*3.0+2.0)*skeltex_pixel_size,0.0)),vec4(0.0,0.0,0.0,1.0))*bone_weights.w;
 
-		vertex_in = vertex_in * m;
-		normal_in = (vec4(normal_in,0.0) * m).xyz;
+		vertex = vertex_in * m;
+		normal = (vec4(normal,0.0) * m).xyz;
 #if defined(ENABLE_TANGENT_INTERP)
-		tangent_in = (vec4(tangent_in,0.0) * m).xyz;
+		tangent = (vec4(tangent,0.0) * m).xyz;
 #endif
 	}
 
 #endif
 
-	vertex_interp = (modelview * vertex_in).xyz;
-	normal_interp = normalize((modelview * vec4(normal_in,0.0)).xyz);
+#if !defined(SKIP_TRANSFORM_USED)
+
+	vertex = modelview * vertex;
+	normal = normalize((modelview * vec4(normal,0.0)).xyz);
+#endif
 
 #if defined(ENABLE_TANGENT_INTERP)
-	tangent_interp=normalize((modelview * vec4(tangent_in,0.0)).xyz);
-	binormal_interp = normalize( cross(normal_interp,tangent_interp) * binormalf );
+# if !defined(SKIP_TRANSFORM_USED)
+
+	tangent=normalize((modelview * vec4(tangent,0.0)).xyz);
+# endif
+	vec3 binormal = normalize( cross(normal,tangent) * binormalf );
 #endif
 
+
+
 #if defined(ENABLE_COLOR_INTERP)
 	color_interp = color_attrib;
 #endif
@@ -161,13 +195,17 @@ void main() {
 #if defined(ENABLE_UV_INTERP)
 	uv_interp = uv_attrib;
 #endif
+
 #if defined(ENABLE_UV2_INTERP)
 	uv2_interp = uv2_attrib;
 #endif
 
+{
 
 VERTEX_SHADER_CODE
 
+}
+
 
 #ifdef USE_SHADOW_PASS
 
@@ -177,26 +215,32 @@ VERTEX_SHADER_CODE
 #endif
 
 
-#ifdef USE_FOG
+	vertex_interp = vertex.xyz;
+	normal_interp = normal;
 
-	fog_interp.a = pow( clamp( (length(vertex_interp)-fog_params.x)/(fog_params.y-fog_params.x), 0.0, 1.0 ), fog_params.z );
-	fog_interp.rgb = mix( fog_color_begin, fog_color_end, fog_interp.a );
+#if defined(ENABLE_TANGENT_INTERP)
+	tangent_interp = tangent;
+	binormal_interp = binormal;
 #endif
 
-#ifndef VERTEX_SHADER_WRITE_POSITION
-//vertex shader might write a position
+#if !defined(SKIP_TRANSFORM_USED)
 	gl_Position = projection_matrix * vec4(vertex_interp,1.0);
+#else
+	gl_Position = vertex;
 #endif
 
 
-
-
 }
 
 
 [fragment]
 
 
+
+#define M_PI 3.14159265359
+
+
+#define ENABLE_UV_INTERP
 //hack to use uv if no uv present so it works with lightmap
 
 
@@ -219,17 +263,27 @@ in vec3 tangent_interp;
 in vec3 binormal_interp;
 #endif
 
-#if defined(ENABLE_VAR1_INTERP)
-in vec4 var1_interp;
-#endif
+in highp vec3 vertex_interp;
+in vec3 normal_interp;
 
-#if defined(ENABLE_VAR2_INTERP)
-in vec4 var2_interp;
-#endif
 
-in vec3 vertex_interp;
-in vec3 normal_interp;
+/* PBR CHANNELS */
+
+#ifdef USE_RADIANCE_CUBEMAP
+
+uniform sampler2D brdf_texture; //texunit:-1
+uniform samplerCube radiance_cube; //texunit:-2
+
+layout(std140) uniform Radiance { //ubo:2
+
+	mat4 radiance_inverse_xform;
+	vec3 radiance_box_min;
+	vec3 radiance_box_max;
+	float radiance_ambient_contribution;
+
+};
 
+#endif
 
 /* Material Uniforms */
 
@@ -255,18 +309,97 @@ layout(std140) uniform SceneData {
 	highp mat4 camera_matrix;
 	highp vec4 time;
 
-	highp vec4 ambient_light;
+	highp vec4 ambient_light_color;
+	highp vec4 bg_color;
+	float ambient_energy;
+	float bg_energy;
 };
 
+
+#ifdef USE_FORWARD_LIGHTING
+
+layout(std140) uniform LightData {
+
+	highp vec4 light_pos_inv_radius;
+	mediump vec4 light_direction_attenuation;
+	mediump vec4 light_color_energy;
+	mediump vec4 light_params; //cone attenuation, specular, shadow darkening,
+	mediump vec4 shadow_split_offsets;
+	highp mat4 shadow_matrix1;
+	highp mat4 shadow_matrix2;
+	highp mat4 shadow_matrix3;
+	highp mat4 shadow_matrix4;
+};
+
+#ifdef USE_FORWARD_1_SHADOW_MAP
+in mediump vec4 forward_shadow_pos1;
+#endif
+
+#ifdef USE_FORWARD_2_SHADOW_MAP
+in mediump vec4 forward_shadow_pos2;
+#endif
+
+#ifdef USE_FORWARD_4_SHADOW_MAP
+in mediump vec4 forward_shadow_pos3;
+in mediump vec4 forward_shadow_pos4;
+#endif
+
+#endif
+
 layout(location=0) out vec4 frag_color;
 
+
+// GGX Specular
+// Source: http://www.filmicworlds.com/images/ggx-opt/optimized-ggx.hlsl
+float G1V(float dotNV, float k)
+{
+    return 1.0 / (dotNV * (1.0 - k) + k);
+}
+
+float specularGGX(vec3 N, vec3 V, vec3 L, float roughness, float F0)
+{
+    float alpha = roughness * roughness;
+
+    vec3 H = normalize(V + L);
+
+    float dotNL = max(dot(N,L), 0.0 );
+    float dotNV = max(dot(N,V), 0.0 );
+    float dotNH = max(dot(N,H), 0.0 );
+    float dotLH = max(dot(L,H), 0.0 );
+
+    // D
+    float alphaSqr = alpha * alpha;
+    float pi = M_PI;
+    float denom = dotNH * dotNH * (alphaSqr - 1.0) + 1.0;
+    float D = alphaSqr / (pi * denom * denom);
+
+    // F
+    float dotLH5 = pow(1.0 - dotLH, 5.0);
+    float F = F0 + (1.0 - F0) * (dotLH5);
+
+    // V
+    float k = alpha / 2.0f;
+    float vis = G1V(dotNL, k) * G1V(dotNV, k);
+
+    return dotNL * D * F * vis;
+}
+
+void light_compute(vec3 normal, vec3 light_vec,vec3 eye_vec,vec3 diffuse_color, vec3 specular_color, float roughness, float attenuation, inout vec3 diffuse, inout vec3 specular) {
+
+	diffuse += max(0.0,dot(normal,light_vec)) * diffuse_color * attenuation;
+	//specular += specular_ggx( roughness, max(0.0,dot(normal,eye_vec)) ) * specular_color * attenuation;
+	float s = roughness > 0.0 ? specularGGX(normal,eye_vec,light_vec,roughness,1.0) : 0.0;
+	specular += s * specular_color * attenuation;
+}
+
+
 void main() {
 
 	//lay out everything, whathever is unused is optimized away anyway
 	vec3 vertex = vertex_interp;
-	vec3 albedo = vec3(0.9,0.9,0.9);
-	vec3 metal = vec3(0.0,0.0,0.0);
-	float rough = 0.0;
+	vec3 albedo = vec3(0.8,0.8,0.8);
+	vec3 specular = vec3(0.2,0.2,0.2);
+	float roughness = 1.0;
 	float alpha = 1.0;
 
 #ifdef METERIAL_DOUBLESIDED
@@ -334,6 +467,66 @@ FRAGMENT_SHADER_CODE
 	}
 #endif
 
+/////////////////////// LIGHTING //////////////////////////////
+
+	vec3 specular_light = vec3(0.0,0.0,0.0);
+	vec3 ambient_light = ambient_light_color.rgb;
+	vec3 diffuse_light = vec3(0.0,0.0,0.0);
+
+	vec3 eye_vec = -normalize( vertex_interp );
+
+#ifdef USE_RADIANCE_CUBEMAP
+
+	{
+
+		float ndotv = clamp(dot(normal,eye_vec),0.0,1.0);
+		vec2 brdf = texture(brdf_texture, vec2(roughness, ndotv)).xy;
+
+		float lod = roughness * 5.0;
+		vec3 r = reflect(-eye_vec,normal); //2.0 * ndotv * normal - view; // reflect(v, n);
+		r=normalize((radiance_inverse_xform * vec4(r,0.0)).xyz);
+		vec3 radiance = textureLod(radiance_cube, r, lod).xyz * ( brdf.x + brdf.y);
+
+		specular_light=mix(albedo,radiance,specular);
+
+	}
+
+	{
+
+		vec3 ambient_dir=normalize((radiance_inverse_xform * vec4(normal,0.0)).xyz);
+		vec3 env_ambient=textureLod(radiance_cube, ambient_dir, 5.0).xyz;
+
+		ambient_light=mix(ambient_light,env_ambient,radiance_ambient_contribution);
+	}
+
+
+#else
+
+	ambient_light=albedo;
+#endif
+
+
+#ifdef USE_FORWARD_LIGHTING
+
+#ifdef USE_FORWARD_DIRECTIONAL
+
+	light_compute(normal,light_direction_attenuation.xyz,eye_vec,albedo,specular,roughness,1.0,diffuse_light,specular_light);
+#endif
+
+#ifdef USE_FORWARD_OMNI
+
+	vec3 light_rel_vec = light_pos_inv_radius.xyz-vertex;
+	float normalized_distance = length( light_rel_vec )*light_pos_inv_radius.w;
+	float light_attenuation = pow( max(1.0 - normalized_distance, 0.0), light_direction_attenuation.w );
+	light_compute(normal,normalize(light_rel_vec),eye_vec,albedo,specular,roughness,light_attenuation,diffuse_light,specular_light);
+
+#endif
+
+#ifdef USE_FORWARD_SPOT
+
+#endif
+
+#endif
 
 
 #if defined(USE_LIGHT_SHADER_CODE)
@@ -345,7 +538,14 @@ LIGHT_SHADER_CODE
 }
 #endif
 
+#ifdef SHADELESS
+
 	frag_color=vec4(albedo,alpha);
+#else
+	frag_color=vec4(ambient_light+diffuse_light+specular_light,alpha);
+
+#endif
+
 }
 
 

+ 2 - 2
modules/gridmap/grid_map.cpp

@@ -960,9 +960,9 @@ void GridMap::_octant_bake(const OctantKey &p_key, const Ref<TriangleMesh>& p_tm
 
 						st->add_to_format(VS::ARRAY_FORMAT_COLOR);
 						if (m.is_valid()) {
-							Ref<FixedMaterial> fm = m;
+							Ref<FixedSpatialMaterial> fm = m;
 							if (fm.is_valid())
-								fm->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true);
+								fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY,true);
 						}
 					}
 				}

+ 8 - 8
platform/iphone/rasterizer_iphone.cpp

@@ -486,7 +486,7 @@ RID RasterizerIPhone::material_create() {
 	return material_owner.make_rid( memnew( Material ) );
 }
 
-void RasterizerIPhone::fixed_material_set_parameter(RID p_material, VS::FixedMaterialParam p_parameter, const Variant& p_value) {
+void RasterizerIPhone::fixed_material_set_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter, const Variant& p_value) {
 
 	Material *m=material_owner.get( p_material );
 	ERR_FAIL_COND(!m);
@@ -494,7 +494,7 @@ void RasterizerIPhone::fixed_material_set_parameter(RID p_material, VS::FixedMat
 
 	m->parameters[p_parameter] = p_value;
 }
-Variant RasterizerIPhone::fixed_material_get_parameter(RID p_material,VS::FixedMaterialParam p_parameter) const {
+Variant RasterizerIPhone::fixed_material_get_parameter(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const {
 
 	Material *m=material_owner.get( p_material );
 	ERR_FAIL_COND_V(!m, Variant());
@@ -503,7 +503,7 @@ Variant RasterizerIPhone::fixed_material_get_parameter(RID p_material,VS::FixedM
 	return m->parameters[p_parameter];
 }
 
-void RasterizerIPhone::fixed_material_set_texture(RID p_material,VS::FixedMaterialParam p_parameter, RID p_texture) {
+void RasterizerIPhone::fixed_material_set_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter, RID p_texture) {
 
 	Material *m=material_owner.get( p_material );
 	ERR_FAIL_COND(!m);
@@ -511,7 +511,7 @@ void RasterizerIPhone::fixed_material_set_texture(RID p_material,VS::FixedMateri
 
 	m->textures[p_parameter] = p_texture;
 }
-RID RasterizerIPhone::fixed_material_get_texture(RID p_material,VS::FixedMaterialParam p_parameter) const {
+RID RasterizerIPhone::fixed_material_get_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const {
 
 	Material *m=material_owner.get( p_material );
 	ERR_FAIL_COND_V(!m, RID());
@@ -535,7 +535,7 @@ VS::MaterialBlendMode RasterizerIPhone::fixed_material_get_detail_blend_mode(RID
 	return m->detail_blend_mode;
 }
 
-void RasterizerIPhone::fixed_material_set_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter, VS::FixedMaterialTexCoordMode p_mode) {
+void RasterizerIPhone::fixed_material_set_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter, VS::FixedSpatialMaterialTexCoordMode p_mode) {
 
 	Material *m=material_owner.get( p_material );
 	ERR_FAIL_COND(!m);
@@ -543,7 +543,7 @@ void RasterizerIPhone::fixed_material_set_texcoord_mode(RID p_material,VS::Fixed
 
 	m->texcoord_mode[p_parameter] = p_mode;
 }
-VS::FixedMaterialTexCoordMode RasterizerIPhone::fixed_material_get_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter) const {
+VS::FixedSpatialMaterialTexCoordMode RasterizerIPhone::fixed_material_get_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const {
 
 	Material *m=material_owner.get( p_material );
 	ERR_FAIL_COND_V(!m, VS::FIXED_MATERIAL_TEXCOORD_TEXGEN);
@@ -552,7 +552,7 @@ VS::FixedMaterialTexCoordMode RasterizerIPhone::fixed_material_get_texcoord_mode
 	return m->texcoord_mode[p_parameter]; // for now
 }
 
-void RasterizerIPhone::fixed_material_set_texgen_mode(RID p_material,VS::FixedMaterialTexGenMode p_mode) {
+void RasterizerIPhone::fixed_material_set_texgen_mode(RID p_material,VS::FixedSpatialMaterialTexGenMode p_mode) {
 
 	Material *m=material_owner.get( p_material );
 	ERR_FAIL_COND(!m);
@@ -560,7 +560,7 @@ void RasterizerIPhone::fixed_material_set_texgen_mode(RID p_material,VS::FixedMa
 	m->texgen_mode = p_mode;
 };
 
-VS::FixedMaterialTexGenMode RasterizerIPhone::fixed_material_get_texgen_mode(RID p_material) const {
+VS::FixedSpatialMaterialTexGenMode RasterizerIPhone::fixed_material_get_texgen_mode(RID p_material) const {
 
 	Material *m=material_owner.get( p_material );
 	ERR_FAIL_COND_V(!m, VS::FIXED_MATERIAL_TEXGEN_SPHERE);

+ 10 - 10
platform/iphone/rasterizer_iphone.h

@@ -100,11 +100,11 @@ class RasterizerIPhone : public Rasterizer {
 		RID textures[VisualServer::FIXED_MATERIAL_PARAM_MAX];
 
 		Transform uv_transform;
-		VS::FixedMaterialTexCoordMode texcoord_mode[VisualServer::FIXED_MATERIAL_PARAM_MAX];
+		VS::FixedSpatialMaterialTexCoordMode texcoord_mode[VisualServer::FIXED_MATERIAL_PARAM_MAX];
 
 		VS::MaterialBlendMode detail_blend_mode;
 
-		VS::FixedMaterialTexGenMode texgen_mode;
+		VS::FixedSpatialMaterialTexGenMode texgen_mode;
 
 		Material() {
 
@@ -624,20 +624,20 @@ public:
 
 	virtual RID material_create();
 
-	virtual void fixed_material_set_parameter(RID p_material, VS::FixedMaterialParam p_parameter, const Variant& p_value);
-	virtual Variant fixed_material_get_parameter(RID p_material,VS::FixedMaterialParam p_parameter) const;
+	virtual void fixed_material_set_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter, const Variant& p_value);
+	virtual Variant fixed_material_get_parameter(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const;
 
-	virtual void fixed_material_set_texture(RID p_material,VS::FixedMaterialParam p_parameter, RID p_texture);
-	virtual RID fixed_material_get_texture(RID p_material,VS::FixedMaterialParam p_parameter) const;
+	virtual void fixed_material_set_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter, RID p_texture);
+	virtual RID fixed_material_get_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const;
 
 	virtual void fixed_material_set_detail_blend_mode(RID p_material,VS::MaterialBlendMode p_mode);
 	virtual VS::MaterialBlendMode fixed_material_get_detail_blend_mode(RID p_material) const;
 
-	virtual void fixed_material_set_texgen_mode(RID p_material,VS::FixedMaterialTexGenMode p_mode);
-	virtual VS::FixedMaterialTexGenMode fixed_material_get_texgen_mode(RID p_material) const;
+	virtual void fixed_material_set_texgen_mode(RID p_material,VS::FixedSpatialMaterialTexGenMode p_mode);
+	virtual VS::FixedSpatialMaterialTexGenMode fixed_material_get_texgen_mode(RID p_material) const;
 
-	virtual void fixed_material_set_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter, VS::FixedMaterialTexCoordMode p_mode);
-	virtual VS::FixedMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter) const;
+	virtual void fixed_material_set_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter, VS::FixedSpatialMaterialTexCoordMode p_mode);
+	virtual VS::FixedSpatialMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const;
 
 	virtual void fixed_material_set_uv_transform(RID p_material,const Transform& p_transform);
 	virtual Transform fixed_material_get_uv_transform(RID p_material) const;

+ 146 - 10
scene/3d/light.cpp

@@ -39,24 +39,88 @@ bool Light::_can_gizmo_scale() const {
 }
 
 
+void Light::set_param(Param p_param, float p_value) {
+
+	ERR_FAIL_INDEX(p_param,PARAM_MAX);
+	param[p_param]=p_value;
+
+	VS::get_singleton()->light_set_param(light,VS::LightParam(p_param),p_value);
+
+	if (p_param==PARAM_SPOT_ANGLE || p_param==PARAM_RANGE) {
+		update_gizmo();;
+	}
+
+
+}
+
+float Light::get_param(Param p_param) const{
+
+	ERR_FAIL_INDEX_V(p_param,PARAM_MAX,0);
+	return param[p_param];
+
+}
+
+void Light::set_shadow(bool p_enable){
+
+	shadow=p_enable;
+	VS::get_singleton()->light_set_shadow(light,p_enable);
+
+}
+bool Light::has_shadow() const{
+
+	return shadow;
+}
+
+void Light::set_negative(bool p_enable){
+
+	negative=p_enable;
+	VS::get_singleton()->light_set_negative(light,p_enable);
+}
+bool Light::is_negative() const{
+
+	return negative;
+}
+
+void Light::set_cull_mask(uint32_t p_cull_mask){
+
+	cull_mask=p_cull_mask;
+	VS::get_singleton()->light_set_cull_mask(light,p_cull_mask);
+
+}
+uint32_t Light::get_cull_mask() const{
+
+	return cull_mask;
+}
+
+void Light::set_color(const Color& p_color){
+
+	color=p_color;
+	VS::get_singleton()->light_set_color(light,p_color);
+}
+Color Light::get_color() const{
+
+	return color;
+}
+
+
 AABB Light::get_aabb() const {
 
-#if 0
+
 	if (type==VisualServer::LIGHT_DIRECTIONAL) {
 
 		return AABB( Vector3(-1,-1,-1), Vector3(2, 2, 2 ) );
 
 	} else if (type==VisualServer::LIGHT_OMNI) {
 
-		return AABB( Vector3(-1,-1,-1) * vars[PARAM_RADIUS], Vector3(2, 2, 2 ) * vars[PARAM_RADIUS]);
+		return AABB( Vector3(-1,-1,-1) * param[PARAM_RANGE], Vector3(2, 2, 2 ) * param[PARAM_RANGE]);
 
 	} else if (type==VisualServer::LIGHT_SPOT) {
 
-		float len=vars[PARAM_RADIUS];
-		float size=Math::tan(Math::deg2rad(vars[PARAM_SPOT_ANGLE]))*len;
+		float len=param[PARAM_RANGE];
+		float size=Math::tan(Math::deg2rad(param[PARAM_SPOT_ANGLE]))*len;
 		return AABB( Vector3( -size,-size,-len ), Vector3( size*2, size*2, len ) );
 	}
-#endif
+
 	return AABB();
 }
 
@@ -118,10 +182,51 @@ void Light::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("is_editor_only"), &Light::is_editor_only );
 
 
-	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "params/editor_only"), _SCS("set_editor_only"), _SCS("is_editor_only"));
-
-
-
+	ObjectTypeDB::bind_method(_MD("set_param","param","value"), &Light::set_param );
+	ObjectTypeDB::bind_method(_MD("get_param","param"), &Light::get_param );
+
+	ObjectTypeDB::bind_method(_MD("set_shadow","enabled"), &Light::set_shadow );
+	ObjectTypeDB::bind_method(_MD("has_shadow"), &Light::has_shadow );
+
+	ObjectTypeDB::bind_method(_MD("set_negative","enabled"), &Light::set_negative );
+	ObjectTypeDB::bind_method(_MD("is_negative"), &Light::is_negative );
+
+	ObjectTypeDB::bind_method(_MD("set_cull_mask","cull_mask"), &Light::set_cull_mask );
+	ObjectTypeDB::bind_method(_MD("get_cull_mask"), &Light::get_cull_mask );
+
+	ObjectTypeDB::bind_method(_MD("set_color","color"), &Light::set_color );
+	ObjectTypeDB::bind_method(_MD("get_color"), &Light::get_color );
+
+	ADD_PROPERTY( PropertyInfo( Variant::COLOR, "light/color"), _SCS("set_color"), _SCS("get_color"));
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/energy"), _SCS("set_param"), _SCS("get_param"), PARAM_ENERGY);
+	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "light/negative"), _SCS("set_negative"), _SCS("is_negative"));
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/specular"), _SCS("set_param"), _SCS("get_param"), PARAM_SPECULAR);
+	ADD_PROPERTY( PropertyInfo( Variant::INT, "light/cull_mask"), _SCS("set_cull_mask"), _SCS("get_cull_mask"));
+	ADD_PROPERTY( PropertyInfo( Variant::INT, "shadow/enabled"), _SCS("set_shadow"), _SCS("has_shadow"));
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/darkness"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_DARKNESS);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/normal_bias"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_NORMAL_BIAS);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/bias"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_BIAS);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/bias_split_scale"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_BIAS_SPLIT_SCALE);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/max_distance"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_MAX_DISTANCE);
+
+	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "editor/editor_only"), _SCS("set_editor_only"), _SCS("is_editor_only"));
+
+	BIND_CONSTANT( PARAM_ENERGY );
+	BIND_CONSTANT( PARAM_SPECULAR );
+	BIND_CONSTANT( PARAM_RANGE );
+	BIND_CONSTANT( PARAM_ATTENUATION );
+	BIND_CONSTANT( PARAM_SPOT_ANGLE );
+	BIND_CONSTANT( PARAM_SPOT_ATTENUATION );
+	BIND_CONSTANT( PARAM_SHADOW_MAX_DISTANCE );
+	BIND_CONSTANT( PARAM_SHADOW_DARKNESS );
+	BIND_CONSTANT( PARAM_SHADOW_SPLIT_1_OFFSET );
+	BIND_CONSTANT( PARAM_SHADOW_SPLIT_2_OFFSET );
+	BIND_CONSTANT( PARAM_SHADOW_SPLIT_3_OFFSET );
+	BIND_CONSTANT( PARAM_SHADOW_SPLIT_4_OFFSET );
+	BIND_CONSTANT( PARAM_SHADOW_NORMAL_BIAS );
+	BIND_CONSTANT( PARAM_SHADOW_BIAS );
+	BIND_CONSTANT( PARAM_SHADOW_BIAS_SPLIT_SCALE );
+	BIND_CONSTANT( PARAM_MAX );
 
 
 }
@@ -131,9 +236,29 @@ Light::Light(VisualServer::LightType p_type) {
 
 	type=p_type;
 	light=VisualServer::get_singleton()->light_create(p_type);
-
+	VS::get_singleton()->instance_set_base(get_instance(),light);
 
 	editor_only=false;
+	set_color(Color(1,1,1,1));
+	set_shadow(false);
+	set_negative(false);
+	set_cull_mask(0xFFFFFFFF);
+
+	set_param(PARAM_ENERGY,1);
+	set_param(PARAM_SPECULAR,1);
+	set_param(PARAM_RANGE,5);
+	set_param(PARAM_ATTENUATION,1);
+	set_param(PARAM_SPOT_ANGLE,45);
+	set_param(PARAM_SPOT_ATTENUATION,1);
+	set_param(PARAM_SHADOW_MAX_DISTANCE,0);
+	set_param(PARAM_SHADOW_DARKNESS,0);
+	set_param(PARAM_SHADOW_SPLIT_1_OFFSET,0.1);
+	set_param(PARAM_SHADOW_SPLIT_2_OFFSET,0.2);
+	set_param(PARAM_SHADOW_SPLIT_3_OFFSET,0.5);
+	set_param(PARAM_SHADOW_SPLIT_4_OFFSET,1.0);
+	set_param(PARAM_SHADOW_NORMAL_BIAS,0.1);
+	set_param(PARAM_SHADOW_BIAS,0.1);
+	set_param(PARAM_SHADOW_BIAS_SPLIT_SCALE,0.1);
 
 }
 
@@ -147,6 +272,8 @@ Light::Light() {
 
 Light::~Light() {
 
+	VS::get_singleton()->instance_set_base(get_instance(),RID());
+
 	if (light.is_valid())
 		VisualServer::get_singleton()->free(light);
 }
@@ -156,6 +283,10 @@ Light::~Light() {
 void DirectionalLight::_bind_methods() {
 
 
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "pssm/split_1"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_1_OFFSET);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "pssm/split_2"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_2_OFFSET);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "pssm/split_3"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_3_OFFSET);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "pssm/split_4"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_4_OFFSET);
 
 }
 
@@ -169,11 +300,16 @@ DirectionalLight::DirectionalLight() : Light( VisualServer::LIGHT_DIRECTIONAL )
 
 void OmniLight::_bind_methods() {
 
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/range"), _SCS("set_param"), _SCS("get_param"), PARAM_RANGE);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/attenuation"), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION);
 
 }
 
 void SpotLight::_bind_methods() {
 
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/spot_angle"), _SCS("set_param"), _SCS("get_param"), PARAM_SPOT_ANGLE);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/spot_attenuation"), _SCS("set_param"), _SCS("get_param"), PARAM_SPOT_ATTENUATION);
+
 }
 
 

+ 40 - 1
scene/3d/light.h

@@ -44,10 +44,32 @@ class Light : public VisualInstance {
 
 public:
 
-
+	enum Param {
+		PARAM_ENERGY,
+		PARAM_SPECULAR,
+		PARAM_RANGE,
+		PARAM_ATTENUATION,
+		PARAM_SPOT_ANGLE,
+		PARAM_SPOT_ATTENUATION,
+		PARAM_SHADOW_MAX_DISTANCE,
+		PARAM_SHADOW_DARKNESS,
+		PARAM_SHADOW_SPLIT_1_OFFSET,
+		PARAM_SHADOW_SPLIT_2_OFFSET,
+		PARAM_SHADOW_SPLIT_3_OFFSET,
+		PARAM_SHADOW_SPLIT_4_OFFSET,
+		PARAM_SHADOW_NORMAL_BIAS,
+		PARAM_SHADOW_BIAS,
+		PARAM_SHADOW_BIAS_SPLIT_SCALE,
+		PARAM_MAX
+	};
 
 private:
 
+	Color color;
+	float param[PARAM_MAX];
+	bool shadow;
+	bool negative;
+	uint32_t cull_mask;
 	VS::LightType type;
 	bool editor_only;
 	void _update_visibility();
@@ -71,6 +93,22 @@ public:
 	void set_editor_only(bool p_editor_only);
 	bool is_editor_only() const;
 
+	void set_param(Param p_param, float p_value);
+	float get_param(Param p_param) const;
+
+	void set_shadow(bool p_enable);
+	bool has_shadow() const;
+
+	void set_negative(bool p_enable);
+	bool is_negative() const;
+
+	void set_cull_mask(uint32_t p_cull_mask);
+	uint32_t get_cull_mask() const;
+
+	void set_color(const Color& p_color);
+	Color get_color() const;
+
+
 	virtual AABB get_aabb() const;
 	virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
 
@@ -79,6 +117,7 @@ public:
 
 };
 
+VARIANT_ENUM_CAST(Light::Param);
 
 
 class DirectionalLight : public Light {

+ 5 - 5
scene/3d/particles.cpp

@@ -319,10 +319,10 @@ RES Particles::_get_gizmo_geometry() const {
 
 	Ref<SurfaceTool> surface_tool( memnew( SurfaceTool ));
 
-	Ref<FixedMaterial> mat( memnew( FixedMaterial ));
+	Ref<FixedSpatialMaterial> mat( memnew( FixedSpatialMaterial ));
 
-	mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.0,0.6,0.7,0.2) );
-	mat->set_parameter( FixedMaterial::PARAM_EMISSION,Color(0.5,0.7,0.8) );
+	mat->set_parameter( FixedSpatialMaterial::PARAM_DIFFUSE,Color(0.0,0.6,0.7,0.2) );
+	mat->set_parameter( FixedSpatialMaterial::PARAM_EMISSION,Color(0.5,0.7,0.8) );
 	mat->set_blend_mode( Material::BLEND_MODE_ADD );
 	mat->set_flag(Material::FLAG_DOUBLE_SIDED,true);
 //	mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
@@ -382,9 +382,9 @@ RES Particles::_get_gizmo_geometry() const {
 
 	Ref<Mesh> mesh = surface_tool->commit();
 
-	Ref<FixedMaterial> mat_aabb( memnew( FixedMaterial ));
+	Ref<FixedSpatialMaterial> mat_aabb( memnew( FixedSpatialMaterial ));
 
-	mat_aabb->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.8,0.8,0.9,0.7) );
+	mat_aabb->set_parameter( FixedSpatialMaterial::PARAM_DIFFUSE,Color(0.8,0.8,0.9,0.7) );
 	mat_aabb->set_line_width(3);
 	mat_aabb->set_flag( Material::FLAG_UNSHADED, true );
 

+ 37 - 15
scene/main/scene_main_loop.cpp

@@ -490,6 +490,8 @@ void SceneTree::input_event( const InputEvent& p_event ) {
 
 	}
 
+	_call_idle_callbacks();
+
 }
 
 void SceneTree::init() {
@@ -528,6 +530,7 @@ bool SceneTree::iteration(float p_time) {
 	root_lock--;
 
 	_flush_delete_queue();
+	_call_idle_callbacks();
 
 	return _quit;
 }
@@ -590,6 +593,8 @@ bool SceneTree::idle(float p_time){
 		E=N;
 	}
 
+	_call_idle_callbacks();
+
 	return _quit;
 }
 
@@ -745,12 +750,12 @@ Ref<Material> SceneTree::get_debug_navigation_material() {
 	if (navigation_material.is_valid())
 		return navigation_material;
 
-	Ref<FixedMaterial> line_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
+	Ref<FixedSpatialMaterial> line_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
 /*	line_material->set_flag(Material::FLAG_UNSHADED, true);
 	line_material->set_line_width(3.0);
-	line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	line_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true);
-	line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,get_debug_navigation_color());*/
+	line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
+	line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true);
+	line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,get_debug_navigation_color());*/
 
 	navigation_material=line_material;
 
@@ -763,12 +768,12 @@ Ref<Material> SceneTree::get_debug_navigation_disabled_material(){
 	if (navigation_disabled_material.is_valid())
 		return navigation_disabled_material;
 
-	Ref<FixedMaterial> line_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
+	Ref<FixedSpatialMaterial> line_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
 /*	line_material->set_flag(Material::FLAG_UNSHADED, true);
 	line_material->set_line_width(3.0);
-	line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	line_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true);
-	line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,get_debug_navigation_disabled_color());*/
+	line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
+	line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true);
+	line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,get_debug_navigation_disabled_color());*/
 
 	navigation_disabled_material=line_material;
 
@@ -781,12 +786,12 @@ Ref<Material> SceneTree::get_debug_collision_material() {
 		return collision_material;
 
 
-	Ref<FixedMaterial> line_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
+	Ref<FixedSpatialMaterial> line_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
 	/*line_material->set_flag(Material::FLAG_UNSHADED, true);
 	line_material->set_line_width(3.0);
-	line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	line_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true);
-	line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,get_debug_collisions_color());*/
+	line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
+	line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true);
+	line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,get_debug_collisions_color());*/
 
 	collision_material=line_material;
 
@@ -800,11 +805,11 @@ Ref<Mesh> SceneTree::get_debug_contact_mesh() {
 
 	debug_contact_mesh = Ref<Mesh>( memnew( Mesh ) );
 
-	Ref<FixedMaterial> mat = memnew( FixedMaterial );
+	Ref<FixedSpatialMaterial> mat = memnew( FixedSpatialMaterial );
 	/*mat->set_flag(Material::FLAG_UNSHADED,true);
 	mat->set_flag(Material::FLAG_DOUBLE_SIDED,true);
-	mat->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
-	mat->set_parameter(FixedMaterial::PARAM_DIFFUSE,get_debug_collision_contact_color());*/
+	mat->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true);
+	mat->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,get_debug_collision_contact_color());*/
 
 	Vector3 diamond[6]={
 		Vector3(-1, 0, 0),
@@ -2259,6 +2264,23 @@ void SceneTree::_bind_methods() {
 
 SceneTree *SceneTree::singleton=NULL;
 
+
+SceneTree::IdleCallback SceneTree::idle_callbacks[SceneTree::MAX_IDLE_CALLBACKS];
+int SceneTree::idle_callback_count=0;
+
+void SceneTree::_call_idle_callbacks() {
+
+	for(int i=0;i<idle_callback_count;i++) {
+		idle_callbacks[i]();
+	}
+}
+
+void SceneTree::add_idle_callback(IdleCallback p_callback) {
+	ERR_FAIL_COND(idle_callback_count>=MAX_IDLE_CALLBACKS);
+	idle_callbacks[idle_callback_count++]=p_callback;
+}
+
+
 SceneTree::SceneTree() {
 
 	singleton=this;

+ 12 - 0
scene/main/scene_main_loop.h

@@ -74,6 +74,8 @@ class SceneTree : public MainLoop {
 public:
 
 
+	typedef void (*IdleCallback)();
+
 	enum StretchMode {
 
 		STRETCH_MODE_DISABLED,
@@ -303,6 +305,15 @@ friend class Viewport;
 	static void _live_edit_reparent_node_funcs(void* self,const NodePath& p_at,const NodePath& p_new_place,const String& p_new_name,int p_at_pos) { reinterpret_cast<SceneTree*>(self)->_live_edit_reparent_node_func(p_at,p_new_place,p_new_name,p_at_pos); }
 
 #endif
+
+	enum {
+		MAX_IDLE_CALLBACKS=256
+	};
+
+	static IdleCallback idle_callbacks[MAX_IDLE_CALLBACKS];
+	static int idle_callback_count;
+	void _call_idle_callbacks();
+
 protected:
 
 
@@ -430,6 +441,7 @@ public:
 	void set_refuse_new_network_connections(bool p_refuse);
 	bool is_refusing_new_network_connections() const;
 
+	static void add_idle_callback(IdleCallback p_callback);
 	SceneTree();
 	~SceneTree();
 

+ 1 - 1
scene/main/viewport.cpp

@@ -2513,7 +2513,7 @@ Vector2 Viewport::get_camera_coords(const Vector2 &p_viewport_coords) const {
 
 Vector2 Viewport::get_camera_rect_size() const {
 
-	return last_vp_rect.size;
+	return size;
 }
 
 

+ 8 - 3
scene/register_scene_types.cpp

@@ -544,14 +544,16 @@ void register_scene_types() {
 #ifndef _3D_DISABLED
 	ObjectTypeDB::register_type<Mesh>();
 	ObjectTypeDB::register_virtual_type<Material>();
-	ObjectTypeDB::register_type<FixedMaterial>();
+	ObjectTypeDB::register_type<FixedSpatialMaterial>();
+	SceneTree::add_idle_callback(FixedSpatialMaterial::flush_changes);
+	FixedSpatialMaterial::init_shaders();
 //	ObjectTypeDB::register_type<ShaderMaterial>();
 	ObjectTypeDB::register_type<RoomBounds>();
 //	ObjectTypeDB::register_type<MaterialShaderGraph>();
 	ObjectTypeDB::register_type<SpatialShader>();
 	ObjectTypeDB::add_compatibility_type("Shader","MaterialShader");
-	ObjectTypeDB::add_compatibility_type("ParticleSystemMaterial","FixedMaterial");
-	ObjectTypeDB::add_compatibility_type("UnshadedMaterial","FixedMaterial");
+	ObjectTypeDB::add_compatibility_type("ParticleSystemMaterial","FixedSpatialMaterial");
+	ObjectTypeDB::add_compatibility_type("UnshadedMaterial","FixedSpatialMaterial");
 	ObjectTypeDB::register_type<MultiMesh>();
 	ObjectTypeDB::register_type<MeshLibrary>();
 
@@ -655,6 +657,7 @@ void unregister_scene_types() {
 	memdelete( resource_loader_wav );
 	memdelete( resource_loader_dynamic_font );
 
+
 #ifdef TOOLS_ENABLED
 
 
@@ -669,5 +672,7 @@ void unregister_scene_types() {
 	if (resource_loader_text) {
 		memdelete(resource_loader_text);
 	}
+
+	FixedSpatialMaterial::finish_shaders();
 	SceneStringNames::free();
 }

+ 14 - 13
scene/resources/environment.cpp

@@ -53,7 +53,7 @@ void Environment::set_skybox(const Ref<CubeMap>& p_skybox){
 		sb_rid=bg_skybox->get_rid();
 	print_line("skybox valid: "+itos(sb_rid.is_valid()));
 
-	VS::get_singleton()->environment_set_skybox(environment,sb_rid,Globals::get_singleton()->get("rendering/skybox/radiance_cube_resolution"),Globals::get_singleton()->get("rendering/skybox/iradiance_cube_resolution"));
+	VS::get_singleton()->environment_set_skybox(environment,sb_rid,Globals::get_singleton()->get("rendering/skybox/radiance_cube_resolution"));
 }
 
 void Environment::set_skybox_scale(float p_scale) {
@@ -80,17 +80,17 @@ void Environment::set_canvas_max_layer(int p_max_layer){
 void Environment::set_ambient_light_color(const Color& p_color){
 
 	ambient_color=p_color;
-	VS::get_singleton()->environment_set_ambient_light(environment,ambient_color,ambient_energy,ambient_skybox_energy);
+	VS::get_singleton()->environment_set_ambient_light(environment,ambient_color,ambient_energy,ambient_skybox_contribution);
 }
 void Environment::set_ambient_light_energy(float p_energy){
 
 	ambient_energy=p_energy;
-	VS::get_singleton()->environment_set_ambient_light(environment,ambient_color,ambient_energy,ambient_skybox_energy);
+	VS::get_singleton()->environment_set_ambient_light(environment,ambient_color,ambient_energy,ambient_skybox_contribution);
 }
-void Environment::set_ambient_light_skybox_energy(float p_energy){
+void Environment::set_ambient_light_skybox_contribution(float p_energy){
 
-	ambient_skybox_energy=p_energy;
-	VS::get_singleton()->environment_set_ambient_light(environment,ambient_color,ambient_energy,ambient_skybox_energy);
+	ambient_skybox_contribution=p_energy;
+	VS::get_singleton()->environment_set_ambient_light(environment,ambient_color,ambient_energy,ambient_skybox_contribution);
 }
 
 Environment::BGMode Environment::get_background() const{
@@ -127,16 +127,16 @@ float Environment::get_ambient_light_energy() const{
 
 	return ambient_energy;
 }
-float Environment::get_ambient_light_skybox_energy() const{
+float Environment::get_ambient_light_skybox_contribution() const{
 
-	return ambient_skybox_energy;
+	return ambient_skybox_contribution;
 }
 
 
 
 void Environment::_validate_property(PropertyInfo& property) const {
 
-	if (property.name=="background/skybox" || property.name=="ambient_light/skybox_energy") {
+	if (property.name=="background/skybox" || property.name=="background/skybox_scale" || property.name=="ambient_light/skybox_contribution") {
 		if (bg_mode!=BG_SKYBOX) {
 			property.usage=PROPERTY_USAGE_NOEDITOR;
 		}
@@ -166,7 +166,7 @@ void Environment::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("set_canvas_max_layer","layer"),&Environment::set_canvas_max_layer);
 	ObjectTypeDB::bind_method(_MD("set_ambient_light_color","color"),&Environment::set_ambient_light_color);
 	ObjectTypeDB::bind_method(_MD("set_ambient_light_energy","energy"),&Environment::set_ambient_light_energy);
-	ObjectTypeDB::bind_method(_MD("set_ambient_light_skybox_energy","energy"),&Environment::set_ambient_light_skybox_energy);
+	ObjectTypeDB::bind_method(_MD("set_ambient_light_skybox_contribution","energy"),&Environment::set_ambient_light_skybox_contribution);
 
 
 	ObjectTypeDB::bind_method(_MD("get_background"),&Environment::get_background);
@@ -177,7 +177,7 @@ void Environment::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("get_canvas_max_layer"),&Environment::get_canvas_max_layer);
 	ObjectTypeDB::bind_method(_MD("get_ambient_light_color"),&Environment::get_ambient_light_color);
 	ObjectTypeDB::bind_method(_MD("get_ambient_light_energy"),&Environment::get_ambient_light_energy);
-	ObjectTypeDB::bind_method(_MD("get_ambient_light_skybox_energy"),&Environment::get_ambient_light_skybox_energy);
+	ObjectTypeDB::bind_method(_MD("get_ambient_light_skybox_contribution"),&Environment::get_ambient_light_skybox_contribution);
 
 
 	ADD_PROPERTY(PropertyInfo(Variant::INT,"background/mode",PROPERTY_HINT_ENUM,"Clear Color,Custom Color,Skybox,Canvas,Keep"),_SCS("set_background"),_SCS("get_background") );
@@ -188,7 +188,7 @@ void Environment::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::INT,"background/canvas_max_layer",PROPERTY_HINT_RANGE,"-1000,1000,1"),_SCS("set_canvas_max_layer"),_SCS("get_canvas_max_layer") );
 	ADD_PROPERTY(PropertyInfo(Variant::COLOR,"ambient_light/color"),_SCS("set_ambient_light_color"),_SCS("get_ambient_light_color") );
 	ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_light/energy",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_ambient_light_energy"),_SCS("get_ambient_light_energy") );
-	ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_light/skybox_energy",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_ambient_light_skybox_energy"),_SCS("get_ambient_light_skybox_energy") );
+	ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_light/skybox_contribution",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_ambient_light_skybox_contribution"),_SCS("get_ambient_light_skybox_contribution") );
 
 	GLOBAL_DEF("rendering/skybox/irradiance_cube_resolution",256);
 	GLOBAL_DEF("rendering/skybox/radiance_cube_resolution",64);
@@ -209,10 +209,11 @@ void Environment::_bind_methods() {
 Environment::Environment() {
 
 	bg_mode=BG_CLEAR_COLOR;
+	bg_skybox_scale=1.0;
 	bg_energy=1.0;
 	bg_canvas_max_layer=0;
 	ambient_energy=1.0;
-	ambient_skybox_energy=0;
+	ambient_skybox_contribution=0;
 
 
 	environment = VS::get_singleton()->environment_create();

+ 3 - 3
scene/resources/environment.h

@@ -66,7 +66,7 @@ private:
 	int bg_canvas_max_layer;
 	Color ambient_color;
 	float ambient_energy;
-	float ambient_skybox_energy;
+	float ambient_skybox_contribution;
 
 protected:
 
@@ -84,7 +84,7 @@ public:
 	void set_canvas_max_layer(int p_max_layer);
 	void set_ambient_light_color(const Color& p_color);
 	void set_ambient_light_energy(float p_energy);
-	void set_ambient_light_skybox_energy(float p_energy);
+	void set_ambient_light_skybox_contribution(float p_energy);
 
 	BGMode get_background() const;
 	Ref<CubeMap> get_skybox() const;
@@ -94,7 +94,7 @@ public:
 	int get_canvas_max_layer() const;
 	Color get_ambient_light_color() const;
 	float get_ambient_light_energy() const;
-	float get_ambient_light_skybox_energy() const;
+	float get_ambient_light_skybox_contribution() const;
 
 
 	virtual RID get_rid() const;

+ 751 - 3
scene/resources/material.cpp

@@ -45,14 +45,762 @@ Material::~Material() {
 }
 
 
-FixedMaterial::FixedMaterial() {
+/////////////////////////////////
+
+Mutex *FixedSpatialMaterial::material_mutex=NULL;
+SelfList<FixedSpatialMaterial>::List FixedSpatialMaterial::dirty_materials;
+Map<FixedSpatialMaterial::MaterialKey,FixedSpatialMaterial::ShaderData> FixedSpatialMaterial::shader_map;
+FixedSpatialMaterial::ShaderNames* FixedSpatialMaterial::shader_names=NULL;
+
+void FixedSpatialMaterial::init_shaders() {
+
+#ifndef NO_THREADS
+	material_mutex = Mutex::create();
+#endif
+
+	shader_names = memnew( ShaderNames );
 
+	shader_names->albedo="albedo";
+	shader_names->specular="specular";
+	shader_names->roughness="roughness";
+	shader_names->emission="emission";
+	shader_names->normal_scale="normal_scale";
+	shader_names->sheen="sheen";
+	shader_names->sheen_color="sheen_color";
+	shader_names->clearcoat="clearcoat";
+	shader_names->clearcoat_gloss="clearcoat_gloss";
+	shader_names->anisotropy="anisotropy";
+	shader_names->height_scale="height_scale";
+	shader_names->subsurface_scattering="subsurface_scattering";
+	shader_names->refraction="refraction";
+	shader_names->refraction_roughness="refraction_roughness";
+
+	shader_names->texture_names[TEXTURE_ALBEDO]="texture_albedo";
+	shader_names->texture_names[TEXTURE_SPECULAR]="texture_specular";
+	shader_names->texture_names[TEXTURE_EMISSION]="texture_emission";
+	shader_names->texture_names[TEXTURE_NORMAL]="texture_normal";
+	shader_names->texture_names[TEXTURE_SHEEN]="texture_sheen";
+	shader_names->texture_names[TEXTURE_CLEARCOAT]="texture_clearcoat";
+	shader_names->texture_names[TEXTURE_ANISOTROPY]="texture_anisotropy";
+	shader_names->texture_names[TEXTURE_AMBIENT_OCCLUSION]="texture_ambient_occlusion";
+	shader_names->texture_names[TEXTURE_HEIGHT]="texture_height";
+	shader_names->texture_names[TEXTURE_SUBSURFACE_SCATTERING]="texture_subsurface_scattering";
+	shader_names->texture_names[TEXTURE_REFRACTION]="texture_refraction";
+	shader_names->texture_names[TEXTURE_REFRACTION_ROUGHNESS]="texture_refraction_roughness";
+	shader_names->texture_names[TEXTURE_DETAIL_MASK]="texture_detail_mask";
+	shader_names->texture_names[TEXTURE_DETAIL_ALBEDO]="texture_detail_albedo";
+	shader_names->texture_names[TEXTURE_DETAIL_NORMAL]="texture_detail_normal";
 
 }
 
-FixedMaterial::~FixedMaterial() {
+void FixedSpatialMaterial::finish_shaders(){
+
+#ifndef NO_THREADS
+	memdelete( material_mutex );
+#endif
 
+	memdelete( shader_names );
 
 }
 
-/////////////////////////////////
+
+
+void FixedSpatialMaterial::_update_shader() {
+
+	dirty_materials.remove( &element );
+
+	MaterialKey mk = _compute_key();
+	if (mk.key==current_key.key)
+		return; //no update required in the end
+
+	if (shader_map.has(current_key)) {
+		shader_map[current_key].users--;
+		if (shader_map[current_key].users==0) {
+			//deallocate shader, as it's no longer in use
+			VS::get_singleton()->free(shader_map[current_key].shader);
+			shader_map.erase(current_key);
+		}
+	}
+
+	current_key=mk;
+
+	if (shader_map.has(mk)) {
+
+		VS::get_singleton()->material_set_shader(_get_material(),shader_map[mk].shader);
+		shader_map[mk].users++;
+		return;
+	}
+
+	//must create a shader!
+
+	String code="render_mode ";
+	switch(blend_mode) {
+		case BLEND_MODE_MIX: code+="blend_mix"; break;
+		case BLEND_MODE_ADD: code+="blend_add"; break;
+		case BLEND_MODE_SUB: code+="blend_sub"; break;
+		case BLEND_MODE_MUL: code+="blend_mul"; break;
+	}
+
+	switch(depth_draw_mode) {
+		case DEPTH_DRAW_OPAQUE_ONLY: code+=",depth_draw_opaque"; break;
+		case DEPTH_DRAW_ALWAYS: code+=",depth_draw_always"; break;
+		case DEPTH_DRAW_DISABLED: code+=",depth_draw_never"; break;
+		case DEPTH_DRAW_ALPHA_OPAQUE_PREPASS: code+=",depth_draw_alpha_prepass"; break;
+	}
+
+	switch(cull_mode) {
+		case CULL_BACK: code+=",cull_back"; break;
+		case CULL_FRONT: code+=",cull_front"; break;
+		case CULL_DISABLED: code+=",cull_disable"; break;
+
+	}
+
+	if (flags[FLAG_UNSHADED]) {
+		code+=",unshaded";
+	}
+	if (flags[FLAG_ONTOP]) {
+		code+=",ontop";
+	}
+
+	code+=";\n";
+
+
+	code+="uniform vec4 albedo : hint_color;\n";
+	code+="uniform sampler2D albedo_texture : hint_albedo;\n";
+	code+="uniform vec4 specular : hint_color;\n";
+	code+="uniform float roughness : hint_range(0,1);\n";
+	code+="uniform sampler2D specular_texture : hint_white;\n";
+	code+="\n\n";
+
+	code+="\n\n";
+	code+="void fragment() {\n";
+	code+="\tvec4 albedo_tex = texture(albedo_texture,UV);\n";
+
+	if (flags[FLAG_ALBEDO_FROM_VERTEX_COLOR]) {
+		code+="\talbedo_tex *= COLOR;\n";
+	}
+
+	code+="\tALBEDO = albedo.rgb * albedo_tex.rgb;\n";
+	if (features[FEATURE_TRANSPARENT]) {
+		code+="\tALPHA = albedo.a * albedo_tex.a;\n";
+	}
+	code+="\tvec4 specular_tex = texture(specular_texture,UV);\n";
+	code+="\tSPECULAR = specular.rgb * specular_tex.rgb;\n";
+	code+="\tROUGHNESS = specular.a * roughness;\n";
+	code+="}\n";
+
+	ShaderData shader_data;
+	shader_data.shader = VS::get_singleton()->shader_create(VS::SHADER_SPATIAL);
+	shader_data.users=1;
+
+	VS::get_singleton()->shader_set_code( shader_data.shader, code );
+
+	shader_map[mk]=shader_data;
+
+	VS::get_singleton()->material_set_shader(_get_material(),shader_data.shader);
+
+}
+
+void FixedSpatialMaterial::flush_changes() {
+
+	if (material_mutex)
+		material_mutex->lock();
+
+	while (dirty_materials.first()) {
+
+		dirty_materials.first()->self()->_update_shader();
+	}
+
+	if (material_mutex)
+		material_mutex->unlock();
+}
+
+void FixedSpatialMaterial::_queue_shader_change() {
+
+	if (material_mutex)
+		material_mutex->lock();
+
+	if (!element.in_list()) {
+		dirty_materials.add(&element);
+	}
+
+	if (material_mutex)
+		material_mutex->unlock();
+
+
+}
+
+bool FixedSpatialMaterial::_is_shader_dirty() const {
+
+	bool dirty=false;
+
+	if (material_mutex)
+		material_mutex->lock();
+
+	dirty=element.in_list();
+
+	if (material_mutex)
+		material_mutex->unlock();
+
+	return dirty;
+}
+void FixedSpatialMaterial::set_albedo(const Color& p_albedo) {
+
+	albedo=p_albedo;
+
+	VS::get_singleton()->material_set_param(_get_material(),shader_names->albedo,p_albedo);
+}
+
+Color FixedSpatialMaterial::get_albedo() const{
+
+	return albedo;
+}
+
+void FixedSpatialMaterial::set_specular(const Color& p_specular){
+
+	specular=p_specular;
+	VS::get_singleton()->material_set_param(_get_material(),shader_names->specular,p_specular);
+
+}
+Color FixedSpatialMaterial::get_specular() const{
+
+	return specular;
+}
+
+void FixedSpatialMaterial::set_roughness(float p_roughness){
+
+	roughness=p_roughness;
+	VS::get_singleton()->material_set_param(_get_material(),shader_names->roughness,p_roughness);
+
+}
+float FixedSpatialMaterial::get_roughness() const{
+
+	return roughness;
+}
+
+void FixedSpatialMaterial::set_emission(const Color& p_emission){
+
+	emission=p_emission;
+	VS::get_singleton()->material_set_param(_get_material(),shader_names->emission,p_emission);
+
+}
+Color FixedSpatialMaterial::get_emission() const{
+
+	return emission;
+}
+
+void FixedSpatialMaterial::set_normal_scale(float p_normal_scale){
+
+	normal_scale=p_normal_scale;
+	VS::get_singleton()->material_set_param(_get_material(),shader_names->normal_scale,p_normal_scale);
+
+}
+float FixedSpatialMaterial::get_normal_scale() const{
+
+	return normal_scale;
+}
+
+void FixedSpatialMaterial::set_sheen(float p_sheen){
+
+	sheen=p_sheen;
+	VS::get_singleton()->material_set_param(_get_material(),shader_names->sheen,p_sheen);
+
+
+}
+float FixedSpatialMaterial::get_sheen() const{
+
+	return sheen;
+}
+
+void FixedSpatialMaterial::set_sheen_color(const Color& p_sheen_color){
+
+	sheen_color=p_sheen_color;
+	VS::get_singleton()->material_set_param(_get_material(),shader_names->sheen_color,p_sheen_color);
+
+}
+Color FixedSpatialMaterial::get_sheen_color() const{
+
+	return sheen_color;
+}
+
+void FixedSpatialMaterial::set_clearcoat(float p_clearcoat){
+
+	clearcoat=p_clearcoat;
+	VS::get_singleton()->material_set_param(_get_material(),shader_names->clearcoat,p_clearcoat);
+
+}
+
+float FixedSpatialMaterial::get_clearcoat() const{
+
+	return clearcoat;
+}
+
+void FixedSpatialMaterial::set_clearcoat_gloss(float p_clearcoat_gloss){
+
+	clearcoat_gloss=p_clearcoat_gloss;
+	VS::get_singleton()->material_set_param(_get_material(),shader_names->clearcoat_gloss,p_clearcoat_gloss);
+
+
+}
+
+float FixedSpatialMaterial::get_clearcoat_gloss() const{
+
+	return clearcoat_gloss;
+}
+
+void FixedSpatialMaterial::set_anisotropy(float p_anisotropy){
+
+	anisotropy=p_anisotropy;
+	VS::get_singleton()->material_set_param(_get_material(),shader_names->anisotropy,p_anisotropy);
+
+}
+float FixedSpatialMaterial::get_anisotropy() const{
+
+	return anisotropy;
+}
+
+void FixedSpatialMaterial::set_height_scale(float p_height_scale){
+
+	height_scale=p_height_scale;
+	VS::get_singleton()->material_set_param(_get_material(),shader_names->height_scale,p_height_scale);
+
+
+}
+
+float FixedSpatialMaterial::get_height_scale() const{
+
+	return height_scale;
+}
+
+void FixedSpatialMaterial::set_subsurface_scattering(float p_subsurface_scattering){
+
+	subsurface_scattering=p_subsurface_scattering;
+	VS::get_singleton()->material_set_param(_get_material(),shader_names->subsurface_scattering,subsurface_scattering);
+
+
+}
+
+float FixedSpatialMaterial::get_subsurface_scattering() const{
+
+	return subsurface_scattering;
+}
+
+void FixedSpatialMaterial::set_refraction(float p_refraction){
+
+	refraction=p_refraction;
+	VS::get_singleton()->material_set_param(_get_material(),shader_names->refraction,refraction);
+
+}
+
+float FixedSpatialMaterial::get_refraction() const {
+
+	return refraction;
+}
+
+void FixedSpatialMaterial::set_refraction_roughness(float p_refraction_roughness) {
+
+	refraction_roughness=p_refraction_roughness;
+	VS::get_singleton()->material_set_param(_get_material(),shader_names->refraction_roughness,refraction_roughness);
+
+
+}
+float FixedSpatialMaterial::get_refraction_roughness() const {
+
+	return refraction_roughness;
+}
+
+void FixedSpatialMaterial::set_detail_uv(DetailUV p_detail_uv) {
+
+	if (detail_uv==p_detail_uv)
+		return;
+
+	detail_uv=p_detail_uv;
+	_queue_shader_change();
+}
+FixedSpatialMaterial::DetailUV FixedSpatialMaterial::get_detail_uv() const {
+
+	return detail_uv;
+}
+
+void FixedSpatialMaterial::set_blend_mode(BlendMode p_mode) {
+
+	if (blend_mode==p_mode)
+		return;
+
+	blend_mode=p_mode;
+	_queue_shader_change();
+}
+FixedSpatialMaterial::BlendMode FixedSpatialMaterial::get_blend_mode() const {
+
+	return blend_mode;
+}
+
+void FixedSpatialMaterial::set_detail_blend_mode(BlendMode p_mode) {
+
+	detail_blend_mode=p_mode;
+	_queue_shader_change();
+}
+FixedSpatialMaterial::BlendMode FixedSpatialMaterial::get_detail_blend_mode() const {
+
+	return detail_blend_mode;
+}
+
+void FixedSpatialMaterial::set_depth_draw_mode(DepthDrawMode p_mode) {
+
+	if (depth_draw_mode==p_mode)
+		return;
+
+	depth_draw_mode=p_mode;
+	_queue_shader_change();
+}
+FixedSpatialMaterial::DepthDrawMode FixedSpatialMaterial::get_depth_draw_mode() const {
+
+	return depth_draw_mode;
+}
+
+void FixedSpatialMaterial::set_cull_mode(CullMode p_mode) {
+
+	if (cull_mode==p_mode)
+		return;
+
+	cull_mode=p_mode;
+	_queue_shader_change();
+}
+FixedSpatialMaterial::CullMode FixedSpatialMaterial::get_cull_mode() const {
+
+	return cull_mode;
+}
+
+void FixedSpatialMaterial::set_diffuse_mode(DiffuseMode p_mode) {
+
+	if (diffuse_mode==p_mode)
+		return;
+
+	diffuse_mode=p_mode;
+	_queue_shader_change();
+}
+FixedSpatialMaterial::DiffuseMode FixedSpatialMaterial::get_diffuse_mode() const {
+
+	return diffuse_mode;
+}
+
+void FixedSpatialMaterial::set_flag(Flags p_flag,bool p_enabled) {
+
+	ERR_FAIL_INDEX(p_flag,FLAG_MAX);
+
+	if (flags[p_flag]==p_enabled)
+		return;
+
+	flags[p_flag]=p_enabled;
+	_queue_shader_change();
+}
+
+bool FixedSpatialMaterial::get_flag(Flags p_flag) const {
+
+	ERR_FAIL_INDEX_V(p_flag,FLAG_MAX,false);
+	return flags[p_flag];
+}
+
+void FixedSpatialMaterial::set_feature(Feature p_feature,bool p_enabled) {
+
+	ERR_FAIL_INDEX(p_feature,FEATURE_MAX);
+	if (features[p_feature]==p_enabled)
+		return;
+
+	features[p_feature]=p_enabled;
+	_change_notify();
+	_queue_shader_change();
+
+
+}
+
+bool FixedSpatialMaterial::get_feature(Feature p_feature) const {
+
+	ERR_FAIL_INDEX_V(p_feature,FEATURE_MAX,false);
+	return features[p_feature];
+}
+
+
+
+void FixedSpatialMaterial::set_texture(TextureParam p_param, const Ref<Texture> &p_texture) {
+
+	ERR_FAIL_INDEX(p_param,TEXTURE_MAX);
+	textures[p_param]=p_texture;
+	VS::get_singleton()->material_set_param(_get_material(),shader_names->texture_names[p_param],p_texture);
+}
+
+Ref<Texture> FixedSpatialMaterial::get_texture(TextureParam p_param) const {
+
+	ERR_FAIL_INDEX_V(p_param,TEXTURE_MAX,Ref<Texture>());
+	return textures[p_param];
+}
+
+
+void FixedSpatialMaterial::_validate_feature(const String& text, Feature feature,PropertyInfo& property) const {
+	if (property.name.begins_with(text) && property.name!=text+"/enabled" && !features[feature]) {
+		property.usage=0;
+	}
+}
+
+void FixedSpatialMaterial::_validate_property(PropertyInfo& property) const {
+	_validate_feature("normal",FEATURE_NORMAL_MAPPING,property);
+	_validate_feature("sheen",FEATURE_SHEEN,property);
+	_validate_feature("clearcoat",FEATURE_CLEARCOAT,property);
+	_validate_feature("anisotropy",FEATURE_ANISOTROPY,property);
+	_validate_feature("ao",FEATURE_AMBIENT_OCCLUSION,property);
+	_validate_feature("height",FEATURE_HEIGHT_MAPPING,property);
+	_validate_feature("subsurf_scatter",FEATURE_SUBSURACE_SCATTERING,property);
+	_validate_feature("refraction",FEATURE_REFRACTION,property);
+	_validate_feature("detail",FEATURE_DETAIL,property);
+
+}
+
+void FixedSpatialMaterial::_bind_methods() {
+
+
+	ObjectTypeDB::bind_method(_MD("set_albedo","albedo"),&FixedSpatialMaterial::set_albedo);
+	ObjectTypeDB::bind_method(_MD("get_albedo"),&FixedSpatialMaterial::get_albedo);
+
+	ObjectTypeDB::bind_method(_MD("set_specular","specular"),&FixedSpatialMaterial::set_specular);
+	ObjectTypeDB::bind_method(_MD("get_specular"),&FixedSpatialMaterial::get_specular);
+
+	ObjectTypeDB::bind_method(_MD("set_roughness","roughness"),&FixedSpatialMaterial::set_roughness);
+	ObjectTypeDB::bind_method(_MD("get_roughness"),&FixedSpatialMaterial::get_roughness);
+
+	ObjectTypeDB::bind_method(_MD("set_emission","emission"),&FixedSpatialMaterial::set_emission);
+	ObjectTypeDB::bind_method(_MD("get_emission"),&FixedSpatialMaterial::get_emission);
+
+	ObjectTypeDB::bind_method(_MD("set_normal_scale","normal_scale"),&FixedSpatialMaterial::set_normal_scale);
+	ObjectTypeDB::bind_method(_MD("get_normal_scale"),&FixedSpatialMaterial::get_normal_scale);
+
+	ObjectTypeDB::bind_method(_MD("set_sheen","sheen"),&FixedSpatialMaterial::set_sheen);
+	ObjectTypeDB::bind_method(_MD("get_sheen"),&FixedSpatialMaterial::get_sheen);
+
+	ObjectTypeDB::bind_method(_MD("set_sheen_color","sheen_color"),&FixedSpatialMaterial::set_sheen_color);
+	ObjectTypeDB::bind_method(_MD("get_sheen_color"),&FixedSpatialMaterial::get_sheen_color);
+
+	ObjectTypeDB::bind_method(_MD("set_clearcoat","clearcoat"),&FixedSpatialMaterial::set_clearcoat);
+	ObjectTypeDB::bind_method(_MD("get_clearcoat"),&FixedSpatialMaterial::get_clearcoat);
+
+	ObjectTypeDB::bind_method(_MD("set_clearcoat_gloss","clearcoat_gloss"),&FixedSpatialMaterial::set_clearcoat_gloss);
+	ObjectTypeDB::bind_method(_MD("get_clearcoat_gloss"),&FixedSpatialMaterial::get_clearcoat_gloss);
+
+	ObjectTypeDB::bind_method(_MD("set_anisotropy","anisotropy"),&FixedSpatialMaterial::set_anisotropy);
+	ObjectTypeDB::bind_method(_MD("get_anisotropy"),&FixedSpatialMaterial::get_anisotropy);
+
+	ObjectTypeDB::bind_method(_MD("set_height_scale","height_scale"),&FixedSpatialMaterial::set_height_scale);
+	ObjectTypeDB::bind_method(_MD("get_height_scale"),&FixedSpatialMaterial::get_height_scale);
+
+	ObjectTypeDB::bind_method(_MD("set_subsurface_scattering","subsurface_scattering"),&FixedSpatialMaterial::set_subsurface_scattering);
+	ObjectTypeDB::bind_method(_MD("get_subsurface_scattering"),&FixedSpatialMaterial::get_subsurface_scattering);
+
+	ObjectTypeDB::bind_method(_MD("set_refraction","refraction"),&FixedSpatialMaterial::set_refraction);
+	ObjectTypeDB::bind_method(_MD("get_refraction"),&FixedSpatialMaterial::get_refraction);
+
+	ObjectTypeDB::bind_method(_MD("set_refraction_roughness","refraction_roughness"),&FixedSpatialMaterial::set_refraction_roughness);
+	ObjectTypeDB::bind_method(_MD("get_refraction_roughness"),&FixedSpatialMaterial::get_refraction_roughness);
+
+	ObjectTypeDB::bind_method(_MD("set_detail_uv","detail_uv"),&FixedSpatialMaterial::set_detail_uv);
+	ObjectTypeDB::bind_method(_MD("get_detail_uv"),&FixedSpatialMaterial::get_detail_uv);
+
+	ObjectTypeDB::bind_method(_MD("set_blend_mode","blend_mode"),&FixedSpatialMaterial::set_blend_mode);
+	ObjectTypeDB::bind_method(_MD("get_blend_mode"),&FixedSpatialMaterial::get_blend_mode);
+
+	ObjectTypeDB::bind_method(_MD("set_depth_draw_mode","depth_draw_mode"),&FixedSpatialMaterial::set_depth_draw_mode);
+	ObjectTypeDB::bind_method(_MD("get_depth_draw_mode"),&FixedSpatialMaterial::get_depth_draw_mode);
+
+	ObjectTypeDB::bind_method(_MD("set_cull_mode","cull_mode"),&FixedSpatialMaterial::set_cull_mode);
+	ObjectTypeDB::bind_method(_MD("get_cull_mode"),&FixedSpatialMaterial::get_cull_mode);
+
+	ObjectTypeDB::bind_method(_MD("set_diffuse_mode","diffuse_mode"),&FixedSpatialMaterial::set_diffuse_mode);
+	ObjectTypeDB::bind_method(_MD("get_diffuse_mode"),&FixedSpatialMaterial::get_diffuse_mode);
+
+	ObjectTypeDB::bind_method(_MD("set_flag","flag","enable"),&FixedSpatialMaterial::set_flag);
+	ObjectTypeDB::bind_method(_MD("get_flag"),&FixedSpatialMaterial::get_flag);
+
+	ObjectTypeDB::bind_method(_MD("set_feature","feature","enable"),&FixedSpatialMaterial::set_feature);
+	ObjectTypeDB::bind_method(_MD("get_feature","feature"),&FixedSpatialMaterial::get_feature);
+
+	ObjectTypeDB::bind_method(_MD("set_texture","param:Texture","texture"),&FixedSpatialMaterial::set_texture);
+	ObjectTypeDB::bind_method(_MD("get_texture:Texture","param:Texture"),&FixedSpatialMaterial::get_texture);
+
+	ObjectTypeDB::bind_method(_MD("set_detail_blend_mode","detail_blend_mode"),&FixedSpatialMaterial::set_detail_blend_mode);
+	ObjectTypeDB::bind_method(_MD("get_detail_blend_mode"),&FixedSpatialMaterial::get_detail_blend_mode);
+
+	ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"flags/transparent"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_TRANSPARENT);
+	ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"flags/unshaded"),_SCS("set_flag"),_SCS("get_flag"),FLAG_UNSHADED);
+	ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"flags/on_top"),_SCS("set_flag"),_SCS("get_flag"),FLAG_ONTOP);
+	ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"flags/vcol_albedo"),_SCS("set_flag"),_SCS("get_flag"),FLAG_ALBEDO_FROM_VERTEX_COLOR);
+
+	ADD_PROPERTY(PropertyInfo(Variant::INT,"params/diffuse_mode",PROPERTY_HINT_ENUM,"Labert,Lambert Wrap,Oren Nayar,Burley"),_SCS("set_diffuse_mode"),_SCS("get_diffuse_mode"));
+	ADD_PROPERTY(PropertyInfo(Variant::INT,"params/blend_mode",PROPERTY_HINT_ENUM,"Mix,Add,Sub,Mul"),_SCS("set_blend_mode"),_SCS("get_blend_mode"));
+	ADD_PROPERTY(PropertyInfo(Variant::INT,"params/cull_mode",PROPERTY_HINT_ENUM,"Back,Front,Disabled"),_SCS("set_cull_mode"),_SCS("get_cull_mode"));
+	ADD_PROPERTY(PropertyInfo(Variant::INT,"params/depth_draw_mode",PROPERTY_HINT_ENUM,"Opaque Only,Always,Never,Opaque Pre-Pass"),_SCS("set_depth_draw_mode"),_SCS("get_depth_draw_mode"));
+
+	ADD_PROPERTY(PropertyInfo(Variant::COLOR,"albedo/color"),_SCS("set_albedo"),_SCS("get_albedo"));
+	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"albedo/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_ALBEDO);
+
+	ADD_PROPERTY(PropertyInfo(Variant::COLOR,"specular/color"),_SCS("set_specular"),_SCS("get_specular"));
+	ADD_PROPERTY(PropertyInfo(Variant::REAL,"specular/roughness",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_roughness"),_SCS("get_roughness"));
+	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"specular/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_SPECULAR);
+
+	ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"normal/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_NORMAL_MAPPING);
+	ADD_PROPERTY(PropertyInfo(Variant::REAL,"normal/scale",PROPERTY_HINT_RANGE,"-16,16,0.01"),_SCS("set_normal_scale"),_SCS("get_normal_scale"));
+	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"normal/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_NORMAL);
+
+	ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"sheen/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_SHEEN);
+	ADD_PROPERTY(PropertyInfo(Variant::REAL,"sheen/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_sheen"),_SCS("get_sheen"));
+	ADD_PROPERTY(PropertyInfo(Variant::REAL,"sheen/color"),_SCS("set_sheen_color"),_SCS("get_sheen_color"));
+	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"sheen/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_SHEEN);
+
+	ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"clearcoat/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_CLEARCOAT);
+	ADD_PROPERTY(PropertyInfo(Variant::REAL,"clearcoat/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_clearcoat"),_SCS("get_clearcoat"));
+	ADD_PROPERTY(PropertyInfo(Variant::REAL,"clearcoat/gloss"),_SCS("set_clearcoat_gloss"),_SCS("get_clearcoat_gloss"));
+	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"clearcoat/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_CLEARCOAT);
+
+	ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"anisotropy/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_ANISOTROPY);
+	ADD_PROPERTY(PropertyInfo(Variant::REAL,"anisotropy/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_anisotropy"),_SCS("get_anisotropy"));
+	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"anisotropy/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_ANISOTROPY);
+
+	ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"ao/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_AMBIENT_OCCLUSION);
+	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"ao/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_AMBIENT_OCCLUSION);
+
+	ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"height/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_HEIGHT_MAPPING);
+	ADD_PROPERTY(PropertyInfo(Variant::REAL,"height/scale",PROPERTY_HINT_RANGE,"-16,16,0.01"),_SCS("set_height_scale"),_SCS("get_height_scale"));
+	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"height/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_HEIGHT);
+
+	ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"subsurf_scatter/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_SUBSURACE_SCATTERING);
+	ADD_PROPERTY(PropertyInfo(Variant::REAL,"subsurf_scatter/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_subsurface_scattering"),_SCS("get_subsurface_scattering"));
+	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"subsurf_scatter/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_SUBSURFACE_SCATTERING);
+
+	ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"refraction/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_REFRACTION);
+	ADD_PROPERTY(PropertyInfo(Variant::REAL,"refraction/displacement",PROPERTY_HINT_RANGE,"-1,1,0.01"),_SCS("set_refraction"),_SCS("get_refraction"));
+	ADD_PROPERTY(PropertyInfo(Variant::REAL,"refraction/roughness",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_refraction_roughness"),_SCS("get_refraction_roughness"));
+	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"refraction/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_REFRACTION);
+
+	ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"detail/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_DETAIL);
+	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"detail/mask",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_DETAIL_MASK);
+	ADD_PROPERTY(PropertyInfo(Variant::INT,"detail/blend_mode",PROPERTY_HINT_ENUM,"Mix,Add,Sub,Mul"),_SCS("set_detail_blend_mode"),_SCS("get_detail_blend_mode"));
+	ADD_PROPERTY(PropertyInfo(Variant::INT,"detail/uv_layer",PROPERTY_HINT_ENUM,"UV1,UV2"),_SCS("set_detail_uv"),_SCS("get_detail_uv"));
+	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"detail/albedo",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_DETAIL_ALBEDO);
+	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"detail/normal",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_DETAIL_NORMAL);
+
+	BIND_CONSTANT( TEXTURE_ALBEDO );
+	BIND_CONSTANT( TEXTURE_SPECULAR );
+	BIND_CONSTANT( TEXTURE_EMISSION );
+	BIND_CONSTANT( TEXTURE_NORMAL );
+	BIND_CONSTANT( TEXTURE_SHEEN );
+	BIND_CONSTANT( TEXTURE_CLEARCOAT );
+	BIND_CONSTANT( TEXTURE_ANISOTROPY );
+	BIND_CONSTANT( TEXTURE_AMBIENT_OCCLUSION );
+	BIND_CONSTANT( TEXTURE_HEIGHT );
+	BIND_CONSTANT( TEXTURE_SUBSURFACE_SCATTERING );
+	BIND_CONSTANT( TEXTURE_REFRACTION );
+	BIND_CONSTANT( TEXTURE_REFRACTION_ROUGHNESS );
+	BIND_CONSTANT( TEXTURE_DETAIL_MASK );
+	BIND_CONSTANT( TEXTURE_DETAIL_ALBEDO );
+	BIND_CONSTANT( TEXTURE_DETAIL_NORMAL );
+	BIND_CONSTANT( TEXTURE_MAX );
+
+
+	BIND_CONSTANT( DETAIL_UV_1 );
+	BIND_CONSTANT( DETAIL_UV_2 );
+
+	BIND_CONSTANT( FEATURE_TRANSPARENT );
+	BIND_CONSTANT( FEATURE_EMISSION );
+	BIND_CONSTANT( FEATURE_NORMAL_MAPPING );
+	BIND_CONSTANT( FEATURE_SHEEN );
+	BIND_CONSTANT( FEATURE_CLEARCOAT );
+	BIND_CONSTANT( FEATURE_ANISOTROPY );
+	BIND_CONSTANT( FEATURE_AMBIENT_OCCLUSION );
+	BIND_CONSTANT( FEATURE_HEIGHT_MAPPING );
+	BIND_CONSTANT( FEATURE_SUBSURACE_SCATTERING );
+	BIND_CONSTANT( FEATURE_REFRACTION );
+	BIND_CONSTANT( FEATURE_DETAIL );
+	BIND_CONSTANT( FEATURE_MAX );
+
+	BIND_CONSTANT( BLEND_MODE_MIX );
+	BIND_CONSTANT( BLEND_MODE_ADD );
+	BIND_CONSTANT( BLEND_MODE_SUB );
+	BIND_CONSTANT( BLEND_MODE_MUL );
+
+	BIND_CONSTANT( DEPTH_DRAW_OPAQUE_ONLY );
+	BIND_CONSTANT( DEPTH_DRAW_ALWAYS );
+	BIND_CONSTANT( DEPTH_DRAW_DISABLED );
+	BIND_CONSTANT( DEPTH_DRAW_ALPHA_OPAQUE_PREPASS );
+
+
+	BIND_CONSTANT( CULL_BACK );
+	BIND_CONSTANT( CULL_FRONT );
+	BIND_CONSTANT( CULL_DISABLED );
+
+	BIND_CONSTANT( FLAG_UNSHADED );
+	BIND_CONSTANT( FLAG_ONTOP );
+	BIND_CONSTANT( FLAG_ALBEDO_FROM_VERTEX_COLOR );
+	BIND_CONSTANT( FLAG_MAX );
+
+	BIND_CONSTANT( DIFFUSE_LAMBERT );
+	BIND_CONSTANT( DIFFUSE_LAMBERT_WRAP );
+	BIND_CONSTANT( DIFFUSE_OREN_NAYAR );
+	BIND_CONSTANT( DIFFUSE_BURLEY );
+}
+
+
+FixedSpatialMaterial::FixedSpatialMaterial() : element(this) {
+
+	//initialize to right values
+	set_albedo(Color(0.7,0.7,0.7,1.0));
+	set_specular(Color(0.1,0.1,0.1));
+	set_roughness(0.0);
+	set_emission(Color(0,0,0));
+	set_normal_scale(1);
+	set_sheen(0);
+	set_sheen_color(Color(1,1,1,1));
+	set_clearcoat(0);
+	set_clearcoat_gloss(0.5);
+	set_anisotropy(0);
+	set_height_scale(1);
+	set_subsurface_scattering(0);
+	set_refraction(0);
+	set_refraction_roughness(0);
+
+	detail_uv=DETAIL_UV_1;
+	blend_mode=BLEND_MODE_MIX;
+	detail_blend_mode=BLEND_MODE_MIX;
+	depth_draw_mode=DEPTH_DRAW_OPAQUE_ONLY;
+	cull_mode=CULL_BACK;
+	for(int i=0;i<FLAG_MAX;i++) {
+		flags[i]=0;
+	}
+	diffuse_mode=DIFFUSE_LAMBERT;
+
+	for(int i=0;i<FEATURE_MAX;i++) {
+		features[i]=false;
+	}
+
+	current_key.key=0;
+	current_key.invalid_key=1;
+	_queue_shader_change();
+}
+
+FixedSpatialMaterial::~FixedSpatialMaterial() {
+
+	if (material_mutex)
+		material_mutex->lock();
+
+	if (shader_map.has(current_key)) {
+		shader_map[current_key].users--;
+		if (shader_map[current_key].users==0) {
+			//deallocate shader, as it's no longer in use
+			VS::get_singleton()->free(shader_map[current_key].shader);
+			shader_map.erase(current_key);
+		}
+
+		VS::get_singleton()->material_set_shader(_get_material(),RID());
+	}
+
+
+	if (material_mutex)
+		material_mutex->unlock();
+
+}

+ 286 - 5
scene/resources/material.h

@@ -34,7 +34,7 @@
 #include "scene/resources/shader.h"
 #include "resource.h"
 #include "servers/visual/shader_language.h"
-
+#include "self_list.h"
 /**
 	@author Juan Linietsky <[email protected]>
 */
@@ -57,17 +57,298 @@ public:
 };
 
 
-class FixedMaterial : public Material {
+class FixedSpatialMaterial : public Material {
 
-	OBJ_TYPE(FixedMaterial,Resource);
+	OBJ_TYPE(FixedSpatialMaterial,Material)
 
 
 public:
 
-	FixedMaterial();
-	virtual ~FixedMaterial();
+	enum TextureParam {
+		TEXTURE_ALBEDO,
+		TEXTURE_SPECULAR,
+		TEXTURE_EMISSION,
+		TEXTURE_NORMAL,
+		TEXTURE_SHEEN,
+		TEXTURE_CLEARCOAT,
+		TEXTURE_ANISOTROPY,
+		TEXTURE_AMBIENT_OCCLUSION,
+		TEXTURE_HEIGHT,
+		TEXTURE_SUBSURFACE_SCATTERING,
+		TEXTURE_REFRACTION,
+		TEXTURE_REFRACTION_ROUGHNESS,
+		TEXTURE_DETAIL_MASK,
+		TEXTURE_DETAIL_ALBEDO,
+		TEXTURE_DETAIL_NORMAL,
+		TEXTURE_MAX
+
+
+	};
+
+
+	enum DetailUV {
+		DETAIL_UV_1,
+		DETAIL_UV_2
+	};
+
+	enum Feature {
+		FEATURE_TRANSPARENT,
+		FEATURE_EMISSION,
+		FEATURE_NORMAL_MAPPING,
+		FEATURE_SHEEN,
+		FEATURE_CLEARCOAT,
+		FEATURE_ANISOTROPY,
+		FEATURE_AMBIENT_OCCLUSION,
+		FEATURE_HEIGHT_MAPPING,
+		FEATURE_SUBSURACE_SCATTERING,
+		FEATURE_REFRACTION,
+		FEATURE_DETAIL,
+		FEATURE_MAX
+	};
+
+
+	enum BlendMode {
+		BLEND_MODE_MIX,
+		BLEND_MODE_ADD,
+		BLEND_MODE_SUB,
+		BLEND_MODE_MUL,
+	};
+
+	enum DepthDrawMode {
+		DEPTH_DRAW_OPAQUE_ONLY,
+		DEPTH_DRAW_ALWAYS,
+		DEPTH_DRAW_DISABLED,
+		DEPTH_DRAW_ALPHA_OPAQUE_PREPASS
+
+	};
+
+	enum CullMode {
+		CULL_BACK,
+		CULL_FRONT,
+		CULL_DISABLED
+	};
+
+	enum Flags {
+		FLAG_UNSHADED,
+		FLAG_ONTOP,
+		FLAG_ALBEDO_FROM_VERTEX_COLOR,
+		FLAG_MAX
+	};
+
+	enum DiffuseMode {
+		DIFFUSE_LAMBERT,
+		DIFFUSE_LAMBERT_WRAP,
+		DIFFUSE_OREN_NAYAR,
+		DIFFUSE_BURLEY,
+	};
+
+private:
+	union MaterialKey {
+
+		struct {
+			uint32_t feature_mask : 16;
+			uint32_t detail_uv : 1;
+			uint32_t blend_mode : 2;
+			uint32_t depth_draw_mode : 2;
+			uint32_t cull_mode : 2;
+			uint32_t flags : 3;
+			uint32_t detail_blend_mode : 2;
+			uint32_t diffuse_mode : 2;
+			uint32_t invalid_key : 1;
+		};
+
+		uint32_t key;
+
+		bool operator<(const MaterialKey& p_key) const {
+			return key < p_key.key;
+		}
+
+	};
+
+	struct ShaderData {
+		RID shader;
+		int users;
+	};
+
+	static Map<MaterialKey,ShaderData> shader_map;
+
+	MaterialKey current_key;
+
+	_FORCE_INLINE_ MaterialKey _compute_key() const {
+
+		MaterialKey mk;
+		mk.key=0;
+		for(int i=0;i<FEATURE_MAX;i++) {
+			if (features[i]) {
+				mk.feature_mask|=(1<<i);
+			}
+		}
+		mk.detail_uv=detail_uv;
+		mk.blend_mode=blend_mode;
+		mk.depth_draw_mode=depth_draw_mode;
+		mk.cull_mode=cull_mode;
+		for(int i=0;i<FLAG_MAX;i++) {
+			if (flags[i]) {
+				mk.flags|=(1<<i);
+			}
+		}
+		mk.detail_blend_mode=detail_blend_mode;
+		mk.diffuse_mode=diffuse_mode;
+
+		return mk;
+	}
+
+	struct ShaderNames {
+		StringName albedo;
+		StringName specular;
+		StringName roughness;
+		StringName emission;
+		StringName normal_scale;
+		StringName sheen;
+		StringName sheen_color;
+		StringName clearcoat;
+		StringName clearcoat_gloss;
+		StringName anisotropy;
+		StringName height_scale;
+		StringName subsurface_scattering;
+		StringName refraction;
+		StringName refraction_roughness;
+		StringName texture_names[TEXTURE_MAX];
+	};
+
+	static Mutex *material_mutex;
+	static SelfList<FixedSpatialMaterial>::List dirty_materials;
+	static ShaderNames* shader_names;
+
+	SelfList<FixedSpatialMaterial> element;
+
+	void _update_shader();
+	_FORCE_INLINE_ void _queue_shader_change();
+	_FORCE_INLINE_ bool _is_shader_dirty() const;
+
+	Color albedo;
+	Color specular;
+	float roughness;
+	Color emission;
+	float normal_scale;
+	float sheen;
+	Color sheen_color;
+	float clearcoat;
+	float clearcoat_gloss;
+	float anisotropy;
+	float height_scale;
+	float subsurface_scattering;
+	float refraction;
+	float refraction_roughness;
+
+	DetailUV detail_uv;
+
+	BlendMode blend_mode;
+	BlendMode detail_blend_mode;
+	DepthDrawMode depth_draw_mode;
+	CullMode cull_mode;
+	bool flags[FLAG_MAX];
+	DiffuseMode diffuse_mode;
+
+	bool features[FEATURE_MAX];
+
+	Ref<Texture> textures[TEXTURE_MAX];
+
+	_FORCE_INLINE_ void _validate_feature(const String& text, Feature feature,PropertyInfo& property) const;
+
+protected:
+
+	static void _bind_methods();
+	void _validate_property(PropertyInfo& property) const;
+
+public:
+
+
+	void set_albedo(const Color& p_albedo);
+	Color get_albedo() const;
+
+	void set_specular(const Color& p_specular);
+	Color get_specular() const;
+
+	void set_roughness(float p_roughness);
+	float get_roughness() const;
+
+	void set_emission(const Color& p_emission);
+	Color get_emission() const;
+
+	void set_normal_scale(float p_normal_scale);
+	float get_normal_scale() const;
+
+	void set_sheen(float p_sheen);
+	float get_sheen() const;
+
+	void set_sheen_color(const Color& p_sheen_color);
+	Color get_sheen_color() const;
+
+	void set_clearcoat(float p_clearcoat);
+	float get_clearcoat() const;
+
+	void set_clearcoat_gloss(float p_clearcoat_gloss);
+	float get_clearcoat_gloss() const;
+
+	void set_anisotropy(float p_anisotropy);
+	float get_anisotropy() const;
+
+	void set_height_scale(float p_height_scale);
+	float get_height_scale() const;
+
+	void set_subsurface_scattering(float p_subsurface_scattering);
+	float get_subsurface_scattering() const;
+
+	void set_refraction(float p_refraction);
+	float get_refraction() const;
+
+	void set_refraction_roughness(float p_refraction_roughness);
+	float get_refraction_roughness() const;
+
+	void set_detail_uv(DetailUV p_detail_uv);
+	DetailUV get_detail_uv() const;
+
+	void set_blend_mode(BlendMode p_mode);
+	BlendMode get_blend_mode() const;
+
+	void set_detail_blend_mode(BlendMode p_mode);
+	BlendMode get_detail_blend_mode() const;
+
+	void set_depth_draw_mode(DepthDrawMode p_mode);
+	DepthDrawMode get_depth_draw_mode() const;
+
+	void set_cull_mode(CullMode p_mode);
+	CullMode get_cull_mode() const;
+
+	void set_diffuse_mode(DiffuseMode p_mode);
+	DiffuseMode get_diffuse_mode() const;
+
+	void set_flag(Flags p_flag,bool p_enabled);
+	bool get_flag(Flags p_flag) const;
+
+	void set_texture(TextureParam p_param,const Ref<Texture>& p_texture);
+	Ref<Texture> get_texture(TextureParam p_param) const;
+
+	void set_feature(Feature p_feature,bool p_enabled);
+	bool get_feature(Feature p_feature) const;
+
+	static void init_shaders();
+	static void finish_shaders();
+	static void flush_changes();
+
+	FixedSpatialMaterial();
+	virtual ~FixedSpatialMaterial();
 };
 
+VARIANT_ENUM_CAST( FixedSpatialMaterial::TextureParam )
+VARIANT_ENUM_CAST( FixedSpatialMaterial::DetailUV )
+VARIANT_ENUM_CAST( FixedSpatialMaterial::Feature )
+VARIANT_ENUM_CAST( FixedSpatialMaterial::BlendMode )
+VARIANT_ENUM_CAST( FixedSpatialMaterial::DepthDrawMode )
+VARIANT_ENUM_CAST( FixedSpatialMaterial::CullMode )
+VARIANT_ENUM_CAST( FixedSpatialMaterial::Flags )
+VARIANT_ENUM_CAST( FixedSpatialMaterial::DiffuseMode )
 
 //////////////////////
 

+ 49 - 49
servers/visual/rasterizer.cpp

@@ -55,10 +55,10 @@ RID Rasterizer::create_default_material() {
 
 /* Fixed MAterial SHADER API */
 
-RID Rasterizer::_create_shader(const FixedMaterialShaderKey& p_key) {
+RID Rasterizer::_create_shader(const FixedSpatialMaterialShaderKey& p_key) {
 
 	ERR_FAIL_COND_V(!p_key.valid,RID());
-	Map<FixedMaterialShaderKey,FixedMaterialShader>::Element *E=fixed_material_shaders.find(p_key);
+	Map<FixedSpatialMaterialShaderKey,FixedSpatialMaterialShader>::Element *E=fixed_material_shaders.find(p_key);
 
 	if (E) {
 		E->get().refcount++;
@@ -67,7 +67,7 @@ RID Rasterizer::_create_shader(const FixedMaterialShaderKey& p_key) {
 
 	uint64_t t = OS::get_singleton()->get_ticks_usec();
 
-	FixedMaterialShader fms;
+	FixedSpatialMaterialShader fms;
 	fms.refcount=1;
 	fms.shader=shader_create();
 
@@ -313,12 +313,12 @@ RID Rasterizer::_create_shader(const FixedMaterialShaderKey& p_key) {
 	return fms.shader;
 }
 
-void Rasterizer::_free_shader(const FixedMaterialShaderKey& p_key) {
+void Rasterizer::_free_shader(const FixedSpatialMaterialShaderKey& p_key) {
 
 	if (p_key.valid==0)
 		return; //not a valid key
 
-	Map<FixedMaterialShaderKey,FixedMaterialShader>::Element *E=fixed_material_shaders.find(p_key);
+	Map<FixedSpatialMaterialShaderKey,FixedSpatialMaterialShader>::Element *E=fixed_material_shaders.find(p_key);
 
 	ERR_FAIL_COND(!E);
 	E->get().refcount--;
@@ -330,12 +330,12 @@ void Rasterizer::_free_shader(const FixedMaterialShaderKey& p_key) {
 }
 
 
-void Rasterizer::fixed_material_set_flag(RID p_material, VS::FixedMaterialFlags p_flag, bool p_enabled) {
+void Rasterizer::fixed_material_set_flag(RID p_material, VS::FixedSpatialMaterialFlags p_flag, bool p_enabled) {
 
 
-	Map<RID,FixedMaterial*>::Element *E = fixed_materials.find(p_material);
+	Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
 	ERR_FAIL_COND(!E);
-	FixedMaterial &fm=*E->get();
+	FixedSpatialMaterial &fm=*E->get();
 
 	switch(p_flag) {
 
@@ -351,11 +351,11 @@ void Rasterizer::fixed_material_set_flag(RID p_material, VS::FixedMaterialFlags
 
 }
 
-bool Rasterizer::fixed_material_get_flag(RID p_material, VS::FixedMaterialFlags p_flag) const{
+bool Rasterizer::fixed_material_get_flag(RID p_material, VS::FixedSpatialMaterialFlags p_flag) const{
 
-	const Map<RID,FixedMaterial*>::Element *E = fixed_materials.find(p_material);
+	const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
 	ERR_FAIL_COND_V(!E,false);
-	const FixedMaterial &fm=*E->get();
+	const FixedSpatialMaterial &fm=*E->get();
 	switch(p_flag) {
 
 		case VS::FIXED_MATERIAL_FLAG_USE_ALPHA: return fm.use_alpha;; break;
@@ -374,8 +374,8 @@ bool Rasterizer::fixed_material_get_flag(RID p_material, VS::FixedMaterialFlags
 RID Rasterizer::fixed_material_create() {
 
 	RID mat = material_create();
-	fixed_materials[mat]=memnew( FixedMaterial() );
-	FixedMaterial &fm=*fixed_materials[mat];
+	fixed_materials[mat]=memnew( FixedSpatialMaterial() );
+	FixedSpatialMaterial &fm=*fixed_materials[mat];
 	fm.self=mat;
 	fm.get_key();
 	material_set_flag(mat,VS::MATERIAL_FLAG_COLOR_ARRAY_SRGB,true);
@@ -391,11 +391,11 @@ RID Rasterizer::fixed_material_create() {
 
 
 
-void Rasterizer::fixed_material_set_parameter(RID p_material, VS::FixedMaterialParam p_parameter, const Variant& p_value){
+void Rasterizer::fixed_material_set_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter, const Variant& p_value){
 
-	Map<RID,FixedMaterial*>::Element *E = fixed_materials.find(p_material);
+	Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
 	ERR_FAIL_COND(!E);
-	FixedMaterial &fm=*E->get();
+	FixedSpatialMaterial &fm=*E->get();
 	RID material=E->key();
 	ERR_FAIL_INDEX(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX);
 
@@ -418,24 +418,24 @@ void Rasterizer::fixed_material_set_parameter(RID p_material, VS::FixedMaterialP
 
 
 }
-Variant Rasterizer::fixed_material_get_parameter(RID p_material,VS::FixedMaterialParam p_parameter) const{
+Variant Rasterizer::fixed_material_get_parameter(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const{
 
-	const Map<RID,FixedMaterial*>::Element *E = fixed_materials.find(p_material);
+	const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
 	ERR_FAIL_COND_V(!E,Variant());
-	const FixedMaterial &fm=*E->get();
+	const FixedSpatialMaterial &fm=*E->get();
 	ERR_FAIL_INDEX_V(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX,Variant());
 	return fm.param[p_parameter];
 }
 
-void Rasterizer::fixed_material_set_texture(RID p_material,VS::FixedMaterialParam p_parameter, RID p_texture){
+void Rasterizer::fixed_material_set_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter, RID p_texture){
 
-	Map<RID,FixedMaterial*>::Element *E = fixed_materials.find(p_material);
+	Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
 	if (!E) {
 
 		print_line("Not found: "+itos(p_material.get_id()));
 	}
 	ERR_FAIL_COND(!E);
-	FixedMaterial &fm=*E->get();
+	FixedSpatialMaterial &fm=*E->get();
 
 
 	ERR_FAIL_INDEX(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX);
@@ -450,22 +450,22 @@ void Rasterizer::fixed_material_set_texture(RID p_material,VS::FixedMaterialPara
 
 
 }
-RID Rasterizer::fixed_material_get_texture(RID p_material,VS::FixedMaterialParam p_parameter) const{
+RID Rasterizer::fixed_material_get_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const{
 
-	const Map<RID,FixedMaterial*>::Element *E = fixed_materials.find(p_material);
+	const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
 	ERR_FAIL_COND_V(!E,RID());
-	const FixedMaterial &fm=*E->get();
+	const FixedSpatialMaterial &fm=*E->get();
 	ERR_FAIL_INDEX_V(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX,RID());
 
 	return fm.texture[p_parameter];
 }
 
 
-void Rasterizer::fixed_material_set_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter, VS::FixedMaterialTexCoordMode p_mode) {
+void Rasterizer::fixed_material_set_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter, VS::FixedSpatialMaterialTexCoordMode p_mode) {
 
-	Map<RID,FixedMaterial*>::Element *E = fixed_materials.find(p_material);
+	Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
 	ERR_FAIL_COND(!E);
-	FixedMaterial &fm=*E->get();
+	FixedSpatialMaterial &fm=*E->get();
 	ERR_FAIL_INDEX(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX);
 
 	fm.get_key();
@@ -477,11 +477,11 @@ void Rasterizer::fixed_material_set_texcoord_mode(RID p_material,VS::FixedMateri
 
 }
 
-VS::FixedMaterialTexCoordMode Rasterizer::fixed_material_get_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter) const {
+VS::FixedSpatialMaterialTexCoordMode Rasterizer::fixed_material_get_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const {
 
-	const Map<RID,FixedMaterial*>::Element *E = fixed_materials.find(p_material);
+	const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
 	ERR_FAIL_COND_V(!E,VS::FIXED_MATERIAL_TEXCOORD_UV);
-	const FixedMaterial &fm=*E->get();
+	const FixedSpatialMaterial &fm=*E->get();
 	ERR_FAIL_INDEX_V(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX,VS::FIXED_MATERIAL_TEXCOORD_UV);
 
 	return fm.texture_tc[p_parameter];
@@ -489,9 +489,9 @@ VS::FixedMaterialTexCoordMode Rasterizer::fixed_material_get_texcoord_mode(RID p
 
 void Rasterizer::fixed_material_set_uv_transform(RID p_material,const Transform& p_transform) {
 
-	Map<RID,FixedMaterial*>::Element *E = fixed_materials.find(p_material);
+	Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
 	ERR_FAIL_COND(!E);
-	FixedMaterial &fm=*E->get();
+	FixedSpatialMaterial &fm=*E->get();
 	RID material=E->key();
 
 	VS::get_singleton()->material_set_param(material,_fixed_material_uv_xform_name,p_transform);
@@ -504,18 +504,18 @@ void Rasterizer::fixed_material_set_uv_transform(RID p_material,const Transform&
 
 Transform Rasterizer::fixed_material_get_uv_transform(RID p_material) const {
 
-	const Map<RID,FixedMaterial*>::Element *E = fixed_materials.find(p_material);
+	const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
 	ERR_FAIL_COND_V(!E,Transform());
-	const FixedMaterial &fm=*E->get();
+	const FixedSpatialMaterial &fm=*E->get();
 
 	return fm.uv_xform;
 }
 
-void Rasterizer::fixed_material_set_light_shader(RID p_material,VS::FixedMaterialLightShader p_shader) {
+void Rasterizer::fixed_material_set_light_shader(RID p_material,VS::FixedSpatialMaterialLightShader p_shader) {
 
-	Map<RID,FixedMaterial*>::Element *E = fixed_materials.find(p_material);
+	Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
 	ERR_FAIL_COND(!E);
-	FixedMaterial &fm=*E->get();
+	FixedSpatialMaterial &fm=*E->get();
 
 	fm.light_shader=p_shader;
 
@@ -524,20 +524,20 @@ void Rasterizer::fixed_material_set_light_shader(RID p_material,VS::FixedMateria
 
 }
 
-VS::FixedMaterialLightShader Rasterizer::fixed_material_get_light_shader(RID p_material) const {
+VS::FixedSpatialMaterialLightShader Rasterizer::fixed_material_get_light_shader(RID p_material) const {
 
-	const Map<RID,FixedMaterial*>::Element *E = fixed_materials.find(p_material);
+	const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
 	ERR_FAIL_COND_V(!E,VS::FIXED_MATERIAL_LIGHT_SHADER_LAMBERT);
-	const FixedMaterial &fm=*E->get();
+	const FixedSpatialMaterial &fm=*E->get();
 
 	return fm.light_shader;
 }
 
 void Rasterizer::fixed_material_set_point_size(RID p_material,float p_size) {
 
-	Map<RID,FixedMaterial*>::Element *E = fixed_materials.find(p_material);
+	Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
 	ERR_FAIL_COND(!E);
-	FixedMaterial &fm=*E->get();
+	FixedSpatialMaterial &fm=*E->get();
 	RID material=E->key();
 
 	VS::get_singleton()->material_set_param(material,_fixed_material_point_size_name,p_size);
@@ -549,9 +549,9 @@ void Rasterizer::fixed_material_set_point_size(RID p_material,float p_size) {
 
 float Rasterizer::fixed_material_get_point_size(RID p_material) const{
 
-	const Map<RID,FixedMaterial*>::Element *E = fixed_materials.find(p_material);
+	const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
 	ERR_FAIL_COND_V(!E,1.0);
-	const FixedMaterial &fm=*E->get();
+	const FixedSpatialMaterial &fm=*E->get();
 
 	return fm.point_size;
 
@@ -562,9 +562,9 @@ void Rasterizer::_update_fixed_materials() {
 
 	while(fixed_material_dirty_list.first()) {
 
-		FixedMaterial &fm=*fixed_material_dirty_list.first()->self();
+		FixedSpatialMaterial &fm=*fixed_material_dirty_list.first()->self();
 
-		FixedMaterialShaderKey new_key = fm.get_key();
+		FixedSpatialMaterialShaderKey new_key = fm.get_key();
 		if (new_key.key!=fm.current_key.key) {
 
 			_free_shader(fm.current_key);
@@ -594,7 +594,7 @@ void Rasterizer::_update_fixed_materials() {
 
 void Rasterizer::_free_fixed_material(const RID& p_material) {
 
-	Map<RID,FixedMaterial*>::Element *E = fixed_materials.find(p_material);
+	Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
 
 	if (E) {
 
@@ -637,7 +637,7 @@ Rasterizer::Rasterizer() {
 
 	draw_viewport_func=NULL;
 
-	ERR_FAIL_COND( sizeof(FixedMaterialShaderKey)!=4);
+	ERR_FAIL_COND( sizeof(FixedSpatialMaterialShaderKey)!=4);
 
 }
 

+ 31 - 29
servers/visual/rasterizer.h

@@ -44,12 +44,12 @@ public:
 	virtual RID environment_create()=0;
 
 	virtual void environment_set_background(RID p_env,VS::EnvironmentBG p_bg)=0;
-	virtual void environment_set_skybox(RID p_env,RID p_skybox,int p_radiance_size,int p_irradiance_size)=0;
+	virtual void environment_set_skybox(RID p_env,RID p_skybox,int p_radiance_size)=0;
 	virtual void environment_set_skybox_scale(RID p_env,float p_scale)=0;
 	virtual void environment_set_bg_color(RID p_env,const Color& p_color)=0;
 	virtual void environment_set_bg_energy(RID p_env,float p_energy)=0;
 	virtual void environment_set_canvas_max_layer(RID p_env,int p_max_layer)=0;
-	virtual void environment_set_ambient_light(RID p_env,const Color& p_color,float p_energy=1.0,float p_skybox_energy=0.0)=0;
+	virtual void environment_set_ambient_light(RID p_env,const Color& p_color,float p_energy=1.0,float p_skybox_contribution=0.0)=0;
 
 	virtual void environment_set_glow(RID p_env,bool p_enable,int p_radius,float p_intensity,float p_strength,float p_bloom_treshold,VS::EnvironmentGlowBlendMode p_blend_mode)=0;
 	virtual void environment_set_fog(RID p_env,bool p_enable,float p_begin,float p_end,RID p_gradient_texture)=0;
@@ -90,6 +90,8 @@ public:
 		bool billboard_y :8;
 		bool receive_shadows : 8;
 
+		float depth; //used for sorting
+
 		SelfList<InstanceBase> dependency_item;
 
 		virtual void base_removed()=0;
@@ -146,7 +148,7 @@ public:
 
 	virtual void texture_debug_usage(List<VS::TextureInfo> *r_info)=0;
 
-	virtual RID texture_create_pbr_cubemap(RID p_source,VS::PBRCubeMapMode p_mode,int p_resolution=-1) const=0;
+	virtual RID texture_create_radiance_cubemap(RID p_source,int p_resolution=-1) const=0;
 
 	/* SHADER API */
 
@@ -798,7 +800,7 @@ protected:
 
 	/* Fixed Material Shader API */
 
-	union FixedMaterialShaderKey {
+	union FixedSpatialMaterialShaderKey {
 
 		struct {
 			uint16_t texcoord_mask;
@@ -814,21 +816,21 @@ protected:
 
 		uint32_t key;
 
-		_FORCE_INLINE_ bool operator<(const FixedMaterialShaderKey& p_key) const { return key<p_key.key; }
+		_FORCE_INLINE_ bool operator<(const FixedSpatialMaterialShaderKey& p_key) const { return key<p_key.key; }
 	};
 
-	struct FixedMaterialShader {
+	struct FixedSpatialMaterialShader {
 
 		int refcount;
 		RID shader;
 	};
 
-	Map<FixedMaterialShaderKey,FixedMaterialShader> fixed_material_shaders;
+	Map<FixedSpatialMaterialShaderKey,FixedSpatialMaterialShader> fixed_material_shaders;
 
-	RID _create_shader(const FixedMaterialShaderKey& p_key);
-	void _free_shader(const FixedMaterialShaderKey& p_key);
+	RID _create_shader(const FixedSpatialMaterialShaderKey& p_key);
+	void _free_shader(const FixedSpatialMaterialShaderKey& p_key);
 
-	struct FixedMaterial {
+	struct FixedSpatialMaterial {
 
 
 		RID self;
@@ -839,19 +841,19 @@ protected:
 		bool use_xy_normalmap;
 		float point_size;
 		Transform uv_xform;
-		VS::FixedMaterialLightShader light_shader;
+		VS::FixedSpatialMaterialLightShader light_shader;
 		RID texture[VS::FIXED_MATERIAL_PARAM_MAX];
 		Variant param[VS::FIXED_MATERIAL_PARAM_MAX];
-		VS::FixedMaterialTexCoordMode texture_tc[VS::FIXED_MATERIAL_PARAM_MAX];
+		VS::FixedSpatialMaterialTexCoordMode texture_tc[VS::FIXED_MATERIAL_PARAM_MAX];
 
-		SelfList<FixedMaterial> dirty_list;
+		SelfList<FixedSpatialMaterial> dirty_list;
 
-		FixedMaterialShaderKey current_key;
+		FixedSpatialMaterialShaderKey current_key;
 
-		_FORCE_INLINE_ FixedMaterialShaderKey get_key() const {
+		_FORCE_INLINE_ FixedSpatialMaterialShaderKey get_key() const {
 
 
-			FixedMaterialShaderKey k;
+			FixedSpatialMaterialShaderKey k;
 			k.key=0;
 			k.use_alpha=use_alpha;
 			k.use_color_array=use_color_array;
@@ -872,7 +874,7 @@ protected:
 		}
 
 
-		FixedMaterial() : dirty_list(this) {
+		FixedSpatialMaterial() : dirty_list(this) {
 
 			use_alpha=false;
 			use_color_array=false;
@@ -904,9 +906,9 @@ protected:
 	StringName _fixed_material_uv_xform_name;
 	StringName _fixed_material_point_size_name;
 
-	Map<RID,FixedMaterial*> fixed_materials;
+	Map<RID,FixedSpatialMaterial*> fixed_materials;
 
-	SelfList<FixedMaterial>::List fixed_material_dirty_list;
+	SelfList<FixedSpatialMaterial>::List fixed_material_dirty_list;
 
 protected:
 	void _update_fixed_materials();
@@ -993,23 +995,23 @@ public:
 
 	virtual RID fixed_material_create();
 
-	virtual void fixed_material_set_flag(RID p_material, VS::FixedMaterialFlags p_flag, bool p_enabled);
-	virtual bool fixed_material_get_flag(RID p_material, VS::FixedMaterialFlags p_flag) const;
+	virtual void fixed_material_set_flag(RID p_material, VS::FixedSpatialMaterialFlags p_flag, bool p_enabled);
+	virtual bool fixed_material_get_flag(RID p_material, VS::FixedSpatialMaterialFlags p_flag) const;
 
-	virtual void fixed_material_set_parameter(RID p_material, VS::FixedMaterialParam p_parameter, const Variant& p_value);
-	virtual Variant fixed_material_get_parameter(RID p_material,VS::FixedMaterialParam p_parameter) const;
+	virtual void fixed_material_set_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter, const Variant& p_value);
+	virtual Variant fixed_material_get_parameter(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const;
 
-	virtual void fixed_material_set_texture(RID p_material,VS::FixedMaterialParam p_parameter, RID p_texture);
-	virtual RID fixed_material_get_texture(RID p_material,VS::FixedMaterialParam p_parameter) const;
+	virtual void fixed_material_set_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter, RID p_texture);
+	virtual RID fixed_material_get_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const;
 
-	virtual void fixed_material_set_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter, VS::FixedMaterialTexCoordMode p_mode);
-	virtual VS::FixedMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter) const;
+	virtual void fixed_material_set_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter, VS::FixedSpatialMaterialTexCoordMode p_mode);
+	virtual VS::FixedSpatialMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const;
 
 	virtual void fixed_material_set_uv_transform(RID p_material,const Transform& p_transform);
 	virtual Transform fixed_material_get_uv_transform(RID p_material) const;
 
-	virtual void fixed_material_set_light_shader(RID p_material,VS::FixedMaterialLightShader p_shader);
-	virtual VS::FixedMaterialLightShader fixed_material_get_light_shader(RID p_material) const;
+	virtual void fixed_material_set_light_shader(RID p_material,VS::FixedSpatialMaterialLightShader p_shader);
+	virtual VS::FixedSpatialMaterialLightShader fixed_material_get_light_shader(RID p_material) const;
 
 	virtual void fixed_material_set_point_size(RID p_material,float p_size);
 	virtual float fixed_material_get_point_size(RID p_material) const;

+ 17 - 25
servers/visual/shader_language.cpp

@@ -260,11 +260,11 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[]={
 	{TK_UNIFORM,"uniform"},
 	{TK_VARYING,"varying"},
 	{TK_RENDER_MODE,"render_mode"},
-	{TK_HINT_WHITE_TEXTURE,"white"},
-	{TK_HINT_BLACK_TEXTURE,"black"},
-	{TK_HINT_NORMAL_TEXTURE,"normal"},
-	{TK_HINT_ALBEDO_TEXTURE,"albedo"},
-	{TK_HINT_COLOR,"color"},
+	{TK_HINT_WHITE_TEXTURE,"hint_white"},
+	{TK_HINT_BLACK_TEXTURE,"hint_black"},
+	{TK_HINT_NORMAL_TEXTURE,"hint_normal"},
+	{TK_HINT_ALBEDO_TEXTURE,"hint_albedo"},
+	{TK_HINT_COLOR,"hint_color"},
 	{TK_HINT_RANGE,"hint_range"},
 
 	{TK_ERROR,NULL}
@@ -604,7 +604,7 @@ String ShaderLanguage::token_debug(const String& p_code) {
 
 	Token tk = _get_token();
 	while(tk.type!=TK_EOF && tk.type!=TK_ERROR) {
-		print_line(get_token_text(tk));
+
 		output+=itos(tk_line)+": "+get_token_text(tk)+"\n";
 		tk = _get_token();
 	}
@@ -2232,9 +2232,7 @@ ShaderLanguage::Node* ShaderLanguage::_parse_expression(BlockNode* p_block,const
 		Node *expr=NULL;
 		TkPos prepos = _get_tkpos();
 		Token tk = _get_token();
-		TkPos pos = _get_tkpos();
-
-		print_line("in expr: "+get_token_text(tk));
+		TkPos pos = _get_tkpos();		
 
 
 		if (tk.type==TK_PARENTHESIS_OPEN) {
@@ -2301,8 +2299,6 @@ ShaderLanguage::Node* ShaderLanguage::_parse_expression(BlockNode* p_block,const
 		} else if (is_token_nonvoid_datatype(tk.type)) {
 			//basic type constructor
 
-			print_line("parse constructor");
-
 			OperatorNode *func = alloc_node<OperatorNode>();
 			func->op=OP_CONSTRUCT;
 
@@ -3193,17 +3189,17 @@ Error ShaderLanguage::_parse_shader(const Map< StringName, Map<StringName,DataTy
 						return ERR_PARSE_ERROR;
 					}
 
-					if (!p_render_modes.has(tk.text)) {
-						_set_error("Invalid render mode: '"+String(tk.text)+"'");
+					if (!p_render_modes.has(mode)) {
+						_set_error("Invalid render mode: '"+String(mode)+"'");
 						return ERR_PARSE_ERROR;
 					}
 
-					if (shader->render_modes.find(tk.text)!=-1) {
-						_set_error("Duplicate render mode: '"+String(tk.text)+"'");
+					if (shader->render_modes.find(mode)!=-1) {
+						_set_error("Duplicate render mode: '"+String(mode)+"'");
 						return ERR_PARSE_ERROR;
 					}
 
-					shader->render_modes.push_back(tk.text);
+					shader->render_modes.push_back(mode);
 
 					tk = _get_token();
 					if (tk.type==TK_COMMA) {
@@ -3262,7 +3258,7 @@ Error ShaderLanguage::_parse_shader(const Map< StringName, Map<StringName,DataTy
 				if (uniform) {
 
 					ShaderNode::Uniform uniform;
-					uniform.order=shader->uniforms.size();
+
 					if (is_sampler_type(type)) {
 						uniform.texture_order=texture_uniforms++;
 						uniform.order=-1;
@@ -3331,7 +3327,7 @@ Error ShaderLanguage::_parse_shader(const Map< StringName, Map<StringName,DataTy
 
 							tk = _get_token();
 
-							if (tk.type!=TK_REAL_CONSTANT ||tk.type!=TK_INT_CONSTANT) {
+							if (tk.type!=TK_REAL_CONSTANT && tk.type!=TK_INT_CONSTANT) {
 								_set_error("Expected integer constant");
 								return ERR_PARSE_ERROR;
 							}
@@ -3347,7 +3343,7 @@ Error ShaderLanguage::_parse_shader(const Map< StringName, Map<StringName,DataTy
 
 							tk = _get_token();
 
-							if (tk.type!=TK_REAL_CONSTANT || tk.type!=TK_INT_CONSTANT) {
+							if (tk.type!=TK_REAL_CONSTANT && tk.type!=TK_INT_CONSTANT) {
 								_set_error("Expected integer constant after ','");
 								return ERR_PARSE_ERROR;
 							}
@@ -3359,7 +3355,7 @@ Error ShaderLanguage::_parse_shader(const Map< StringName, Map<StringName,DataTy
 							if (tk.type==TK_COMMA) {
 								tk = _get_token();
 
-								if (tk.type!=TK_REAL_CONSTANT || tk.type!=TK_INT_CONSTANT) {
+								if (tk.type!=TK_REAL_CONSTANT && tk.type!=TK_INT_CONSTANT) {
 									_set_error("Expected integer constant after ','");
 									return ERR_PARSE_ERROR;
 								}
@@ -3390,8 +3386,6 @@ Error ShaderLanguage::_parse_shader(const Map< StringName, Map<StringName,DataTy
 
 						}
 
-						print_line("assigning name: "+String(name));
-
 						tk = _get_token();
 					}
 
@@ -3624,7 +3618,7 @@ Error ShaderLanguage::complete(const String& p_code,const Map< StringName, Map<S
 			return OK;
 		} break;
 		case COMPLETION_MAIN_FUNCTION: {
-			print_line("complete main func");
+
 			for(const Map< StringName, Map<StringName,DataType> >::Element *E=p_functions.front();E;E=E->next()) {
 
 				r_options->push_back(E->key());
@@ -3635,7 +3629,6 @@ Error ShaderLanguage::complete(const String& p_code,const Map< StringName, Map<S
 		case COMPLETION_IDENTIFIER:
 		case COMPLETION_FUNCTION_CALL: {
 
-			print_line("complete identifier");
 			bool comp_ident=completion_type==COMPLETION_IDENTIFIER;
 			Set<String> matches;
 
@@ -3709,7 +3702,6 @@ Error ShaderLanguage::complete(const String& p_code,const Map< StringName, Map<S
 		} break;
 		case COMPLETION_CALL_ARGUMENTS: {
 
-			print_line("complete callargs");
 			for(int i=0;i<shader->functions.size();i++) {
 				if (!shader->functions[i].callable)
 					continue;

+ 8 - 8
servers/visual/shader_types.cpp

@@ -136,16 +136,16 @@ ShaderTypes::ShaderTypes()
 	shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["POINT_COORD"]=ShaderLanguage::TYPE_VEC2;
 	shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["TIME"]=ShaderLanguage::TYPE_FLOAT;
 
-	shader_modes[VS::SHADER_SPATIAL].modes.insert("skip_transform");
+	shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("skip_transform");
 
-	shader_modes[VS::SHADER_SPATIAL].modes.insert("blend_mix");
-	shader_modes[VS::SHADER_SPATIAL].modes.insert("blend_add");
-	shader_modes[VS::SHADER_SPATIAL].modes.insert("blend_sub");
-	shader_modes[VS::SHADER_SPATIAL].modes.insert("blend_mul");
-	shader_modes[VS::SHADER_SPATIAL].modes.insert("blend_premul_alpha");
+	shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("blend_mix");
+	shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("blend_add");
+	shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("blend_sub");
+	shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("blend_mul");
+	shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("blend_premul_alpha");
 
-	shader_modes[VS::SHADER_SPATIAL].modes.insert("unshaded");
-	shader_modes[VS::SHADER_SPATIAL].modes.insert("light_only");
+	shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("unshaded");
+	shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("light_only");
 
 
 

+ 10 - 10
servers/visual/visual_server_raster.cpp

@@ -405,33 +405,33 @@ RID VisualServerRaster::fixed_material_create() {
 	return rasterizer->fixed_material_create();
 }
 
-void VisualServerRaster::fixed_material_set_flag(RID p_material, FixedMaterialFlags p_flag, bool p_enabled) {
+void VisualServerRaster::fixed_material_set_flag(RID p_material, FixedSpatialMaterialFlags p_flag, bool p_enabled) {
 
 	rasterizer->fixed_material_set_flag(p_material,p_flag,p_enabled);
 }
 
-bool VisualServerRaster::fixed_material_get_flag(RID p_material, FixedMaterialFlags p_flag) const {
+bool VisualServerRaster::fixed_material_get_flag(RID p_material, FixedSpatialMaterialFlags p_flag) const {
 
 	return rasterizer->fixed_material_get_flag(p_material,p_flag);
 }
 
-void VisualServerRaster::fixed_material_set_param(RID p_material, FixedMaterialParam p_parameter, const Variant& p_value) {
+void VisualServerRaster::fixed_material_set_param(RID p_material, FixedSpatialMaterialParam p_parameter, const Variant& p_value) {
 	VS_CHANGED;
 	rasterizer->fixed_material_set_parameter(p_material,p_parameter,p_value);
 }
 
-Variant VisualServerRaster::fixed_material_get_param(RID p_material,FixedMaterialParam p_parameter) const {
+Variant VisualServerRaster::fixed_material_get_param(RID p_material,FixedSpatialMaterialParam p_parameter) const {
 
 	return rasterizer->fixed_material_get_parameter(p_material,p_parameter);
 }
 
 
-void VisualServerRaster::fixed_material_set_texture(RID p_material,FixedMaterialParam p_parameter, RID p_texture) {
+void VisualServerRaster::fixed_material_set_texture(RID p_material,FixedSpatialMaterialParam p_parameter, RID p_texture) {
 	VS_CHANGED;
 	rasterizer->fixed_material_set_texture(p_material,p_parameter,p_texture);
 }
 
-RID VisualServerRaster::fixed_material_get_texture(RID p_material,FixedMaterialParam p_parameter) const {
+RID VisualServerRaster::fixed_material_get_texture(RID p_material,FixedSpatialMaterialParam p_parameter) const {
 
 	return rasterizer->fixed_material_get_texture(p_material,p_parameter);
 }
@@ -439,12 +439,12 @@ RID VisualServerRaster::fixed_material_get_texture(RID p_material,FixedMaterialP
 
 
 
-void VisualServerRaster::fixed_material_set_texcoord_mode(RID p_material,FixedMaterialParam p_parameter, FixedMaterialTexCoordMode p_mode) {
+void VisualServerRaster::fixed_material_set_texcoord_mode(RID p_material,FixedSpatialMaterialParam p_parameter, FixedSpatialMaterialTexCoordMode p_mode) {
 	VS_CHANGED;
 	rasterizer->fixed_material_set_texcoord_mode(p_material,p_parameter,p_mode);
 }
 
-VS::FixedMaterialTexCoordMode VisualServerRaster::fixed_material_get_texcoord_mode(RID p_material,FixedMaterialParam p_parameter) const {
+VS::FixedSpatialMaterialTexCoordMode VisualServerRaster::fixed_material_get_texcoord_mode(RID p_material,FixedSpatialMaterialParam p_parameter) const {
 
 	return rasterizer->fixed_material_get_texcoord_mode(p_material,p_parameter);
 }
@@ -471,14 +471,14 @@ Transform VisualServerRaster::fixed_material_get_uv_transform(RID p_material) co
 	return rasterizer->fixed_material_get_uv_transform(p_material);
 }
 
-void VisualServerRaster::fixed_material_set_light_shader(RID p_material,FixedMaterialLightShader p_shader) {
+void VisualServerRaster::fixed_material_set_light_shader(RID p_material,FixedSpatialMaterialLightShader p_shader) {
 
 	VS_CHANGED;
 	rasterizer->fixed_material_set_light_shader(p_material,p_shader);
 
 }
 
-VisualServerRaster::FixedMaterialLightShader VisualServerRaster::fixed_material_get_light_shader(RID p_material) const{
+VisualServerRaster::FixedSpatialMaterialLightShader VisualServerRaster::fixed_material_get_light_shader(RID p_material) const{
 
 	return rasterizer->fixed_material_get_light_shader(p_material);
 }

+ 2 - 2
servers/visual/visual_server_raster.h

@@ -620,7 +620,7 @@ public:
 	BIND1RC(uint32_t,texture_get_width,RID)
 	BIND1RC(uint32_t,texture_get_height,RID)
 	BIND3(texture_set_size_override,RID,int,int)
-	BIND3RC(RID,texture_create_pbr_cubemap,RID,PBRCubeMapMode,int)
+	BIND2RC(RID,texture_create_radiance_cubemap,RID,int)
 
 
 
@@ -854,7 +854,7 @@ public:
 	BIND0R(RID,environment_create)
 
 	BIND2(environment_set_background,RID ,EnvironmentBG )
-	BIND4(environment_set_skybox,RID,RID ,int,int )
+	BIND3(environment_set_skybox,RID,RID ,int )
 	BIND2(environment_set_skybox_scale,RID,float)
 	BIND2(environment_set_bg_color,RID,const Color& )
 	BIND2(environment_set_bg_energy,RID,float )

+ 56 - 7
servers/visual/visual_server_scene.cpp

@@ -337,8 +337,7 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base){
 					light->D=NULL;
 				}
 				VSG::scene_render->free(light->instance);
-
-			}
+			} break;
 		}
 
 		if (instance->base_data) {
@@ -492,12 +491,12 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base){
 				light->instance = VSG::scene_render->light_instance_create(p_base);
 
 				instance->base_data=light;
-			}
+			} break;
 			case VS::INSTANCE_MESH: {
 
 				InstanceGeometryData *geom = memnew( InstanceGeometryData );
 				instance->base_data=geom;
-			}
+			} break;
 
 		}
 
@@ -596,7 +595,7 @@ void VisualServerScene::instance_set_scenario(RID p_instance, RID p_scenario){
 					instance->scenario->directional_lights.erase( light->D );
 					light->D=NULL;
 				}
-			}
+			} break;
 		}
 
 		instance->scenario=NULL;
@@ -623,7 +622,7 @@ void VisualServerScene::instance_set_scenario(RID p_instance, RID p_scenario){
 				if (VSG::storage->light_get_type(instance->base)==VS::LIGHT_DIRECTIONAL) {
 					light->D = scenario->directional_lights.push_back(instance);
 				}
-			}
+			} break;
 		}
 
 		_instance_queue_update(instance,true,true);
@@ -711,12 +710,59 @@ Vector<ObjectID> VisualServerScene::instances_cull_convex(const Vector<Plane>& p
 
 void VisualServerScene::instance_geometry_set_flag(RID p_instance,VS::InstanceFlags p_flags,bool p_enabled){
 
+	Instance *instance = instance_owner.get( p_instance );
+	ERR_FAIL_COND( !instance );
+
+	switch(p_flags) {
+
+		case VS::INSTANCE_FLAG_VISIBLE: {
+
+			instance->visible=p_enabled;
+
+		} break;
+		case VS::INSTANCE_FLAG_BILLBOARD: {
+
+			instance->billboard=p_enabled;
+
+		} break;
+		case VS::INSTANCE_FLAG_BILLBOARD_FIX_Y: {
+
+			instance->billboard_y=p_enabled;
+
+		} break;
+		case VS::INSTANCE_FLAG_CAST_SHADOW: {
+			/*if (p_enabled == true) {
+				instance->cast_shadows = SHADOW_CASTING_SETTING_ON;
+			}
+			else {
+				instance->cast_shadows = SHADOW_CASTING_SETTING_OFF;
+			}*/
+
+		} break;
+		case VS::INSTANCE_FLAG_DEPH_SCALE: {
+
+			instance->depth_scale=p_enabled;
+
+		} break;
+		case VS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS: {
+
+			instance->visible_in_all_rooms=p_enabled;
+
+		} break;
+
+	}
 }
 void VisualServerScene::instance_geometry_set_cast_shadows_setting(RID p_instance, VS::ShadowCastingSetting p_shadow_casting_setting) {
 
 }
 void VisualServerScene::instance_geometry_set_material_override(RID p_instance, RID p_material){
 
+	Instance *instance = instance_owner.get( p_instance );
+	ERR_FAIL_COND( !instance );
+
+	instance->material_override=p_material;
+
+
 }
 
 
@@ -1151,7 +1197,8 @@ void VisualServerScene::render_camera(RID p_camera, RID p_scenario,Size2 p_viewp
 			//failure
 		} else if (ins->base_type==VS::INSTANCE_LIGHT && ins->visible) {
 
-			if (light_cull_count<MAX_LIGHTS_CULLED) {
+
+			if (ins->visible && light_cull_count<MAX_LIGHTS_CULLED) {
 
 				InstanceLightData * light = static_cast<InstanceLightData*>(ins->base_data);
 
@@ -1253,6 +1300,8 @@ void VisualServerScene::render_camera(RID p_camera, RID p_scenario,Size2 p_viewp
 				geom->lighting_dirty=false;
 			}
 
+			ins->depth = near_plane.distance_to(ins->transform.origin);
+
 		}
 
 		if (!keep) {

+ 0 - 7
servers/visual_server.cpp

@@ -1036,30 +1036,23 @@ void VisualServer::mesh_add_surface_from_arrays(RID p_mesh,PrimitiveType p_primi
 			}
 		}
 
-		print_line("type "+itos(i)+" size: "+itos(elem_size)+" offset "+itos(total_elem_size));
 		offsets[i]=total_elem_size;
 		total_elem_size+=elem_size;
 
 
 	}
 
-	print_line("total elemn size: "+itos(total_elem_size));
-
 	uint32_t mask = (1<<ARRAY_MAX)-1;
 	format|=~mask&p_compress_format; //make the full format
 
 
 	int array_size = total_elem_size * array_len;
 
-	print_line("array size: "+itos(array_size));
-
 	DVector<uint8_t> vertex_array;
 	vertex_array.resize(array_size);
 
 	int index_array_size = offsets[VS::ARRAY_INDEX]*index_array_len;
 
-	print_line("index array size: "+itos(index_array_size));
-
 	DVector<uint8_t> index_array;
 	index_array.resize(index_array_size);
 

+ 7 - 12
servers/visual_server.h

@@ -125,12 +125,7 @@ public:
 
 	virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable)=0;
 
-	enum PBRCubeMapMode {
-		PBR_CUBEMAP_RADIANCE,
-		PBR_CUBEMAP_IRRADIANCE,
-	};
-
-	virtual RID texture_create_pbr_cubemap(RID p_source,PBRCubeMapMode p_mode,int p_resolution=-1) const=0;
+	virtual RID texture_create_radiance_cubemap(RID p_source,int p_resolution=-1) const=0;
 
 	struct TextureInfo {
 		RID texture;
@@ -349,7 +344,9 @@ public:
 		LIGHT_PARAM_ENERGY,
 		LIGHT_PARAM_SPECULAR,
 		LIGHT_PARAM_RANGE,
+		LIGHT_PARAM_ATTENUATION,
 		LIGHT_PARAM_SPOT_ANGLE,
+		LIGHT_PARAM_SPOT_ATTENUATION,
 		LIGHT_PARAM_SHADOW_MAX_DISTANCE,
 		LIGHT_PARAM_SHADOW_DARKNESS,
 		LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET,
@@ -357,10 +354,8 @@ public:
 		LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET,
 		LIGHT_PARAM_SHADOW_SPLIT_4_OFFSET,
 		LIGHT_PARAM_SHADOW_NORMAL_BIAS,
-		LIGHT_PARAM_SHADOW_BIAS_1,
-		LIGHT_PARAM_SHADOW_BIAS_2,
-		LIGHT_PARAM_SHADOW_BIAS_3,
-		LIGHT_PARAM_SHADOW_BIAS_4,
+		LIGHT_PARAM_SHADOW_BIAS,
+		LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE,
 		LIGHT_PARAM_MAX
 	};
 
@@ -494,12 +489,12 @@ public:
 	};
 
 	virtual void environment_set_background(RID p_env,EnvironmentBG p_bg)=0;
-	virtual void environment_set_skybox(RID p_env,RID p_skybox,int p_radiance_size,int p_irradiance_size)=0;
+	virtual void environment_set_skybox(RID p_env,RID p_skybox,int p_radiance_size)=0;
 	virtual void environment_set_skybox_scale(RID p_env,float p_scale)=0;
 	virtual void environment_set_bg_color(RID p_env,const Color& p_color)=0;
 	virtual void environment_set_bg_energy(RID p_env,float p_energy)=0;
 	virtual void environment_set_canvas_max_layer(RID p_env,int p_max_layer)=0;
-	virtual void environment_set_ambient_light(RID p_env,const Color& p_color,float p_energy=1.0,float p_skybox_energy=0.0)=0;
+	virtual void environment_set_ambient_light(RID p_env,const Color& p_color,float p_energy=1.0,float p_skybox_contribution=0.0)=0;
 
 	//set default SSAO options
 	//set default SSR options

+ 13 - 13
tools/editor/io_plugins/editor_import_collada.cpp

@@ -377,7 +377,7 @@ Error ColladaImport::_create_material(const String& p_target) {
 	ERR_FAIL_COND_V(!collada.state.effect_map.has(src_mat.instance_effect),ERR_INVALID_PARAMETER);
 	Collada::Effect &effect=collada.state.effect_map[src_mat.instance_effect];
 
-	Ref<FixedMaterial> material= memnew( FixedMaterial );
+	Ref<FixedSpatialMaterial> material= memnew( FixedSpatialMaterial );
 
 	if (src_mat.name!="")
 		material->set_name(src_mat.name);
@@ -394,14 +394,14 @@ Error ColladaImport::_create_material(const String& p_target) {
 			Ref<Texture> texture = ResourceLoader::load(texfile,"Texture");
 			if (texture.is_valid()) {
 
-//				material->set_texture(FixedMaterial::PARAM_DIFFUSE,texture);
-//				material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,1));
+//				material->set_texture(FixedSpatialMaterial::PARAM_DIFFUSE,texture);
+//				material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1,1));
 			} else {
 				missing_textures.push_back(texfile.get_file());
 			}
 		}
 	} else {
-//		material->set_parameter(FixedMaterial::PARAM_DIFFUSE,effect.diffuse.color);
+//		material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,effect.diffuse.color);
 	}
 
 	// SPECULAR
@@ -414,15 +414,15 @@ Error ColladaImport::_create_material(const String& p_target) {
 			Ref<Texture> texture = ResourceLoader::load(texfile,"Texture");
 			if (texture.is_valid()) {
 
-//				material->set_texture(FixedMaterial::PARAM_SPECULAR,texture);
-//				material->set_parameter(FixedMaterial::PARAM_SPECULAR,Color(1,1,1,1));
+//				material->set_texture(FixedSpatialMaterial::PARAM_SPECULAR,texture);
+//				material->set_parameter(FixedSpatialMaterial::PARAM_SPECULAR,Color(1,1,1,1));
 			} else {
 				missing_textures.push_back(texfile.get_file());
 			}
 
 		}
 	} else {
-//		material->set_parameter(FixedMaterial::PARAM_SPECULAR,effect.specular.color);
+//		material->set_parameter(FixedSpatialMaterial::PARAM_SPECULAR,effect.specular.color);
 	}
 
 	// EMISSION
@@ -435,15 +435,15 @@ Error ColladaImport::_create_material(const String& p_target) {
 			Ref<Texture> texture = ResourceLoader::load(texfile,"Texture");
 			if (texture.is_valid()) {
 
-//				material->set_texture(FixedMaterial::PARAM_EMISSION,texture);
-//				material->set_parameter(FixedMaterial::PARAM_EMISSION,Color(1,1,1,1));
+//				material->set_texture(FixedSpatialMaterial::PARAM_EMISSION,texture);
+//				material->set_parameter(FixedSpatialMaterial::PARAM_EMISSION,Color(1,1,1,1));
 			}else {
 //				missing_textures.push_back(texfile.get_file());
 			}
 
 		}
 	} else {
-//		material->set_parameter(FixedMaterial::PARAM_EMISSION,effect.emission.color);
+//		material->set_parameter(FixedSpatialMaterial::PARAM_EMISSION,effect.emission.color);
 	}
 
 	// NORMAL
@@ -456,7 +456,7 @@ Error ColladaImport::_create_material(const String& p_target) {
 			Ref<Texture> texture = ResourceLoader::load(texfile,"Texture");
 			if (texture.is_valid()) {
 
-	//			material->set_texture(FixedMaterial::PARAM_NORMAL,texture);
+	//			material->set_texture(FixedSpatialMaterial::PARAM_NORMAL,texture);
 			}else {
 //				missing_textures.push_back(texfile.get_file());
 			}
@@ -465,7 +465,7 @@ Error ColladaImport::_create_material(const String& p_target) {
 	}
 
 
-//	material->set_parameter(FixedMaterial::PARAM_SPECULAR_EXP,effect.shininess);
+//	material->set_parameter(FixedSpatialMaterial::PARAM_SPECULAR_EXP,effect.shininess);
 //	material->set_flag(Material::FLAG_DOUBLE_SIDED,effect.double_sided);
 //	material->set_flag(Material::FLAG_UNSHADED,effect.unshaded);
 
@@ -1042,7 +1042,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
 
 		{
 
-			Ref<FixedMaterial> material;
+			Ref<FixedSpatialMaterial> material;
 
 			//find material
 			Mesh::PrimitiveType primitive=Mesh::PRIMITIVE_TRIANGLES;

+ 15 - 15
tools/editor/io_plugins/editor_scene_import_plugin.cpp

@@ -1392,7 +1392,7 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<Imag
 					for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) {
 
 						if (E->get().type==Variant::OBJECT || E->get().type==Variant::ARRAY || E->get().type==Variant::DICTIONARY) {
-							if (E->get().type==Variant::OBJECT && res->cast_to<FixedMaterial>() && (E->get().name=="textures/diffuse" || E->get().name=="textures/detail" || E->get().name=="textures/emission")) {
+							if (E->get().type==Variant::OBJECT && res->cast_to<FixedSpatialMaterial>() && (E->get().name=="textures/diffuse" || E->get().name=="textures/detail" || E->get().name=="textures/emission")) {
 
 								Ref<ImageTexture> tex =res->get(E->get().name);
 								if (tex.is_valid()) {
@@ -1400,14 +1400,14 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<Imag
 									image_map.insert(tex,TEXTURE_ROLE_DIFFUSE);
 								}
 
-							} else if (E->get().type==Variant::OBJECT && res->cast_to<FixedMaterial>() && (E->get().name=="textures/normal")) {
+							} else if (E->get().type==Variant::OBJECT && res->cast_to<FixedSpatialMaterial>() && (E->get().name=="textures/normal")) {
 
 								Ref<ImageTexture> tex =res->get(E->get().name);
 								if (tex.is_valid()) {
 
 									image_map.insert(tex,TEXTURE_ROLE_NORMALMAP);
 									//if (p_flags&SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY)
-									//	res->cast_to<FixedMaterial>()->set_fixed_flag(FixedMaterial::FLAG_USE_XY_NORMALMAP,true);
+									//	res->cast_to<FixedSpatialMaterial>()->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_XY_NORMALMAP,true);
 								}//
 
 
@@ -1514,12 +1514,12 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
 				Ref<Mesh> m = mi->get_mesh();
 				for(int i=0;i<m->get_surface_count();i++) {
 
-					Ref<FixedMaterial> fm = m->surface_get_material(i);
+					Ref<FixedSpatialMaterial> fm = m->surface_get_material(i);
 					if (fm.is_valid()) {
 					//	fm->set_flag(Material::FLAG_UNSHADED,true);
 					//	fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
 					//	fm->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER);
-					//	fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
+					//	fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true);
 					}
 				}
 			}
@@ -1537,18 +1537,18 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
 
 			for(int i=0;i<m->get_surface_count();i++) {
 
-				Ref<FixedMaterial> mat = m->surface_get_material(i);
+				Ref<FixedSpatialMaterial> mat = m->surface_get_material(i);
 				if (!mat.is_valid())
 					continue;
 
 				if (p_flags&SCENE_FLAG_DETECT_ALPHA && _teststr(mat->get_name(),"alpha")) {
 
-				//	mat->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
+				//	mat->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true);
 				//	mat->set_name(_fixstr(mat->get_name(),"alpha"));
 				}
 				if (p_flags&SCENE_FLAG_DETECT_VCOLOR && _teststr(mat->get_name(),"vcol")) {
 
-					//mat->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true);
+					//mat->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY,true);
 					//mat->set_name(_fixstr(mat->get_name(),"vcol"));
 				}
 
@@ -1623,12 +1623,12 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
 						Ref<Mesh> m = mi->get_mesh();
 						for(int i=0;i<m->get_surface_count();i++) {
 
-							Ref<FixedMaterial> fm = m->surface_get_material(i);
+							Ref<FixedSpatialMaterial> fm = m->surface_get_material(i);
 							if (fm.is_valid()) {
 							//	fm->set_flag(Material::FLAG_UNSHADED,true);
 							//	fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
 							//	fm->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER);
-							//	fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
+							//	fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true);
 							}
 						}
 					}
@@ -1671,12 +1671,12 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
 			Ref<Mesh> m = mi->get_mesh();
 			for(int i=0;i<m->get_surface_count();i++) {
 
-			    Ref<FixedMaterial> fm = m->surface_get_material(i);
+			    Ref<FixedSpatialMaterial> fm = m->surface_get_material(i);
 			    if (fm.is_valid()) {
 				fm->set_flag(Material::FLAG_UNSHADED,true);
 				fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
 				fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
-				fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
+				fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true);
 			    }
 			}
 		    }*/
@@ -2044,16 +2044,16 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
 
 			for(int i=0;i<mesh->get_surface_count();i++) {
 
-				Ref<FixedMaterial> fm = mesh->surface_get_material(i);
+				Ref<FixedSpatialMaterial> fm = mesh->surface_get_material(i);
 				if (fm.is_valid()) {
 					String name = fm->get_name();
 				/*	if (_teststr(name,"alpha")) {
-						fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
+						fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true);
 						name=_fixstr(name,"alpha");
 					}
 
 					if (_teststr(name,"vcol")) {
-						fm->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true);
+						fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY,true);
 						name=_fixstr(name,"vcol");
 					}*/
 					fm->set_name(name);

+ 12 - 12
tools/editor/io_plugins/editor_scene_importer_fbxconv.cpp

@@ -482,29 +482,29 @@ void EditorSceneImporterFBXConv::_parse_materials(State& state) {
 		ERR_CONTINUE(!material.has("id"));
 		String id = _id(material["id"]);
 
-		Ref<FixedMaterial> mat = memnew( FixedMaterial );
+		Ref<FixedSpatialMaterial> mat = memnew( FixedSpatialMaterial );
 
 		if (material.has("diffuse")) {
-			mat->set_parameter(FixedMaterial::PARAM_DIFFUSE,_get_color(material["diffuse"]));
+			mat->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,_get_color(material["diffuse"]));
 		}
 
 		if (material.has("specular")) {
-			mat->set_parameter(FixedMaterial::PARAM_SPECULAR,_get_color(material["specular"]));
+			mat->set_parameter(FixedSpatialMaterial::PARAM_SPECULAR,_get_color(material["specular"]));
 		}
 
 		if (material.has("emissive")) {
-			mat->set_parameter(FixedMaterial::PARAM_EMISSION,_get_color(material["emissive"]));
+			mat->set_parameter(FixedSpatialMaterial::PARAM_EMISSION,_get_color(material["emissive"]));
 		}
 
 		if (material.has("shininess")) {
 			float exp = material["shininess"];
-			mat->set_parameter(FixedMaterial::PARAM_SPECULAR_EXP,exp);
+			mat->set_parameter(FixedSpatialMaterial::PARAM_SPECULAR_EXP,exp);
 		}
 
 		if (material.has("opacity")) {
-			Color c = mat->get_parameter(FixedMaterial::PARAM_DIFFUSE);
+			Color c = mat->get_parameter(FixedSpatialMaterial::PARAM_DIFFUSE);
 			c.a=material["opacity"];
-			mat->set_parameter(FixedMaterial::PARAM_DIFFUSE,c);
+			mat->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,c);
 		}
 
 
@@ -536,15 +536,15 @@ void EditorSceneImporterFBXConv::_parse_materials(State& state) {
 
 					String type=texture["type"];
 					if (type=="DIFFUSE")
-						mat->set_texture(FixedMaterial::PARAM_DIFFUSE,tex);
+						mat->set_texture(FixedSpatialMaterial::PARAM_DIFFUSE,tex);
 					else if (type=="SPECULAR")
-						mat->set_texture(FixedMaterial::PARAM_SPECULAR,tex);
+						mat->set_texture(FixedSpatialMaterial::PARAM_SPECULAR,tex);
 					else if (type=="SHININESS")
-						mat->set_texture(FixedMaterial::PARAM_SPECULAR_EXP,tex);
+						mat->set_texture(FixedSpatialMaterial::PARAM_SPECULAR_EXP,tex);
 					else if (type=="NORMAL")
-						mat->set_texture(FixedMaterial::PARAM_NORMAL,tex);
+						mat->set_texture(FixedSpatialMaterial::PARAM_NORMAL,tex);
 					else if (type=="EMISSIVE")
-						mat->set_texture(FixedMaterial::PARAM_EMISSION,tex);
+						mat->set_texture(FixedSpatialMaterial::PARAM_EMISSION,tex);
 				}
 
 			}

+ 5 - 5
tools/editor/plugins/baked_light_baker.cpp

@@ -143,18 +143,18 @@ void BakedLightBaker::_add_mesh(const Ref<Mesh>& p_mesh,const Ref<Material>& p_m
 
 				MeshMaterial mm;
 
-				Ref<FixedMaterial> fm = mat;
+				Ref<FixedSpatialMaterial> fm = mat;
 				if (fm.is_valid()) {
 					//fixed route
-					mm.diffuse.color=fm->get_parameter(FixedMaterial::PARAM_DIFFUSE);
+					mm.diffuse.color=fm->get_parameter(FixedSpatialMaterial::PARAM_DIFFUSE);
 					if (linear_color)
 						mm.diffuse.color=mm.diffuse.color.to_linear();
-					mm.diffuse.tex=_get_mat_tex(fm->get_texture(FixedMaterial::PARAM_DIFFUSE));
-					mm.specular.color=fm->get_parameter(FixedMaterial::PARAM_SPECULAR);
+					mm.diffuse.tex=_get_mat_tex(fm->get_texture(FixedSpatialMaterial::PARAM_DIFFUSE));
+					mm.specular.color=fm->get_parameter(FixedSpatialMaterial::PARAM_SPECULAR);
 					if (linear_color)
 						mm.specular.color=mm.specular.color.to_linear();
 
-					mm.specular.tex=_get_mat_tex(fm->get_texture(FixedMaterial::PARAM_SPECULAR));
+					mm.specular.tex=_get_mat_tex(fm->get_texture(FixedSpatialMaterial::PARAM_SPECULAR));
 				} else {
 
 					mm.diffuse.color=Color(1,1,1,1);

+ 10 - 10
tools/editor/plugins/collision_polygon_editor_plugin.cpp

@@ -570,25 +570,25 @@ CollisionPolygonEditor::CollisionPolygonEditor(EditorNode *p_editor) {
 	imgeom->set_transform(Transform(Matrix3(),Vector3(0,0,0.00001)));
 
 
-	line_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
+	line_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
 	line_material->set_flag(Material::FLAG_UNSHADED, true);
 	line_material->set_line_width(3.0);
-	line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	line_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true);
-	line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1));
+	line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
+	line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true);
+	line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1));
 
 
 
 
-	handle_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
+	handle_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
 	handle_material->set_flag(Material::FLAG_UNSHADED, true);
-	handle_material->set_fixed_flag(FixedMaterial::FLAG_USE_POINT_SIZE, true);
-	handle_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1));
-	handle_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	handle_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, false);
+	handle_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_POINT_SIZE, true);
+	handle_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1));
+	handle_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
+	handle_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, false);
 	Ref<Texture> handle=editor->get_gui_base()->get_icon("Editor3DHandle","EditorIcons");
 	handle_material->set_point_size(handle->get_width());
-	handle_material->set_texture(FixedMaterial::PARAM_DIFFUSE,handle);
+	handle_material->set_texture(FixedSpatialMaterial::PARAM_DIFFUSE,handle);
 
 	pointsm = memnew( MeshInstance );
 	imgeom->add_child(pointsm);

+ 2 - 2
tools/editor/plugins/collision_polygon_editor_plugin.h

@@ -62,8 +62,8 @@ class CollisionPolygonEditor : public HBoxContainer {
 	ToolButton *button_edit;
 
 
-	Ref<FixedMaterial> line_material;
-	Ref<FixedMaterial> handle_material;
+	Ref<FixedSpatialMaterial> line_material;
+	Ref<FixedSpatialMaterial> handle_material;
 
 	EditorNode *editor;
 	Panel *panel;

+ 6 - 6
tools/editor/plugins/path_editor_plugin.cpp

@@ -523,16 +523,16 @@ PathEditorPlugin::PathEditorPlugin(EditorNode *p_node) {
 	editor=p_node;
 	singleton=this;
 
-	path_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
-	path_material->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.5,0.5,1.0,0.8) );
-	path_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
+	path_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
+	path_material->set_parameter( FixedSpatialMaterial::PARAM_DIFFUSE,Color(0.5,0.5,1.0,0.8) );
+	path_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
 	path_material->set_line_width(3);
 	path_material->set_flag(Material::FLAG_DOUBLE_SIDED,true);
 	path_material->set_flag(Material::FLAG_UNSHADED,true);
 
-	path_thin_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
-	path_thin_material->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.5,0.5,1.0,0.4) );
-	path_thin_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
+	path_thin_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
+	path_thin_material->set_parameter( FixedSpatialMaterial::PARAM_DIFFUSE,Color(0.5,0.5,1.0,0.4) );
+	path_thin_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
 	path_thin_material->set_line_width(1);
 	path_thin_material->set_flag(Material::FLAG_DOUBLE_SIDED,true);
 	path_thin_material->set_flag(Material::FLAG_UNSHADED,true);

+ 2 - 2
tools/editor/plugins/path_editor_plugin.h

@@ -79,8 +79,8 @@ public:
 	Path *get_edited_path() { return path; }
 
 	static PathEditorPlugin* singleton;
-	Ref<FixedMaterial> path_material;
-	Ref<FixedMaterial> path_thin_material;
+	Ref<FixedSpatialMaterial> path_material;
+	Ref<FixedSpatialMaterial> path_thin_material;
 	virtual bool forward_spatial_input_event(Camera* p_camera,const InputEvent& p_event);
 
 //	virtual bool forward_input_event(const InputEvent& p_event) { return collision_polygon_editor->forward_input_event(p_event); }

+ 26 - 30
tools/editor/plugins/spatial_editor_plugin.cpp

@@ -2548,11 +2548,11 @@ void SpatialEditor::_generate_selection_box() {
 
 	}
 
-	Ref<FixedMaterial> mat = memnew( FixedMaterial );
-	/*mat->set_flag(Material::FLAG_UNSHADED,true);
-	mat->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1));
-	mat->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
-	mat->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true);*/
+	Ref<FixedSpatialMaterial> mat = memnew( FixedSpatialMaterial );
+	mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED,true);
+	mat->set_albedo(Color(1,1,1));
+	mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT,true);
+	mat->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR,true);
 	st->set_material(mat);
 	selection_box = st->commit();
 }
@@ -3139,11 +3139,11 @@ void SpatialEditor::_init_indicators() {
 
 	{
 
-		indicator_mat = VisualServer::get_singleton()->material_create();
-		/*VisualServer::get_singleton()->material_set_flag( indicator_mat, VisualServer::MATERIAL_FLAG_UNSHADED, true );
-		VisualServer::get_singleton()->material_set_flag( indicator_mat, VisualServer::MATERIAL_FLAG_ONTOP, false );
-		VisualServer::get_singleton()->fixed_material_set_flag(indicator_mat, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA,true);
-		VisualServer::get_singleton()->fixed_material_set_flag(indicator_mat, VisualServer::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true);*/
+		indicator_mat.instance();;
+		indicator_mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED,true);
+		indicator_mat->set_flag(FixedSpatialMaterial::FLAG_ONTOP,true);
+		indicator_mat->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR,true);
+		indicator_mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT,true);
 
 		DVector<Color> grid_colors[3];
 		DVector<Vector3> grid_points[3];
@@ -3186,7 +3186,7 @@ void SpatialEditor::_init_indicators() {
 			d[VisualServer::ARRAY_VERTEX]=grid_points[i];
 			d[VisualServer::ARRAY_COLOR]=grid_colors[i];
 			VisualServer::get_singleton()->mesh_add_surface_from_arrays(grid[i],VisualServer::PRIMITIVE_LINES,d);
-			VisualServer::get_singleton()->mesh_surface_set_material(grid[i],0,indicator_mat);
+			VisualServer::get_singleton()->mesh_surface_set_material(grid[i],0,indicator_mat->get_rid());
 			grid_instance[i] = VisualServer::get_singleton()->instance_create2(grid[i],get_tree()->get_root()->get_world()->get_scenario());
 
 			grid_visible[i]=false;
@@ -3205,7 +3205,7 @@ void SpatialEditor::_init_indicators() {
 		d[VisualServer::ARRAY_COLOR]=origin_colors;
 
 		VisualServer::get_singleton()->mesh_add_surface_from_arrays(origin,VisualServer::PRIMITIVE_LINES,d);
-		VisualServer::get_singleton()->mesh_surface_set_material(origin,0,indicator_mat);
+		VisualServer::get_singleton()->mesh_surface_set_material(origin,0,indicator_mat->get_rid());
 
 
 //		origin = VisualServer::get_singleton()->poly_create();
@@ -3236,17 +3236,15 @@ void SpatialEditor::_init_indicators() {
 		cursor_points.push_back(Vector3(0,-cs,0));
 		cursor_points.push_back(Vector3(0,0,+cs));
 		cursor_points.push_back(Vector3(0,0,-cs));
-		cursor_material=VisualServer::get_singleton()->material_create();
-		/*VisualServer::get_singleton()->fixed_material_set_param(cursor_material,VS::FIXED_MATERIAL_PARAM_DIFFUSE,Color(0,1,1));
-		VisualServer::get_singleton()->material_set_flag( cursor_material, VisualServer::MATERIAL_FLAG_UNSHADED, true );
-		VisualServer::get_singleton()->fixed_material_set_flag(cursor_material, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA,true);
-		VisualServer::get_singleton()->fixed_material_set_flag(cursor_material, VisualServer::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true);*/
+		cursor_material.instance();
+		cursor_material->set_albedo(Color(0,1,1));
+		cursor_material->set_flag(FixedSpatialMaterial::FLAG_UNSHADED,true);
 
 		Array d;
 		d.resize(VS::ARRAY_MAX);
 		d[VS::ARRAY_VERTEX]=cursor_points;
 		VisualServer::get_singleton()->mesh_add_surface_from_arrays(cursor_mesh,VS::PRIMITIVE_LINES,d);
-		VisualServer::get_singleton()->mesh_surface_set_material(cursor_mesh,0,cursor_material);
+		VisualServer::get_singleton()->mesh_surface_set_material(cursor_mesh,0,cursor_material->get_rid());
 
 		cursor_instance = VisualServer::get_singleton()->instance_create2(cursor_mesh,get_tree()->get_root()->get_world()->get_scenario());
 		VS::get_singleton()->instance_set_layer_mask(cursor_instance,1<<SpatialEditorViewport::GIZMO_GRID_LAYER);
@@ -3264,11 +3262,11 @@ void SpatialEditor::_init_indicators() {
 
 		float gizmo_alph = EditorSettings::get_singleton()->get("3d_editor/manipulator_gizmo_opacity");
 
-		gizmo_hl = Ref<FixedMaterial>( memnew( FixedMaterial ) );
-	/*	gizmo_hl->set_flag(Material::FLAG_UNSHADED, true);
-		gizmo_hl->set_flag(Material::FLAG_ONTOP, true);
-		gizmo_hl->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-		gizmo_hl->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,gizmo_alph+0.2f));*/
+		gizmo_hl = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ) );
+		gizmo_hl->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
+		gizmo_hl->set_flag(FixedSpatialMaterial::FLAG_ONTOP, true);
+		gizmo_hl->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+		gizmo_hl->set_albedo(Color(1,1,1,gizmo_alph+0.2f));
 
 		for(int i=0;i<3;i++) {
 
@@ -3276,14 +3274,14 @@ void SpatialEditor::_init_indicators() {
 			rotate_gizmo[i]=Ref<Mesh>( memnew( Mesh ) );
 
 
-			Ref<FixedMaterial> mat = memnew( FixedMaterial );
-		/*	mat->set_flag(Material::FLAG_UNSHADED, true);
-			mat->set_flag(Material::FLAG_ONTOP, true);
-			mat->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
+			Ref<FixedSpatialMaterial> mat = memnew( FixedSpatialMaterial );
+			mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
+			mat->set_flag(FixedSpatialMaterial::FLAG_ONTOP, true);
+			mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
 			Color col;
 			col[i]=1.0;
 			col.a= gizmo_alph;
-			mat->set_parameter(FixedMaterial::PARAM_DIFFUSE,col);*/
+			mat->set_albedo(col);
 			gizmo_color[i]=mat;
 
 
@@ -3429,8 +3427,6 @@ void SpatialEditor::_finish_indicators() {
 
 	VisualServer::get_singleton()->free(cursor_instance);
 	VisualServer::get_singleton()->free(cursor_mesh);
-	VisualServer::get_singleton()->free(indicator_mat);
-	VisualServer::get_singleton()->free(cursor_material);
 }
 
 void SpatialEditor::_instance_scene() {

+ 4 - 4
tools/editor/plugins/spatial_editor_plugin.h

@@ -331,8 +331,8 @@ private:
 	bool grid_enabled;
 
 	Ref<Mesh> move_gizmo[3], rotate_gizmo[3];
-	Ref<FixedMaterial> gizmo_color[3];
-	Ref<FixedMaterial> gizmo_hl;
+	Ref<FixedSpatialMaterial> gizmo_color[3];
+	Ref<FixedSpatialMaterial> gizmo_hl;
 
 
 	int over_gizmo_handle;
@@ -344,8 +344,8 @@ private:
 	RID indicators_instance;
 	RID cursor_mesh;
 	RID cursor_instance;
-	RID indicator_mat;
-	RID cursor_material;
+	Ref<FixedSpatialMaterial> indicator_mat;
+	Ref<FixedSpatialMaterial> cursor_material;
 
 /*
 	struct Selected {

+ 49 - 49
tools/editor/spatial_editor_gizmos.cpp

@@ -2976,25 +2976,25 @@ Ref<SpatialEditorGizmo> SpatialEditorGizmos::get_gizmo(Spatial *p_spatial) {
 }
 
 
-Ref<FixedMaterial> SpatialEditorGizmos::create_line_material(const Color& p_base_color) {
+Ref<FixedSpatialMaterial> SpatialEditorGizmos::create_line_material(const Color& p_base_color) {
 
-	Ref<FixedMaterial> line_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
+	Ref<FixedSpatialMaterial> line_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
 	line_material->set_flag(Material::FLAG_UNSHADED, true);
 	line_material->set_line_width(3.0);
-	line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	line_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true);
-	line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,p_base_color);
+	line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
+	line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true);
+	line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,p_base_color);
 
 	return line_material;
 
 }
 
-Ref<FixedMaterial> SpatialEditorGizmos::create_solid_material(const Color& p_base_color) {
+Ref<FixedSpatialMaterial> SpatialEditorGizmos::create_solid_material(const Color& p_base_color) {
 
-	Ref<FixedMaterial> line_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
+	Ref<FixedSpatialMaterial> line_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
 	line_material->set_flag(Material::FLAG_UNSHADED, true);
-	line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,p_base_color);
+	line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
+	line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,p_base_color);
 
 	return line_material;
 
@@ -3004,50 +3004,50 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
 
 	singleton=this;
 
-	handle_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
+	handle_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
 	handle_material->set_flag(Material::FLAG_UNSHADED, true);
-	handle_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(0.8,0.8,0.8));
+	handle_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(0.8,0.8,0.8));
 
-	handle2_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
+	handle2_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
 	handle2_material->set_flag(Material::FLAG_UNSHADED, true);
-	handle2_material->set_fixed_flag(FixedMaterial::FLAG_USE_POINT_SIZE, true);
+	handle2_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_POINT_SIZE, true);
 	handle_t = SpatialEditor::get_singleton()->get_icon("Editor3DHandle","EditorIcons");
 	handle2_material->set_point_size(handle_t->get_width());
-	handle2_material->set_texture(FixedMaterial::PARAM_DIFFUSE,handle_t);
-	handle2_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1));
-	handle2_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	handle2_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true);
+	handle2_material->set_texture(FixedSpatialMaterial::PARAM_DIFFUSE,handle_t);
+	handle2_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1));
+	handle2_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
+	handle2_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true);
 
 	light_material = create_line_material(Color(1,1,0.2));
 
-	light_material_omni_icon = Ref<FixedMaterial>( memnew( FixedMaterial ));
+	light_material_omni_icon = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
 	light_material_omni_icon->set_flag(Material::FLAG_UNSHADED, true);
 	light_material_omni_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true);
 	light_material_omni_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER);
-	light_material_omni_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	light_material_omni_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9));
-	light_material_omni_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoLight","EditorIcons"));
+	light_material_omni_icon->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
+	light_material_omni_icon->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9));
+	light_material_omni_icon->set_texture(FixedSpatialMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoLight","EditorIcons"));
 
 
-	light_material_directional_icon = Ref<FixedMaterial>( memnew( FixedMaterial ));
+	light_material_directional_icon = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
 	light_material_directional_icon->set_flag(Material::FLAG_UNSHADED, true);
 	light_material_directional_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true);
 	light_material_directional_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER);
-	light_material_directional_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	light_material_directional_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9));
-	light_material_directional_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoDirectionalLight","EditorIcons"));
+	light_material_directional_icon->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
+	light_material_directional_icon->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9));
+	light_material_directional_icon->set_texture(FixedSpatialMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoDirectionalLight","EditorIcons"));
 
 	camera_material = create_line_material(Color(1.0,0.5,1.0));
 
 
 	navmesh_edge_material = create_line_material(Color(0.1,0.8,1.0));
 	navmesh_solid_material = create_solid_material(Color(0.1,0.8,1.0,0.4));
-	navmesh_edge_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, false);
+	navmesh_edge_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, false);
 	navmesh_solid_material->set_flag(Material::FLAG_DOUBLE_SIDED,true);
 
 	navmesh_edge_material_disabled = create_line_material(Color(1.0,0.8,0.1));
 	navmesh_solid_material_disabled = create_solid_material(Color(1.0,0.8,0.1,0.4));
-	navmesh_edge_material_disabled->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, false);
+	navmesh_edge_material_disabled->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, false);
 	navmesh_solid_material_disabled->set_flag(Material::FLAG_DOUBLE_SIDED,true);
 
 	skeleton_material = create_line_material(Color(0.6,1.0,0.3));
@@ -3077,10 +3077,10 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
 		cursor_colors.push_back(Color(0.5,0.5,1,0.7));
 		cursor_colors.push_back(Color(0.5,0.5,1,0.7));
 
-		Ref<FixedMaterial> mat = memnew( FixedMaterial );
+		Ref<FixedSpatialMaterial> mat = memnew( FixedSpatialMaterial );
 		mat->set_flag(Material::FLAG_UNSHADED,true);
-		mat->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true);
-		mat->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
+		mat->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY,true);
+		mat->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true);
 		mat->set_line_width(3);
 		Array d;
 		d.resize(VS::ARRAY_MAX);
@@ -3100,10 +3100,10 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
 		cursor_colors.push_back(Color(0.5, 0.5, 0.5, 0.7));
 		cursor_colors.push_back(Color(0.5, 0.5, 0.5, 0.7));
 
-		Ref<FixedMaterial> mat = memnew(FixedMaterial);
+		Ref<FixedSpatialMaterial> mat = memnew(FixedSpatialMaterial);
 		mat->set_flag(Material::FLAG_UNSHADED, true);
-		mat->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true);
-		mat->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
+		mat->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true);
+		mat->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
 		mat->set_line_width(3);
 		Array d;
 		d.resize(VS::ARRAY_MAX);
@@ -3114,13 +3114,13 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
 	}
 
 
-	sample_player_icon = Ref<FixedMaterial>( memnew( FixedMaterial ));
+	sample_player_icon = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
 	sample_player_icon->set_flag(Material::FLAG_UNSHADED, true);
 	sample_player_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true);
 	sample_player_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER);
-	sample_player_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	sample_player_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9));
-	sample_player_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoSpatialSamplePlayer","EditorIcons"));
+	sample_player_icon->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
+	sample_player_icon->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9));
+	sample_player_icon->set_texture(FixedSpatialMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoSpatialSamplePlayer","EditorIcons"));
 
 	room_material = create_line_material(Color(1.0,0.6,0.9));
 	portal_material = create_line_material(Color(1.0,0.8,0.6));
@@ -3129,29 +3129,29 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
 	visibility_notifier_material = create_line_material(Color(1.0,0.5,1.0));
 	joint_material = create_line_material(Color(0.6,0.8,1.0));
 
-	stream_player_icon = Ref<FixedMaterial>( memnew( FixedMaterial ));
+	stream_player_icon = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
 	stream_player_icon->set_flag(Material::FLAG_UNSHADED, true);
 	stream_player_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true);
 	stream_player_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER);
-	stream_player_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	stream_player_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9));
-	stream_player_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoSpatialStreamPlayer","EditorIcons"));
+	stream_player_icon->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
+	stream_player_icon->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9));
+	stream_player_icon->set_texture(FixedSpatialMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoSpatialStreamPlayer","EditorIcons"));
 
-	visibility_notifier_icon = Ref<FixedMaterial>( memnew( FixedMaterial ));
+	visibility_notifier_icon = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
 	visibility_notifier_icon->set_flag(Material::FLAG_UNSHADED, true);
 	visibility_notifier_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true);
 	visibility_notifier_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER);
-	visibility_notifier_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	visibility_notifier_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9));
-	visibility_notifier_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("Visible","EditorIcons"));
+	visibility_notifier_icon->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
+	visibility_notifier_icon->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9));
+	visibility_notifier_icon->set_texture(FixedSpatialMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("Visible","EditorIcons"));
 
-	listener_icon = Ref<FixedMaterial>(memnew(FixedMaterial));
+	listener_icon = Ref<FixedSpatialMaterial>(memnew(FixedSpatialMaterial));
 	listener_icon->set_flag(Material::FLAG_UNSHADED, true);
 	listener_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true);
 	listener_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER);
-	listener_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	listener_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE, Color(1, 1, 1, 0.9));
-	listener_icon->set_texture(FixedMaterial::PARAM_DIFFUSE, SpatialEditor::get_singleton()->get_icon("GizmoListener", "EditorIcons"));
+	listener_icon->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
+	listener_icon->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE, Color(1, 1, 1, 0.9));
+	listener_icon->set_texture(FixedSpatialMaterial::PARAM_DIFFUSE, SpatialEditor::get_singleton()->get_icon("GizmoListener", "EditorIcons"));
 
 	{
 

+ 28 - 28
tools/editor/spatial_editor_gizmos.h

@@ -464,34 +464,34 @@ public:
 class SpatialEditorGizmos  {
 public:
 
-	Ref<FixedMaterial> create_line_material(const Color& p_base_color);
-	Ref<FixedMaterial> create_solid_material(const Color& p_base_color);
-	Ref<FixedMaterial> handle2_material;
-	Ref<FixedMaterial> handle_material;
-	Ref<FixedMaterial> light_material;
-	Ref<FixedMaterial> light_material_omni_icon;
-	Ref<FixedMaterial> light_material_directional_icon;
-	Ref<FixedMaterial> camera_material;
-	Ref<FixedMaterial> skeleton_material;
-	Ref<FixedMaterial> room_material;
-	Ref<FixedMaterial> portal_material;
-	Ref<FixedMaterial> raycast_material;
-	Ref<FixedMaterial> visibility_notifier_material;
-	Ref<FixedMaterial> car_wheel_material;
-	Ref<FixedMaterial> joint_material;
-
-	Ref<FixedMaterial> navmesh_edge_material;
-	Ref<FixedMaterial> navmesh_solid_material;
-	Ref<FixedMaterial> navmesh_edge_material_disabled;
-	Ref<FixedMaterial> navmesh_solid_material_disabled;
-
-	Ref<FixedMaterial> listener_icon;
-
-	Ref<FixedMaterial> sample_player_icon;
-	Ref<FixedMaterial> stream_player_icon;
-	Ref<FixedMaterial> visibility_notifier_icon;
-
-	Ref<FixedMaterial> shape_material;
+	Ref<FixedSpatialMaterial> create_line_material(const Color& p_base_color);
+	Ref<FixedSpatialMaterial> create_solid_material(const Color& p_base_color);
+	Ref<FixedSpatialMaterial> handle2_material;
+	Ref<FixedSpatialMaterial> handle_material;
+	Ref<FixedSpatialMaterial> light_material;
+	Ref<FixedSpatialMaterial> light_material_omni_icon;
+	Ref<FixedSpatialMaterial> light_material_directional_icon;
+	Ref<FixedSpatialMaterial> camera_material;
+	Ref<FixedSpatialMaterial> skeleton_material;
+	Ref<FixedSpatialMaterial> room_material;
+	Ref<FixedSpatialMaterial> portal_material;
+	Ref<FixedSpatialMaterial> raycast_material;
+	Ref<FixedSpatialMaterial> visibility_notifier_material;
+	Ref<FixedSpatialMaterial> car_wheel_material;
+	Ref<FixedSpatialMaterial> joint_material;
+
+	Ref<FixedSpatialMaterial> navmesh_edge_material;
+	Ref<FixedSpatialMaterial> navmesh_solid_material;
+	Ref<FixedSpatialMaterial> navmesh_edge_material_disabled;
+	Ref<FixedSpatialMaterial> navmesh_solid_material_disabled;
+
+	Ref<FixedSpatialMaterial> listener_icon;
+
+	Ref<FixedSpatialMaterial> sample_player_icon;
+	Ref<FixedSpatialMaterial> stream_player_icon;
+	Ref<FixedSpatialMaterial> visibility_notifier_icon;
+
+	Ref<FixedSpatialMaterial> shape_material;
 	Ref<Texture> handle_t;
 
 	Ref<Mesh> pos3d_mesh;

Some files were not shown because too many files changed in this diff