Ver código fonte

More scene work, can display a skybox

Juan Linietsky 9 anos atrás
pai
commit
cb34b70df1

+ 0 - 1
drivers/gles3/rasterizer_canvas_gles3.cpp

@@ -117,7 +117,6 @@ void RasterizerCanvasGLES3::canvas_begin(){
 		glClearColor( storage->frame.clear_request_color.r, storage->frame.clear_request_color.g, storage->frame.clear_request_color.b, storage->frame.clear_request_color.a );
 		glClear(GL_COLOR_BUFFER_BIT);
 		storage->frame.clear_request=false;
-		print_line("canvas clear?");
 
 	}
 

+ 224 - 1
drivers/gles3/rasterizer_scene_gles3.cpp

@@ -1,5 +1,10 @@
 #include "rasterizer_scene_gles3.h"
 #include "globals.h"
+
+
+
+
+
 static _FORCE_INLINE_ void store_matrix32(const Matrix32& p_mtx, float* p_array) {
 
 	p_array[ 0]=p_mtx.elements[0][0];
@@ -52,6 +57,121 @@ static _FORCE_INLINE_ void store_camera(const CameraMatrix& p_mtx, float* p_arra
 
 
 
+
+/* ENVIRONMENT API */
+
+RID RasterizerSceneGLES3::environment_create(){
+
+
+	Environment *env = memnew( Environment );
+
+	return environment_owner.make_rid(env);
+}
+
+void RasterizerSceneGLES3::environment_set_background(RID p_env,VS::EnvironmentBG p_bg){
+
+	Environment *env=environment_owner.getornull(p_env);
+	ERR_FAIL_COND(!env);
+	env->bg_mode=p_bg;
+}
+
+void RasterizerSceneGLES3::environment_set_skybox(RID p_env, RID p_skybox, int p_radiance_size, int p_irradiance_size){
+
+	Environment *env=environment_owner.getornull(p_env);
+	ERR_FAIL_COND(!env);
+
+	if (env->skybox_color.is_valid()) {
+		env->skybox_color=RID();
+	}
+	if (env->skybox_radiance.is_valid()) {
+		storage->free(env->skybox_radiance);
+		env->skybox_radiance=RID();
+	}
+	if (env->skybox_irradiance.is_valid()) {
+		storage->free(env->skybox_irradiance);
+		env->skybox_irradiance=RID();
+	}
+
+	if (p_skybox.is_valid()) {
+
+		env->skybox_color=p_skybox;
+	//	env->skybox_radiance=storage->texture_create_pbr_cubemap(p_skybox,VS::PBR_CUBEMAP_RADIANCE,p_radiance_size);
+		//env->skybox_irradiance=storage->texture_create_pbr_cubemap(p_skybox,VS::PBR_CUBEMAP_IRRADIANCE,p_irradiance_size);
+	}
+
+}
+
+void RasterizerSceneGLES3::environment_set_skybox_scale(RID p_env,float p_scale) {
+
+	Environment *env=environment_owner.getornull(p_env);
+	ERR_FAIL_COND(!env);
+
+	env->skybox_scale=p_scale;
+
+}
+
+void RasterizerSceneGLES3::environment_set_bg_color(RID p_env,const Color& p_color){
+
+	Environment *env=environment_owner.getornull(p_env);
+	ERR_FAIL_COND(!env);
+
+	env->bg_color=p_color;
+
+}
+void RasterizerSceneGLES3::environment_set_bg_energy(RID p_env,float p_energy) {
+
+	Environment *env=environment_owner.getornull(p_env);
+	ERR_FAIL_COND(!env);
+
+	env->energy=p_energy;
+
+}
+
+void RasterizerSceneGLES3::environment_set_canvas_max_layer(RID p_env,int p_max_layer){
+
+	Environment *env=environment_owner.getornull(p_env);
+	ERR_FAIL_COND(!env);
+
+	env->canvas_max_layer=p_max_layer;
+
+}
+void RasterizerSceneGLES3::environment_set_ambient_light(RID p_env, const Color& p_color, float p_energy, float p_skybox_energy){
+
+	Environment *env=environment_owner.getornull(p_env);
+	ERR_FAIL_COND(!env);
+
+	env->ambient_color=p_color;
+	env->ambient_anergy=p_energy;
+	env->skybox_ambient=p_skybox_energy;
+
+}
+
+void RasterizerSceneGLES3::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){
+
+}
+void RasterizerSceneGLES3::environment_set_fog(RID p_env,bool p_enable,float p_begin,float p_end,RID p_gradient_texture){
+
+}
+
+void RasterizerSceneGLES3::environment_set_tonemap(RID p_env,bool p_enable,float p_exposure,float p_white,float p_min_luminance,float p_max_luminance,float p_auto_exp_speed,VS::EnvironmentToneMapper p_tone_mapper){
+
+}
+void RasterizerSceneGLES3::environment_set_brightness(RID p_env,bool p_enable,float p_brightness){
+
+}
+void RasterizerSceneGLES3::environment_set_contrast(RID p_env,bool p_enable,float p_contrast){
+
+}
+void RasterizerSceneGLES3::environment_set_saturation(RID p_env,bool p_enable,float p_saturation){
+
+}
+void RasterizerSceneGLES3::environment_set_color_correction(RID p_env,bool p_enable,RID p_ramp){
+
+}
+
+
+
+
 RID RasterizerSceneGLES3::light_instance_create(RID p_light) {
 
 
@@ -493,6 +613,70 @@ void RasterizerSceneGLES3::_add_geometry(  RasterizerStorageGLES3::Geometry* p_g
 #endif
 }
 
+void RasterizerSceneGLES3::_draw_skybox(RID p_skybox,CameraMatrix& p_projection,const Transform& p_transform,bool p_vflip,float p_scale) {
+
+	RasterizerStorageGLES3::Texture *tex = storage->texture_owner.getornull(p_skybox);
+
+	ERR_FAIL_COND(!tex);
+	glActiveTexture(GL_TEXTURE0);
+	glBindTexture(tex->target,tex->tex_id);
+
+	glDepthMask(GL_TRUE);
+	glEnable(GL_DEPTH_TEST);
+	glDisable(GL_CULL_FACE);
+	glDisable(GL_BLEND);
+	glColorMask(1,1,1,1);
+
+	float flip_sign = p_vflip?-1:1;
+
+	Vector3 vertices[8]={
+		Vector3(-1,-1*flip_sign,0.1),
+		Vector3( 0, 1, 0),
+		Vector3( 1,-1*flip_sign,0.1),
+		Vector3( 1, 1, 0),
+		Vector3( 1, 1*flip_sign,0.1),
+		Vector3( 1, 0, 0),
+		Vector3(-1, 1*flip_sign,0.1),
+		Vector3( 0, 0, 0),
+
+	};
+
+
+
+	//skybox uv vectors
+	float vw,vh,zn;
+	p_projection.get_viewport_size(vw,vh);
+	zn=p_projection.get_z_near();
+
+	float scale=p_scale;
+
+	for(int i=0;i<4;i++) {
+
+		Vector3 uv=vertices[i*2+1];
+		uv.x=(uv.x*2.0-1.0)*vw*scale;
+		uv.y=-(uv.y*2.0-1.0)*vh*scale;
+		uv.z=-zn;
+		vertices[i*2+1] = p_transform.basis.xform(uv).normalized();
+		vertices[i*2+1].z = -vertices[i*2+1].z;
+	}
+
+	glBindBuffer(GL_ARRAY_BUFFER,state.skybox_verts);
+	glBufferSubData(GL_ARRAY_BUFFER,0,sizeof(Vector3)*8,vertices);
+	glBindBuffer(GL_ARRAY_BUFFER,0); //unbind
+
+	glBindVertexArray(state.skybox_array);
+
+	storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_CUBEMAP,true);
+	storage->shaders.copy.bind();
+
+	glDrawArrays(GL_TRIANGLE_FAN,0,4);
+
+	glBindVertexArray(0);
+
+	storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_CUBEMAP,false);
+
+}
+
 void RasterizerSceneGLES3::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){
 
 
@@ -561,7 +745,9 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,CameraM
 	glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->front.fbo);
 
 
