Changeset View
Standalone View
source/blender/draw/engines/eevee/eevee_shaders_extra.cc
| Show All 10 Lines | |||||
| #include "BLI_string_ref.hh" | #include "BLI_string_ref.hh" | ||||
| #include "gpu_shader_create_info.hh" | #include "gpu_shader_create_info.hh" | ||||
| #include "eevee_private.h" | #include "eevee_private.h" | ||||
| using blender::gpu::shader::StageInterfaceInfo; | using blender::gpu::shader::StageInterfaceInfo; | ||||
| static StageInterfaceInfo *stage_interface = nullptr; | |||||
| void eevee_shader_extra_init() | |||||
| { | |||||
| if (stage_interface != nullptr) { | |||||
| return; | |||||
| } | |||||
| using namespace blender::gpu::shader; | |||||
| stage_interface = new StageInterfaceInfo("ShaderStageInterface", ""); | |||||
| stage_interface->smooth(Type::VEC3, "worldPosition"); | |||||
| stage_interface->smooth(Type::VEC3, "viewPosition"); | |||||
| stage_interface->smooth(Type::VEC3, "worldNormal"); | |||||
| stage_interface->smooth(Type::VEC3, "viewNormal"); | |||||
| stage_interface->flat(Type::INT, "resourceIDFrag"); | |||||
| } | |||||
| void eevee_shader_extra_exit() | |||||
| { | |||||
| delete stage_interface; | |||||
| } | |||||
| void eevee_shader_material_create_info_amend(GPUMaterial *gpumat, | void eevee_shader_material_create_info_amend(GPUMaterial *gpumat, | ||||
fclem: Why is this necessary? | |||||
Not Done Inline ActionsIn order for each shader type to have its correct properties from ShaderCreateInfo, the correct info name needs to be passed in. Each of the input vert/geom/frag base sources for each material type (Surface, Volume, World etc and Mesh/Hair/Pointcloud) require a unique create-info. As these were resolved in a separate function, it seemed to make sense to determine the correct associated create info to use in the same place, to reduce code duplication. I had experimented with referencing the vert/geom/frag source file directly inside the create-info, though these caused a few issues, as there are some source modifications when using the DRW_shader_library_create_shader_string path. The relevant descriptions are located alongside the source/info fetching functions: e.g. eevee_get_vert_info. Though please let me know if a different approach is preferable. MichaelPW: In order for each shader type to have its correct properties from ShaderCreateInfo, the correct… | |||||
| GPUCodegenOutput *codegen_, | GPUCodegenOutput *codegen_, | ||||
| char *frag, | |||||
| char *vert, | char *vert, | ||||
| char *geom, | char *geom, | ||||
| char *frag, | |||||
| const char *vert_info_name, | |||||
| const char *geom_info_name, | |||||
| const char *frag_info_name, | |||||
| char *defines) | char *defines) | ||||
| { | { | ||||
| using namespace blender::gpu::shader; | using namespace blender::gpu::shader; | ||||
| uint64_t options = GPU_material_uuid_get(gpumat); | uint64_t options = GPU_material_uuid_get(gpumat); | ||||
| const bool is_background = (options & (VAR_WORLD_PROBE | VAR_WORLD_BACKGROUND)) != 0; | const bool is_background = (options & (VAR_WORLD_PROBE | VAR_WORLD_BACKGROUND)) != 0; | ||||
| const bool is_volume = (options & (VAR_MAT_VOLUME)) != 0; | const bool is_volume = (options & (VAR_MAT_VOLUME)) != 0; | ||||
| const bool is_hair = (options & (VAR_MAT_HAIR)) != 0; | const bool is_hair = (options & (VAR_MAT_HAIR)) != 0; | ||||
| const bool is_mesh = (options & (VAR_MAT_MESH)) != 0; | const bool is_mesh = (options & (VAR_MAT_MESH)) != 0; | ||||
| const bool is_point_cloud = (options & (VAR_MAT_POINTCLOUD)) != 0; | const bool is_point_cloud = (options & (VAR_MAT_POINTCLOUD)) != 0; | ||||
| GPUCodegenOutput &codegen = *codegen_; | GPUCodegenOutput &codegen = *codegen_; | ||||
| ShaderCreateInfo &info = *reinterpret_cast<ShaderCreateInfo *>(codegen.create_info); | ShaderCreateInfo &info = *reinterpret_cast<ShaderCreateInfo *>(codegen.create_info); | ||||
| info.legacy_resource_location(true); | /* Append stage-specific create info. */ | ||||
| if (vert_info_name) { | |||||
| info.additional_info(vert_info_name); | |||||
| } | |||||
| if (geom_info_name) { | |||||
| info.additional_info(geom_info_name); | |||||
| } | |||||
| if (frag_info_name) { | |||||
| info.additional_info(frag_info_name); | |||||
| } | |||||
| info.auto_resource_location(true); | info.auto_resource_location(true); | ||||
| if (GPU_material_flag_get(gpumat, GPU_MATFLAG_SUBSURFACE)) { | if (GPU_material_flag_get(gpumat, GPU_MATFLAG_SUBSURFACE)) { | ||||
| info.define("USE_SSS"); | info.define("USE_SSS"); | ||||
| } | } | ||||
| if (GPU_material_flag_get(gpumat, GPU_MATFLAG_SHADER_TO_RGBA)) { | if (GPU_material_flag_get(gpumat, GPU_MATFLAG_SHADER_TO_RGBA)) { | ||||
| info.define("USE_SHADER_TO_RGBA"); | info.define("USE_SHADER_TO_RGBA"); | ||||
| } | } | ||||
| if (GPU_material_flag_get(gpumat, GPU_MATFLAG_BARYCENTRIC) && !is_volume && !is_hair && | if (GPU_material_flag_get(gpumat, GPU_MATFLAG_BARYCENTRIC) && !is_volume && !is_hair && | ||||
| !is_point_cloud && !is_background) { | !is_point_cloud && !is_background) { | ||||
| info.define("USE_BARYCENTRICS"); | info.define("USE_BARYCENTRICS"); | ||||
| info.builtins(BuiltinBits::BARYCENTRIC_COORD); | info.builtins(BuiltinBits::BARYCENTRIC_COORD); | ||||
| } | } | ||||
| if (GPU_material_flag_get(gpumat, GPU_MATFLAG_BARYCENTRIC) && is_hair) { | if (GPU_material_flag_get(gpumat, GPU_MATFLAG_BARYCENTRIC) && is_hair) { | ||||
| info.define("USE_BARYCENTRICS"); | info.define("USE_BARYCENTRICS"); | ||||
| } | } | ||||
| /* Lookdev - Add FragDepth. */ | |||||
| if (options & VAR_MAT_LOOKDEV) { | |||||
| info.define("LOOKDEV"); | |||||
| info.depth_write(DepthWrite::ANY); | |||||
| } | |||||
| std::stringstream attr_load; | std::stringstream attr_load; | ||||
| const bool do_fragment_attrib_load = is_background || is_volume; | const bool do_fragment_attrib_load = is_background || is_volume; | ||||
| if (is_hair && !info.vertex_out_interfaces_.is_empty()) { | if (is_hair && !info.vertex_out_interfaces_.is_empty()) { | ||||
| /** Hair attributes come from sampler buffer. Transfer attributes to sampler. */ | /** Hair attributes come from sampler buffer. Transfer attributes to sampler. */ | ||||
| for (auto &input : info.vertex_inputs_) { | for (auto &input : info.vertex_inputs_) { | ||||
| info.sampler(0, ImageType::FLOAT_BUFFER, input.name, Frequency::BATCH); | info.sampler(0, ImageType::FLOAT_BUFFER, input.name, Frequency::BATCH); | ||||
| Show All 32 Lines | void eevee_shader_material_create_info_amend(GPUMaterial *gpumat, | ||||
| } | } | ||||
| if (is_hair) { | if (is_hair) { | ||||
| info.additional_info("draw_curves_infos"); | info.additional_info("draw_curves_infos"); | ||||
| } | } | ||||
| if (!is_volume) { | if (!is_volume) { | ||||
| info.define("EEVEE_GENERATED_INTERFACE"); | info.define("EEVEE_GENERATED_INTERFACE"); | ||||
| info.vertex_out(*stage_interface); | |||||
| } | } | ||||
| attr_load << "void attrib_load()\n"; | attr_load << "void attrib_load()\n"; | ||||
| attr_load << "{\n"; | attr_load << "{\n"; | ||||
| attr_load << ((codegen.attr_load) ? codegen.attr_load : ""); | attr_load << ((codegen.attr_load) ? codegen.attr_load : ""); | ||||
| attr_load << "}\n\n"; | attr_load << "}\n\n"; | ||||
| std::stringstream vert_gen, frag_gen, geom_gen; | std::stringstream vert_gen, frag_gen, geom_gen; | ||||
| ▲ Show 20 Lines • Show All 56 Lines • Show Last 20 Lines | |||||
Why is this necessary?