2021-03-10 12:23:55 +01:00
/*************************************************************************/
/* scene_shader_forward_mobile.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
# include "scene_shader_forward_mobile.h"
# include "core/config/project_settings.h"
2021-05-19 14:12:55 +02:00
# include "core/math/math_defs.h"
2021-03-10 12:23:55 +01:00
# include "render_forward_mobile.h"
2021-05-07 15:19:04 +02:00
# include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
2021-03-10 12:23:55 +01:00
using namespace RendererSceneRenderImplementation ;
/* ShaderData */
void SceneShaderForwardMobile : : ShaderData : : set_code ( const String & p_code ) {
//compile
code = p_code ;
valid = false ;
ubo_size = 0 ;
uniforms . clear ( ) ;
uses_screen_texture = false ;
if ( code = = String ( ) ) {
return ; //just invalid, but no error
}
ShaderCompilerRD : : GeneratedCode gen_code ;
int blend_mode = BLEND_MODE_MIX ;
int depth_testi = DEPTH_TEST_ENABLED ;
int alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF ;
int cull = CULL_BACK ;
uses_point_size = false ;
uses_alpha = false ;
uses_blend_alpha = false ;
uses_depth_pre_pass = false ;
uses_discard = false ;
uses_roughness = false ;
uses_normal = false ;
bool wireframe = false ;
unshaded = false ;
uses_vertex = false ;
uses_sss = false ;
uses_transmittance = false ;
uses_screen_texture = false ;
uses_depth_texture = false ;
uses_normal_texture = false ;
uses_time = false ;
writes_modelview_or_projection = false ;
uses_world_coordinates = false ;
uses_particle_trails = false ;
int depth_drawi = DEPTH_DRAW_OPAQUE ;
ShaderCompilerRD : : IdentifierActions actions ;
actions . entry_point_stages [ " vertex " ] = ShaderCompilerRD : : STAGE_VERTEX ;
actions . entry_point_stages [ " fragment " ] = ShaderCompilerRD : : STAGE_FRAGMENT ;
actions . entry_point_stages [ " light " ] = ShaderCompilerRD : : STAGE_FRAGMENT ;
actions . render_mode_values [ " blend_add " ] = Pair < int * , int > ( & blend_mode , BLEND_MODE_ADD ) ;
actions . render_mode_values [ " blend_mix " ] = Pair < int * , int > ( & blend_mode , BLEND_MODE_MIX ) ;
actions . render_mode_values [ " blend_sub " ] = Pair < int * , int > ( & blend_mode , BLEND_MODE_SUB ) ;
actions . render_mode_values [ " blend_mul " ] = Pair < int * , int > ( & blend_mode , BLEND_MODE_MUL ) ;
actions . render_mode_values [ " alpha_to_coverage " ] = Pair < int * , int > ( & alpha_antialiasing_mode , ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE ) ;
actions . render_mode_values [ " alpha_to_coverage_and_one " ] = Pair < int * , int > ( & alpha_antialiasing_mode , ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE ) ;
actions . render_mode_values [ " depth_draw_never " ] = Pair < int * , int > ( & depth_drawi , DEPTH_DRAW_DISABLED ) ;
actions . render_mode_values [ " depth_draw_opaque " ] = Pair < int * , int > ( & depth_drawi , DEPTH_DRAW_OPAQUE ) ;
actions . render_mode_values [ " depth_draw_always " ] = Pair < int * , int > ( & depth_drawi , DEPTH_DRAW_ALWAYS ) ;
actions . render_mode_values [ " depth_test_disabled " ] = Pair < int * , int > ( & depth_testi , DEPTH_TEST_DISABLED ) ;
actions . render_mode_values [ " cull_disabled " ] = Pair < int * , int > ( & cull , CULL_DISABLED ) ;
actions . render_mode_values [ " cull_front " ] = Pair < int * , int > ( & cull , CULL_FRONT ) ;
actions . render_mode_values [ " cull_back " ] = Pair < int * , int > ( & cull , CULL_BACK ) ;
actions . render_mode_flags [ " unshaded " ] = & unshaded ;
actions . render_mode_flags [ " wireframe " ] = & wireframe ;
actions . render_mode_flags [ " particle_trails " ] = & uses_particle_trails ;
actions . usage_flag_pointers [ " ALPHA " ] = & uses_alpha ;
actions . render_mode_flags [ " depth_prepass_alpha " ] = & uses_depth_pre_pass ;
// actions.usage_flag_pointers["SSS_STRENGTH"] = &uses_sss;
// actions.usage_flag_pointers["SSS_TRANSMITTANCE_DEPTH"] = &uses_transmittance;
actions . usage_flag_pointers [ " SCREEN_TEXTURE " ] = & uses_screen_texture ;
actions . usage_flag_pointers [ " DEPTH_TEXTURE " ] = & uses_depth_texture ;
actions . usage_flag_pointers [ " NORMAL_TEXTURE " ] = & uses_normal_texture ;
actions . usage_flag_pointers [ " DISCARD " ] = & uses_discard ;
actions . usage_flag_pointers [ " TIME " ] = & uses_time ;
actions . usage_flag_pointers [ " ROUGHNESS " ] = & uses_roughness ;
actions . usage_flag_pointers [ " NORMAL " ] = & uses_normal ;
actions . usage_flag_pointers [ " NORMAL_MAP " ] = & uses_normal ;
actions . usage_flag_pointers [ " POINT_SIZE " ] = & uses_point_size ;
actions . usage_flag_pointers [ " POINT_COORD " ] = & uses_point_size ;
actions . write_flag_pointers [ " MODELVIEW_MATRIX " ] = & writes_modelview_or_projection ;
actions . write_flag_pointers [ " PROJECTION_MATRIX " ] = & writes_modelview_or_projection ;
actions . write_flag_pointers [ " VERTEX " ] = & uses_vertex ;
actions . uniforms = & uniforms ;
SceneShaderForwardMobile * shader_singleton = ( SceneShaderForwardMobile * ) SceneShaderForwardMobile : : singleton ;
Error err = shader_singleton - > compiler . compile ( RS : : SHADER_SPATIAL , code , & actions , path , gen_code ) ;
ERR_FAIL_COND ( err ! = OK ) ;
if ( version . is_null ( ) ) {
version = shader_singleton - > shader . version_create ( ) ;
}
depth_draw = DepthDraw ( depth_drawi ) ;
depth_test = DepthTest ( depth_testi ) ;
#if 0
print_line ( " **compiling shader: " ) ;
print_line ( " **defines: \n " ) ;
for ( int i = 0 ; i < gen_code . defines . size ( ) ; i + + ) {
print_line ( gen_code . defines [ i ] ) ;
}
Map < String , String > : : Element * el = gen_code . code . front ( ) ;
while ( el ) {
print_line ( " \n **code " + el - > key ( ) + " : \n " + el - > value ( ) ) ;
el = el - > next ( ) ;
}
print_line ( " \n **uniforms: \n " + gen_code . uniforms ) ;
print_line ( " \n **vertex_globals: \n " + gen_code . stage_globals [ ShaderCompilerRD : : STAGE_VERTEX ] ) ;
print_line ( " \n **fragment_globals: \n " + gen_code . stage_globals [ ShaderCompilerRD : : STAGE_FRAGMENT ] ) ;
# endif
shader_singleton - > shader . version_set_code ( version , gen_code . code , gen_code . uniforms , gen_code . stage_globals [ ShaderCompilerRD : : STAGE_VERTEX ] , gen_code . stage_globals [ ShaderCompilerRD : : STAGE_FRAGMENT ] , gen_code . defines ) ;
ERR_FAIL_COND ( ! shader_singleton - > shader . version_is_valid ( version ) ) ;
ubo_size = gen_code . uniform_total_size ;
ubo_offsets = gen_code . uniform_offsets ;
texture_uniforms = gen_code . texture_uniforms ;
//blend modes
// if any form of Alpha Antialiasing is enabled, set the blend mode to alpha to coverage
if ( alpha_antialiasing_mode ! = ALPHA_ANTIALIASING_OFF ) {
blend_mode = BLEND_MODE_ALPHA_TO_COVERAGE ;
}
RD : : PipelineColorBlendState : : Attachment blend_attachment ;
switch ( blend_mode ) {
case BLEND_MODE_MIX : {
blend_attachment . enable_blend = true ;
blend_attachment . alpha_blend_op = RD : : BLEND_OP_ADD ;
blend_attachment . color_blend_op = RD : : BLEND_OP_ADD ;
blend_attachment . src_color_blend_factor = RD : : BLEND_FACTOR_SRC_ALPHA ;
blend_attachment . dst_color_blend_factor = RD : : BLEND_FACTOR_ONE_MINUS_SRC_ALPHA ;
blend_attachment . src_alpha_blend_factor = RD : : BLEND_FACTOR_ONE ;
blend_attachment . dst_alpha_blend_factor = RD : : BLEND_FACTOR_ONE_MINUS_SRC_ALPHA ;
} break ;
case BLEND_MODE_ADD : {
blend_attachment . enable_blend = true ;
blend_attachment . alpha_blend_op = RD : : BLEND_OP_ADD ;
blend_attachment . color_blend_op = RD : : BLEND_OP_ADD ;
blend_attachment . src_color_blend_factor = RD : : BLEND_FACTOR_SRC_ALPHA ;
blend_attachment . dst_color_blend_factor = RD : : BLEND_FACTOR_ONE ;
blend_attachment . src_alpha_blend_factor = RD : : BLEND_FACTOR_SRC_ALPHA ;
blend_attachment . dst_alpha_blend_factor = RD : : BLEND_FACTOR_ONE ;
uses_blend_alpha = true ; //force alpha used because of blend
} break ;
case BLEND_MODE_SUB : {
blend_attachment . enable_blend = true ;
blend_attachment . alpha_blend_op = RD : : BLEND_OP_SUBTRACT ;
blend_attachment . color_blend_op = RD : : BLEND_OP_SUBTRACT ;
blend_attachment . src_color_blend_factor = RD : : BLEND_FACTOR_SRC_ALPHA ;
blend_attachment . dst_color_blend_factor = RD : : BLEND_FACTOR_ONE ;
blend_attachment . src_alpha_blend_factor = RD : : BLEND_FACTOR_SRC_ALPHA ;
blend_attachment . dst_alpha_blend_factor = RD : : BLEND_FACTOR_ONE ;
uses_blend_alpha = true ; //force alpha used because of blend
} break ;
case BLEND_MODE_MUL : {
blend_attachment . enable_blend = true ;
blend_attachment . alpha_blend_op = RD : : BLEND_OP_ADD ;
blend_attachment . color_blend_op = RD : : BLEND_OP_ADD ;
blend_attachment . src_color_blend_factor = RD : : BLEND_FACTOR_DST_COLOR ;
blend_attachment . dst_color_blend_factor = RD : : BLEND_FACTOR_ZERO ;
blend_attachment . src_alpha_blend_factor = RD : : BLEND_FACTOR_DST_ALPHA ;
blend_attachment . dst_alpha_blend_factor = RD : : BLEND_FACTOR_ZERO ;
uses_blend_alpha = true ; //force alpha used because of blend
} break ;
case BLEND_MODE_ALPHA_TO_COVERAGE : {
blend_attachment . enable_blend = true ;
blend_attachment . alpha_blend_op = RD : : BLEND_OP_ADD ;
blend_attachment . color_blend_op = RD : : BLEND_OP_ADD ;
blend_attachment . src_color_blend_factor = RD : : BLEND_FACTOR_SRC_ALPHA ;
blend_attachment . dst_color_blend_factor = RD : : BLEND_FACTOR_ONE_MINUS_SRC_ALPHA ;
blend_attachment . src_alpha_blend_factor = RD : : BLEND_FACTOR_ONE ;
blend_attachment . dst_alpha_blend_factor = RD : : BLEND_FACTOR_ZERO ;
}
}
RD : : PipelineColorBlendState blend_state_blend ;
blend_state_blend . attachments . push_back ( blend_attachment ) ;
RD : : PipelineColorBlendState blend_state_opaque = RD : : PipelineColorBlendState : : create_disabled ( 1 ) ;
RD : : PipelineColorBlendState blend_state_opaque_specular = RD : : PipelineColorBlendState : : create_disabled ( 2 ) ;
RD : : PipelineColorBlendState blend_state_depth_normal_roughness = RD : : PipelineColorBlendState : : create_disabled ( 1 ) ;
RD : : PipelineColorBlendState blend_state_depth_normal_roughness_giprobe = RD : : PipelineColorBlendState : : create_disabled ( 2 ) ;
//update pipelines
RD : : PipelineDepthStencilState depth_stencil_state ;
if ( depth_test ! = DEPTH_TEST_DISABLED ) {
depth_stencil_state . enable_depth_test = true ;
depth_stencil_state . depth_compare_operator = RD : : COMPARE_OP_LESS_OR_EQUAL ;
depth_stencil_state . enable_depth_write = depth_draw ! = DEPTH_DRAW_DISABLED ? true : false ;
}
for ( int i = 0 ; i < CULL_VARIANT_MAX ; i + + ) {
RD : : PolygonCullMode cull_mode_rd_table [ CULL_VARIANT_MAX ] [ 3 ] = {
{ RD : : POLYGON_CULL_DISABLED , RD : : POLYGON_CULL_FRONT , RD : : POLYGON_CULL_BACK } ,
{ RD : : POLYGON_CULL_DISABLED , RD : : POLYGON_CULL_BACK , RD : : POLYGON_CULL_FRONT } ,
{ RD : : POLYGON_CULL_DISABLED , RD : : POLYGON_CULL_DISABLED , RD : : POLYGON_CULL_DISABLED }
} ;
RD : : PolygonCullMode cull_mode_rd = cull_mode_rd_table [ i ] [ cull ] ;
for ( int j = 0 ; j < RS : : PRIMITIVE_MAX ; j + + ) {
RD : : RenderPrimitive primitive_rd_table [ RS : : PRIMITIVE_MAX ] = {
RD : : RENDER_PRIMITIVE_POINTS ,
RD : : RENDER_PRIMITIVE_LINES ,
RD : : RENDER_PRIMITIVE_LINESTRIPS ,
RD : : RENDER_PRIMITIVE_TRIANGLES ,
RD : : RENDER_PRIMITIVE_TRIANGLE_STRIPS ,
} ;
RD : : RenderPrimitive primitive_rd = uses_point_size ? RD : : RENDER_PRIMITIVE_POINTS : primitive_rd_table [ j ] ;
for ( int k = 0 ; k < SHADER_VERSION_MAX ; k + + ) {
if ( ! static_cast < SceneShaderForwardMobile * > ( singleton ) - > shader . is_variant_enabled ( k ) ) {
continue ;
}
RD : : PipelineRasterizationState raster_state ;
raster_state . cull_mode = cull_mode_rd ;
raster_state . wireframe = wireframe ;
RD : : PipelineColorBlendState blend_state ;
RD : : PipelineDepthStencilState depth_stencil = depth_stencil_state ;
RD : : PipelineMultisampleState multisample_state ;
if ( uses_alpha | | uses_blend_alpha ) {
// only allow these flags to go through if we have some form of msaa
if ( alpha_antialiasing_mode = = ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE ) {
multisample_state . enable_alpha_to_coverage = true ;
} else if ( alpha_antialiasing_mode = = ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE ) {
multisample_state . enable_alpha_to_coverage = true ;
multisample_state . enable_alpha_to_one = true ;
}
2021-05-07 15:19:04 +02:00
if ( k = = SHADER_VERSION_COLOR_PASS | | k = = SHADER_VERSION_COLOR_PASS_MULTIVIEW | | k = = SHADER_VERSION_LIGHTMAP_COLOR_PASS | | k = = SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW ) {
2021-03-10 12:23:55 +01:00
blend_state = blend_state_blend ;
if ( depth_draw = = DEPTH_DRAW_OPAQUE ) {
depth_stencil . enable_depth_write = false ; //alpha does not draw depth
}
2021-05-07 15:19:04 +02:00
} else if ( k = = SHADER_VERSION_SHADOW_PASS | | k = = SHADER_VERSION_SHADOW_PASS_MULTIVIEW | | k = = SHADER_VERSION_SHADOW_PASS_DP ) {
2021-03-10 12:23:55 +01:00
//none, blend state contains nothing
} else if ( k = = SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL ) {
blend_state = RD : : PipelineColorBlendState : : create_disabled ( 5 ) ; //writes to normal and roughness in opaque way
} else {
pipelines [ i ] [ j ] [ k ] . clear ( ) ;
continue ; // do not use this version (will error if using it is attempted)
}
} else {
2021-05-07 15:19:04 +02:00
if ( k = = SHADER_VERSION_COLOR_PASS | | k = = SHADER_VERSION_COLOR_PASS_MULTIVIEW | | k = = SHADER_VERSION_LIGHTMAP_COLOR_PASS | | k = = SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW ) {
2021-03-10 12:23:55 +01:00
blend_state = blend_state_opaque ;
2021-05-07 15:19:04 +02:00
} else if ( k = = SHADER_VERSION_SHADOW_PASS | | k = = SHADER_VERSION_SHADOW_PASS_MULTIVIEW | | k = = SHADER_VERSION_SHADOW_PASS_DP ) {
2021-03-10 12:23:55 +01:00
//none, leave empty
} else if ( k = = SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL ) {
blend_state = RD : : PipelineColorBlendState : : create_disabled ( 5 ) ; //writes to normal and roughness in opaque way
} else {
// ???
}
}
RID shader_variant = shader_singleton - > shader . version_get_shader ( version , k ) ;
pipelines [ i ] [ j ] [ k ] . setup ( shader_variant , primitive_rd , raster_state , multisample_state , depth_stencil , blend_state , 0 ) ;
}
}
}
valid = true ;
}
void SceneShaderForwardMobile : : ShaderData : : set_default_texture_param ( const StringName & p_name , RID p_texture ) {
if ( ! p_texture . is_valid ( ) ) {
default_texture_params . erase ( p_name ) ;
} else {
default_texture_params [ p_name ] = p_texture ;
}
}
void SceneShaderForwardMobile : : ShaderData : : get_param_list ( List < PropertyInfo > * p_param_list ) const {
Map < int , StringName > order ;
for ( Map < StringName , ShaderLanguage : : ShaderNode : : Uniform > : : Element * E = uniforms . front ( ) ; E ; E = E - > next ( ) ) {
if ( E - > get ( ) . scope ! = ShaderLanguage : : ShaderNode : : Uniform : : SCOPE_LOCAL ) {
continue ;
}
if ( E - > get ( ) . texture_order > = 0 ) {
order [ E - > get ( ) . texture_order + 100000 ] = E - > key ( ) ;
} else {
order [ E - > get ( ) . order ] = E - > key ( ) ;
}
}
for ( Map < int , StringName > : : Element * E = order . front ( ) ; E ; E = E - > next ( ) ) {
PropertyInfo pi = ShaderLanguage : : uniform_to_property_info ( uniforms [ E - > get ( ) ] ) ;
pi . name = E - > get ( ) ;
p_param_list - > push_back ( pi ) ;
}
}
void SceneShaderForwardMobile : : ShaderData : : get_instance_param_list ( List < RendererStorage : : InstanceShaderParam > * p_param_list ) const {
for ( Map < StringName , ShaderLanguage : : ShaderNode : : Uniform > : : Element * E = uniforms . front ( ) ; E ; E = E - > next ( ) ) {
if ( E - > get ( ) . scope ! = ShaderLanguage : : ShaderNode : : Uniform : : SCOPE_INSTANCE ) {
continue ;
}
RendererStorage : : InstanceShaderParam p ;
p . info = ShaderLanguage : : uniform_to_property_info ( E - > get ( ) ) ;
p . info . name = E - > key ( ) ; //supply name
p . index = E - > get ( ) . instance_index ;
p . default_value = ShaderLanguage : : constant_value_to_variant ( E - > get ( ) . default_value , E - > get ( ) . type , E - > get ( ) . hint ) ;
p_param_list - > push_back ( p ) ;
}
}
bool SceneShaderForwardMobile : : ShaderData : : is_param_texture ( const StringName & p_param ) const {
if ( ! uniforms . has ( p_param ) ) {
return false ;
}
return uniforms [ p_param ] . texture_order > = 0 ;
}
bool SceneShaderForwardMobile : : ShaderData : : is_animated ( ) const {
return false ;
}
bool SceneShaderForwardMobile : : ShaderData : : casts_shadows ( ) const {
return false ;
}
Variant SceneShaderForwardMobile : : ShaderData : : get_default_parameter ( const StringName & p_parameter ) const {
if ( uniforms . has ( p_parameter ) ) {
ShaderLanguage : : ShaderNode : : Uniform uniform = uniforms [ p_parameter ] ;
Vector < ShaderLanguage : : ConstantNode : : Value > default_value = uniform . default_value ;
return ShaderLanguage : : constant_value_to_variant ( default_value , uniform . type , uniform . hint ) ;
}
return Variant ( ) ;
}
RS : : ShaderNativeSourceCode SceneShaderForwardMobile : : ShaderData : : get_native_source_code ( ) const {
SceneShaderForwardMobile * shader_singleton = ( SceneShaderForwardMobile * ) SceneShaderForwardMobile : : singleton ;
return shader_singleton - > shader . version_get_native_source_code ( version ) ;
}
SceneShaderForwardMobile : : ShaderData : : ShaderData ( ) {
valid = false ;
uses_screen_texture = false ;
}
SceneShaderForwardMobile : : ShaderData : : ~ ShaderData ( ) {
SceneShaderForwardMobile * shader_singleton = ( SceneShaderForwardMobile * ) SceneShaderForwardMobile : : singleton ;
ERR_FAIL_COND ( ! shader_singleton ) ;
//pipeline variants will clear themselves if shader is gone
if ( version . is_valid ( ) ) {
shader_singleton - > shader . version_free ( version ) ;
}
}
RendererStorageRD : : ShaderData * SceneShaderForwardMobile : : _create_shader_func ( ) {
ShaderData * shader_data = memnew ( ShaderData ) ;
return shader_data ;
}
void SceneShaderForwardMobile : : MaterialData : : set_render_priority ( int p_priority ) {
priority = p_priority - RS : : MATERIAL_RENDER_PRIORITY_MIN ; //8 bits
}
void SceneShaderForwardMobile : : MaterialData : : set_next_pass ( RID p_pass ) {
next_pass = p_pass ;
}
2021-07-06 23:56:28 +02:00
bool SceneShaderForwardMobile : : MaterialData : : update_parameters ( const Map < StringName , Variant > & p_parameters , bool p_uniform_dirty , bool p_textures_dirty ) {
2021-03-10 12:23:55 +01:00
SceneShaderForwardMobile * shader_singleton = ( SceneShaderForwardMobile * ) SceneShaderForwardMobile : : singleton ;
2021-07-06 23:56:28 +02:00
return update_parameters_uniform_set ( p_parameters , p_uniform_dirty , p_textures_dirty , shader_data - > uniforms , shader_data - > ubo_offsets . ptr ( ) , shader_data - > texture_uniforms , shader_data - > default_texture_params , shader_data - > ubo_size , uniform_set , shader_singleton - > shader . version_get_shader ( shader_data - > version , 0 ) , RenderForwardMobile : : MATERIAL_UNIFORM_SET , RD : : BARRIER_MASK_RASTER ) ;
2021-03-10 12:23:55 +01:00
}
SceneShaderForwardMobile : : MaterialData : : ~ MaterialData ( ) {
2021-07-08 00:55:20 +02:00
free_parameters_uniform_set ( uniform_set ) ;
2021-03-10 12:23:55 +01:00
}
RendererStorageRD : : MaterialData * SceneShaderForwardMobile : : _create_material_func ( ShaderData * p_shader ) {
MaterialData * material_data = memnew ( MaterialData ) ;
material_data - > shader_data = p_shader ;
material_data - > last_frame = false ;
//update will happen later anyway so do nothing.
return material_data ;
}
/* Scene Shader */
SceneShaderForwardMobile * SceneShaderForwardMobile : : singleton = nullptr ;
SceneShaderForwardMobile : : SceneShaderForwardMobile ( ) {
// there should be only one of these, contained within our RenderForwardMobile singleton.
singleton = this ;
}
void SceneShaderForwardMobile : : init ( RendererStorageRD * p_storage , const String p_defines ) {
storage = p_storage ;
/* SCENE SHADER */
{
Vector < String > shader_versions ;
shader_versions . push_back ( " " ) ; // SHADER_VERSION_COLOR_PASS
shader_versions . push_back ( " \n #define USE_LIGHTMAP \n " ) ; // SHADER_VERSION_LIGHTMAP_COLOR_PASS
2021-05-07 15:19:04 +02:00
shader_versions . push_back ( " \n #define MODE_RENDER_DEPTH \n " ) ; // SHADER_VERSION_SHADOW_PASS, should probably change this to MODE_RENDER_SHADOW because we don't have a depth pass here...
shader_versions . push_back ( " \n #define MODE_RENDER_DEPTH \n #define MODE_DUAL_PARABOLOID \n " ) ; // SHADER_VERSION_SHADOW_PASS_DP
2021-03-10 12:23:55 +01:00
shader_versions . push_back ( " \n #define MODE_RENDER_DEPTH \n #define MODE_RENDER_MATERIAL \n " ) ; // SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL
2021-05-07 15:19:04 +02:00
// multiview versions of our shaders
shader_versions . push_back ( " \n #define USE_MULTIVIEW \n " ) ; // SHADER_VERSION_COLOR_PASS_MULTIVIEW
shader_versions . push_back ( " \n #define USE_MULTIVIEW \n #define USE_LIGHTMAP \n " ) ; // SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW
shader_versions . push_back ( " \n #define USE_MULTIVIEW \n #define MODE_RENDER_DEPTH \n " ) ; // SHADER_VERSION_SHADOW_PASS_MULTIVIEW
2021-03-10 12:23:55 +01:00
shader . initialize ( shader_versions , p_defines ) ;
2021-05-07 15:19:04 +02:00
if ( ! RendererCompositorRD : : singleton - > is_xr_enabled ( ) ) {
shader . set_variant_enabled ( SHADER_VERSION_COLOR_PASS_MULTIVIEW , false ) ;
shader . set_variant_enabled ( SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW , false ) ;
shader . set_variant_enabled ( SHADER_VERSION_SHADOW_PASS_MULTIVIEW , false ) ;
}
2021-03-10 12:23:55 +01:00
}
storage - > shader_set_data_request_function ( RendererStorageRD : : SHADER_TYPE_3D , _create_shader_funcs ) ;
storage - > material_set_data_request_function ( RendererStorageRD : : SHADER_TYPE_3D , _create_material_funcs ) ;
{
//shader compiler
ShaderCompilerRD : : DefaultIdentifierActions actions ;
actions . renames [ " WORLD_MATRIX " ] = " world_matrix " ;
actions . renames [ " WORLD_NORMAL_MATRIX " ] = " world_normal_matrix " ;
actions . renames [ " INV_CAMERA_MATRIX " ] = " scene_data.inv_camera_matrix " ;
actions . renames [ " CAMERA_MATRIX " ] = " scene_data.camera_matrix " ;
actions . renames [ " PROJECTION_MATRIX " ] = " projection_matrix " ;
2021-05-07 15:19:04 +02:00
actions . renames [ " INV_PROJECTION_MATRIX " ] = " inv_projection_matrix " ;
2021-03-10 12:23:55 +01:00
actions . renames [ " MODELVIEW_MATRIX " ] = " modelview " ;
actions . renames [ " MODELVIEW_NORMAL_MATRIX " ] = " modelview_normal " ;
actions . renames [ " VERTEX " ] = " vertex " ;
actions . renames [ " NORMAL " ] = " normal " ;
actions . renames [ " TANGENT " ] = " tangent " ;
actions . renames [ " BINORMAL " ] = " binormal " ;
actions . renames [ " POSITION " ] = " position " ;
actions . renames [ " UV " ] = " uv_interp " ;
actions . renames [ " UV2 " ] = " uv2_interp " ;
actions . renames [ " COLOR " ] = " color_interp " ;
actions . renames [ " POINT_SIZE " ] = " gl_PointSize " ;
actions . renames [ " INSTANCE_ID " ] = " gl_InstanceIndex " ;
actions . renames [ " ALPHA_SCISSOR_THRESHOLD " ] = " alpha_scissor_threshold " ;
actions . renames [ " ALPHA_HASH_SCALE " ] = " alpha_hash_scale " ;
actions . renames [ " ALPHA_ANTIALIASING_EDGE " ] = " alpha_antialiasing_edge " ;
actions . renames [ " ALPHA_TEXTURE_COORDINATE " ] = " alpha_texture_coordinate " ;
//builtins
actions . renames [ " TIME " ] = " scene_data.time " ;
2021-05-19 14:12:55 +02:00
actions . renames [ " PI " ] = _MKSTR ( Math_PI ) ;
actions . renames [ " TAU " ] = _MKSTR ( Math_TAU ) ;
actions . renames [ " E " ] = _MKSTR ( Math_E ) ;
2021-03-10 12:23:55 +01:00
actions . renames [ " VIEWPORT_SIZE " ] = " scene_data.viewport_size " ;
actions . renames [ " FRAGCOORD " ] = " gl_FragCoord " ;
actions . renames [ " FRONT_FACING " ] = " gl_FrontFacing " ;
actions . renames [ " NORMAL_MAP " ] = " normal_map " ;
actions . renames [ " NORMAL_MAP_DEPTH " ] = " normal_map_depth " ;
actions . renames [ " ALBEDO " ] = " albedo " ;
actions . renames [ " ALPHA " ] = " alpha " ;
actions . renames [ " METALLIC " ] = " metallic " ;
actions . renames [ " SPECULAR " ] = " specular " ;
actions . renames [ " ROUGHNESS " ] = " roughness " ;
actions . renames [ " RIM " ] = " rim " ;
actions . renames [ " RIM_TINT " ] = " rim_tint " ;
actions . renames [ " CLEARCOAT " ] = " clearcoat " ;
actions . renames [ " CLEARCOAT_GLOSS " ] = " clearcoat_gloss " ;
actions . renames [ " ANISOTROPY " ] = " anisotropy " ;
actions . renames [ " ANISOTROPY_FLOW " ] = " anisotropy_flow " ;
actions . renames [ " SSS_STRENGTH " ] = " sss_strength " ;
actions . renames [ " SSS_TRANSMITTANCE_COLOR " ] = " transmittance_color " ;
actions . renames [ " SSS_TRANSMITTANCE_DEPTH " ] = " transmittance_depth " ;
actions . renames [ " SSS_TRANSMITTANCE_BOOST " ] = " transmittance_boost " ;
actions . renames [ " BACKLIGHT " ] = " backlight " ;
actions . renames [ " AO " ] = " ao " ;
actions . renames [ " AO_LIGHT_AFFECT " ] = " ao_light_affect " ;
actions . renames [ " EMISSION " ] = " emission " ;
actions . renames [ " POINT_COORD " ] = " gl_PointCoord " ;
actions . renames [ " INSTANCE_CUSTOM " ] = " instance_custom " ;
actions . renames [ " SCREEN_UV " ] = " screen_uv " ;
actions . renames [ " SCREEN_TEXTURE " ] = " color_buffer " ;
actions . renames [ " DEPTH_TEXTURE " ] = " depth_buffer " ;
actions . renames [ " NORMAL_ROUGHNESS_TEXTURE " ] = " normal_roughness_buffer " ;
actions . renames [ " DEPTH " ] = " gl_FragDepth " ;
actions . renames [ " OUTPUT_IS_SRGB " ] = " true " ;
actions . renames [ " FOG " ] = " custom_fog " ;
actions . renames [ " RADIANCE " ] = " custom_radiance " ;
actions . renames [ " IRRADIANCE " ] = " custom_irradiance " ;
actions . renames [ " BONE_INDICES " ] = " bone_attrib " ;
actions . renames [ " BONE_WEIGHTS " ] = " weight_attrib " ;
actions . renames [ " CUSTOM0 " ] = " custom0_attrib " ;
actions . renames [ " CUSTOM1 " ] = " custom1_attrib " ;
actions . renames [ " CUSTOM2 " ] = " custom2_attrib " ;
actions . renames [ " CUSTOM3 " ] = " custom3_attrib " ;
2021-05-07 15:19:04 +02:00
actions . renames [ " VIEW_INDEX " ] = " ViewIndex " ;
actions . renames [ " VIEW_MONO_LEFT " ] = " 0 " ;
actions . renames [ " VIEW_RIGHT " ] = " 1 " ;
2021-03-10 12:23:55 +01:00
//for light
actions . renames [ " VIEW " ] = " view " ;
actions . renames [ " LIGHT_COLOR " ] = " light_color " ;
actions . renames [ " LIGHT " ] = " light " ;
actions . renames [ " ATTENUATION " ] = " attenuation " ;
actions . renames [ " SHADOW_ATTENUATION " ] = " shadow_attenuation " ;
actions . renames [ " DIFFUSE_LIGHT " ] = " diffuse_light " ;
actions . renames [ " SPECULAR_LIGHT " ] = " specular_light " ;
actions . usage_defines [ " NORMAL " ] = " #define NORMAL_USED \n " ;
actions . usage_defines [ " TANGENT " ] = " #define TANGENT_USED \n " ;
actions . usage_defines [ " BINORMAL " ] = " @TANGENT " ;
actions . usage_defines [ " RIM " ] = " #define LIGHT_RIM_USED \n " ;
actions . usage_defines [ " RIM_TINT " ] = " @RIM " ;
actions . usage_defines [ " CLEARCOAT " ] = " #define LIGHT_CLEARCOAT_USED \n " ;
actions . usage_defines [ " CLEARCOAT_GLOSS " ] = " @CLEARCOAT " ;
actions . usage_defines [ " ANISOTROPY " ] = " #define LIGHT_ANISOTROPY_USED \n " ;
actions . usage_defines [ " ANISOTROPY_FLOW " ] = " @ANISOTROPY " ;
actions . usage_defines [ " AO " ] = " #define AO_USED \n " ;
actions . usage_defines [ " AO_LIGHT_AFFECT " ] = " #define AO_USED \n " ;
actions . usage_defines [ " UV " ] = " #define UV_USED \n " ;
actions . usage_defines [ " UV2 " ] = " #define UV2_USED \n " ;
actions . usage_defines [ " BONE_INDICES " ] = " #define BONES_USED \n " ;
actions . usage_defines [ " BONE_WEIGHTS " ] = " #define WEIGHTS_USED \n " ;
actions . usage_defines [ " CUSTOM0 " ] = " #define CUSTOM0 \n " ;
actions . usage_defines [ " CUSTOM1 " ] = " #define CUSTOM1 \n " ;
actions . usage_defines [ " CUSTOM2 " ] = " #define CUSTOM2 \n " ;
actions . usage_defines [ " CUSTOM3 " ] = " #define CUSTOM3 \n " ;
actions . usage_defines [ " NORMAL_MAP " ] = " #define NORMAL_MAP_USED \n " ;
actions . usage_defines [ " NORMAL_MAP_DEPTH " ] = " @NORMAL_MAP " ;
actions . usage_defines [ " COLOR " ] = " #define COLOR_USED \n " ;
actions . usage_defines [ " INSTANCE_CUSTOM " ] = " #define ENABLE_INSTANCE_CUSTOM \n " ;
actions . usage_defines [ " POSITION " ] = " #define OVERRIDE_POSITION \n " ;
actions . usage_defines [ " ALPHA_SCISSOR_THRESHOLD " ] = " #define ALPHA_SCISSOR_USED \n " ;
actions . usage_defines [ " ALPHA_HASH_SCALE " ] = " #define ALPHA_HASH_USED \n " ;
actions . usage_defines [ " ALPHA_ANTIALIASING_EDGE " ] = " #define ALPHA_ANTIALIASING_EDGE_USED \n " ;
actions . usage_defines [ " ALPHA_TEXTURE_COORDINATE " ] = " @ALPHA_ANTIALIASING_EDGE " ;
actions . usage_defines [ " SSS_STRENGTH " ] = " #define ENABLE_SSS \n " ;
actions . usage_defines [ " SSS_TRANSMITTANCE_DEPTH " ] = " #define ENABLE_TRANSMITTANCE \n " ;
actions . usage_defines [ " BACKLIGHT " ] = " #define LIGHT_BACKLIGHT_USED \n " ;
actions . usage_defines [ " SCREEN_TEXTURE " ] = " #define SCREEN_TEXTURE_USED \n " ;
actions . usage_defines [ " SCREEN_UV " ] = " #define SCREEN_UV_USED \n " ;
actions . usage_defines [ " DIFFUSE_LIGHT " ] = " #define USE_LIGHT_SHADER_CODE \n " ;
actions . usage_defines [ " SPECULAR_LIGHT " ] = " #define USE_LIGHT_SHADER_CODE \n " ;
actions . usage_defines [ " FOG " ] = " #define CUSTOM_FOG_USED \n " ;
actions . usage_defines [ " RADIANCE " ] = " #define CUSTOM_RADIANCE_USED \n " ;
actions . usage_defines [ " IRRADIANCE " ] = " #define CUSTOM_IRRADIANCE_USED \n " ;
actions . render_mode_defines [ " skip_vertex_transform " ] = " #define SKIP_TRANSFORM_USED \n " ;
actions . render_mode_defines [ " world_vertex_coords " ] = " #define VERTEX_WORLD_COORDS_USED \n " ;
actions . render_mode_defines [ " ensure_correct_normals " ] = " #define ENSURE_CORRECT_NORMALS \n " ;
actions . render_mode_defines [ " cull_front " ] = " #define DO_SIDE_CHECK \n " ;
actions . render_mode_defines [ " cull_disabled " ] = " #define DO_SIDE_CHECK \n " ;
actions . render_mode_defines [ " particle_trails " ] = " #define USE_PARTICLE_TRAILS \n " ;
bool force_lambert = GLOBAL_GET ( " rendering/shading/overrides/force_lambert_over_burley " ) ;
if ( ! force_lambert ) {
actions . render_mode_defines [ " diffuse_burley " ] = " #define DIFFUSE_BURLEY \n " ;
}
actions . render_mode_defines [ " diffuse_lambert_wrap " ] = " #define DIFFUSE_LAMBERT_WRAP \n " ;
actions . render_mode_defines [ " diffuse_toon " ] = " #define DIFFUSE_TOON \n " ;
actions . render_mode_defines [ " sss_mode_skin " ] = " #define SSS_MODE_SKIN \n " ;
bool force_blinn = GLOBAL_GET ( " rendering/shading/overrides/force_blinn_over_ggx " ) ;
if ( ! force_blinn ) {
actions . render_mode_defines [ " specular_schlick_ggx " ] = " #define SPECULAR_SCHLICK_GGX \n " ;
} else {
actions . render_mode_defines [ " specular_schlick_ggx " ] = " #define SPECULAR_BLINN \n " ;
}
actions . render_mode_defines [ " specular_blinn " ] = " #define SPECULAR_BLINN \n " ;
actions . render_mode_defines [ " specular_phong " ] = " #define SPECULAR_PHONG \n " ;
actions . render_mode_defines [ " specular_toon " ] = " #define SPECULAR_TOON \n " ;
actions . render_mode_defines [ " specular_disabled " ] = " #define SPECULAR_DISABLED \n " ;
actions . render_mode_defines [ " shadows_disabled " ] = " #define SHADOWS_DISABLED \n " ;
actions . render_mode_defines [ " ambient_light_disabled " ] = " #define AMBIENT_LIGHT_DISABLED \n " ;
actions . render_mode_defines [ " shadow_to_opacity " ] = " #define USE_SHADOW_TO_OPACITY \n " ;
actions . render_mode_defines [ " unshaded " ] = " #define MODE_UNSHADED \n " ;
actions . sampler_array_name = " material_samplers " ;
actions . base_texture_binding_index = 1 ;
actions . texture_layout_set = RenderForwardMobile : : MATERIAL_UNIFORM_SET ;
actions . base_uniform_string = " material. " ;
actions . base_varying_index = 10 ;
actions . default_filter = ShaderLanguage : : FILTER_LINEAR_MIPMAP ;
actions . default_repeat = ShaderLanguage : : REPEAT_ENABLE ;
actions . global_buffer_array_variable = " global_variables.data " ;
actions . instance_uniform_index_variable = " draw_call.instance_uniforms_ofs " ;
compiler . initialize ( actions ) ;
}
{
//default material and shader
default_shader = storage - > shader_allocate ( ) ;
storage - > shader_initialize ( default_shader ) ;
storage - > shader_set_code ( default_shader , " shader_type spatial; void vertex() { ROUGHNESS = 0.8; } void fragment() { ALBEDO=vec3(0.6); ROUGHNESS=0.8; METALLIC=0.2; } \n " ) ;
default_material = storage - > material_allocate ( ) ;
storage - > material_initialize ( default_material ) ;
storage - > material_set_shader ( default_material , default_shader ) ;
MaterialData * md = ( MaterialData * ) storage - > material_get_data ( default_material , RendererStorageRD : : SHADER_TYPE_3D ) ;
default_shader_rd = shader . version_get_shader ( md - > shader_data - > version , SHADER_VERSION_COLOR_PASS ) ;
2021-07-03 19:50:36 +02:00
default_material_shader_ptr = md - > shader_data ;
default_material_uniform_set = md - > uniform_set ;
2021-03-10 12:23:55 +01:00
}
{
overdraw_material_shader = storage - > shader_allocate ( ) ;
storage - > shader_initialize ( overdraw_material_shader ) ;
2021-07-04 00:18:38 +02:00
// Use relatively low opacity so that more "layers" of overlapping objects can be distinguished.
storage - > shader_set_code ( overdraw_material_shader , " shader_type spatial; \n render_mode blend_add,unshaded; \n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.1; } " ) ;
2021-03-10 12:23:55 +01:00
overdraw_material = storage - > material_allocate ( ) ;
storage - > material_initialize ( overdraw_material ) ;
storage - > material_set_shader ( overdraw_material , overdraw_material_shader ) ;
2021-07-03 19:50:36 +02:00
MaterialData * md = ( MaterialData * ) storage - > material_get_data ( overdraw_material , RendererStorageRD : : SHADER_TYPE_3D ) ;
overdraw_material_shader_ptr = md - > shader_data ;
overdraw_material_uniform_set = md - > uniform_set ;
2021-03-10 12:23:55 +01:00
}
{
default_vec4_xform_buffer = RD : : get_singleton ( ) - > storage_buffer_create ( 256 ) ;
Vector < RD : : Uniform > uniforms ;
RD : : Uniform u ;
u . uniform_type = RD : : UNIFORM_TYPE_STORAGE_BUFFER ;
u . ids . push_back ( default_vec4_xform_buffer ) ;
u . binding = 0 ;
uniforms . push_back ( u ) ;
default_vec4_xform_uniform_set = RD : : get_singleton ( ) - > uniform_set_create ( uniforms , default_shader_rd , RenderForwardMobile : : TRANSFORMS_UNIFORM_SET ) ;
}
{
RD : : SamplerState sampler ;
sampler . mag_filter = RD : : SAMPLER_FILTER_LINEAR ;
sampler . min_filter = RD : : SAMPLER_FILTER_LINEAR ;
sampler . enable_compare = true ;
sampler . compare_op = RD : : COMPARE_OP_LESS ;
shadow_sampler = RD : : get_singleton ( ) - > sampler_create ( sampler ) ;
}
}
SceneShaderForwardMobile : : ~ SceneShaderForwardMobile ( ) {
RD : : get_singleton ( ) - > free ( default_vec4_xform_buffer ) ;
RD : : get_singleton ( ) - > free ( shadow_sampler ) ;
storage - > free ( overdraw_material_shader ) ;
storage - > free ( default_shader ) ;
storage - > free ( overdraw_material ) ;
storage - > free ( default_material ) ;
}