-	if (true) {
+	Environment *env = environment_owner.getornull(p_environment);
+
+	if (!env || env->bg_mode==VS::ENV_BG_CLEAR_COLOR) {
 
 		if (storage->frame.clear_request) {
 
@@ -570,6 +756,16 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,CameraM
 			storage->frame.clear_request=false;
 
 		}
+	} else if (env->bg_mode==VS::ENV_BG_COLOR) {
+
+
+		glClearColor( env->bg_color.r, env->bg_color.g, env->bg_color.b, env->bg_color.a );
+		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+		storage->frame.clear_request=false;
+	} else {
+		glClear(GL_DEPTH_BUFFER_BIT);
+		storage->frame.clear_request=false;
+
 	}
 
 	state.current_depth_test=true;
@@ -616,6 +812,12 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,CameraM
 
 	_render_list(render_list.elements,render_list.element_count,p_cam_transform,p_cam_projection,false,false);
 
+
+	if (env && env->bg_mode==VS::ENV_BG_SKYBOX) {
+
+		_draw_skybox(env->skybox_color,p_cam_projection,p_cam_transform,storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP],env->skybox_scale);
+	}
+
 	//_render_list_forward(&alpha_render_list,camera_transform,camera_transform_inverse,camera_projection,false,fragment_lighting,true);
 	//glColorMask(1,1,1,1);
 
