More scene work, can display a skybox

This commit is contained in:
Juan Linietsky 2016-10-21 07:27:13 -03:00
parent 4428115916
commit cb34b70df1
15 changed files with 861 additions and 84 deletions

View file

@ -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?");
}

View file

@ -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();
}

View file

@ -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);

View file

@ -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() {

View file

@ -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 */

View file

@ -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');

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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 {
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

View file

@ -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 */

View file

@ -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 )

View file

@ -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 */

View file

@ -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 */

View file

@ -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