Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntony Riakiotakis <kalast@gmail.com>2014-11-24 19:18:56 +0300
committerAntony Riakiotakis <kalast@gmail.com>2014-11-26 17:07:26 +0300
commit8fa55d95e43392a0e7925e1327e86220a33b4394 (patch)
treeb68b040a975e6231c8ec40d89cebad93582c52af
parent8bc84e10f501e516e0839b6a3efa573d55fb4f7b (diff)
World background working on cycle nodes.
This is added in the spirit of the general cycles GLSL system which is pretty much WIP still. This will only work on cycles at the moment but generating for blender internal is possible too of course though it will be done in a separate commit. This hasn't been tested with all and every node in cycles, but environment and regular textures with texture coordinates work. There is some difference between the way cycles treats some coordinates, which is in world space and the way GLSL treats them, which is in view space. We might want to explore and improve this further in the future. ...also </drumroll>
-rw-r--r--SConstruct1
-rw-r--r--source/blender/blenkernel/intern/material.c4
-rw-r--r--source/blender/blenkernel/intern/world.c5
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/editors/render/render_update.c31
-rw-r--r--source/blender/editors/space_node/node_edit.c23
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c37
-rw-r--r--source/blender/gpu/CMakeLists.txt1
-rw-r--r--source/blender/gpu/GPU_material.h11
-rw-r--r--source/blender/gpu/SConscript1
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c28
-rw-r--r--source/blender/gpu/intern/gpu_codegen.h2
-rw-r--r--source/blender/gpu/intern/gpu_material.c160
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl45
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vertex_world.glsl13
-rw-r--r--source/blender/makesdna/DNA_world_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_space.c2
-rw-r--r--source/blender/makesrna/intern/rna_world.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_background.c6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_world.c13
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_coord.c16
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c12
23 files changed, 324 insertions, 94 deletions
diff --git a/SConstruct b/SConstruct
index 45c9ae3b84d..4c2097f8879 100644
--- a/SConstruct
+++ b/SConstruct
@@ -757,6 +757,7 @@ if B.targets != ['cudakernels']:
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vertex.glsl")
+ data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vertex_world.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl")
data_to_c_simple("intern/opencolorio/gpu_shader_display_transform.glsl")
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index ea1b9a3f13d..af2080c1b61 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -116,7 +116,7 @@ void BKE_material_free_ex(Material *ma, bool do_id_user)
MEM_freeN(ma->texpaintslot);
if (ma->gpumaterial.first)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
}
void init_material(Material *ma)
@@ -1724,7 +1724,7 @@ void paste_matcopybuf(Material *ma)
MEM_freeN(ma->nodetree);
}
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
id = (ma->id);
memcpy(ma, &matcopybuf, sizeof(Material));
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 8e3c92314e6..29a345e111b 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -49,6 +49,8 @@
#include "BKE_node.h"
#include "BKE_world.h"
+#include "GPU_material.h"
+
void BKE_world_free_ex(World *wrld, bool do_id_user)
{
MTex *mtex;
@@ -69,6 +71,9 @@ void BKE_world_free_ex(World *wrld, bool do_id_user)
MEM_freeN(wrld->nodetree);
}
+ if (wrld->gpumaterial.first)
+ GPU_material_free(&wrld->gpumaterial);
+
BKE_icon_delete((struct ID *)wrld);
wrld->id.icon_id = 0;
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 9b043c6dbda..05af147eb86 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3260,6 +3260,7 @@ static void direct_link_world(FileData *fd, World *wrld)
}
wrld->preview = direct_link_preview_image(fd, wrld->preview);
+ BLI_listbase_clear(&wrld->gpumaterial);
}
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 1320fedbfa7..e4e16dd03fc 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -281,7 +281,7 @@ static void material_changed(Main *bmain, Material *ma)
/* glsl */
if (ma->gpumaterial.first)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
/* find node materials using this */
for (parent = bmain->mat.first; parent; parent = parent->id.next) {
@@ -295,7 +295,7 @@ static void material_changed(Main *bmain, Material *ma)
BKE_icon_changed(BKE_icon_getid(&parent->id));
if (parent->gpumaterial.first)
- GPU_material_free(parent);
+ GPU_material_free(&parent->gpumaterial);
}
/* find if we have a scene with textured display */
@@ -341,10 +341,10 @@ static void lamp_changed(Main *bmain, Lamp *la)
for (ma = bmain->mat.first; ma; ma = ma->id.next)
if (ma->gpumaterial.first)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
if (defmaterial.gpumaterial.first)
- GPU_material_free(&defmaterial);
+ GPU_material_free(&defmaterial.gpumaterial);
}
static int material_uses_texture(Material *ma, Tex *tex)
@@ -382,7 +382,7 @@ static void texture_changed(Main *bmain, Tex *tex)
BKE_icon_changed(BKE_icon_getid(&ma->id));
if (ma->gpumaterial.first)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
}
/* find lamps */
@@ -411,6 +411,9 @@ static void texture_changed(Main *bmain, Tex *tex)
}
BKE_icon_changed(BKE_icon_getid(&wo->id));
+
+ if (wo->gpumaterial.first)
+ GPU_material_free(&wo->gpumaterial);
}
/* find compositing nodes */
@@ -456,14 +459,17 @@ static void world_changed(Main *bmain, World *wo)
/* icons */
BKE_icon_changed(BKE_icon_getid(&wo->id));
-
+
/* glsl */
for (ma = bmain->mat.first; ma; ma = ma->id.next)
if (ma->gpumaterial.first)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
if (defmaterial.gpumaterial.first)
- GPU_material_free(&defmaterial);
+ GPU_material_free(&defmaterial.gpumaterial);
+
+ if (wo->gpumaterial.first)
+ GPU_material_free(&wo->gpumaterial);
}
static void image_changed(Main *bmain, Image *ima)
@@ -483,6 +489,7 @@ static void scene_changed(Main *bmain, Scene *scene)
{
Object *ob;
Material *ma;
+ World *wo;
/* glsl */
for (ob = bmain->object.first; ob; ob = ob->id.next) {
@@ -498,10 +505,14 @@ static void scene_changed(Main *bmain, Scene *scene)
for (ma = bmain->mat.first; ma; ma = ma->id.next)
if (ma->gpumaterial.first)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
+ for (wo = bmain->world.first; wo; wo = wo->id.next)
+ if (wo->gpumaterial.first)
+ GPU_material_free(&wo->gpumaterial);
+
if (defmaterial.gpumaterial.first)
- GPU_material_free(&defmaterial);
+ GPU_material_free(&defmaterial.gpumaterial);
}
void ED_render_id_flush_update(Main *bmain, ID *id)
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index d52a351ffc2..1b82e89a364 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -342,14 +342,22 @@ void snode_dag_update(bContext *C, SpaceNode *snode)
void snode_notify(bContext *C, SpaceNode *snode)
{
+ ID *id = snode->id;
+
WM_event_add_notifier(C, NC_NODE | NA_EDITED, NULL);
- if (ED_node_is_shader(snode))
- WM_event_add_notifier(C, NC_MATERIAL | ND_NODES, snode->id);
+ if (ED_node_is_shader(snode)) {
+ if (GS(id->name) == ID_MA)
+ WM_main_add_notifier(NC_MATERIAL | ND_SHADING, id);
+ else if (GS(id->name) == ID_LA)
+ WM_main_add_notifier(NC_LAMP | ND_LIGHTING, id);
+ else if (GS(id->name) == ID_WO)
+ WM_main_add_notifier(NC_WORLD | ND_WORLD, id);
+ }
else if (ED_node_is_compositor(snode))
- WM_event_add_notifier(C, NC_SCENE | ND_NODES, snode->id);
+ WM_event_add_notifier(C, NC_SCENE | ND_NODES, id);
else if (ED_node_is_texture(snode))
- WM_event_add_notifier(C, NC_TEXTURE | ND_NODES, snode->id);
+ WM_event_add_notifier(C, NC_TEXTURE | ND_NODES, id);
}
void ED_node_set_tree_type(SpaceNode *snode, bNodeTreeType *typeinfo)
@@ -662,11 +670,16 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
/* if active texture changed, free glsl materials */
if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) {
Material *ma;
+ World *wo;
for (ma = bmain->mat.first; ma; ma = ma->id.next)
if (ma->nodetree && ma->use_nodes && ntreeHasTree(ma->nodetree, ntree))
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
+ for (wo = bmain->world.first; wo; wo = wo->id.next)
+ if (wo->nodetree && wo->use_nodes && ntreeHasTree(wo->nodetree, ntree))
+ GPU_material_free(&wo->gpumaterial);
+
WM_main_add_notifier(NC_IMAGE, NULL);
}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 81f926e5048..95b11d1731f 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -414,7 +414,7 @@ static void view3d_free(SpaceLink *sl)
/* matcap material, its preview rect gets freed via icons */
if (vd->defmaterial) {
if (vd->defmaterial->gpumaterial.first)
- GPU_material_free(vd->defmaterial);
+ GPU_material_free(&vd->defmaterial->gpumaterial);
BKE_previewimg_free(&vd->defmaterial->preview);
MEM_freeN(vd->defmaterial);
}
@@ -1168,6 +1168,7 @@ static void space_view3d_listener(bScreen *UNUSED(sc), ScrArea *sa, struct wmNot
case NC_WORLD:
switch (wmn->data) {
case ND_WORLD_DRAW:
+ case ND_WORLD:
if (v3d->flag3 & V3D_SHOW_WORLD)
ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW);
break;
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index d4a0c01518b..26ce64fd8ca 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -2807,10 +2807,34 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d)
static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar, bool force)
{
/* clear background */
- if (scene->world && ((v3d->flag3 & V3D_SHOW_WORLD) || force)) { /* clear with solid color */
+ if (scene->world && ((v3d->flag3 & V3D_SHOW_WORLD) || force)) {
float alpha = (force) ? 1.0f : 0.0;
+ bool glsl = GPU_glsl_support() && BKE_scene_use_new_shading_nodes(scene) && scene->world->nodetree && scene->world->use_nodes;
- if (scene->world->skytype & WO_SKYBLEND) { /* blend sky */
+ if (glsl) {
+ RegionView3D *rv3d = ar->regiondata;
+ GPUMaterial *gpumat = GPU_material_world(scene, scene->world);
+
+ /* calculate full shader for background */
+ GPU_material_bind(gpumat, 1, 1, 1.0, true, rv3d->viewmat, rv3d->viewinv, (v3d->scenelock != 0));
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_ALWAYS);
+ glShadeModel(GL_SMOOTH);
+ glBegin(GL_QUADS);
+ glVertex3f(-1.0, -1.0, 1.0);
+ glVertex3f(1.0, -1.0, 1.0);
+ glVertex3f(1.0, 1.0, 1.0);
+ glVertex3f(-1.0, 1.0, 1.0);
+ glEnd();
+ glShadeModel(GL_FLAT);
+
+ GPU_material_unbind(gpumat);
+
+ glDepthFunc(GL_LEQUAL);
+ glDisable(GL_DEPTH_TEST);
+ }
+ else if (scene->world->skytype & WO_SKYBLEND) { /* blend sky */
int x, y;
float col_hor[3];
float col_zen[3];
@@ -3009,7 +3033,9 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx,
* warning! can be slow so only free animated images - campbell */
GPU_free_images_anim();
}
-
+ /* setup view matrices */
+ view3d_main_area_setup_view(scene, v3d, ar, viewmat, winmat);
+
/* clear opengl buffers */
if (do_sky) {
view3d_main_area_clear(scene, v3d, ar, true);
@@ -3019,11 +3045,6 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx,
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
-
- /* setup view matrices */
- view3d_main_area_setup_view(scene, v3d, ar, viewmat, winmat);
-
-
/* main drawing call */
view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true);
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 63eea9486ed..361c247767f 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -73,6 +73,7 @@ data_to_c_simple(shaders/gpu_shader_sep_gaussian_blur_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_simple_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_simple_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_vertex.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_vertex_world.glsl SRC)
data_to_c_simple(shaders/gpu_shader_vsm_store_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_vsm_store_vert.glsl SRC)
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index fab9c28cb61..09a5653b1ec 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -58,6 +58,7 @@ struct GPUMaterial;
struct GPUTexture;
struct GPULamp;
struct PreviewImage;
+struct World;
typedef struct GPUNode GPUNode;
typedef struct GPUNodeLink GPUNodeLink;
@@ -95,6 +96,12 @@ typedef enum GPUOpenGLBuiltin {
GPU_COLOR = 2,
} GPUOpenGLBuiltin;
+typedef enum GPUMatType {
+ GPU_MATERIAL_TYPE_MESH = 1,
+ GPU_MATERIAL_TYPE_WORLD = 2,
+} GPUMatType;
+
+
typedef enum GPUBlendMode {
GPU_BLEND_SOLID = 0,
GPU_BLEND_ADD = 1,
@@ -131,10 +138,11 @@ void GPU_material_enable_alpha(GPUMaterial *material);
GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4]);
/* High level functions to create and use GPU materials */
+GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo);
GPUMaterial *GPU_material_from_blender(struct Scene *scene, struct Material *ma);
GPUMaterial *GPU_material_matcap(struct Scene *scene, struct Material *ma);
-void GPU_material_free(struct Material *ma);
+void GPU_material_free(struct ListBase *gpumaterial);
void GPU_materials_free(void);
@@ -144,6 +152,7 @@ void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float
void GPU_material_unbind(GPUMaterial *material);
int GPU_material_bound(GPUMaterial *material);
struct Scene *GPU_material_scene(GPUMaterial *material);
+GPUMatType GPU_Material_get_type(GPUMaterial *material);
void GPU_material_vertex_attributes(GPUMaterial *material,
struct GPUVertexAttribs *attrib);
diff --git a/source/blender/gpu/SConscript b/source/blender/gpu/SConscript
index f11ecafc986..e44a99286a8 100644
--- a/source/blender/gpu/SConscript
+++ b/source/blender/gpu/SConscript
@@ -69,6 +69,7 @@ sources.extend((
os.path.join(env['DATA_SOURCES'], "gpu_shader_sep_gaussian_blur_frag.glsl.c"),
os.path.join(env['DATA_SOURCES'], "gpu_shader_sep_gaussian_blur_vert.glsl.c"),
os.path.join(env['DATA_SOURCES'], "gpu_shader_vertex.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_vertex_world.glsl.c"),
os.path.join(env['DATA_SOURCES'], "gpu_shader_vsm_store_frag.glsl.c"),
os.path.join(env['DATA_SOURCES'], "gpu_shader_vsm_store_vert.glsl.c"),
))
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 4182f51561b..1b99c6ee49a 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -58,6 +58,7 @@
extern char datatoc_gpu_shader_material_glsl[];
extern char datatoc_gpu_shader_vertex_glsl[];
+extern char datatoc_gpu_shader_vertex_world_glsl[];
static char *glsl_material_library = NULL;
@@ -252,7 +253,7 @@ void gpu_codegen_exit(void)
extern Material defmaterial; // render module abuse...
if (defmaterial.gpumaterial.first)
- GPU_material_free(&defmaterial);
+ GPU_material_free(&defmaterial.gpumaterial);
if (FUNCTION_HASH) {
BLI_ghash_free(FUNCTION_HASH, NULL, MEM_freeN);
@@ -624,8 +625,7 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, const ch
if (builtins & GPU_VIEW_NORMAL)
BLI_dynstr_append(ds, "\tvec3 facingnormal = (gl_FrontFacing)? varnormal: -varnormal;\n");
-
-
+
codegen_declare_tmps(ds, nodes);
codegen_call_functions(ds, nodes, output);
@@ -640,12 +640,13 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, const ch
return code;
}
-static char *code_generate_vertex(ListBase *nodes)
+static char *code_generate_vertex(ListBase *nodes, int type)
{
DynStr *ds = BLI_dynstr_new();
GPUNode *node;
GPUInput *input;
char *code;
+ char *vertcode;
for (node=nodes->first; node; node=node->next) {
for (input=node->inputs.first; input; input=input->next) {
@@ -659,8 +660,21 @@ static char *code_generate_vertex(ListBase *nodes)
}
BLI_dynstr_append(ds, "\n");
- BLI_dynstr_append(ds, datatoc_gpu_shader_vertex_glsl);
+ switch (type) {
+ case GPU_MATERIAL_TYPE_MESH:
+ vertcode = datatoc_gpu_shader_vertex_glsl;
+ break;
+ case GPU_MATERIAL_TYPE_WORLD:
+ vertcode = datatoc_gpu_shader_vertex_world_glsl;
+ break;
+ default:
+ fprintf(stderr, "invalid material type, set one after GPU_material_construct_begin\n");
+ break;
+ }
+
+ BLI_dynstr_append(ds, vertcode);
+
for (node=nodes->first; node; node=node->next)
for (input=node->inputs.first; input; input=input->next)
if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
@@ -1386,7 +1400,7 @@ static void gpu_nodes_prune(ListBase *nodes, GPUNodeLink *outlink)
}
}
-GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttribs *attribs, int *builtins, const char *name)
+GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttribs *attribs, int *builtins, int type, const char *name)
{
GPUShader *shader;
GPUPass *pass;
@@ -1405,7 +1419,7 @@ GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttri
/* generate code and compile with opengl */
fragmentcode = code_generate_fragment(nodes, outlink->output, name);
- vertexcode = code_generate_vertex(nodes);
+ vertexcode = code_generate_vertex(nodes, type);
shader = GPU_shader_create(vertexcode, fragmentcode, glsl_material_library, NULL);
/* failed? */
diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h
index 69213925931..a0698235db6 100644
--- a/source/blender/gpu/intern/gpu_codegen.h
+++ b/source/blender/gpu/intern/gpu_codegen.h
@@ -175,7 +175,7 @@ struct GPUPass {
typedef struct GPUPass GPUPass;
GPUPass *GPU_generate_pass(ListBase *nodes, struct GPUNodeLink *outlink,
- struct GPUVertexAttribs *attribs, int *builtin, const char *name);
+ struct GPUVertexAttribs *attribs, int *builtin, int type, const char *name);
struct GPUShader *GPU_pass_shader(GPUPass *pass);
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index e4228bedf9d..31b499d54ab 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -76,10 +76,15 @@ typedef enum DynMatProperty {
DYN_LAMP_PERSMAT = 8,
} DynMatProperty;
+
struct GPUMaterial {
Scene *scene;
Material *ma;
+ /* material for mesh surface, worlds or something else.
+ * some code generation is done differently depending on the use case */
+ int type;
+
/* for creating the material */
ListBase nodes;
GPUNodeLink *outlink;
@@ -194,7 +199,7 @@ static void gpu_material_set_attrib_id(GPUMaterial *material)
attribs->totlayer = b;
}
-static int GPU_material_construct_end(GPUMaterial *material)
+static int GPU_material_construct_end(GPUMaterial *material, const char *passname)
{
if (material->outlink) {
GPUNodeLink *outlink;
@@ -202,7 +207,7 @@ static int GPU_material_construct_end(GPUMaterial *material)
outlink = material->outlink;
material->pass = GPU_generate_pass(&material->nodes, outlink,
- &material->attribs, &material->builtins, material->ma->id.name);
+ &material->attribs, &material->builtins, material->type, passname);
if (!material->pass)
return 0;
@@ -229,12 +234,12 @@ static int GPU_material_construct_end(GPUMaterial *material)
return 0;
}
-void GPU_material_free(Material *ma)
+void GPU_material_free(ListBase *gpumaterial)
{
LinkData *link;
LinkData *nlink, *mlink, *next;
- for (link=ma->gpumaterial.first; link; link=link->next) {
+ for (link=gpumaterial->first; link; link=link->next) {
GPUMaterial *material = link->data;
if (material->pass)
@@ -243,19 +248,23 @@ void GPU_material_free(Material *ma)
for (nlink=material->lamps.first; nlink; nlink=nlink->next) {
GPULamp *lamp = nlink->data;
- for (mlink=lamp->materials.first; mlink; mlink=next) {
- next = mlink->next;
- if (mlink->data == ma)
- BLI_freelinkN(&lamp->materials, mlink);
+ if (material->ma) {
+ Material *ma = material->ma;
+
+ for (mlink=lamp->materials.first; mlink; mlink=next) {
+ next = mlink->next;
+ if (mlink->data == ma)
+ BLI_freelinkN(&lamp->materials, mlink);
+ }
}
}
-
+
BLI_freelistN(&material->lamps);
MEM_freeN(material);
}
- BLI_freelistN(&ma->gpumaterial);
+ BLI_freelistN(gpumaterial);
}
bool GPU_lamp_override_visible(GPULamp *lamp, SceneRenderLayer *srl, Material *ma)
@@ -280,42 +289,44 @@ void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double tim
viewlay &= srl->lay;
/* handle layer lamps */
- for (nlink=material->lamps.first; nlink; nlink=nlink->next) {
- lamp= nlink->data;
-
- if (!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay))
- && GPU_lamp_override_visible(lamp, srl, material->ma)) {
- lamp->dynenergy = lamp->energy;
- copy_v3_v3(lamp->dyncol, lamp->col);
- }
- else {
- lamp->dynenergy = 0.0f;
- lamp->dyncol[0]= lamp->dyncol[1]= lamp->dyncol[2] = 0.0f;
- }
-
- if (material->dynproperty & DYN_LAMP_VEC) {
- copy_v3_v3(lamp->dynvec, lamp->vec);
- normalize_v3(lamp->dynvec);
- negate_v3(lamp->dynvec);
- mul_mat3_m4_v3(viewmat, lamp->dynvec);
- }
-
- if (material->dynproperty & DYN_LAMP_CO) {
- copy_v3_v3(lamp->dynco, lamp->co);
- mul_m4_v3(viewmat, lamp->dynco);
- }
-
- if (material->dynproperty & DYN_LAMP_IMAT) {
- mul_m4_m4m4(lamp->dynimat, lamp->imat, viewinv);
- }
-
- if (material->dynproperty & DYN_LAMP_PERSMAT) {
- if (!GPU_lamp_has_shadow_buffer(lamp)) /* The lamp matrices are already updated if we're using shadow buffers */
- GPU_lamp_update_buffer_mats(lamp);
- mul_m4_m4m4(lamp->dynpersmat, lamp->persmat, viewinv);
+ if (material->type == GPU_MATERIAL_TYPE_MESH) {
+ for (nlink=material->lamps.first; nlink; nlink=nlink->next) {
+ lamp= nlink->data;
+
+ if (!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay))
+ && GPU_lamp_override_visible(lamp, srl, material->ma)) {
+ lamp->dynenergy = lamp->energy;
+ copy_v3_v3(lamp->dyncol, lamp->col);
+ }
+ else {
+ lamp->dynenergy = 0.0f;
+ lamp->dyncol[0]= lamp->dyncol[1]= lamp->dyncol[2] = 0.0f;
+ }
+
+ if (material->dynproperty & DYN_LAMP_VEC) {
+ copy_v3_v3(lamp->dynvec, lamp->vec);
+ normalize_v3(lamp->dynvec);
+ negate_v3(lamp->dynvec);
+ mul_mat3_m4_v3(viewmat, lamp->dynvec);
+ }
+
+ if (material->dynproperty & DYN_LAMP_CO) {
+ copy_v3_v3(lamp->dynco, lamp->co);
+ mul_m4_v3(viewmat, lamp->dynco);
+ }
+
+ if (material->dynproperty & DYN_LAMP_IMAT) {
+ mul_m4_m4m4(lamp->dynimat, lamp->imat, viewinv);
+ }
+
+ if (material->dynproperty & DYN_LAMP_PERSMAT) {
+ if (!GPU_lamp_has_shadow_buffer(lamp)) /* The lamp matrices are already updated if we're using shadow buffers */
+ GPU_lamp_update_buffer_mats(lamp);
+ mul_m4_m4m4(lamp->dynpersmat, lamp->persmat, viewinv);
+ }
}
}
-
+
/* note material must be bound before setting uniforms */
GPU_pass_bind(material->pass, time, mipmap);
@@ -376,6 +387,12 @@ Scene *GPU_material_scene(GPUMaterial *material)
return material->scene;
}
+GPUMatType GPU_Material_get_type(GPUMaterial *material)
+{
+ return material->type;
+}
+
+
void GPU_material_vertex_attributes(GPUMaterial *material, GPUVertexAttribs *attribs)
{
*attribs = material->attribs;
@@ -1589,6 +1606,7 @@ GPUMaterial *GPU_material_matcap(Scene *scene, Material *ma)
/* allocate material */
mat = GPU_material_construct_begin(ma);
mat->scene = scene;
+ mat->type = GPU_MATERIAL_TYPE_MESH;
if (ma->preview && ma->preview->rect[0]) {
outlink = gpu_material_preview_matcap(mat, ma);
@@ -1599,7 +1617,7 @@ GPUMaterial *GPU_material_matcap(Scene *scene, Material *ma)
GPU_material_output_link(mat, outlink);
- GPU_material_construct_end(mat);
+ GPU_material_construct_end(mat, "matcap_pass");
/* note that even if building the shader fails in some way, we still keep
* it to avoid trying to compile again and again, and simple do not use
@@ -1612,6 +1630,45 @@ GPUMaterial *GPU_material_matcap(Scene *scene, Material *ma)
return mat;
}
+GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo)
+{
+ LinkData *link;
+ GPUMaterial *mat;
+
+ for (link=wo->gpumaterial.first; link; link=link->next)
+ if (((GPUMaterial*)link->data)->scene == scene)
+ return link->data;
+
+ /* allocate material */
+ mat = GPU_material_construct_begin(NULL);
+ mat->scene = scene;
+ mat->type = GPU_MATERIAL_TYPE_WORLD;
+
+ /* create nodes */
+ if (BKE_scene_use_new_shading_nodes(scene) && wo->nodetree && wo->use_nodes)
+ ntreeGPUMaterialNodes(wo->nodetree, mat, NODE_NEW_SHADING);
+ else {
+ /* old fixed function world */
+ }
+
+ if (GPU_material_do_color_management(mat))
+ if (mat->outlink)
+ GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
+
+ GPU_material_construct_end(mat, wo->id.name);
+
+ /* note that even if building the shader fails in some way, we still keep
+ * it to avoid trying to compile again and again, and simple do not use
+ * the actual shader on drawing */
+
+ link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
+ link->data = mat;
+ BLI_addtail(&wo->gpumaterial, link);
+
+ return mat;
+}
+
+
GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
{
GPUMaterial *mat;
@@ -1625,6 +1682,7 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
/* allocate material */
mat = GPU_material_construct_begin(ma);
mat->scene = scene;
+ mat->type = GPU_MATERIAL_TYPE_MESH;
/* render pipeline option */
if (ma->mode & MA_TRANSP)
@@ -1654,7 +1712,7 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
if (mat->outlink)
GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
- GPU_material_construct_end(mat);
+ GPU_material_construct_end(mat, ma->id.name);
/* note that even if building the shader fails in some way, we still keep
* it to avoid trying to compile again and again, and simple do not use
@@ -1671,12 +1729,16 @@ void GPU_materials_free(void)
{
Object *ob;
Material *ma;
+ World *wo;
extern Material defmaterial;
for (ma=G.main->mat.first; ma; ma=ma->id.next)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
- GPU_material_free(&defmaterial);
+ for (wo=G.main->world.first; wo; wo=wo->id.next)
+ GPU_material_free(&ma->gpumaterial);
+
+ GPU_material_free(&defmaterial.gpumaterial);
for (ob=G.main->object.first; ob; ob=ob->id.next)
GPU_lamp_free(ob);
@@ -1945,7 +2007,7 @@ void GPU_lamp_free(Object *ob)
BLI_freelinkN(&lamp->materials, nlink);
if (ma->gpumaterial.first)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
}
gpu_lamp_shadow_free(lamp);
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 867270a6d7a..c463fb25ded 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -2256,6 +2256,22 @@ void node_emission(vec4 color, float strength, vec3 N, out vec4 result)
result = color*strength;
}
+/* background */
+
+void background_transform_to_world(vec3 viewvec, out vec3 worldvec)
+{
+ vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
+ vec4 co_homogenous = (gl_ProjectionMatrixInverse * v);
+
+ vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
+ worldvec = (gl_ModelViewMatrixInverse * co).xyz;
+}
+
+void node_background(vec4 color, float strength, vec3 N, out vec4 result)
+{
+ result = color*strength;
+}
+
/* closures */
void node_mix_shader(float fac, vec4 shader1, vec4 shader2, out vec4 shader)
@@ -2364,6 +2380,30 @@ void node_tex_coord(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat,
reflection = (viewinvmat*vec4(view_reflection, 0.0)).xyz;
}
+void node_tex_coord_background(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat,
+ vec3 attr_orco, vec3 attr_uv,
+ out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
+ out vec3 camera, out vec3 window, out vec3 reflection)
+{
+ vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
+ vec4 co_homogenous = (gl_ProjectionMatrixInverse * v);
+
+ vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
+
+ co = normalize(co);
+ vec3 coords = (gl_ModelViewMatrixInverse * co).xyz;
+
+ generated = coords;
+ normal = -coords;
+ uv = attr_uv;
+ object = coords;
+
+ camera = co.xyz;
+ window = mtex_2d_mapping(I);
+
+ reflection = -coords;
+}
+
/* textures */
void node_tex_gradient(vec3 co, out vec4 color, out float fac)
@@ -2525,6 +2565,11 @@ void node_output_material(vec4 surface, vec4 volume, float displacement, out vec
result = surface;
}
+void node_output_world(vec4 surface, vec4 volume, out vec4 result)
+{
+ result = surface;
+}
+
/* ********************** matcap style render ******************** */
void material_preview_matcap(vec4 color, sampler2D ima, vec4 N, vec4 mask, out vec4 result)
diff --git a/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl b/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl
new file mode 100644
index 00000000000..9dbcaeb7a32
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl
@@ -0,0 +1,13 @@
+
+varying vec3 varposition;
+varying vec3 varnormal;
+
+void main()
+{
+ /* position does not need to be transformed, we already have it */
+ gl_Position = gl_Vertex;
+
+ varposition = gl_Vertex.xyz;
+
+ varnormal = normalize(-varposition);
+
diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h
index 50542797f0b..2a9bcc20a9f 100644
--- a/source/blender/makesdna/DNA_world_types.h
+++ b/source/blender/makesdna/DNA_world_types.h
@@ -128,6 +128,7 @@ typedef struct World {
/* nodes */
struct bNodeTree *nodetree;
+ ListBase gpumaterial; /* runtime */
} World;
/* **************** WORLD ********************* */
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index a191cc32bb2..e3d44cb1349 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -485,7 +485,7 @@ static void rna_SpaceView3D_matcap_update(Main *UNUSED(bmain), Scene *UNUSED(sce
BKE_previewimg_free(&ma->preview);
if (ma->gpumaterial.first)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
WM_main_add_notifier(NC_MATERIAL | ND_SHADING_DRAW, ma);
}
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index f63350ea0ae..721cbaf21c7 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -89,7 +89,7 @@ static void rna_World_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerR
World *wo = ptr->id.data;
DAG_id_tag_update(&wo->id, 0);
- WM_main_add_notifier(NC_WORLD, wo);
+ WM_main_add_notifier(NC_WORLD | ND_WORLD, wo);
}
static void rna_World_draw_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
diff --git a/source/blender/nodes/shader/nodes/node_shader_background.c b/source/blender/nodes/shader/nodes/node_shader_background.c
index 2478fb4d38c..b387529e456 100644
--- a/source/blender/nodes/shader/nodes/node_shader_background.c
+++ b/source/blender/nodes/shader/nodes/node_shader_background.c
@@ -40,6 +40,11 @@ static bNodeSocketTemplate sh_node_background_out[] = {
{ -1, 0, "" }
};
+static int node_shader_gpu_background(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ return GPU_stack_link(mat, "node_background", in, out, GPU_builtin(GPU_VIEW_NORMAL));
+}
+
/* node type definition */
void register_node_type_sh_background(void)
{
@@ -50,6 +55,7 @@ void register_node_type_sh_background(void)
node_type_socket_templates(&ntype, sh_node_background_in, sh_node_background_out);
node_type_init(&ntype, NULL);
node_type_storage(&ntype, "", NULL, NULL);
+ node_type_gpu(&ntype, node_shader_gpu_background);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_world.c b/source/blender/nodes/shader/nodes/node_shader_output_world.c
index c8e47c47c5f..ad7389fd56e 100644
--- a/source/blender/nodes/shader/nodes/node_shader_output_world.c
+++ b/source/blender/nodes/shader/nodes/node_shader_output_world.c
@@ -35,6 +35,16 @@ static bNodeSocketTemplate sh_node_output_world_in[] = {
{ -1, 0, "" }
};
+static int node_shader_gpu_output_world(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ GPUNodeLink *outlink;
+
+ GPU_stack_link(mat, "node_output_world", in, out, &outlink);
+ GPU_material_output_link(mat, outlink);
+
+ return 1;
+}
+
/* node type definition */
void register_node_type_sh_output_world(void)
{
@@ -45,7 +55,8 @@ void register_node_type_sh_output_world(void)
node_type_socket_templates(&ntype, sh_node_output_world_in, NULL);
node_type_init(&ntype, NULL);
node_type_storage(&ntype, "", NULL, NULL);
-
+ node_type_gpu(&ntype, node_shader_gpu_output_world);
+
/* Do not allow muting output node. */
node_type_internal_links(&ntype, NULL);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
index 781b1bb5a93..85eca6ae990 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
@@ -46,10 +46,18 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat, bNode *UNUSED(node), bNod
{
GPUNodeLink *orco = GPU_attribute(CD_ORCO, "");
GPUNodeLink *mtface = GPU_attribute(CD_MTFACE, "");
-
- return GPU_stack_link(mat, "node_tex_coord", in, out,
- GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
- GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), orco, mtface);
+ GPUMatType type = GPU_Material_get_type(mat);
+
+ if (type == GPU_MATERIAL_TYPE_MESH) {
+ return GPU_stack_link(mat, "node_tex_coord", in, out,
+ GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
+ GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), orco, mtface);
+ }
+ else {
+ return GPU_stack_link(mat, "node_tex_coord_background", in, out,
+ GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
+ GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), orco, mtface);
+ }
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
index 56db9dd3b44..f6361331741 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -67,9 +67,15 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, bNode *node, bNodeE
if (!ima)
return GPU_stack_link(mat, "node_tex_environment_empty", in, out);
- if (!in[0].link)
- in[0].link = GPU_builtin(GPU_VIEW_POSITION);
-
+ if (!in[0].link) {
+ GPUMatType type = GPU_Material_get_type(mat);
+
+ if (type == GPU_MATERIAL_TYPE_MESH)
+ in[0].link = GPU_builtin(GPU_VIEW_POSITION);
+ else
+ GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &in[0].link);
+ }
+
node_shader_gpu_tex_mapping(mat, node, in, out);
if (tex->projection == SHD_PROJ_EQUIRECTANGULAR)