@@ -793,6 +995,27 @@ void RasterizerSceneGLES3::initialize() {
 	if (render_list.max_elements<1024)
 		render_list.max_elements=1024;
 
+
+
+	{
+		//quad buffers
+
+		glGenBuffers(1,&state.skybox_verts);
+		glBindBuffer(GL_ARRAY_BUFFER,state.skybox_verts);
+		glBufferData(GL_ARRAY_BUFFER,sizeof(Vector3)*8,NULL,GL_DYNAMIC_DRAW);
+		glBindBuffer(GL_ARRAY_BUFFER,0); //unbind
+
+
+		glGenVertexArrays(1,&state.skybox_array);
+		glBindVertexArray(state.skybox_array);
+		glBindBuffer(GL_ARRAY_BUFFER,state.skybox_verts);
+		glVertexAttribPointer(VS::ARRAY_VERTEX,3,GL_FLOAT,GL_FALSE,sizeof(Vector3)*2,0);
+		glEnableVertexAttribArray(VS::ARRAY_VERTEX);
+		glVertexAttribPointer(VS::ARRAY_TEX_UV,3,GL_FLOAT,GL_FALSE,sizeof(Vector3)*2,((uint8_t*)NULL)+sizeof(Vector3));
+		glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
+		glBindVertexArray(0);
+		glBindBuffer(GL_ARRAY_BUFFER,0); //unbind
+	}
 	render_list.init();
 }
 

+ 63 - 3
drivers/gles3/rasterizer_scene_gles3.h

@@ -16,8 +16,6 @@ public:
 
 	RasterizerStorageGLES3 *storage;
 
-
-
 	struct State {
 
 		bool current_depth_test;
@@ -40,10 +38,70 @@ public:
 
 		GLuint scene_ubo;
 
-
+		GLuint skybox_verts;
+		GLuint skybox_array;
 
 	} state;
 
+
+
+
+	/* ENVIRONMENT API */
+
+	struct Environment : public RID_Data {
+
+		VS::EnvironmentBG bg_mode;
+
+		RID skybox_color;
+		RID skybox_radiance;
+		RID skybox_irradiance;
+		float skybox_scale;
+
+		Color bg_color;
+		float energy;
+		float skybox_ambient;
+
+		Color ambient_color;
+		float ambient_anergy;
+		float ambient_skybox_energy;
+
+		int canvas_max_layer;
+
+
+		Environment() {
+			bg_mode=VS::ENV_BG_CLEAR_COLOR;
+			skybox_scale=1.0;
+			energy=1.0;
+			skybox_ambient=0;
+			ambient_anergy=1.0;
+			ambient_skybox_energy=0.0;
+			canvas_max_layer=0;
+		}
+	};
+
+	RID_Owner<Environment> environment_owner;
+
+	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_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_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);
+
+	virtual void environment_set_tonemap(RID p_env,bool p_enable,float p_exposure,float p_white,float p_min_luminance,float p_max_luminance,float p_auto_exp_speed,VS::EnvironmentToneMapper p_tone_mapper);
+	virtual void environment_set_brightness(RID p_env,bool p_enable,float p_brightness);
+	virtual void environment_set_contrast(RID p_env,bool p_enable,float p_contrast);
+	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);
+
+	/* RENDER LIST */
+
 	struct RenderList {
 
 		enum {
@@ -166,6 +224,8 @@ public:
 
 	_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);
+
 	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);

