Blender  V3.3
eevee_shaders_extra.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2022 Blender Foundation. */
3 
10 #include "GPU_shader.h"
11 
12 #include "BLI_string_ref.hh"
13 
15 
16 #include "eevee_private.h"
17 
19 
21 
23 {
24  if (stage_interface != nullptr) {
25  return;
26  }
27 
28  using namespace blender::gpu::shader;
29  stage_interface = new StageInterfaceInfo("ShaderStageInterface", "");
30  stage_interface->smooth(Type::VEC3, "worldPosition");
31  stage_interface->smooth(Type::VEC3, "viewPosition");
32  stage_interface->smooth(Type::VEC3, "worldNormal");
33  stage_interface->smooth(Type::VEC3, "viewNormal");
34  stage_interface->flat(Type::INT, "resourceIDFrag");
35 }
36 
38 {
39  delete stage_interface;
40 }
41 
43  GPUCodegenOutput *codegen_,
44  char *frag,
45  char *vert,
46  char *geom,
47  char *defines)
48 {
49  using namespace blender::gpu::shader;
50 
52  const bool is_background = (options & (VAR_WORLD_PROBE | VAR_WORLD_BACKGROUND)) != 0;
53  const bool is_volume = (options & (VAR_MAT_VOLUME)) != 0;
54  const bool is_hair = (options & (VAR_MAT_HAIR)) != 0;
55  const bool is_mesh = (options & (VAR_MAT_MESH)) != 0;
56  const bool is_point_cloud = (options & (VAR_MAT_POINTCLOUD)) != 0;
57 
58  GPUCodegenOutput &codegen = *codegen_;
59  ShaderCreateInfo &info = *reinterpret_cast<ShaderCreateInfo *>(codegen.create_info);
60 
61  info.legacy_resource_location(true);
62  info.auto_resource_location(true);
63 
65  info.define("USE_SSS");
66  }
68  info.define("USE_SHADER_TO_RGBA");
69  }
70  if (GPU_material_flag_get(gpumat, GPU_MATFLAG_BARYCENTRIC) && !is_volume && !is_hair &&
71  !is_point_cloud && !is_background) {
72  info.define("USE_BARYCENTRICS");
74  }
75  if (GPU_material_flag_get(gpumat, GPU_MATFLAG_BARYCENTRIC) && is_hair) {
76  info.define("USE_BARYCENTRICS");
77  }
78 
79  std::stringstream attr_load;
80 
81  const bool do_fragment_attrib_load = is_background || is_volume;
82 
83  if (is_hair && !info.vertex_out_interfaces_.is_empty()) {
85  for (auto &input : info.vertex_inputs_) {
87  }
88  info.vertex_inputs_.clear();
89  }
90  else if (do_fragment_attrib_load && !info.vertex_out_interfaces_.is_empty()) {
91  /* Codegen outputs only one interface. */
92  const StageInterfaceInfo &iface = *info.vertex_out_interfaces_.first();
93  /* Globals the attrib_load() can write to when it is in the fragment shader. */
94  attr_load << "struct " << iface.name << " {\n";
95  for (const auto &inout : iface.inouts) {
96  attr_load << " " << inout.type << " " << inout.name << ";\n";
97  }
98  attr_load << "};\n";
99  attr_load << iface.name << " " << iface.instance_name << ";\n";
100  if (!is_volume) {
101  /* Global vars just to make code valid. Only Orco is supported. */
102  for (const ShaderCreateInfo::VertIn &in : info.vertex_inputs_) {
103  attr_load << in.type << " " << in.name << ";\n";
104  }
105  }
106  info.vertex_out_interfaces_.clear();
107  }
108  if (is_volume) {
110  for (auto &input : info.vertex_inputs_) {
112  }
113  info.additional_info("draw_volume_infos");
114  /* Do not add twice. */
116  info.additional_info("draw_object_infos");
117  }
118  info.vertex_inputs_.clear();
119  }
120 
121  if (is_hair) {
122  info.additional_info("draw_curves_infos");
123  }
124 
125  if (!is_volume) {
126  info.define("EEVEE_GENERATED_INTERFACE");
128  }
129 
130  attr_load << "void attrib_load()\n";
131  attr_load << "{\n";
132  attr_load << ((codegen.attr_load) ? codegen.attr_load : "");
133  attr_load << "}\n\n";
134 
135  std::stringstream vert_gen, frag_gen, geom_gen;
136 
137  if (do_fragment_attrib_load) {
138  frag_gen << attr_load.str();
139  }
140  else {
141  vert_gen << attr_load.str();
142  }
143 
144  {
145  vert_gen << vert;
146  info.vertex_source_generated = vert_gen.str();
147  /* Everything is in generated source. */
148  info.vertex_source(is_volume ? "eevee_empty_volume.glsl" : "eevee_empty.glsl");
149  }
150 
151  {
152  frag_gen << frag;
153  if (codegen.material_functions) {
154  frag_gen << codegen.material_functions;
155  }
156  frag_gen << "Closure nodetree_exec()\n";
157  frag_gen << "{\n";
158  if (is_volume) {
159  frag_gen << ((codegen.volume) ? codegen.volume : "return CLOSURE_DEFAULT;\n");
160  }
161  else {
162  frag_gen << ((codegen.surface) ? codegen.surface : "return CLOSURE_DEFAULT;\n");
163  }
164  frag_gen << "}\n\n";
165 
166  if (codegen.displacement && (is_hair || is_mesh)) {
167  info.define("EEVEE_DISPLACEMENT_BUMP");
168 
169  frag_gen << "vec3 displacement_exec()\n";
170  frag_gen << "{\n";
171  frag_gen << codegen.displacement;
172  frag_gen << "}\n\n";
173  }
174 
175  info.fragment_source_generated = frag_gen.str();
176  /* Everything is in generated source. */
177  info.fragment_source(is_volume ? "eevee_empty_volume.glsl" : "eevee_empty.glsl");
178  }
179 
180  if (geom) {
181  geom_gen << geom;
182  info.geometry_source_generated = geom_gen.str();
184  /* Everything is in generated source. */
185  info.geometry_source("eevee_empty.glsl");
186  }
187 
188  if (defines) {
190  }
191 }
uint64_t GPU_material_uuid_get(GPUMaterial *mat)
Definition: gpu_material.c:619
bool GPU_material_flag_get(const GPUMaterial *mat, eGPUMaterialFlag flag)
Definition: gpu_material.c:601
@ GPU_MATFLAG_SHADER_TO_RGBA
Definition: GPU_material.h:78
@ GPU_MATFLAG_OBJECT_INFO
Definition: GPU_material.h:82
@ GPU_MATFLAG_BARYCENTRIC
Definition: GPU_material.h:85
@ GPU_MATFLAG_SUBSURFACE
Definition: GPU_material.h:72
CCL_NAMESPACE_BEGIN struct Options options
@ VAR_WORLD_BACKGROUND
@ VAR_WORLD_PROBE
@ VAR_MAT_VOLUME
@ VAR_MAT_POINTCLOUD
@ VAR_MAT_MESH
@ VAR_MAT_HAIR
void eevee_shader_extra_init()
void eevee_shader_material_create_info_amend(GPUMaterial *gpumat, GPUCodegenOutput *codegen_, char *frag, char *vert, char *geom, char *defines)
void eevee_shader_extra_exit()
static StageInterfaceInfo * stage_interface
ccl_global KernelShaderEvalInput * input
unsigned __int64 uint64_t
Definition: stdint.h:90
char * material_functions
Definition: GPU_material.h:132
GPUShaderCreateInfo * create_info
Definition: GPU_material.h:134
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
Vector< StageInterfaceInfo * > vertex_out_interfaces_
Self & sampler(int slot, ImageType type, StringRefNull name, Frequency freq=Frequency::PASS, eGPUSamplerState sampler=(eGPUSamplerState) -1)
Self & geometry_source(StringRefNull filename)
Self & fragment_source(StringRefNull filename)
Self & additional_info(StringRefNull info_name0, StringRefNull info_name1="", StringRefNull info_name2="", StringRefNull info_name3="", StringRefNull info_name4="", StringRefNull info_name5="", StringRefNull info_name6="")
Self & vertex_out(StageInterfaceInfo &interface)
Self & define(StringRefNull name, StringRefNull value="")
Self & vertex_source(StringRefNull filename)
Self & geometry_layout(PrimitiveIn prim_in, PrimitiveOut prim_out, int max_vertices, int invocations=-1)
Self & smooth(Type type, StringRefNull _name)
Self & flat(Type type, StringRefNull _name)