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:
authorClément Foucault <foucault.clem@gmail.com>2017-05-01 19:09:50 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-05-01 19:11:21 +0300
commit62ea911e1a22d2a717c225ea1bbd130ac5c367bf (patch)
tree567bc7e5a352749c05df88937d79815a7ff86f92 /source/blender
parent19f86a3d5f7f1f8267fef480604c39cf53c491fd (diff)
GPUMaterial: Making material node tree compatible with new drawmanager.
- code_generate_fragment : Making sure that shaders uses the new uniforms. - code_generate_vertex_new : create require attribute based on their names and not their id (see draw_cache_impl_mesh.c). - add support for ramp textures.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/draw/intern/draw_manager.c9
-rw-r--r--source/blender/gpu/GPU_material.h2
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c135
-rw-r--r--source/blender/gpu/intern/gpu_material.c7
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl1
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_coord.c6
6 files changed, 140 insertions, 20 deletions
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 059ebc6eab3..bc11ab48d48 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -145,6 +145,7 @@ struct DRWInterface {
int modelview;
int projection;
int view;
+ int viewinverse;
int modelviewprojection;
int viewprojection;
int normal;
@@ -505,6 +506,7 @@ static DRWInterface *DRW_interface_create(GPUShader *shader)
interface->modelview = GPU_shader_get_uniform(shader, "ModelViewMatrix");
interface->projection = GPU_shader_get_uniform(shader, "ProjectionMatrix");
interface->view = GPU_shader_get_uniform(shader, "ViewMatrix");
+ interface->viewinverse = GPU_shader_get_uniform(shader, "ViewMatrixInverse");
interface->viewprojection = GPU_shader_get_uniform(shader, "ViewProjectionMatrix");
interface->modelviewprojection = GPU_shader_get_uniform(shader, "ModelViewProjectionMatrix");
interface->normal = GPU_shader_get_uniform(shader, "NormalMatrix");
@@ -648,6 +650,10 @@ DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPa
DRW_shgroup_uniform_texture(grp, input->shadername, tex, max_tex - input->texid);
}
}
+ /* Color Ramps */
+ else if (input->tex) {
+ DRW_shgroup_uniform_texture(grp, input->shadername, input->tex, max_tex - input->texid);
+ }
/* Floats */
else {
switch (input->type) {
@@ -1191,6 +1197,9 @@ static void draw_geometry(DRWShadingGroup *shgroup, Batch *geom, const float (*o
if (interface->modelviewprojection != -1) {
GPU_shader_uniform_vector(shgroup->shader, interface->modelviewprojection, 16, 1, (float *)mvp);
}
+ if (interface->viewinverse != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, interface->viewinverse, 16, 1, (float *)rv3d->viewinv);
+ }
if (interface->viewprojection != -1) {
GPU_shader_uniform_vector(shgroup->shader, interface->viewprojection, 16, 1, (float *)rv3d->persmat);
}
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 31785a0121f..4345a31839a 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -220,7 +220,7 @@ 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_nodetree(
- struct bNodeTree *ntree, struct ListBase *gpumaterials, void *engine_type, int options,
+ struct Scene *scene, struct bNodeTree *ntree, struct ListBase *gpumaterials, void *engine_type, int options,
const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines);
GPUMaterial *GPU_material_from_blender(struct Scene *scene, struct Material *ma, bool use_opensubdiv);
GPUMaterial *GPU_material_matcap(struct Scene *scene, struct Material *ma, bool use_opensubdiv);
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 89c58eb8495..d291db2a84d 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -622,7 +622,11 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
"tmp", input->link->output->id);
}
else if (input->source == GPU_SOURCE_BUILTIN) {
- if (input->builtin == GPU_VIEW_NORMAL)
+ if (input->builtin == GPU_INVERSE_VIEW_MATRIX)
+ BLI_dynstr_append(ds, "viewinv");
+ else if (input->builtin == GPU_VIEW_POSITION)
+ BLI_dynstr_append(ds, "viewposition");
+ else if (input->builtin == GPU_VIEW_NORMAL)
BLI_dynstr_append(ds, "facingnormal");
else
BLI_dynstr_append(ds, GPU_builtin_name(input->builtin));
@@ -660,7 +664,7 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
BLI_dynstr_append(ds, ";\n");
}
-static char *code_generate_fragment(ListBase *nodes, GPUOutput *output)
+static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, bool use_new_shading)
{
DynStr *ds = BLI_dynstr_new();
char *code;
@@ -686,8 +690,23 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output)
BLI_dynstr_append(ds, "void main()\n{\n");
- if (builtins & GPU_VIEW_NORMAL)
- BLI_dynstr_append(ds, "\tvec3 facingnormal = gl_FrontFacing? varnormal: -varnormal;\n");
+ if (use_new_shading) {
+ if (builtins & GPU_INVERSE_VIEW_MATRIX)
+ BLI_dynstr_append(ds, "\tmat4 viewinv = ViewMatrixInverse;\n");
+ if (builtins & GPU_VIEW_NORMAL)
+ BLI_dynstr_append(ds, "\tvec3 facingnormal = gl_FrontFacing? viewNormal: -viewNormal;\n");
+ if (builtins & GPU_VIEW_POSITION)
+ BLI_dynstr_append(ds, "\tvec3 viewposition = viewPosition;\n");
+
+ }
+ else {
+ if (builtins & GPU_INVERSE_VIEW_MATRIX)
+ BLI_dynstr_append(ds, "\tmat4 viewinv = unfinvviewmat;\n");
+ if (builtins & GPU_VIEW_NORMAL)
+ BLI_dynstr_append(ds, "\tvec3 facingnormal = gl_FrontFacing? varnormal: -varnormal;\n");
+ if (builtins & GPU_VIEW_POSITION)
+ BLI_dynstr_append(ds, "\tvec3 viewposition = varposition;\n");
+ }
/* Calculate tangent space. */
#ifdef WITH_OPENSUBDIV
@@ -733,6 +752,87 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output)
return code;
}
+static const char *attrib_prefix_get(CustomDataType type)
+{
+ switch (type) {
+ case CD_ORCO: return "orco";
+ case CD_MTFACE: return "u";
+ case CD_TANGENT: return "t";
+ case CD_MCOL: return "c";
+ case CD_AUTO_FROM_NAME: return "a";
+ default: BLI_assert(false && "Attrib Prefix type not found : This should not happen!"); return "";
+ }
+}
+
+static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code)
+{
+ DynStr *ds = BLI_dynstr_new();
+ GPUNode *node;
+ GPUInput *input;
+ char *code;
+
+ 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) {
+ /* XXX FIXME : see notes in mesh_render_data_create() */
+ /* NOTE : Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */
+ if (input->attribname[0] == '\0') {
+ BLI_dynstr_appendf(ds, "in %s %s;\n", GPU_DATATYPE_STR[input->type], attrib_prefix_get(input->attribtype));
+ BLI_dynstr_appendf(ds, "#define att%d %s\n", input->attribid, attrib_prefix_get(input->attribtype));
+ }
+ else {
+ unsigned int hash = BLI_ghashutil_strhash_p(input->attribname);
+ BLI_dynstr_appendf(ds, "in %s %s%u;\n",
+ GPU_DATATYPE_STR[input->type], attrib_prefix_get(input->attribtype), hash);
+ BLI_dynstr_appendf(ds, "#define att%d %s%u\n",
+ input->attribid, attrib_prefix_get(input->attribtype), hash);
+ }
+ BLI_dynstr_appendf(ds, "out %s var%d;\n",
+ GPU_DATATYPE_STR[input->type], input->attribid);
+ }
+ }
+ }
+
+ BLI_dynstr_append(ds, "\n");
+
+ BLI_dynstr_append(ds, "#define ATTRIB\n");
+ BLI_dynstr_append(ds, "uniform mat3 NormalMatrix;\n");
+ BLI_dynstr_append(ds, "void pass_attrib(void) {\n");
+
+ 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) {
+ if (input->attribtype == CD_TANGENT) { /* silly exception */
+ BLI_dynstr_appendf(
+ ds, "\tvar%d.xyz = normalize(NormalMatrix * att%d.xyz);\n",
+ input->attribid, input->attribid);
+ BLI_dynstr_appendf(
+ ds, "\tvar%d.w = att%d.w;\n",
+ input->attribid, input->attribid);
+ }
+ else {
+ BLI_dynstr_appendf(ds, "\tvar%d = att%d;\n",
+ input->attribid, input->attribid);
+ }
+ }
+ }
+ }
+
+ BLI_dynstr_append(ds, "}\n");
+
+ BLI_dynstr_append(ds, vert_code);
+
+ code = BLI_dynstr_get_cstring(ds);
+
+ BLI_dynstr_free(ds);
+
+#if 0
+ if (G.debug & G_DEBUG) printf("%s\n", code);
+#endif
+
+ return code;
+}
+
static char *code_generate_vertex(ListBase *nodes, const GPUMatType type)
{
DynStr *ds = BLI_dynstr_new();
@@ -1448,7 +1548,14 @@ GPUNodeLink *GPU_attribute(const CustomDataType type, const char *name)
{
GPUNodeLink *link = GPU_node_link_create();
- link->attribtype = type;
+ /* Fall back to the UV layer, which matches old behavior. */
+ if (type == CD_AUTO_FROM_NAME && name[0] == '\0') {
+ link->attribtype = CD_MTFACE;
+ }
+ else {
+ link->attribtype = type;
+ }
+
link->attribname = name;
return link;
@@ -1720,16 +1827,20 @@ GPUPass *GPU_generate_pass_new(ListBase *nodes, struct GPUNodeLink *frag_outlink
/* prune unused nodes */
gpu_nodes_prune(nodes, frag_outlink);
+ /* Hacky */
+ GPUVertexAttribs attribs;
+ gpu_nodes_get_vertex_attributes(nodes, &attribs);
+
/* generate code and compile with opengl */
- fragmentgen = code_generate_fragment(nodes, frag_outlink->output);
- // vertexgen = code_generate_vertex(nodes, GPU_MATERIAL_TYPE_MESH);
+ fragmentgen = code_generate_fragment(nodes, frag_outlink->output, true);
+ vertexgen = code_generate_vertex_new(nodes, vert_code);
// geometrygen = code_generate_geometry(nodes, false);
- UNUSED_VARS(vertexgen, geometrygen);
+ UNUSED_VARS(geometrygen);
tmp = BLI_strdupcat(frag_lib, glsl_material_library);
fragmentcode = BLI_strdupcat(tmp, fragmentgen);
- vertexcode = BLI_strdup(vert_code);
- geometrycode = BLI_strdup(geom_code);
+ vertexcode = BLI_strdup(vertexgen);
+ geometrycode = (geom_code) ? BLI_strdup(geom_code) : NULL;
shader = GPU_shader_create(vertexcode,
fragmentcode,
@@ -1748,6 +1859,7 @@ GPUPass *GPU_generate_pass_new(ListBase *nodes, struct GPUNodeLink *frag_outlink
if (geometrycode)
MEM_freeN(geometrycode);
MEM_freeN(fragmentgen);
+ MEM_freeN(vertexgen);
gpu_nodes_free(nodes);
return NULL;
}
@@ -1765,6 +1877,7 @@ GPUPass *GPU_generate_pass_new(ListBase *nodes, struct GPUNodeLink *frag_outlink
gpu_nodes_free(nodes);
MEM_freeN(fragmentgen);
+ MEM_freeN(vertexgen);
return pass;
}
@@ -1794,7 +1907,7 @@ GPUPass *GPU_generate_pass(
gpu_nodes_get_builtin_flag(nodes, builtins);
/* generate code and compile with opengl */
- fragmentcode = code_generate_fragment(nodes, outlink->output);
+ fragmentcode = code_generate_fragment(nodes, outlink->output, false);
vertexcode = code_generate_vertex(nodes, type);
geometrycode = code_generate_geometry(nodes, use_opensubdiv);
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 083b0596b1c..c00baef2856 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -477,10 +477,6 @@ void gpu_material_add_node(GPUMaterial *material, GPUNode *node)
bool GPU_material_do_color_management(GPUMaterial *mat)
{
- /* XXX mat->scene == NULL in that case */
- if (mat->engine)
- return true;
-
if (!BKE_scene_check_color_management_enabled(mat->scene))
return false;
@@ -2109,7 +2105,7 @@ GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo)
/* TODO : This is supposed to replace GPU_material_from_blender/_world in the future */
GPUMaterial *GPU_material_from_nodetree(
- struct bNodeTree *ntree, ListBase *gpumaterials, void *engine_type, int options,
+ Scene *scene, struct bNodeTree *ntree, ListBase *gpumaterials, void *engine_type, int options,
const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines)
{
GPUMaterial *mat;
@@ -2127,6 +2123,7 @@ GPUMaterial *GPU_material_from_nodetree(
/* allocate material */
mat = GPU_material_construct_begin(NULL); /* TODO remove GPU_material_construct_begin */
+ mat->scene = scene;
mat->engine = engine_type;
mat->options = options;
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index a0c56e9ebf4..8bfbd07bce8 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -4,6 +4,7 @@ uniform mat4 ModelViewMatrix;
uniform mat4 ProjectionMatrix;
#endif
uniform mat4 ModelViewMatrixInverse;
+uniform mat4 ViewMatrixInverse;
uniform mat4 ProjectionMatrixInverse;
uniform mat3 NormalMatrix;
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 be393582a42..23571e24501 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
@@ -48,14 +48,14 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat, bNode *UNUSED(node), bNod
GPUNodeLink *mtface = GPU_attribute(CD_MTFACE, "");
GPUMatType type = GPU_Material_get_type(mat);
- if (type == GPU_MATERIAL_TYPE_MESH) {
- return GPU_stack_link(mat, "node_tex_coord", in, out,
+ if (type == GPU_MATERIAL_TYPE_WORLD) {
+ 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),
GPU_builtin(GPU_CAMERA_TEXCO_FACTORS), orco, mtface);
}
else {
- return GPU_stack_link(mat, "node_tex_coord_background", in, out,
+ 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),
GPU_builtin(GPU_CAMERA_TEXCO_FACTORS), orco, mtface);