+ 137 - 0
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -995,6 +995,104 @@ 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 {
+
+	Texture * texture = texture_owner.get(p_source);
+	ERR_FAIL_COND_V(!texture,RID());
+	ERR_FAIL_COND_V(!(texture->flags&VS::TEXTURE_FLAG_CUBEMAP),RID());
+
+	bool use_float=true;
+
+	if (p_resolution<0) {
+		p_resolution=texture->width;
+	}
+
+
+	glBindVertexArray(0);
+	glDisable(GL_CULL_FACE);
+	glDisable(GL_DEPTH_TEST);
+	glDisable(GL_SCISSOR_TEST);
+#ifdef GLEW_ENABLED
+	glDisable(GL_POINT_SPRITE);
+	glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
+#endif
+	glDisable(GL_BLEND);
+
+
+	glActiveTexture(GL_TEXTURE1);
+	glBindTexture(texture->target, texture->tex_id);
+
+	glActiveTexture(GL_TEXTURE0);
+	GLuint new_cubemap;
+	glGenTextures(1, &new_cubemap);
+
+
+	GLuint tmp_fb;
+
+	glGenFramebuffers(1, &tmp_fb);
+	glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb);
+
+
+	int w = texture->width;
+	int h = texture->height;
+
+	int lod=0;
+
+	shaders.cubemap_filter.bind();
+
+	int mipmaps=6;
+
+	int mm_level=mipmaps;
+
+	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);
+
+			glViewport(0,0,w,h);
+			glBindVertexArray(resources.quadie_array);
+
+			shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::FACE_ID,i);
+			shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::ROUGHNESS,lod/float(mipmaps));
+
+
+			glDrawArrays(GL_TRIANGLE_FAN,0,4);
+			glBindVertexArray(0);
+#ifdef DEBUG_ENABLED
+			GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+			ERR_CONTINUE(status!=GL_FRAMEBUFFER_COMPLETE);
+#endif
+		}
+
+
+
+		if (w>1)
+			w>>=1;
+		if (h>1)
+			h>>=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);
+
+	}
+
+	glBindFramebuffer(GL_FRAMEBUFFER, config.system_fbo);
+	glDeleteFramebuffers(1, &tmp_fb);
+
+
+	return RID();
+}
 
 
 /* SHADER API */
@@ -3649,6 +3747,45 @@ void RasterizerStorageGLES3::initialize() {
 #else
 	config.use_rgba_2d_shadows=true;
 #endif
+
+
+	//generic quadie for copying
+
+	{
+		//quad buffers
+
+		glGenBuffers(1,&resources.quadie);
+		glBindBuffer(GL_ARRAY_BUFFER,resources.quadie);
+		{
+			const float qv[16]={
+				-1,-1,
+				 0, 0,
+				-1, 1,
+				 0, 1,
+				 1, 1,
+				 1, 1,
+				 1,-1,
+				 1, 0,
+			};
+
+			glBufferData(GL_ARRAY_BUFFER,sizeof(float)*16,qv,GL_STATIC_DRAW);
+		}
+
+		glBindBuffer(GL_ARRAY_BUFFER,0); //unbind
+
+
+		glGenVertexArrays(1,&resources.quadie_array);
+		glBindVertexArray(resources.quadie_array);
+		glBindBuffer(GL_ARRAY_BUFFER,resources.quadie);
+		glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,sizeof(float)*4,0);
+		glEnableVertexAttribArray(0);
+		glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,sizeof(float)*4,((uint8_t*)NULL)+8);
+		glEnableVertexAttribArray(1);
+		glBindVertexArray(0);
+		glBindBuffer(GL_ARRAY_BUFFER,0); //unbind
+	}
+
+	shaders.cubemap_filter.init();
 }
 
 void RasterizerStorageGLES3::finalize() {

+ 8 - 0
drivers/gles3/rasterizer_storage_gles3.h

@@ -6,6 +6,7 @@
 #include "shader_gles3.h"
 #include "shaders/copy.glsl.h"
 #include "shaders/canvas.glsl.h"
+#include "shaders/cubemap_filter.glsl.h"
 #include "self_list.h"
 #include "shader_compiler_gles3.h"
 
@@ -60,6 +61,8 @@ public:
 
 		ShaderCompilerGLES3 compiler;
 
+		CubemapFilterShaderGLES3 cubemap_filter;
+
 		ShaderCompilerGLES3::IdentifierActions actions_canvas;
 		ShaderCompilerGLES3::IdentifierActions actions_scene;
 	} shaders;
@@ -70,6 +73,9 @@ public:
 		GLuint black_tex;
 		GLuint normal_tex;
 
