Eevee: World nodetree gpumaterial compatibility.
- Unify GPUMaterial creation (world/mesh). - Support for multiple shader variations (not used for now). - Convert GPUInputs to DRWUniforms to be used with the draw manager. - Nodetree Update is not supported. The only way to refresh the shaders is to change render engine. - Cleanup in GPUPass. - Add new temporary Node Compatibility type. Compatibility types should be removed in the future.
This commit is contained in:
@@ -253,6 +253,7 @@ typedef struct bNodeType {
|
||||
/* nodetype->compatibility */
|
||||
#define NODE_OLD_SHADING 1
|
||||
#define NODE_NEW_SHADING 2
|
||||
#define NODE_NEWER_SHADING 3
|
||||
|
||||
/* node resize directions */
|
||||
#define NODE_RESIZE_TOP 1
|
||||
|
@@ -29,6 +29,8 @@
|
||||
|
||||
#include "BLI_dynstr.h"
|
||||
#include "BLI_rand.h"
|
||||
|
||||
#include "GPU_material.h"
|
||||
#include "GPU_glew.h"
|
||||
|
||||
#include "eevee_engine.h"
|
||||
@@ -39,6 +41,8 @@
|
||||
|
||||
/* *********** STATIC *********** */
|
||||
static struct {
|
||||
char *frag_shader_lib;
|
||||
|
||||
struct GPUShader *default_lit;
|
||||
struct GPUShader *default_world;
|
||||
struct GPUShader *depth_sh;
|
||||
@@ -214,6 +218,16 @@ static void EEVEE_engine_init(void *ved)
|
||||
(int)viewport_size[0], (int)viewport_size[1],
|
||||
&tex, 1);
|
||||
|
||||
if (!e_data.frag_shader_lib) {
|
||||
DynStr *ds_frag = BLI_dynstr_new();
|
||||
BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
|
||||
BLI_dynstr_append(ds_frag, datatoc_ltc_lib_glsl);
|
||||
BLI_dynstr_append(ds_frag, datatoc_bsdf_direct_lib_glsl);
|
||||
BLI_dynstr_append(ds_frag, datatoc_lit_surface_frag_glsl);
|
||||
e_data.frag_shader_lib = BLI_dynstr_get_cstring(ds_frag);
|
||||
BLI_dynstr_free(ds_frag);
|
||||
}
|
||||
|
||||
if (!e_data.depth_sh) {
|
||||
e_data.depth_sh = DRW_shader_create_3D_depth_only();
|
||||
}
|
||||
@@ -222,10 +236,7 @@ static void EEVEE_engine_init(void *ved)
|
||||
char *frag_str = NULL;
|
||||
|
||||
DynStr *ds_frag = BLI_dynstr_new();
|
||||
BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
|
||||
BLI_dynstr_append(ds_frag, datatoc_ltc_lib_glsl);
|
||||
BLI_dynstr_append(ds_frag, datatoc_bsdf_direct_lib_glsl);
|
||||
BLI_dynstr_append(ds_frag, datatoc_lit_surface_frag_glsl);
|
||||
BLI_dynstr_append(ds_frag, e_data.frag_shader_lib);
|
||||
BLI_dynstr_append(ds_frag, datatoc_default_frag_glsl);
|
||||
frag_str = BLI_dynstr_get_cstring(ds_frag);
|
||||
BLI_dynstr_free(ds_frag);
|
||||
@@ -345,6 +356,8 @@ static DRWShadingGroup *eevee_cascade_shadow_shgroup(
|
||||
|
||||
static void EEVEE_cache_init(void *vedata)
|
||||
{
|
||||
static int zero = 0;
|
||||
|
||||
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
|
||||
EEVEE_TextureList *txl = ((EEVEE_Data *)vedata)->txl;
|
||||
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
|
||||
@@ -373,26 +386,48 @@ static void EEVEE_cache_init(void *vedata)
|
||||
psl->probe_background = DRW_pass_create("Probe Background Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR);
|
||||
|
||||
struct Batch *geom = DRW_cache_fullscreen_quad_get();
|
||||
DRWShadingGroup *grp;
|
||||
DRWShadingGroup *grp = NULL;
|
||||
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
Scene *scene = draw_ctx->scene;
|
||||
World *wo = scene->world;
|
||||
|
||||
if (false) { /* TODO check for world nodetree */
|
||||
// GPUMaterial *gpumat = GPU_material_from_nodetree(struct bNodeTree *ntree, ListBase *gpumaterials, void *engine_type, int options)
|
||||
float *col = ts.colorBackground;
|
||||
if (wo) {
|
||||
col = &wo->horr;
|
||||
}
|
||||
else {
|
||||
float *col = ts.colorBackground;
|
||||
static int zero = 0;
|
||||
|
||||
if (wo) {
|
||||
col = &wo->horr;
|
||||
if (wo && wo->use_nodes && wo->nodetree) {
|
||||
struct GPUMaterial *gpumat = GPU_material_from_nodetree(
|
||||
wo->nodetree, &wo->gpumaterial, &DRW_engine_viewport_eevee_type, 0,
|
||||
datatoc_probe_vert_glsl, datatoc_probe_geom_glsl, e_data.frag_shader_lib,
|
||||
"#define PROBE_CAPTURE\n"
|
||||
"#define MAX_LIGHT 128\n"
|
||||
"#define MAX_SHADOW_CUBE 42\n"
|
||||
"#define MAX_SHADOW_MAP 64\n"
|
||||
"#define MAX_SHADOW_CASCADE 8\n"
|
||||
"#define MAX_CASCADE_NUM 4\n");
|
||||
|
||||
grp = DRW_shgroup_material_instance_create(gpumat, psl->probe_background, geom);
|
||||
|
||||
if (grp) {
|
||||
DRW_shgroup_uniform_int(grp, "Layer", &zero, 1);
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
DRW_shgroup_call_dynamic_add_empty(grp);
|
||||
}
|
||||
else {
|
||||
/* Shader failed : pink background */
|
||||
static float pink[3] = {1.0f, 0.0f, 1.0f};
|
||||
col = pink;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fallback if shader fails or if not using nodetree. */
|
||||
if (grp == NULL) {
|
||||
grp = eevee_cube_shgroup(e_data.default_world, psl->probe_background, geom);
|
||||
DRW_shgroup_uniform_int(grp, "Layer", &zero, 1);
|
||||
DRW_shgroup_uniform_vec3(grp, "color", col, 1);
|
||||
DRW_shgroup_uniform_int(grp, "Layer", &zero, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -591,6 +626,7 @@ static void EEVEE_draw_scene(void *vedata)
|
||||
|
||||
static void EEVEE_engine_free(void)
|
||||
{
|
||||
MEM_SAFE_FREE(e_data.frag_shader_lib);
|
||||
DRW_SHADER_FREE_SAFE(e_data.default_lit);
|
||||
DRW_SHADER_FREE_SAFE(e_data.shadow_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.default_world);
|
||||
@@ -628,7 +664,7 @@ DrawEngineType draw_engine_eevee_type = {
|
||||
|
||||
RenderEngineType DRW_engine_viewport_eevee_type = {
|
||||
NULL, NULL,
|
||||
EEVEE_ENGINE, N_("Eevee"), RE_INTERNAL | RE_USE_OGL_PIPELINE,
|
||||
EEVEE_ENGINE, N_("Eevee"), RE_INTERNAL | RE_USE_OGL_PIPELINE | RE_USE_SHADING_NODES,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, &EEVEE_collection_settings_create,
|
||||
&draw_engine_eevee_type,
|
||||
{NULL, NULL, NULL}
|
||||
|
@@ -54,7 +54,7 @@ struct ShadowMapData {
|
||||
#define sh_map_bias near_far_bias.z
|
||||
|
||||
#ifndef MAX_CASCADE_NUM
|
||||
#define MAX_CASCADE_NUM 1
|
||||
#define MAX_CASCADE_NUM 4
|
||||
#endif
|
||||
|
||||
struct ShadowCascadeData {
|
||||
@@ -94,8 +94,6 @@ vec4 saturate(vec4 a) { return vec4(saturate(a.x), saturate(a.y), saturate(a.z),
|
||||
float distance_squared(vec2 a, vec2 b) { a -= b; return dot(a, a); }
|
||||
float distance_squared(vec3 a, vec3 b) { a -= b; return dot(a, a); }
|
||||
|
||||
float hypot(float x, float y) { return sqrt(x*x + y*y); }
|
||||
|
||||
float inverse_distance(vec3 V) { return max( 1 / length(V), 1e-8); }
|
||||
|
||||
float line_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal)
|
||||
|
@@ -3,9 +3,11 @@ uniform vec3 diffuse_col;
|
||||
uniform vec3 specular_col;
|
||||
uniform int hardness;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
float roughness = 1.0 - float(hardness) / 511.0;
|
||||
roughness *= roughness;
|
||||
fragColor = vec4(eevee_surface_lit(worldNormal, diffuse_col, specular_col, roughness), 1.0);
|
||||
FragColor = vec4(eevee_surface_lit(worldNormal, diffuse_col, specular_col, roughness), 1.0);
|
||||
}
|
||||
|
@@ -28,8 +28,6 @@ layout(std140) uniform shadow_block {
|
||||
in vec3 worldPosition;
|
||||
in vec3 worldNormal;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
/* type */
|
||||
#define POINT 0.0
|
||||
#define SUN 1.0
|
||||
|
@@ -8,7 +8,7 @@ in vec4 vPos[];
|
||||
in int face[];
|
||||
|
||||
out vec3 worldPosition;
|
||||
out vec3 worldNormal;
|
||||
out vec3 worldNormal; /* Required. otherwise generate linking error on AMD. */
|
||||
|
||||
const vec3 maj_axes[6] = vec3[6](vec3(1.0, 0.0, 0.0), vec3(-1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(0.0, -1.0, 0.0), vec3( 0.0, 0.0, 1.0), vec3( 0.0, 0.0, -1.0));
|
||||
const vec3 x_axis[6] = vec3[6](vec3(0.0, 0.0, -1.0), vec3( 0.0, 0.0, 1.0), vec3(1.0, 0.0, 0.0), vec3(1.0, 0.0, 0.0), vec3( 1.0, 0.0, 0.0), vec3(-1.0, 0.0, 0.0));
|
||||
|
@@ -56,6 +56,7 @@
|
||||
struct bContext;
|
||||
struct GPUFrameBuffer;
|
||||
struct GPUShader;
|
||||
struct GPUMaterial;
|
||||
struct GPUTexture;
|
||||
struct GPUUniformBuffer;
|
||||
struct Object;
|
||||
@@ -245,6 +246,8 @@ typedef enum {
|
||||
} DRWState;
|
||||
|
||||
DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass);
|
||||
DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass);
|
||||
DRWShadingGroup *DRW_shgroup_material_instance_create(struct GPUMaterial *material, DRWPass *pass, struct Batch *geom);
|
||||
DRWShadingGroup *DRW_shgroup_instance_create(struct GPUShader *shader, DRWPass *pass, struct Batch *geom);
|
||||
DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPass *pass);
|
||||
DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass *pass);
|
||||
|
@@ -47,11 +47,13 @@
|
||||
#include "ED_space_api.h"
|
||||
#include "ED_screen.h"
|
||||
|
||||
#include "intern/gpu_codegen.h"
|
||||
#include "GPU_batch.h"
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_extensions.h"
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_lamp.h"
|
||||
#include "GPU_material.h"
|
||||
#include "GPU_shader.h"
|
||||
#include "GPU_texture.h"
|
||||
#include "GPU_uniformbuffer.h"
|
||||
@@ -614,6 +616,80 @@ DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
|
||||
return shgroup;
|
||||
}
|
||||
|
||||
DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass)
|
||||
{
|
||||
double time = 0.0; /* TODO make time variable */
|
||||
const int max_tex = GPU_max_textures() - 1;
|
||||
|
||||
/* TODO : Ideally we should not convert. But since the whole codegen
|
||||
* is relying on GPUPass we keep it as is for now. */
|
||||
|
||||
GPUPass *gpupass = GPU_material_get_pass(material);
|
||||
|
||||
if (!gpupass) {
|
||||
/* Shader compilation error */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct GPUShader *shader = GPU_pass_shader(gpupass);
|
||||
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
|
||||
|
||||
/* Converting dynamic GPUInput to DRWUniform */
|
||||
ListBase *inputs = &gpupass->inputs;
|
||||
|
||||
for (GPUInput *input = inputs->first; input; input = input->next) {
|
||||
/* Textures */
|
||||
if (input->ima) {
|
||||
GPUTexture *tex = GPU_texture_from_blender(input->ima, input->iuser, input->textarget, input->image_isdata, time, 1);
|
||||
|
||||
if (input->bindtex) {
|
||||
/* TODO maybe track texture slot usage to avoid clash with engine textures */
|
||||
DRW_shgroup_uniform_texture(grp, input->shadername, tex, max_tex - input->texid);
|
||||
}
|
||||
}
|
||||
/* Floats */
|
||||
else {
|
||||
switch (input->type) {
|
||||
case 1:
|
||||
DRW_shgroup_uniform_float(grp, input->shadername, (float *)input->dynamicvec, 1);
|
||||
break;
|
||||
case 2:
|
||||
DRW_shgroup_uniform_vec2(grp, input->shadername, (float *)input->dynamicvec, 1);
|
||||
break;
|
||||
case 3:
|
||||
DRW_shgroup_uniform_vec3(grp, input->shadername, (float *)input->dynamicvec, 1);
|
||||
break;
|
||||
case 4:
|
||||
DRW_shgroup_uniform_vec4(grp, input->shadername, (float *)input->dynamicvec, 1);
|
||||
break;
|
||||
case 9:
|
||||
DRW_shgroup_uniform_mat3(grp, input->shadername, (float *)input->dynamicvec);
|
||||
break;
|
||||
case 16:
|
||||
DRW_shgroup_uniform_mat4(grp, input->shadername, (float *)input->dynamicvec);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return grp;
|
||||
}
|
||||
|
||||
DRWShadingGroup *DRW_shgroup_material_instance_create(struct GPUMaterial *material, DRWPass *pass, Batch *geom)
|
||||
{
|
||||
DRWShadingGroup *shgroup = DRW_shgroup_material_create(material, pass);
|
||||
|
||||
if (shgroup) {
|
||||
shgroup->type = DRW_SHG_INSTANCE;
|
||||
shgroup->instance_geom = geom;
|
||||
}
|
||||
|
||||
return shgroup;
|
||||
}
|
||||
|
||||
DRWShadingGroup *DRW_shgroup_instance_create(struct GPUShader *shader, DRWPass *pass, Batch *geom)
|
||||
{
|
||||
DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
|
||||
|
@@ -56,6 +56,7 @@ struct GPUTexture;
|
||||
struct GPULamp;
|
||||
struct PreviewImage;
|
||||
struct World;
|
||||
struct bNodeTree;
|
||||
|
||||
typedef struct GPUNode GPUNode;
|
||||
typedef struct GPUNodeLink GPUNodeLink;
|
||||
@@ -218,7 +219,9 @@ 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,
|
||||
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);
|
||||
void GPU_material_free(struct ListBase *gpumaterial);
|
||||
@@ -235,6 +238,7 @@ void GPU_material_unbind(GPUMaterial *material);
|
||||
bool GPU_material_bound(GPUMaterial *material);
|
||||
struct Scene *GPU_material_scene(GPUMaterial *material);
|
||||
GPUMatType GPU_Material_get_type(GPUMaterial *material);
|
||||
struct GPUPass *GPU_material_get_pass(GPUMaterial *material);
|
||||
|
||||
void GPU_material_vertex_attributes(GPUMaterial *material,
|
||||
struct GPUVertexAttribs *attrib);
|
||||
|
@@ -928,6 +928,67 @@ GPUShader *GPU_pass_shader(GPUPass *pass)
|
||||
return pass->shader;
|
||||
}
|
||||
|
||||
static void gpu_nodes_extract_dynamic_inputs_new(GPUPass *pass, ListBase *nodes)
|
||||
{
|
||||
GPUShader *shader = pass->shader;
|
||||
GPUNode *node;
|
||||
GPUInput *next, *input;
|
||||
ListBase *inputs = &pass->inputs;
|
||||
int extract, z;
|
||||
|
||||
memset(inputs, 0, sizeof(*inputs));
|
||||
|
||||
if (!shader)
|
||||
return;
|
||||
|
||||
GPU_shader_bind(shader);
|
||||
|
||||
for (node = nodes->first; node; node = node->next) {
|
||||
z = 0;
|
||||
for (input = node->inputs.first; input; input = next, z++) {
|
||||
next = input->next;
|
||||
|
||||
/* attributes don't need to be bound, they already have
|
||||
* an id that the drawing functions will use */
|
||||
if (input->source == GPU_SOURCE_ATTRIB) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (input->source == GPU_SOURCE_BUILTIN ||
|
||||
input->source == GPU_SOURCE_OPENGL_BUILTIN)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (input->ima || input->tex || input->prv)
|
||||
BLI_snprintf(input->shadername, sizeof(input->shadername), "samp%d", input->texid);
|
||||
else
|
||||
BLI_snprintf(input->shadername, sizeof(input->shadername), "unf%d", input->id);
|
||||
|
||||
/* pass non-dynamic uniforms to opengl */
|
||||
extract = 0;
|
||||
|
||||
if (input->ima || input->tex || input->prv) {
|
||||
if (input->bindtex)
|
||||
extract = 1;
|
||||
}
|
||||
else if (input->dynamicvec)
|
||||
extract = 1;
|
||||
|
||||
if (extract)
|
||||
input->shaderloc = GPU_shader_get_uniform(shader, input->shadername);
|
||||
|
||||
/* extract nodes */
|
||||
if (extract) {
|
||||
BLI_remlink(&node->inputs, input);
|
||||
BLI_addtail(inputs, input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GPU_shader_unbind();
|
||||
}
|
||||
|
||||
static void gpu_nodes_extract_dynamic_inputs(GPUPass *pass, ListBase *nodes)
|
||||
{
|
||||
GPUShader *shader = pass->shader;
|
||||
@@ -1647,6 +1708,67 @@ static void gpu_nodes_prune(ListBase *nodes, GPUNodeLink *outlink)
|
||||
}
|
||||
}
|
||||
|
||||
GPUPass *GPU_generate_pass_new(ListBase *nodes, struct GPUNodeLink *frag_outlink,
|
||||
const char *vert_code, const char *geom_code,
|
||||
const char *frag_lib, const char *defines)
|
||||
{
|
||||
GPUShader *shader;
|
||||
GPUPass *pass;
|
||||
char *vertexgen, *geometrygen, *fragmentgen, *tmp;
|
||||
char *vertexcode, *geometrycode, *fragmentcode;
|
||||
|
||||
/* prune unused nodes */
|
||||
gpu_nodes_prune(nodes, frag_outlink);
|
||||
|
||||
/* generate code and compile with opengl */
|
||||
fragmentgen = code_generate_fragment(nodes, frag_outlink->output);
|
||||
// vertexgen = code_generate_vertex(nodes, GPU_MATERIAL_TYPE_MESH);
|
||||
// geometrygen = code_generate_geometry(nodes, false);
|
||||
UNUSED_VARS(vertexgen, geometrygen);
|
||||
|
||||
tmp = BLI_strdupcat(frag_lib, glsl_material_library);
|
||||
fragmentcode = BLI_strdupcat(tmp, fragmentgen);
|
||||
vertexcode = BLI_strdup(vert_code);
|
||||
geometrycode = BLI_strdup(geom_code);
|
||||
|
||||
shader = GPU_shader_create(vertexcode,
|
||||
fragmentcode,
|
||||
geometrycode,
|
||||
NULL,
|
||||
defines);
|
||||
|
||||
MEM_freeN(tmp);
|
||||
|
||||
/* failed? */
|
||||
if (!shader) {
|
||||
if (fragmentcode)
|
||||
MEM_freeN(fragmentcode);
|
||||
if (vertexcode)
|
||||
MEM_freeN(vertexcode);
|
||||
if (geometrycode)
|
||||
MEM_freeN(geometrycode);
|
||||
MEM_freeN(fragmentgen);
|
||||
gpu_nodes_free(nodes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* create pass */
|
||||
pass = MEM_callocN(sizeof(GPUPass), "GPUPass");
|
||||
pass->shader = shader;
|
||||
pass->fragmentcode = fragmentcode;
|
||||
pass->geometrycode = geometrycode;
|
||||
pass->vertexcode = vertexcode;
|
||||
pass->libcode = glsl_material_library;
|
||||
|
||||
/* extract dynamic inputs and throw away nodes */
|
||||
gpu_nodes_extract_dynamic_inputs_new(pass, nodes);
|
||||
gpu_nodes_free(nodes);
|
||||
|
||||
MEM_freeN(fragmentgen);
|
||||
|
||||
return pass;
|
||||
}
|
||||
|
||||
GPUPass *GPU_generate_pass(
|
||||
ListBase *nodes, GPUNodeLink *outlink,
|
||||
GPUVertexAttribs *attribs, int *builtins,
|
||||
@@ -1705,7 +1827,6 @@ GPUPass *GPU_generate_pass(
|
||||
/* create pass */
|
||||
pass = MEM_callocN(sizeof(GPUPass), "GPUPass");
|
||||
|
||||
pass->output = outlink->output;
|
||||
pass->shader = shader;
|
||||
pass->fragmentcode = fragmentcode;
|
||||
pass->geometrycode = geometrycode;
|
||||
|
@@ -156,10 +156,7 @@ typedef struct GPUInput {
|
||||
} GPUInput;
|
||||
|
||||
struct GPUPass {
|
||||
struct GPUPass *next, *prev;
|
||||
|
||||
ListBase inputs;
|
||||
struct GPUOutput *output;
|
||||
struct GPUShader *shader;
|
||||
char *fragmentcode;
|
||||
char *geometrycode;
|
||||
@@ -170,6 +167,9 @@ struct GPUPass {
|
||||
|
||||
typedef struct GPUPass GPUPass;
|
||||
|
||||
GPUPass *GPU_generate_pass_new(ListBase *nodes, struct GPUNodeLink *frag_outlink,
|
||||
const char *vert_code, const char *geom_code,
|
||||
const char *frag_lib, const char *defines);
|
||||
GPUPass *GPU_generate_pass(ListBase *nodes, struct GPUNodeLink *outlink,
|
||||
struct GPUVertexAttribs *attribs, int *builtin,
|
||||
const GPUMatType type, const char *name,
|
||||
|
@@ -94,12 +94,15 @@ static struct GPUWorld {
|
||||
} GPUWorld;
|
||||
|
||||
struct GPUMaterial {
|
||||
Scene *scene;
|
||||
Scene *scene; /* DEPRECATED was only usefull for lamps */
|
||||
Material *ma;
|
||||
|
||||
/* material for mesh surface, worlds or something else.
|
||||
* some code generation is done differently depending on the use case */
|
||||
int type;
|
||||
int type; /* DEPRECATED */
|
||||
|
||||
void *engine; /* attached engine type */
|
||||
int options; /* to identify shader variations (shadow, probe, world background...) */
|
||||
|
||||
/* for creating the material */
|
||||
ListBase nodes;
|
||||
@@ -436,6 +439,10 @@ GPUMatType GPU_Material_get_type(GPUMaterial *material)
|
||||
return material->type;
|
||||
}
|
||||
|
||||
GPUPass *GPU_material_get_pass(GPUMaterial *material)
|
||||
{
|
||||
return material->pass;
|
||||
}
|
||||
|
||||
void GPU_material_vertex_attributes(GPUMaterial *material, GPUVertexAttribs *attribs)
|
||||
{
|
||||
@@ -470,6 +477,10 @@ 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;
|
||||
|
||||
@@ -2096,6 +2107,47 @@ GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo)
|
||||
return mat;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines)
|
||||
{
|
||||
GPUMaterial *mat;
|
||||
GPUNodeLink *outlink;
|
||||
LinkData *link;
|
||||
|
||||
for (link = gpumaterials->first; link; link = link->next) {
|
||||
GPUMaterial *current_material = (GPUMaterial *)link->data;
|
||||
if (current_material->engine == engine_type &&
|
||||
current_material->options == options)
|
||||
{
|
||||
return current_material;
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate material */
|
||||
mat = GPU_material_construct_begin(NULL); /* TODO remove GPU_material_construct_begin */
|
||||
mat->engine = engine_type;
|
||||
mat->options = options;
|
||||
|
||||
ntreeGPUMaterialNodes(ntree, mat, NODE_NEWER_SHADING);
|
||||
|
||||
/* Let Draw manager finish the construction. */
|
||||
if (mat->outlink) {
|
||||
outlink = mat->outlink;
|
||||
mat->pass = GPU_generate_pass_new(&mat->nodes, outlink, vert_code, geom_code, frag_lib, defines);
|
||||
}
|
||||
|
||||
/* 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(gpumaterials, link);
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma, bool use_opensubdiv)
|
||||
{
|
||||
|
@@ -1,6 +1,8 @@
|
||||
|
||||
uniform mat4 ModelViewMatrix;
|
||||
#ifndef PROBE_CAPTURE
|
||||
uniform mat4 ProjectionMatrix;
|
||||
#endif
|
||||
uniform mat4 ModelViewMatrixInverse;
|
||||
uniform mat4 ProjectionMatrixInverse;
|
||||
uniform mat3 NormalMatrix;
|
||||
@@ -172,7 +174,7 @@ void color_to_blender_normal_new_shading(vec3 color, out vec3 normal)
|
||||
}
|
||||
|
||||
#define M_PI 3.14159265358979323846
|
||||
#define M_1_PI 0.31830988618379069
|
||||
#define M_1_PI 0.318309886183790671538
|
||||
|
||||
/*********** SHADER NODES ***************/
|
||||
|
||||
@@ -2813,6 +2815,13 @@ void background_transform_to_world(vec3 viewvec, out vec3 worldvec)
|
||||
worldvec = (ModelViewMatrixInverse * co).xyz;
|
||||
}
|
||||
|
||||
#ifdef PROBE_CAPTURE
|
||||
void environment_default_vector(out vec3 worldvec)
|
||||
{
|
||||
worldvec = normalize(worldPosition);
|
||||
}
|
||||
#endif
|
||||
|
||||
void node_background(vec4 color, float strength, vec3 N, out vec4 result)
|
||||
{
|
||||
result = color * strength;
|
||||
|
@@ -119,6 +119,7 @@ static void rna_World_use_nodes_update(bContext *C, PointerRNA *ptr)
|
||||
ED_node_shader_default(C, &wrld->id);
|
||||
|
||||
rna_World_update(CTX_data_main(C), CTX_data_scene(C), ptr);
|
||||
rna_World_draw_update(CTX_data_main(C), CTX_data_scene(C), ptr);
|
||||
}
|
||||
|
||||
#else
|
||||
|
@@ -69,8 +69,10 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, bNode *node, bNodeE
|
||||
|
||||
if (type == GPU_MATERIAL_TYPE_MESH)
|
||||
in[0].link = GPU_builtin(GPU_VIEW_POSITION);
|
||||
else
|
||||
else if (type == GPU_MATERIAL_TYPE_WORLD)
|
||||
GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &in[0].link);
|
||||
else
|
||||
GPU_link(mat, "environment_default_vector", &in[0].link);
|
||||
}
|
||||
|
||||
node_shader_gpu_tex_mapping(mat, node, in, out);
|
||||
|
Reference in New Issue
Block a user