+		GLuint quadie;
+		GLuint quadie_array;
+
 	} resources;
 
 	struct Info {
@@ -178,6 +184,8 @@ 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;
+
 
 	/* SHADER API */
 

+ 1 - 0
drivers/gles3/shaders/SCsub

@@ -5,4 +5,5 @@ if env['BUILDERS'].has_key('GLES3_GLSL'):
 	env.GLES3_GLSL('canvas.glsl');
 	env.GLES3_GLSL('canvas_shadow.glsl');
 	env.GLES3_GLSL('scene.glsl');
+	env.GLES3_GLSL('cubemap_filter.glsl');
 

+ 14 - 3
drivers/gles3/shaders/copy.glsl

@@ -33,20 +33,31 @@ void main() {
 
 #ifdef USE_CUBEMAP
 in vec3 cube_interp;
-uniform samplerCube source_cube;
+uniform samplerCube source_cube; //texunit:0
 #else
 in vec2 uv_interp;
-uniform sampler2D source;
+uniform sampler2D source; //texunit:0
 #endif
 
+
+uniform float stuff;
+
 in vec2 uv2_interp;
 
-layout(location = 0) vec4 frag_color; //color:0
+layout(location = 0) out vec4 frag_color;
 
 void main() {
 
 	//vec4 color = color_interp;
 
+#ifdef USE_CUBEMAP
+	vec4 color = texture( source_cube,  normalize(cube_interp) );
+
+#else
+	vec4 color = texture( source,  uv_interp );
+#endif
+
+
 	frag_color = color;
 }
 

+ 143 - 0
drivers/gles3/shaders/cubemap_filter.glsl

@@ -0,0 +1,143 @@
+[vertex]
+
+
+layout(location=0) in highp vec2 vertex;
+
+layout(location=1) in highp vec2 uv;
+
+out highp vec2 uv_interp;
+
+void main() {
+
+	uv_interp=uv;
+	gl_Position=vec4(vertex,0,1);
+}
+
+[fragment]
+
+
+uniform samplerCube source_cube; //texunit:1
+uniform int face_id;
+uniform float roughness;
+in highp vec2 uv_interp;
+
+
+layout(location = 0) vec4 frag_color;
+
+
+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
+    faceUvVectors[1][2] = vec3(-1.0, 0.0, 0.0); // -x 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
+
+    // -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
+
+    // +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
+
+    // -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
+
+    // +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
+
+    // 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];
+    return normalize(result);
+}
+
+vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N)
+{
+	float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph]
+
+	// Compute distribution direction
+	float Phi = 2.0 * M_PI * Xi.x;
+	float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y));
+	float SinTheta = sqrt(1.0 - CosTheta * CosTheta);
+
+	// Convert to spherical direction
+	vec3 H;
+	H.x = SinTheta * cos(Phi);
+	H.y = SinTheta * sin(Phi);
+	H.z = CosTheta;
+
+	vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+	vec3 TangentX = normalize(cross(UpVector, N));
+	vec3 TangentY = cross(N, TangentX);
+
+	// Tangent to world space
+	return TangentX * H.x + TangentY * H.y + N * H.z;
+}
+
+// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
+float GGX(float NdotV, float a)
+{
+	float k = a / 2.0;
+	return NdotV / (NdotV * (1.0 - k) + k);
+}
+
+// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
+float G_Smith(float a, float nDotV, float nDotL)
+{
+	return GGX(nDotL, a * a) * GGX(nDotV, a * a);
+}
+
+float radicalInverse_VdC(uint bits) {
+    bits = (bits << 16u) | (bits >> 16u);
+    bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
+    bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
+    bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
+    bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
+    return float(bits) * 2.3283064365386963e-10; // / 0x100000000
+}
+
+vec2 Hammersley(uint i, uint N) {
+     return vec2(float(i)/float(N), radicalInverse_VdC(i));
+}
+
+#define SAMPLE_COUNT 1024
+
+void main() {
+
+	vec2 uv         = (uv_interp * 2.0) - 1.0;
+	vec3 N          = texelCoordToVec(uv, face_id);
+
+	//vec4 color = color_interp;
+	vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
+
+	for(int sampleNum = 0; 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;
+
+		sum += vec4(s, 1.0);
+	}
+	sum /= sum.w;
+
+	frag_color = vec4(sum.rgb, 1.0);
+}
+

+ 174 - 1
scene/resources/environment.cpp

@@ -28,20 +28,193 @@
 /*************************************************************************/
 #include "environment.h"
 #include "texture.h"
-
+#include "globals.h"
+#include "servers/visual_server.h"
 
 RID Environment::get_rid() const {
 
 	return environment;
 }
 
+
+void Environment::set_background(BGMode p_bg) {
+
+	bg_mode=p_bg;
+	VS::get_singleton()->environment_set_background(environment,VS::EnvironmentBG(p_bg));
+	_change_notify();
+}
+
+void Environment::set_skybox(const Ref<CubeMap>& p_skybox){
+
+	bg_skybox=p_skybox;
+
+	RID sb_rid;
+	if (bg_skybox.is_valid())
+		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"));
+}
+
+void Environment::set_skybox_scale(float p_scale) {
+
+	bg_skybox_scale=p_scale;
+	VS::get_singleton()->environment_set_skybox_scale(environment,p_scale);
+}
+
+void Environment::set_bg_color(const Color& p_color){
+
+	bg_color=p_color;
+	VS::get_singleton()->environment_set_bg_color(environment,p_color);
+}
+void Environment::set_bg_energy(float p_energy){
+
+	bg_energy=p_energy;
+	VS::get_singleton()->environment_set_bg_energy(environment,p_energy);
+}
+void Environment::set_canvas_max_layer(int p_max_layer){
+
+	bg_canvas_max_layer=p_max_layer;
+	VS::get_singleton()->environment_set_canvas_max_layer(environment,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);
+}
+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);
+}
+void Environment::set_ambient_light_skybox_energy(float p_energy){
+
+	ambient_skybox_energy=p_energy;
+	VS::get_singleton()->environment_set_ambient_light(environment,ambient_color,ambient_energy,ambient_skybox_energy);
+}
+
+Environment::BGMode Environment::get_background() const{
+
+	return bg_mode;
+}
+Ref<CubeMap> Environment::get_skybox() const{
+
+	return bg_skybox;
+}
+
+float Environment::get_skybox_scale() const {
+
+	return bg_skybox_scale;
+}
+
+Color Environment::get_bg_color() const{
+
+	return bg_color;
+}
+float Environment::get_bg_energy() const{
+
+	return bg_energy;
+}
+int Environment::get_canvas_max_layer() const{
+
+	return bg_canvas_max_layer;
+}
+Color Environment::get_ambient_light_color() const{
+
+	return ambient_color;
+}
+float Environment::get_ambient_light_energy() const{
+
+	return ambient_energy;
+}
+float Environment::get_ambient_light_skybox_energy() const{
+
+	return ambient_skybox_energy;
+}
+
+
+
+void Environment::_validate_property(PropertyInfo& property) const {
+
+	if (property.name=="background/skybox" || property.name=="ambient_light/skybox_energy") {
+		if (bg_mode!=BG_SKYBOX) {
+			property.usage=PROPERTY_USAGE_NOEDITOR;
+		}
+	}
+
+	if (property.name=="background/color") {
+		if (bg_mode!=BG_COLOR) {
+			property.usage=PROPERTY_USAGE_NOEDITOR;
+		}
+	}
+
+	if (property.name=="background/canvas_max_layer") {
+		if (bg_mode!=BG_CANVAS) {
+			property.usage=PROPERTY_USAGE_NOEDITOR;
+		}
+	}
+
+}
+
 void Environment::_bind_methods() {
 
+	ObjectTypeDB::bind_method(_MD("set_background","mode"),&Environment::set_background);
+	ObjectTypeDB::bind_method(_MD("set_skybox","skybox:CubeMap"),&Environment::set_skybox);
+	ObjectTypeDB::bind_method(_MD("set_skybox_scale","scale"),&Environment::set_skybox_scale);
+	ObjectTypeDB::bind_method(_MD("set_bg_color","color"),&Environment::set_bg_color);
+	ObjectTypeDB::bind_method(_MD("set_bg_energy","energy"),&Environment::set_bg_energy);
+	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("get_background"),&Environment::get_background);
+	ObjectTypeDB::bind_method(_MD("get_skybox:CubeMap"),&Environment::get_skybox);
+	ObjectTypeDB::bind_method(_MD("get_skybox_scale"),&Environment::get_skybox_scale);
+	ObjectTypeDB::bind_method(_MD("get_bg_color"),&Environment::get_bg_color);
+	ObjectTypeDB::bind_method(_MD("get_bg_energy"),&Environment::get_bg_energy);
+	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);
+
+
+	ADD_PROPERTY(PropertyInfo(Variant::INT,"background/mode",PROPERTY_HINT_ENUM,"Clear Color,Custom Color,Skybox,Canvas,Keep"),_SCS("set_background"),_SCS("get_background") );
+	ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"background/skybox",PROPERTY_HINT_RESOURCE_TYPE,"CubeMap"),_SCS("set_skybox"),_SCS("get_skybox") );
+	ADD_PROPERTY(PropertyInfo(Variant::REAL,"background/skybox_scale",PROPERTY_HINT_RANGE,"0,32,0.01"),_SCS("set_skybox_scale"),_SCS("get_skybox_scale") );
+	ADD_PROPERTY(PropertyInfo(Variant::COLOR,"background/color"),_SCS("set_bg_color"),_SCS("get_bg_color") );
+	ADD_PROPERTY(PropertyInfo(Variant::REAL,"background/energy",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_bg_energy"),_SCS("get_bg_energy") );
+	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") );
+
+	GLOBAL_DEF("rendering/skybox/irradiance_cube_resolution",256);
+	GLOBAL_DEF("rendering/skybox/radiance_cube_resolution",64);
+
+	BIND_CONSTANT(BG_KEEP);
+	BIND_CONSTANT(BG_CLEAR_COLOR);
+	BIND_CONSTANT(BG_COLOR);
+	BIND_CONSTANT(BG_SKYBOX);
+	BIND_CONSTANT(BG_CANVAS);
+	BIND_CONSTANT(BG_MAX);
+	BIND_CONSTANT(GLOW_BLEND_MODE_ADDITIVE);
+	BIND_CONSTANT(GLOW_BLEND_MODE_SCREEN);
+	BIND_CONSTANT(GLOW_BLEND_MODE_SOFTLIGHT);
+	BIND_CONSTANT(GLOW_BLEND_MODE_DISABLED);
 
 }
 
 Environment::Environment() {
 
+	bg_mode=BG_CLEAR_COLOR;
+	bg_energy=1.0;
+	bg_canvas_max_layer=0;
+	ambient_energy=1.0;
+	ambient_skybox_energy=0;
+
+
 	environment = VS::get_singleton()->environment_create();
 
 }

+ 53 - 1
scene/resources/environment.h

@@ -31,28 +31,80 @@
 
 #include "resource.h"
 #include "servers/visual_server.h"
+#include "scene/resources/texture.h"
 
 class Environment : public Resource {
 
 	OBJ_TYPE(Environment,Resource);
 public:
 
+	enum BGMode {
 
-private:
+		BG_CLEAR_COLOR,
+		BG_COLOR,
+		BG_SKYBOX,
+		BG_CANVAS,
+		BG_KEEP,
+		BG_MAX
+	};
 
+	enum GlowBlendMode {
+		GLOW_BLEND_MODE_ADDITIVE,
+		GLOW_BLEND_MODE_SCREEN,
+		GLOW_BLEND_MODE_SOFTLIGHT,
+		GLOW_BLEND_MODE_DISABLED,
+	};
 
+private:
 	RID environment;
 
+	BGMode bg_mode;
+	Ref<CubeMap> bg_skybox;
+	float bg_skybox_scale;
+	Color bg_color;
+	float bg_energy;
+	int bg_canvas_max_layer;
+	Color ambient_color;
+	float ambient_energy;
+	float ambient_skybox_energy;
+
 protected:
 
 	static void _bind_methods();
+	virtual void _validate_property(PropertyInfo& property) const;
+
 public:
 
+
+	void set_background(BGMode p_bg);
+	void set_skybox(const Ref<CubeMap>& p_skybox);
+	void set_skybox_scale(float p_scale);
+	void set_bg_color(const Color& p_color);
+	void set_bg_energy(float p_energy);
+	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);
+
+	BGMode get_background() const;
+	Ref<CubeMap> get_skybox() const;
+	float get_skybox_scale() const;
+	Color get_bg_color() const;
+	float get_bg_energy() const;
+	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;
+
+
 	virtual RID get_rid() const;
 
 	Environment();
 	~Environment();
 };
 
+VARIANT_ENUM_CAST(Environment::BGMode)
+VARIANT_ENUM_CAST(Environment::GlowBlendMode)
+
 
 #endif // ENVIRONMENT_H

+ 21 - 0
servers/visual/rasterizer.h

@@ -39,6 +39,26 @@
 class RasterizerScene {
 public:
 
+	/* ENVIRONMENT API */
+
+	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_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_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;
+
+	virtual void environment_set_tonemap(RID p_env,bool p_enable,float p_exposure,float p_white,float p_min_luminance,float p_max_luminance,float p_auto_exp_speed,VS::EnvironmentToneMapper p_tone_mapper)=0;
+	virtual void environment_set_brightness(RID p_env,bool p_enable,float p_brightness)=0;
+	virtual void environment_set_contrast(RID p_env,bool p_enable,float p_contrast)=0;
+	virtual void environment_set_saturation(RID p_env,bool p_enable,float p_saturation)=0;
+	virtual void environment_set_color_correction(RID p_env,bool p_enable,RID p_ramp)=0;
 
 	struct InstanceBase : RID_Data {
 
@@ -126,6 +146,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;
 
 	/* SHADER API */
 

+ 9 - 3
servers/visual/visual_server_raster.h

@@ -620,6 +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)
 
 
 
@@ -848,15 +849,17 @@ public:
 
 #undef BINDBASE
 //from now on, calls forwarded to this singleton
-#define BINDBASE VSG::scene
+#define BINDBASE VSG::scene_render
 
 	BIND0R(RID,environment_create)
 
 	BIND2(environment_set_background,RID ,EnvironmentBG )
-	BIND3(environment_set_skybox,RID,RID ,float )
+	BIND4(environment_set_skybox,RID,RID ,int,int )
+	BIND2(environment_set_skybox_scale,RID,float)
 	BIND2(environment_set_bg_color,RID,const Color& )
+	BIND2(environment_set_bg_energy,RID,float )
 	BIND2(environment_set_canvas_max_layer,RID,int )
-	BIND3(environment_set_ambient_light,RID,const Color& ,float )
+	BIND4(environment_set_ambient_light,RID,const Color& ,float,float )
 
 	BIND7(environment_set_glow,RID,bool ,int ,float ,float ,float ,EnvironmentGlowBlendMode )
 	BIND5(environment_set_fog,RID,bool ,float ,float ,RID )
@@ -871,6 +874,9 @@ public:
 	/* SCENARIO API */
 
 
+#undef BINDBASE
+#define BINDBASE VSG::scene
+
 	BIND0R(RID,scenario_create)
 
 	BIND2(scenario_set_debug,RID,ScenarioDebugMode )

+ 0 - 48
servers/visual/visual_server_scene.cpp

@@ -69,54 +69,6 @@ void VisualServerScene::camera_set_use_vertical_aspect(RID p_camera,bool p_enabl
 }
 
 
-
-/* ENVIRONMENT API */
-
-RID VisualServerScene::environment_create(){
-
-	return RID();
-}
-
-void VisualServerScene::environment_set_background(RID p_env,VS::EnvironmentBG p_bg){
-
-}
-void VisualServerScene::environment_set_skybox(RID p_env,RID p_skybox,float p_energy){
-
-}
-void VisualServerScene::environment_set_bg_color(RID p_env,const Color& p_color){
-
-}
-void VisualServerScene::environment_set_canvas_max_layer(RID p_env,int p_max_layer){
-
-}
-void VisualServerScene::environment_set_ambient_light(RID p_env,const Color& p_color,float p_energy){
-
-}
-
-void VisualServerScene::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){
-
-}
-void VisualServerScene::environment_set_fog(RID p_env,bool p_enable,float p_begin,float p_end,RID p_gradient_texture){
-
-}
-
-void VisualServerScene::environment_set_tonemap(RID p_env,bool p_enable,float p_exposure,float p_white,float p_min_luminance,float p_max_luminance,float p_auto_exp_speed,VS::EnvironmentToneMapper p_tone_mapper){
-
-}
-void VisualServerScene::environment_set_brightness(RID p_env,bool p_enable,float p_brightness){
-
-}
-void VisualServerScene::environment_set_contrast(RID p_env,bool p_enable,float p_contrast){
-
-}
-void VisualServerScene::environment_set_saturation(RID p_env,bool p_enable,float p_saturation){
-
-}
-void VisualServerScene::environment_set_color_correction(RID p_env,bool p_enable,RID p_ramp){
-
-}
-
-
 /* SCENARIO API */
 
 

+ 0 - 19
servers/visual/visual_server_scene.h

@@ -139,25 +139,6 @@ public:
 	};
 */
 
-	/* ENVIRONMENT API */
-
-	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,float p_energy=1.0);
-	virtual void environment_set_bg_color(RID p_env,const Color& p_color);
-	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);
-
-	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);
-
-	virtual void environment_set_tonemap(RID p_env,bool p_enable,float p_exposure,float p_white,float p_min_luminance,float p_max_luminance,float p_auto_exp_speed,VS::EnvironmentToneMapper p_tone_mapper);
-	virtual void environment_set_brightness(RID p_env,bool p_enable,float p_brightness);
-	virtual void environment_set_contrast(RID p_env,bool p_enable,float p_contrast);
-	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);
-
 
 	/* SCENARIO API */
 

+ 13 - 3
servers/visual_server.h

@@ -125,6 +125,13 @@ 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;
+
 	struct TextureInfo {
 		RID texture;
 		Size2 size;
@@ -478,18 +485,21 @@ public:
 
 	enum EnvironmentBG {
 
-		ENV_BG_KEEP,
+		ENV_BG_CLEAR_COLOR,
 		ENV_BG_COLOR,
 		ENV_BG_SKYBOX,
 		ENV_BG_CANVAS,
+		ENV_BG_KEEP,
 		ENV_BG_MAX
 	};
 
 	virtual void environment_set_background(RID p_env,EnvironmentBG p_bg)=0;
-	virtual void environment_set_skybox(RID p_env,RID p_skybox,float p_energy=1.0)=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_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)=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;
 
 	//set default SSAO options
 	//set default SSR options