Warning: Undefined array key "translationlc" in /usr/www/users/fabook/_diggets/doc/v2/lib/plugins/translation/action.php on line 237

Warning: Cannot modify header information - headers already sent by (output started at /usr/www/users/fabook/_diggets/doc/v2/lib/plugins/translation/action.php:237) in /usr/www/users/fabook/_diggets/doc/v2/inc/Action/Export.php on line 104

Warning: Cannot modify header information - headers already sent by (output started at /usr/www/users/fabook/_diggets/doc/v2/lib/plugins/translation/action.php:237) in /usr/www/users/fabook/_diggets/doc/v2/inc/Action/Export.php on line 104

Warning: Cannot modify header information - headers already sent by (output started at /usr/www/users/fabook/_diggets/doc/v2/lib/plugins/translation/action.php:237) in /usr/www/users/fabook/_diggets/doc/v2/inc/Action/Export.php on line 104
====== DefaultMaterial ====== The default material is the approach to centralize basic shader operations, like: * vertex transformation * displacement mapping * handling of multiple light sources * handling of different light types: directional, spot or point light * texture tiling * normal mapping * parallax occlusion mapping * various shading models: lambert, phong, blinn-phong, PBR * plane clipping * color clipping * color computation by ambient, diffuse, specular and emissive color * point sprite rendering (particle effects) * fog * shadowing: shadow mapping or variant shadow mapping * weighted blended order independent transparency * reflection, refraction and environment mapping The simple reason is that those functionality is used in nearly all materials and should not be reinvented each time. Those operations also getting very complex in combination and its hard to keep them still efficient. ===== Node-Based Shaders ===== The default material uses a node based memory structure to build shader source code. This means that each shader (vertex- and fragmentshader) holds a nodes hierarchy from which the shader source code is generated from. Source code getting build by a TGorillaNodeBuilder instance, which each shader provides. The attached nodes are **TGorillaNodeEntity** instances or inherited from that class. When the shader is getting compiled, the **ToString()** method is getting called for each node in hierarchy. Depending on the activated defines, the node itself decides how its output code looks like. This is a very flexible way and allows to modify or replace specific nodes, to produce your own shader code. On rendering, the source code will automatically be compiled and registered in GPU. ==== Default Vertex Shader ==== The default vertex shader is setting up the following node hierarchy. Root * SourceCode [TGorillaCompositeNode] - <0> [TGorillaGLSLPragma] - Globals [TGorillaGlobalsNode] - Constants [TGorillaCompositeNode] - Types [TGorillaCompositeNode] - <0> [TGorillaGLSLLightType] // DEACTIVATED - <1> [TGorillaGLSLTextureType] // DEACTIVATED - <2> [TGorillaGLSLMaterialType] // DEACTIVATED - <3> [TGorillaGLSLPassDataType] - <4> [TGorillaGLSLVertexShaderLocalsStructNode] - Attributes [TGorillaCompositeNode] - <0> [TGorillaGLSLAttributesNode] - Uniforms [TGorillaUniformsNode] - <0> [TGorillaGLSLUBOShaderData] - Varying [TGorillaCompositeNode] - <0> [TGorillaGLSLInOutNode] - Functions [TGorillaCompositeNode] - <0> [TGorillaGLSLTransformFuncsNode] - <1> [TGorillaGLSLGetTextureFuncsNode] - <2> [TGorillaVertexShaderFuncNode] - Variables [TGorillaCompositeNode] - EntryPoint [TGorillaGLSLMainNode] - <0> [TGorillaGLSLVertexShaderLocalsNode] - <1> [TGorillaGLSLMatricesOutNode] - <2> [TGorillaGLSLGetVertexPositionNode] - <3> [TGorillaGLSLDisplacementMappingGetNode] - <4> [TGorillaGLSLDisplacementMappingApplyNode] - <5> [TGorillaGLSLClippingPlaneGetNode] - <6> [TGorillaGLSLVertexShaderOutputNode] - <7> [TGorillaGLSLAdjustPointSizeNode] - SurfaceShader [TGorillaSurfaceShaderNode] - <0> [TGorillaGLSLVertexShaderExec] - <1> [TGorillaGLSLVertexPositionOutputNode] ==== Default Fragment Shader ==== The default fragment shader is setting up the following node hierarchy. Root * SourcCode [TGorillaCompositeNode] - <0> [TGorillaGLSLPragma] - Globals [TGorillaGlobalsNode] - Constants [TGorillaCompositeNode] - Types [TGorillaCompositeNode] - <0> [TGorillaGLSLLightType] - <1> [TGorillaGLSLTextureType] - <2> [TGorillaGLSLMaterialType] - <3> [TGorillaGLSLPassDataType] - <4> [TGorillaGLSLFragmentShaderLocalsStructNode] - Attributes [TGorillaCompositeNode] - Uniforms [TGorillaUniformsNode] - <0> [TGorillaGLSLUBOShaderData] - Varying [TGorillaCompositeNode] - <0> [TGorillaGLSLInOutNode] - Functions [TGorillaCompositeNode] - <0> [TGorillaGLSLPackingFuncsNode] - <1> [TGorillaGLSLGetDirLightDirectionFuncNode] - <2> [TGorillaGLSLGetPointLightDirectionFuncNode] - <3> [TGorillaGLSLGetSpotLightDirectionFuncNode] - <4> [TGorillaGLSLGetLightDirectionFuncNode] - <5> [TGorillaGLSLGetSpotFalloffFuncNode] - <6> [TGorillaGLSLGetLightAttenuationFuncNode] - <7> [TGorillaGLSLGetShadingFuncsNode] - <8> [TGorillaGLSLGetTextureFuncsNode] - <9> [TGorillaGLSLGetTextureAtlasFuncNode] - <10> [TGorillaGLSLBasicShadowFuncsNode] - <11> [TGorillaGLSLFaketracingShadowFuncsNode] // DEPRECATED - <12> [TGorillaGLSLBumpFuncsNode] - <13> [TGorillaGLSLPOMFuncsNode] - <14> [TGorillaGLSLPBRFuncsNode] - <15> [TGorillaGLSLFogFuncNode] - <16> [TGorillaSurfaceShaderFuncNode] - Variables [TGorillaCompositeNode] - <0> [TGorillaGLSLLayoutLocation] (o_Albedo) - <1> [TGorillaGLSLLayoutLocation] (o_Alpha) - <2> [TGorillaGLSLLayoutLocation] (o_Position) - <3> [TGorillaGLSLLayoutLocation] (o_Normals) - <4> [TGorillaGLSLLayoutLocation] (o_Components) // DEFERRED_RENDERING ONLY - <5> [TGorillaGLSLLayoutLocation] (o_Ambient) // DEFERRED_RENDERING ONLY - <6> [TGorillaGLSLLayoutLocation] (o_Emissive) // DEFERRED_RENDERING ONLY - <7> [TGorillaGLSLLayoutLocation] (o_Specular) // DEFERRED_RENDERING ONLY - EntryPoint [TGorillaGLSLMainNode] - <0> [TGorillaGLSLClippingPlaneNode] - <1> [TGorillaGLSLMatricesOutNode] - <2> [TGorillaGLSLLightingLocalsNode] - <3> [TGorillaGLSLSpecularColorNode] - <4> [TGorillaGLSLGetTransfVertPosNode] - <5> [TGorillaGLSLGetNormalNode] - <6> [TGorillaGLSLGetFragViewDirNode] - <7> [TGorillaGLSLTextureCoordsNode] - <8> [TGorillaGLSLPOMApplyNode] - <9> [TGorillaGLSLGetBumpNormalNode] - <10> [TGorillaGLSLPBRPrepareNode] - <11> [TGorillaGLSLLightsLoopNode] - <0> [TGorillaGLSLGetLightShadingNode] - <1> [TGorillaGLSLLightingSumNode] - <2> [TGorillaGLSLAddShadowNode] - <2> [TGorillaGLSLAddFaketracingShadowNode] // DEPRECATED - <12> [TGorillaGLSLPBRAmbientNode] - SurfaceShader [TGorillaSurfaceShaderNode] - <0> [TGorillaGLSLGetBaseColorNode] - <1> [TGorillaGLSLSpecularMapNode] - <2> [TGorillaGLSLAddEnvironmentNode] - <3> [TGorillaGLSLAddSparseVoxelsNode] - <4> [TGorillaGLSLAddReflectionNode] - <5> [TGorillaGLSLAddRefractionNode] - <6> [TGorillaGLSLSurfaceShaderExec] - <7> [TGorillaGLSLMergedColorOutputNode] - <8> [TGorillaGLSLBrightnessColorNode] - <9> [TGorillaGLSLFragColorOutputNode] - <10> [TGorillaGLSLColorClipNode] - <11> [TGorillaGLSLFogApplyNode] - <12> [TGorillaGLSLWeightedBlendedOITNode] ===== Node Classes ===== ^ Class ^ Description ^ | TGorillaNodeEntity | The basic node class for all other node classes. The **ToString()** method returns a source code snippet. The result of all nodes will produce the final shader code. | | TGorillaCompositeNode | Is the basic node, which can hold sub-nodes and outputs those in the ToString() method | | TGorillaUniformsNode | Is the basic node for input variables, which is overwritten in the specific shader language | | TGorillaGlobalsNode | Is the storage point for global variables, constants, attributes, types, inputs, in/out variables and functions | | TGorillaDeclarationNode | Is the basic node for declaring types or functions | | TGorillaTypeNode | Is inherited from TGorillaDeclarationNode and represents a type declaration in shader source code | | TGorillaStructTypeNode | Is inherited from TGorillaTypeNode and represents a structured type declaration in shader source code | | TGorillaVariableNode | Is inherited from TGorillaDeclarationNode and represents a variable declaration in a type or as global / local. | | TGorillaConstantNode | Is a simple entity to declare a constant value | | TGorillaOperationNode | Allows to build mathmatical or logical expressions in node format. | | TGorillaStatementNode | Basic node to hold a number of operation nodes, which delimits the line on output, f.e. by a semicolon. | | TGorillaReferenceNode | A node instance with a reference to another node. This is used by syntax nodes to build mathmatical or logical expressions in node format. | | TGorillaForLoopNode | A node which will output a for-loop statement. | | TGorillaSurfaceInputNode | Structure type definition node used by the TGorillaSurfaceShaderNode as input parameter. | | TGorillaSurfaceOutputNode | Structured type definition node used by the TGorillaSurfaceShaderNode as output parameter. | | TGorillaVertexShaderFuncNode | Defines the empty **void VertexShader(inout TLocals DATA){}** function declaration for integrating DesignTime Shader functionality| | TGorillaSurfaceShaderFuncNode | Defines the empty **void SurfaceShader(inout TLocals DATA){}** function declaration for integrating DesignTime Shader functionality | | TGorillaGLSLVertexShaderExec | Node to call user specific vertex shader function for DesignTime functionality. | | TGorillaGLSLSurfaceShaderExec | Node to call user specific fragment shader function for DesignTime functionality. | | TGorillaSurfaceShaderNode | This node type is intended to be the entry point for user specific source code implementation. | | TGorillaEntryPointNode | Defines the shader source code entry point. On GLSL this is the main() function (the first function called, when a shader gets executed) | ===== GLSL Node Classes ===== In the following we list the most common GLSL shader nodes. This should help to understand where you can manipulate or influence shader source code compilation. ==== Top-Level Nodes ==== At the top-level of a shader code tree either //TGorillaGLSLVertexShader// or //TGorillaGLSLFragmentShader// is attached to the node builder instance. ^ Class ^ Description ^ | TGorillaGLSLVertexShader | The basic vertex shader node builder type | | TGorillaGLSLFragmentShader | The basic fragment shader node builder type | ==== Second-Level Nodes ==== Attached to one of those nodes are the following container nodes: ^ Class ^ Description ^ | TGorillaGLSLPragma | Pragma definition node, f.e. to define the GLSL version: **#version 310** and float/int precisions. | | [[#tgorillaglobalsnode_globals|TGorillaGlobalsNode]] | Containing global declarations, f.e. for variables or functions. | | [[#tgorillaglslmainnode_entrypoint|TGorillaGLSLMainNode]]| Containing the main function code for GLSL shaders. | ==== TGorillaGlobalsNode (Globals) ==== A //TGorillaGlobalsNode// node automatically provides sub-containers for structuring, f.e. variables, types, functions, ... The following list is showing which node type should be inserted into which sub-container. ^ Sub-Container ^ Class ^ Description ^ | Constants | TGorillaGLSLConstant | Create an instance of this class for your own constant declaration and insert it into the //Constants// sub-container. | | - |- |- | | Variables | TGorillaGLSLVariable | Create an instance of this class for your own global variable declaration and insert it into the //Variables// sub-container. | | - |- |- | | Types | TGorillaGLSLStructType | Extend this class for your own structure declaration and insert it into the //Types// sub-container. | | Types | TGorillaGLSLLightType | Defines the internal light structure type. //It is not recommend to change it.// | | Types | TGorillaGLSLTextureType | Defines the internal texture structure type. //It is not recommend to change it.// | | Types | TGorillaGLSLMaterialType | Defines the internal material structure type. //It is not recommend to change it.// | | Types | TGorillaGLSLPassDataType | Defines the internal pass variable structure type. //It is not recommend to change it.// | | Types | TGorillaGLSLVertexShaderLocalsStructNode |Defines the TLOCALS structure with all pre-defined properties: * LOCALS.**Position** * LOCALS.**TransfVertexPos** * LOCALS.**WorldViewProjVertPos** * LOCALS.**TexCoord0** * LOCALS.**Color0** * LOCALS.**Normal** * LOCALS.**Tangent** * LOCALS.**Binormal** * LOCALS.**Displace** * LOCALS.**ClippingPlane** Values inside of TLOCALS will be applied at the end of the shader to the varying parameters. //It's recommended to modify those values instead of varying values directly (could be overwritten again).// | | Types | TGorillaGLSLFragmentShaderLocalsStructNode | Defines the TLOCALS structure with all pre-defined properties: * LOCALS.**LightDir** * LOCALS.**LightVec** * LOCALS.**LightType** * LOCALS.**LightDist** * LOCALS.**Attenuation** * LOCALS.**SceneAttenuation** * LOCALS.**Ambient** * LOCALS.**Diffuse** * LOCALS.**Specular** * LOCALS.**TexCoord0** * LOCALS.**TransfVertPos** * LOCALS.**Normal** * LOCALS.**FragViewDir** * LOCALS.**SpecularColor** * LOCALS.**BaseColor** * LOCALS.**SumColor** * LOCALS.**Alpha** * LOCALS.**Shading** * LOCALS.**ShadowSum** * LOCALS.**BumpSum** Values inside of TLOCALS will be applied at the end of the shader to the fragment output. //It's recommended to modify those values instead of output values directly (could be overwritten again).// NOTICE: values getting filled up during computation and are not set at all times. | | - |- |- | | Uniforms | TGorillaGLSLUBOShaderData | Defines the internal uniform buffer object (v3) or variable declaration (v2). | | Uniforms | TGorillaGLSLUniformsNode | Create an instance of this class, if you need additional input variables in your shader | | - |- |- | | Attributes | TGorillaGLSLAttributesNode | Holds the available vertex attributes. It is not recommend to change this node, if you are not sure if the additional attributes are provided by the mesh data. * **a_Position** * **a_Normal** * **a_Tangent** * **a_Binormal** * **a_TexCoord0** * **a_TexCoord1** * **a_TexCoord2** * **a_TexCoord3** * **a_Color** * **a_Color1** * **a_Color2** * **a_Color3** | | - |- |- | | Varying | TGorillaGLSLInOutNode | Holds the input/output variables (varying) used by each shader. On GLES v3+ everything is encapsulated in the **__INOUT__** structure accessable by: **vars.*** Available varying values are: * vars.**v_VertPos** * vars.**v_TransfVertPos** * vars.**v_WorldViewProjVertPos** * vars.**v_TexCoord0** * vars.**v_Color0** * vars.**v_TBN** * vars.**v_TBN_UT** * vars.**v_ReflProjTextureCoords** * vars.**v_ClipDistance** * (**v_ViewDir** deprecated)] | | - |- |- | | Functions | TGorillaDeclarationNode | Extend the declaration node for a user-specific function node and attach it to the //Functions// property of the //Globals// node. | | Functions | TGorillaGLSLTransformFuncsNode | Provides functions for vertex transformation: * **TransformModel()** * **TransformModelViewProjection()** * **TransformModelNormal()** | | Functions | TGorillaGLSLPackingFuncsNode | Provides function declarations for packaging / unpackaging: * **Common_PackNormal()** * **Common_UnpackNormal()** * **Common_UnpackNormalLA()** | | Functions | TGorillaGLSLGetDirLightDirectionFuncNode | Providing function declarations for retrieving light direction depending on the supplied light type. | | Functions | TGorillaGLSLGetPointLightDirectionFuncNode | Providing function declarations for retrieving light direction for point lights | | Functions | TGorillaGLSLGetSpotLightDirectionFuncNode | Providing function declarations for retrieving light direction for spot lights | | Functions | TGorillaGLSLGetLightDirectionFuncNode | Providing function declarations for retrieving light direction for directional lights | | Functions | TGorillaGLSLGetSpotFalloffFuncNode| Providing function declarations for computing spot light fall off. | | Functions | TGorillaGLSLGetLightAttenuationFuncNode | Providing function declarations for computing light attenuation depending on the light type. | | Functions | TGorillaGLSLGetShadingFuncsNode| Providing function declarations for computing lambert, phong or blinn-phong shading . | | Functions | TGorillaGLSLGetTextureFuncsNode | Provides function declarations for: * **tex2D()** * **tex2DProj()** * **tex3D()** * **texCube()** * **Texture_GetNormal()** | | Functions | TGorillaGLSLGetTextureAtlasFuncNode | Providing function declarations for extracting specific frames from texture atlas. | | Functions | TGorillaGLSLBasicShadowFuncsNode | Providing shadow computation functions for shadow mapping or variance shadow mapping depending on the material settings. | | Functions | TGorillaGLSLFaketracingShadowFuncsNode | DEPRECATED: A bad approach for better shadow computation. | | Functions | TGorillaGLSLBumpFuncsNode | Providing function declarations for bump mapping and normal mapping. | | Functions | TGorillaGLSLPOMFuncsNode | Providing function declaration for parallax occlusion mapping functionality | | Functions | TGorillaGLSLPBRFuncsNode | Providing function declaration for physically based rendering functionality. | | Functions | TGorillaGLSLFogFuncNode | Provididing fog computation function declarations. | | Functions | TGorillaVertexShaderFuncNode | By default it's providing an empty function: **void VertexShader(inout TLocals DATA){}** which can be filled up by users at designtime or runtime. | | Functions | TGorillaSurfaceShaderFuncNode| By default it's providing an empty function: **void SurfaceShader(inout TLocals DATA){}** which can be filled up by users at designtime or runtime. | | - |- |- | | - | TGorillaGLSLLayoutLocation | Defines a layout location for render target output. This node is only available for modern OpenGL 4.3+ or OpenGLES 3.1+ syntax. In the default fragment shader the following layouts are automatically registered: * **o_Albedo** * **o_Alpha** * **o_Position** * **o_Normals** * **o_Components** (Deferred Rendering Only) * **o_Ambient** (Deferred Rendering Only) * **o_Emissive** (Deferred Rendering Only) * **o_Specular** (Deferred Rendering Only) | ==== TGorillaGLSLMainNode (EntryPoint) ==== === Vertex Shader === ^Class ^ Description ^ | - | TGorillaGLSLVertexShaderLocalsNode | Empty node. Variable declaration was moved to TGorillaGLSLVertexShaderLocalsStructNode. | | - | TGorillaGLSLMatricesOutNode| DEPRECATED: Pushes all transformation matrices to varying parameters (OpenGLES v2): * **v_ModelMatrix** * **v_ModelViewProjectionMatrix** * **v_ModelNormalMatrix** * **v_ViewMatrix** * **v_ProjectionMatrix** * **v_ShadowMatrix** . While in modern OpenGL (GLES v3.1+) everything is already stored in the uniform buffer. | | - | TGorillaGLSLGetVertexPositionNode| Automatically sets the following LOCALS properties by attributes and uniforms: **LOCALS.Position**, **LOCALS.ClippingPlane** and **LOCALS.Displace** | | - | TGorillaGLSLDisplacementMappingGetNode| Requests **LOCALS.Displace** value from **_DisplacementMapTexture**. | | - | TGorillaGLSLDisplacementMappingApplyNode| Adds **LOCALS.Displace** to **LOCALS.Position** for vertex displacement. | | - | TGorillaGLSLClippingPlaneGetNode| Sets the locals value for **LOCALS.ClippingPlane**. | | - | TGorillaGLSLVertexShaderOutputNode| Automatically sets the following locals and varying parameters * **LOCALS.TransfVertexPos** * **LOCALS.WorldViewProjVertPos** * **LOCALS.TexCoord0** * **LOCALS.Color0** * **LOCALS.Normal** * **LOCALS.Tangent** * **LOCALS.Binormal** * **vars.v_TBN** * **vars.v_TBN_UT** | | - | TGorillaGLSLAdjustPointSizeNode| Computes sprite distance and sets **gl_PointSize** value. | | - | TGorillaSurfaceShaderNode| Sets up a container node **SurfaceShader** for surface computation, where further sub-nodes are attached to (TGorillaGLSLVertexShaderExec, TGorillaGLSLVertexPositionOutputNode). | | - | - | - | | SurfaceShader | TGorillaGLSLVertexShaderExec| Calls **VertexShader(LOCALS);**. | | SurfaceShader | TGorillaGLSLVertexPositionOutputNode| Sets varying values from TLOCALS structure for: * **vars.v_VertPos** * **vars.v_TransfVertPos** * **vars.v_WorldViewProjVertPos** * **vars.v_TexCoord0** * **vars.v_Color0** * **vars.v_ClipDistance** * **vars.v_TBN** * **vars.v_TBN_UT** * **gl_Position** | === Fragment Shader === ^Class ^ Description ^ | - | TGorillaGLSLClippingPlaneNode | If GORILLA_GLSL_DEFINE_CLIPPINGPLANE is activated, it checks if clipping plane is activated and discards the fragment in case of clipping. | | - | TGorillaGLSLMatricesOutNode | Empty node and only compiled for vertex shader. | | - | TGorillaGLSLLightingLocalsNode | Empty node. Source code was moved to TGorillaGLSLFragmentShaderLocalsStructNode. | | - | TGorillaGLSLSpecularColorNode | If GORILLA_GLSL_DEFINE_USE_SPECULAR is activated, it sets **LOCALS.SpecularColor** from Material.Specular settings, otherwise the value is set to zero. | | - | TGorillaGLSLGetTransfVertPosNode | Sets **LOCALS.TransfVertPos** from //vars.v_TransfVertPos// and **LOCALS.FragDepth** from //gl_FragCoord.z// | | - | TGorillaGLSLGetNormalNode | If GORILLA_GLSL_DEFINE_BUMP is activated, it sets **LOCALS.Normal** from //vars.v_TBN[2]// | | - | TGorillaGLSLGetFragViewDirNode |Computes **LOCALS.FragViewDir** from direction between camera position and transformed vertex position. | | - | TGorillaGLSLTextureCoordsNode | If GORILLA_GLSL_DEFINE_USE_TEXTURE is activated, it sets **LOCALS.TexCoord0** from //vars.v_TexCoord0// and automatically applies tiling from first texture in material settings. | | - | TGorillaGLSLPOMApplyNode | If GORILLA_GLSL_DEFINE_POM is activated, it computes **LOCALS.TexCoord0** by //ParallaxOcclusionMapping()// function. | | - | TGorillaGLSLGetBumpNormalNode | If GORILLA_GLSL_DEFINE_LIGHTING, GORILLA_GLSL_DEFINE_NORMALMAP and GORILLA_GLSL_DEFINE_BUMP are activated, it computes **LOCALS.Normal** by //CalcBumpedNormal()// function. | | - | TGorillaGLSLPBRPrepareNode | If GORILLA_GLSL_DEFINE_LIGHTING and GORILLA_GLSL_DEFINE_PBR are activated, it prepares values for physically based rendering. | | - | TGorillaGLSLLightsLoopNode |Sets up a loop for all available light sources inside of **_Light[x]**. Further node will be attached to it. Those subnodes will be executed for each light source. | | LightsLoop | TGorillaGLSLGetLightShadingNode | If GORILLA_GLSL_DEFINE_LIGHTING is activated the node will compute shading depending on the shading model: lambert, phong, blinn-phong or PBR. | | LightsLoop | TGorillaGLSLLightingSumNode | If GORILLA_GLSL_DEFINE_LIGHTING is activated the node will sum up lighting. If GORILLA_GLSL_DEFINE_PBR is activated it will output no code. If GORILLA_GLSL_DEFINE_USE_SPECULAR is activated, it will also apply specular lighting. | | LightsLoop | TGorillaGLSLAddShadowNode |If GORILLA_GLSL_DEFINE_LIGHTING and GORILLA_GLSL_DEFINE_SHADOW are activated, it will calculate **LOCALS.ShadowSum** depending on the GORILLA_GLSL_DEFINE_SHADOW_SM or GORILLA_GLSL_DEFINE_SHADOW_VSM define. | | LightsLoop | TGorillaGLSLAddFaketracingShadowNode | DEPRECATED: This node is deprecated and should not be used anymore. | | - | - |- | | - | TGorillaGLSLPBRAmbientNode |If GORILLA_GLSL_DEFINE_LIGHTING and GORILLA_GLSL_DEFINE_PBR are activated, it will set **LOCALS.Ambient** and **LOCALS.Specular** from albedo, AO and specular settings. | | - | TGorillaSurfaceShaderNode | Is a container node for the final surface color computation. | | SurfaceShader | TGorillaGLSLGetBaseColorNode | It will compute **LOCALS.BaseColor** and **LOCALS.Alpha** depending on GORILLA_GLSL_DEFINE_BUMP, GORILLA_GLSL_DEFINE_PBR, GORILLA_GLSL_DEFINE_USE_TEXTURE_ATLAS, GORILLA_GLSL_DEFINE_USE_POINTSPRITE, GORILLA_GLSL_DEFINE_LIGHTING , GORILLA_GLSL_DEFINE_USE_TEXTURE and GORILLA_GLSL_DEFINE_USE_VERTEXCOLOR defines. The node is way to complex to explain it's functionality here.| | SurfaceShader | TGorillaGLSLSpecularMapNode | If GORILLA_GLSL_DEFINE_SPECULARMAP is activated, it computes **LOCALS.SpecularColor** from //_SpecularMapTexture//. | | SurfaceShader | TGorillaGLSLAddEnvironmentNode | If GORILLA_GLSL_DEFINE_ENVIRONMENT is activated, it computes **LOCALS.BaseColor** and **LOCALS.Ambient** values from //_EnvironmentTexture// | | SurfaceShader | TGorillaGLSLAddReflectionNode| If GORILLA_GLSL_DEFINE_REFLECTION is activated, it merges //_ReflectionTexture// with **LOCALS.BaseColor**. | | SurfaceShader | TGorillaGLSLAddRefractionNode| If GORILLA_GLSL_DEFINE_REFRACTION is activated, it merges //_RefractionTexture// with **LOCALS.BaseColor**. | | SurfaceShader | TGorillaGLSLSurfaceShaderExec| Calls **SurfaceShader(LOCALS);** | | SurfaceShader | TGorillaGLSLMergedColorOutputNode |It will compute the final **LOCALS.SumColor** depending if GORILLA_GLSL_DEFINE_LIGHTING, GORILLA_GLSL_DEFINE_SPECULARMAP, GORILLA_GLSL_DEFINE_SHADOW or GORILLA_GLSL_DEFINE_PBR are activated. | | SurfaceShader | TGorillaGLSLBrightnessColorNode | It will multiply **_Brightness** value with **LOCALS.SumColor** (since v0.8.4.2322)| | SurfaceShader | TGorillaGLSLFragColorOutputNode | It will apply material alpha value to **LOCALS.Alpha** and finally write **vec4(LOCALS.SumColor, LOCALS.Alpha)** to //o_Albedo// render target. | | SurfaceShader | TGorillaGLSLColorClipNode | If GORILLA_GLSL_DEFINE_USE_COLORCLIP is activated, it will discard the fragment if threshold was reached. | | SurfaceShader | TGorillaGLSLFogApplyNode |It will compute fog value by calling //computeFog()// and modify the **o_Albedo** render target. | | SurfaceShader | TGorillaGLSLWeightedBlendedOITNode | It will perform WBOIT value computation and sets all other render target outputs * **o_Position** * **o_Normals** * **o_Alpha** * **o_Components** (Deferred Rendering only) * **o_Ambient** (Deferred Rendering only) * **o_Emissive** (Deferred Rendering only) * **o_Specular** (Deferred Rendering only) | ===== Using Defines ===== Not all nodes are enabled by default, so you have to unlock them by using the define management of the node builder. The following defines are provided in the default material: ^ Define ^Notice ^ | GORILLA_GLSL_DEFINE_VERTEXSHADER | Defines the specific nodebuilder as vertex shader source code | | GORILLA_GLSL_DEFINE_FRAGMENTSHADER | Defines the specific nodebuilder as fragment shader source code| | GORILLA_GLSL_DEFINE_DEPTH | Activates the depth map functionality. Nevertheless a depth render pass needs to be attached to the material | | GORILLA_GLSL_DEFINE_DEFERRED | NOT IMPLEMENTATED YET. DO NOT USE! | | GORILLA_GLSL_DEFINE_SHADOW | Activates shadow casting. The GORILLA_GLSL_DEFINE_DEPTH needs to be activated too. | | GORILLA_GLSL_DEFINE_SHADOW_SM | Activates simple shadow mapping. The GORILLA_GLSL_DEFINE_SHADOW needs to be activated too. | | GORILLA_GLSL_DEFINE_SHADOW_VSM | Activates variance shadow mapping. The GORILLA_GLSL_DEFINE_SHADOW needs to be activated too. | | GORILLA_GLSL_DEFINE_SHADOW_FT | DEPRECATED! DO NOT USE ANYMORE! | | GORILLA_GLSL_DEFINE_REFLECTION | Activates reflection handling. | | GORILLA_GLSL_DEFINE_REFRACTION | Activates refraction handling. | | GORILLA_GLSL_DEFINE_ENVIRONMENT | Activates enviroment mapping for reflection and refraction. //Do not combine with GORILLA_GLSL_DEFINE_REFLECTION or GORILLA_GLSL_DEFINE_REFRACTION// | | GORILLA_GLSL_DEFINE_CLIPPINGPLANE | Activates clipping plane handling. | | GORILLA_GLSL_DEFINE_NORMALMAP | Activates normal mapping functionality. | | GORILLA_GLSL_DEFINE_BUMP | Activates bump mapping functionality in combination with GORILLA_GLSL_DEFINE_NORMALMAP | | GORILLA_GLSL_DEFINE_POM | Activates parallax occlusion mapping computation | | GORILLA_GLSL_DEFINE_POM_DISCARD | Activates discarding edge fragments during parallax occlusion mapping. GORILLA_GLSL_DEFINE_POM needs to be activated.| | GORILLA_GLSL_DEFINE_SPECULARMAP | Allows to supply a specular texture for model specific specular color computation. | | GORILLA_GLSL_DEFINE_DISPLACEMENT | Enables the displacement mapping functionality in the vertex shader. | | GORILLA_GLSL_DEFINE_LIGHTING | Enables lighting computation with lambert, phong or blinnphong algorithm. | | GORILLA_GLSL_DEFINE_PHONG | Enables phong shading source code for the material | | GORILLA_GLSL_DEFINE_BLINNPHONG | Enables blinn-phong shading source code for the material | |GORILLA_GLSL_DEFINE_PBR | Enables physically based rendering source code for the material. | | GORILLA_GLSL_DEFINE_PBR_TEXTURE0 | Activates usage of **_Texture0** in shader. If not activated, it expects **LOCALS.BaseColor** to be already set | | GORILLA_GLSL_DEFINE_PBR_TEXTURES | Enables usage of all PBR textures (Metalness, Roughness, AmbientOcclusion). Otherwise the bias values will be used *MetallicBias* and *RoughnessBias*| | GORILLA_GLSL_DEFINE_USE_SPECULAR | Enables specular light computation. | | GORILLA_GLSL_DEFINE_USE_VERTEXCOLOR | Enables to use the color of each vertex. | | GORILLA_GLSL_DEFINE_USE_TEXTURE | Enables general texture functionality (tex2D, tex2DProj, ... methods) | | GORILLA_GLSL_DEFINE_USE_TEXTURE0 | Enables the Texture0 handling in the material | | GORILLA_GLSL_DEFINE_USE_TEXTURE_ATLAS | Declares texture atlas mapping functionality: **GetTextureAtlasColor()**| | GORILLA_GLSL_DEFINE_USE_POINTSPRITE | In combination with GORILLA_GLSL_DEFINE_USE_TEXTURE_ATLAS the Texture0 will be used as atlas and mapped onto each vertex point: **GetTextureAtlasColor()** | | GORILLA_GLSL_DEFINE_PACKED_NORMAL | Enables packed normals | | GORILLA_GLSL_DEFINE_INOUTVARS | Enables in/out variables for GLSLv3+ | | GORILLA_GLSL_DEFINE_VARYINGSTRUCTS | Enables varying structs. This define manages backwards compatibility | | GORILLA_GLSL_DEFINE_DEPRECATED | DO NOT USE ANYMORE! | | GORILLA_GLSL_DEFINE_INTEL | Automatically set by the system, in case of an Intel graphics card. | | GORILLA_GLSL_DEFINE_AMD | Automatically set by the system, in case of an AMD graphics card. | | GORILLA_GLSL_DEFINE_NVIDIA | Automatically set by the system, in case of an NVidia graphics card. | | GORILLA_GLSL_DEFINE_GEFORCE | Automatically set by the system, in case of an GeForce graphics card. | | GORILLA_GLSL_DEFINE_RADEON | Automatically set by the system, in case of an Radeon graphics card. | | GORILLA_GLSL_DEFINE_HDGRAPHICS | Automatically set by the system, in case of an HDGraphics graphics card. | To enable a shader section call: **AddDefine(GORILLA_GLSL_DEFINE_*)** To disable a shader section call: **RemoveDefine(GORILLA_GLSL_DEFINE_*)** In most cases definitions need to be applied to vertex- and fragmentshader, because in both shaders functionality is available. The DefaultMaterial defines the following sections by default: ^ Shader ^ Defines ^ | VertexShader | GORILLA_GLSL_DEFINE_VERTEXSHADER, GORILLA_GLSL_DEFINE_CLIPPINGPLANE | | FragmentShader | GORILLA_GLSL_DEFINE_FRAGMENTSHADER, GORILLA_GLSL_DEFINE_CLIPPINGPLANE | ===== Globals ===== As already mentioned in the sections above, the default shader declares attributes, types, constants and variables automatically. Those entities can be used inside the shader and can of course be modified. In the following we list the available presets. ==== Attributes ==== Each vertex provides further information besides the position of it. But depending on the mesh data given, not all of those properties may be available. Nevertheless the shader defines a fixed set of attributes, even if they are not filled by the mesh data. ^ Name ^ Delphi-Type ^ GLSL-Type ^ | a_Position | TPoint3D | vec3 | | a_Normal | TPoint3D | vec3 | | a_Tangent | TPoint3D | vec3 | | a_Binormal | TPoint3D | vec3 | | a_TexCoord0 | TPointF | vec2 | | a_TexCoord1 | TPointF | vec2 | | a_TexCoord2 | TPointF | vec2 | | a_TexCoord3 | TPointF | vec2 | | a_Color | TAlphaColorF | vec4 | | a_Color1 | TAlphaColorF | vec4 | | a_Color2 | TAlphaColorF | vec4 | | a_Color3 | TAlphaColorF | vec4 | ==== Uniform Buffer ==== In the current implementation of the default material a uniform buffer is used to submit settings as block to the shaders. While in previous implementations each variable was submitted separately, it became very inefficient on the large number of settings. The default material allows to register multiple uniform buffers, but by default only the **TGorillaShaderData** structure is registered. __Notice:__ Structures inside of Delphi need a fixed alignment to OpenGL's std140 layout. You might have recognized a few "Reserved" fields. Those are marking a memory alignment inside of the structure. Read more about OpenGL memory alignment here: [[https://www.khronos.org/opengl/wiki/Interface_Block_(GLSL)]] === TGorillaShaderData === The TGorillaDefaultMaterial therefore registers a packed record as exchanging buffer. Having a closer look at the structure below, it's showing further sub structures for lights, material, textures and render pass data. Those sub structures are automatically submitted to shaders too. TGorillaShaderData = packed record /// /// Defines the multiplied model and view matrix. /// ModelMatrix : TMatrix3D; /// /// Defines the multiplied model, view and projection matrix. /// ModelViewProjectionMatrix : TMatrix3D; /// /// Defines the inverted and transposed multiplied model and view matrix. /// ModelNormalMatrix : TMatrix3D; /// /// Defines the view / camera matrix. /// ViewMatrix : TMatrix3D; /// /// Defines the projection matrix. /// ProjectionMatrix : TMatrix3D; /// /// Provides information about start, current, previous and delta time /// X - Starting time /// Y - Current time /// Z - Previous time /// W - Delta time /// TimeInfo : TVector3D; /// /// The absolute camera position. /// EyePos : TVector3D; /// /// The camera view direction. /// ViewDir : TPoint3D; /// /// Defines the used shading model: lambert (default), phong, blinnphong, pbr, ... /// ShadingModel : FixedInt; {TGorillaShadingModel} /// /// Defines material properties, like diffuse, specular, ambient, emissive /// color or information about uniform textures. /// Material : Array[0..0] of TGorillaShaderMaterial; /// /// Defines activated light sources with their properties. /// Lights : Array[0..GORILLA_MATERIAL_DEFAULT_LIGHTS-1] of TGorillaShaderLight; /// /// Defines the number of lights used in the fix-sized lights array above, /// beginning at 0. /// LightsCount : FixedInt; /// /// Shader specific options. /// Options : FixedInt; /// /// Defines how much shading is applied to diffuse and specular color. /// ShadingIntensity : Single; /// /// Defines the brightness factor applied to the diffuse color. /// Brightness : Single; /// /// FogMode contains information about the algorithm to be used and if /// fog is enabled or not. /// FogMode : FixedInt; // $01 enabled, $02 - linear, $04 - exp, $08 - exp2 /// /// Defines the density of fog, used for exp and exp2 algorithm /// FogDensity : Single; // default = 0.001 /// /// Defines the eye-vertex distance where fog begins. /// FogStart : Single; // default = 100.0 /// /// Defines the eye-vertex distance where fog ends. /// FogEnd : Single; // default = 500.0 /// /// Define the fog color used for computation. /// FogColor : TAlphaColorF; // default = vec4(0, 0, 0, 1); /// /// Provides the camera frustum bounding box top-left-near corner. /// FrustumMin : TVector3D; /// /// Provides the camera frustum bounding box bottom-right-far corner. /// FrustumMax : TVector3D; /// /// Provides the top-left-near corner of the scenery bounds. /// SceneMin : TVector3D; /// /// Provides the bottom-right-far corner of the scenery bounds. /// SceneMax : TVector3D; /// /// Provides the top-left-near corner of the scenery bounds. /// BoundaryMin : TVector3D; /// /// Provides the bottom-right-far corner of the scenery bounds. /// BoundaryMax : TVector3D; /// /// Current viewport rendering size and near / far limitation. /// /// /// /// X - viewport width /// /// /// Y - viewport height /// /// /// Z - camera frustum near /// /// /// W - camera frustum far /// /// ViewSize : TVector3D; /// /// You can define a single clipping plane for discarding fragments below. /// ClippingPlane : TVector3D; /// /// Defines some pass data information, f.e. for raytracing, reflection and refraction. /// PassData : Array[0..0] of TGorillaShaderPassData; class function Create() : TGorillaShaderData; static; end; **__NOTICE:__ Properties in uniform structures need to be accessed in OpenGL shaders by prefixing those witth an underscore ("_"), even for sub-properties of sub-structures.** You can access a top-level property inside of TShaderData in OpenGL shader, like: vars.v_Position *= _ModelMatrix; === TGorillaShaderMaterial === The material property inside of the TGorillaShaderData struct defines a sub structure. __Notice:__ Even the material is defined as array, there is only a single material structure available. Material : Array[0..0] of TGorillaShaderMaterial; And the Delphi implementation of this structure is represented by the following packed record. TGorillaShaderMaterial = packed record /// /// Emissive color value. /// Emissive : TAlphaColorF; /// /// Ambient color value. /// Ambient : TAlphaColorF; /// /// Diffuse color value. /// Diffuse : TAlphaColorF; /// /// Specular color value. /// Specular : TAlphaColorF; /// /// Clipping color value. R/G/B is the color value, A is the tolerance. /// Clipping : TAlphaColorF; /// /// Displacement factor to scale the influence of a displacement map. /// Default value is set to vec4(0.1, 0.1, 0.1, 1.0) /// /// /// /// (x, y, z) are the extension factors applied to the vertex normal. /// /// /// w - is the extension direction, while -1 means shrinking /// but +1 means model extrusion. /// /// Displacement : TVector3D; /// /// X - Current object opacity value. /// Y - reserved for future values /// Z - reserved for future values /// W - reserved for future values /// Features : TVector3D; /// /// Specular shining factor. If the value is <= 1.0, shading is deativated. /// Shininess : Single; /// /// Number of all textures /// Textures : FixedInt; /// /// The index of the first pool texture to find in texture settings: /// _Material[0]._Texture[_Material[0]._PoolTexturesOffset] /// PoolTexturesOffset : FixedInt; /// /// Number of total pool textures. /// PoolTextures : FixedInt; /// /// Fixed array of texture settings. /// Texture : TGorillaShaderTextures; class function Create() : TGorillaShaderMaterial; static; end; You can access material settings in OpenGL shader, f.e. by: LOCALS.Ambient = _Material[0]._Ambient; === TGorillaShaderTexture === Each material structure **TGorillaShaderMaterial** supports a set of **max. 16 texture** structures. // type TGorillaShaderTextures = Array[0..GORILLA_SHADER_TEXTURES_MAX - 1] of TGorillaShaderTexture; Texture : TGorillaShaderTextures; This allows to texture specific settings like transition values (for terrain material) or tile settings. TGorillaShaderTexture = packed record /// /// for terrain textures we need information about height and transition /// between textures - those we put inside of a vec4 /// MinHeight, MaxHeight, LowTransition, HighTransition : Single /// Feature : TVector3D; /// /// Texture repeating value /// Tiling : TPointF; {$IFDEF GL_ES_VERSION_3_0} /// /// Due to memory alignment in gpu - we have to adjust memory here by /// some dummy bytes. /// Reserved1 : Array[0..7] of Byte; {$ENDIF} end; You can access those settings in OpenGL shader, like: LOCALS.Tiling.xy = _Material[0]._Texture[0]._Tiling.xy; === TGorillaShaderLight === The default material supports multiple light sources, which are submitted inside the TGorillaShaderData uniform structure as array of **TGorillaShaderLight** structure. Lights : Array[0..GORILLA_MATERIAL_DEFAULT_LIGHTS-1] of TGorillaShaderLight; //The size of that array is platform dependent.// While on Windows platforms it is limited to 32, on Android it is limited to max. 8 lights. TGorillaShaderLight = packed record LightType : FixedInt; {TLightType} {$IFDEF GL_ES_VERSION_3_0} // due to memory alignment in gpu - we have to adjust Reserved1 : Array[0..11] of Byte; {$ENDIF} Position : TVector3D; /// /// A "halfway vector" (if you mean that by "half vector") is the unit /// vector at the half angle between two other vectors. Normally the /// halfway vector [...] is computed between the vector to the viewer v /// and the light source. /// /// /// H(a,b) = normalize(normalize(a) + normalize(b)) /// // HalfVector : TVector3D; Direction : TVector3D; Ambient : TAlphaColorF; Diffuse : TAlphaColorF; Specular : TAlphaColorF; SpotCutoff : Single; SpotCosCutoff : Single; SpotExponent : Single; ConstantAttenuation : Single; LinearAttenuation : Single; QuadraticAttenuation : Single; {$IFDEF GL_ES_VERSION_3_0} // due to memory alignment in gpu - we have to adjust Reserved4 : Array[0..7] of Byte; {$ENDIF} constructor Create(ALight : TLightDescription); end; You can access light settings in OpenGL shader, like: LOCALS.BaseColor = _Light[0]._Diffuse; === TGorillaShaderPassData === In case you have run a render pass like reflections in a previous stage, some additional settings might be needed, like //ReflectTextureMatrix// or //ReflectionPower//. So the //PassData// structure was introduced to group those settings in one place. //Even if it is defined as an array, there is only a single pass data structure available.// PassData : Array[0..0] of TGorillaShaderPassData; For more compressed data and less memory size, we merged various settings into this single structure. It might seem to be a little bit messed up, but it reduces memory usage in general. __Notice:__ We might refactor this structure in future, due to this confusing setup. TGorillaShaderPassData = packed record ShadowMapMatrix : Array[0..7] of TMatrix3D; ReflectTextureMatrix : TMatrix3D; RefractTextureMatrix : TMatrix3D; ReflectionPower : Single; RefractionPower : Single; TranslucentDistance : Single; /// /// A factor that is applied on the normal vector in /// bump mapping / normal mapping / parallax occlusion mapping. /// NormalIntensity : Single; /// /// Define the number raytracing levels during parallax occlusion mapping. /// Allowed values are between 4 and 256. /// More levels meaning less performance due to more intense gpu usage. /// ParallaxLevels : FixedInt; /// /// Metallic value for controlling metalness of physically based rendering output. /// PBRMetallic : Single; /// /// Roughness value for controlling noise computation of physically based rendering output. /// PBRRoughness : Single; /// /// Ambient occlusion value for controlling ambient intensity of physically based rendering output. /// PBRAO : Single; end; The PassData can be access in OpenGL shader like: LOCALS.BaseColor.xyz *= _PassData[0]._ReflectionPower; ==== Varying values ==== We will not go into detail about shader stages. For further reading, please have a look at: [[https://www.khronos.org/opengl/wiki/Rendering_Pipeline_Overview]]. But simply said, the vertex shader is computed at first and already modifies vertex position or precomputes some values, we might use in our final fragment shader. To supply those data, we need some kind of an exchange structure. This is called varying parameter, which is represented in GLSL by the _ _ INOUT _ _ struct, accessable by the "**vars.**" prefix. Because the size of this structure is limited, we can only support a restricted number of properties. // It is not recommended to extend this structure, because exceeding those limits, might have unexpected effects! // The following list shows which properties are already defined: ^ Name ^ Delphi-Type ^ GLSL-Type ^ Description ^ | vars.v_VertPos | TVector3D | vec4 | untransformed vertex position | | vars.v_TransfVertPos | TPoint3D | vec3 | transformed vertex position | | vars.v_WorldVertPos | TVector3D | vec4 | MVP transformed vertex position | | vars.v_TBN | TMatrix | mat3 | Array of three vectors for tangent, binormal and normal //transformed by the model matrix//. | | vars.v_TBN_UT | TMatrix | mat3 | Array of three vectors for tangent, binormal and normal //untransformed (UT)//. | | vars.v_TexCoord0 | TPointF | vec2 | vertex texture coordinate for first texture | | vars.v_Color0 | TAlphaColorF | vec4 | first vertex color information (may be black if not provided) | | vars.v_ReflProjTextureCoords | TVector3D | vec4 | when reflection is active, these are the transformed coordinates for reflection texture | | vars.v_RefrProjTextureCoords | TVector3D | vec4 | when refraction is active, these are the transformed coordinates for refraction texture | ==== Default Textures ==== ^ Name ^ GLSL-Type ^ Description ^ | _DisplacementMapTexture | VertexShader | sampler2D | If GORILLA_GLSL_DEFINE_DISPLACEMENT is activated. | | _Texture0 | FragmentShader | sampler2D / samplerCube / sampler3D (depending on the material used) | If GORILLA_GLSL_DEFINE_USE_TEXTURE is activated. | | _NormalMapTexture | FragmentShader | sampler2D | If GORILLA_GLSL_DEFINE_NORMALMAP is activated. | | _SpecularMapTexture | FragmentShader | sampler2D | If GORILLA_GLSL_DEFINE_USE_SPECULAR is activated. | | _DepthTexture | FragmentShader | sampler2D | If GORILLA_GLSL_DEFINE_DEPTH is activated. | | _EnvironmentTexture | FragmentShader | samplerCube | If GORILLA_GLSL_DEFINE_ENVIRONMENT is activated. | | _ReflectionTexture | FragmentShader | sampler2D | If GORILLA_GLSL_DEFINE_REFLECTION is activated. | | _RefractionTexture | FragmentShader | sampler2D | If GORILLA_GLSL_DEFINE_REFRACTION is activated. | ==== Render Targets ==== The default material is using a multiple render target approach in fragment shaders. This means it outputs values to multiple destination buffers. ^ Render Target ^ Defines ^ Description ^ |o_Albedo | - | o_Albedo = LOCALS.SumColor | |o_Alpha| - | o_Alpha = LOCALS.Alpha | |o_Position| - | o_Position = vec4(LOCALS.TransfVertPos.xyz, LOCALS.FragDepth) | |o_Normals| - | o_Normals = LOCALS.Normal.xyz | |o_Components| GORILLA_GLSL_DEFINE_DEFERRED| o_Components = vec4(TexCoord0.xy, 1.0, 1.0) | |o_Ambient| GORILLA_GLSL_DEFINE_DEFERRED| o_Ambient = LOCALS.Ambient.xyz | |o_Emissive| GORILLA_GLSL_DEFINE_DEFERRED| o_Emissive = LOCALS.Emissive.xyz | |o_Specular| GORILLA_GLSL_DEFINE_DEFERRED| o_Specular = LOCALS.Specular.xyz | ===== Extending the default material ===== Here is a quick example for extending the default material to setup your own shader material to create a vertex color material. unit Gorilla.Material.VertexColor; interface uses System.SysUtils, System.Classes, FMX.Types, FMX.Types3D, FMX.Materials, FMX.MaterialSources, Gorilla.Material.Default; type TGorillaVertexColorMaterial = class(TGorillaDefaultMaterial) protected procedure DoCreateVertexShader(); override; procedure DoCreateFragmentShader(); override; public end; TGorillaVertexColorMaterialSource = class(TGorillaDefaultMaterialSource) protected function CreateMaterial() : TMaterial; override; public end; implementation uses Gorilla.Material.Default.GLSL; { TGorillaVertexColorMaterial } procedure TGorillaVertexColorMaterial.DoCreateVertexShader(); begin inherited; VertexShaderNode.AddDefine(GORILLA_GLSL_DEFINE_USE_COLOR); VertexShaderNode.RemoveDefine(GORILLA_GLSL_DEFINE_USE_TEXTURE); end; procedure TGorillaVertexColorMaterial.DoCreateFragmentShader(); begin inherited; FragmentShaderNode.AddDefine(GORILLA_GLSL_DEFINE_USE_COLOR); FragmentShaderNode.RemoveDefine(GORILLA_GLSL_DEFINE_USE_TEXTURE); end; { TGorillaVertexColorMaterialSource } function TGorillaVertexColorMaterialSource.CreateMaterial() : TMaterial; begin Result := TGorillaVertexColorMaterial.Create(Self); end; end. ==== Register a user-specific UniformBuffer ==== The default material allows to register more than one uniform buffer in shaders. To create a new user-specific uniform buffer, you will need a representation of that structure in your default material class. __Notice:__ Structures inside of Delphi need a fixed alignment to OpenGL's std140 layout. Read more about OpenGL memory alignment here: https://www.khronos.org/opengl/wiki/Interface_Block_(GLSL) At first we define a **packed record** structure inside of Delphi. PMyParams = ^TMyParams; TMyParams = packed record MyValue : Single; Reserved0 : Array[0..2] of Single; // taking care of memory alignment in TVector3D blocks. Point : TPoint3D; Reserved1 : Single; // taking care of memory alignment in TVector3D blocks. end; The example above shows a structure declaration with memory alignment (Reserved0 + Reserved1). It should help to understand, how OpenGL aligns memory in std140 layout. But in this exact case, we can optimize the record! Because //MyValue// and //Point// fields fit into a single //4 * 4 Byte memory block// of std140 alignment. PMyParams = ^TMyParams; TMyParams = packed record Point : TPoint3D; MyValue : Single; end; In GLSL the structure will appear as: layout (binding=1, std140) uniform MyParams{ vec3 _Point; float _MyValue; }; In the next step, create a field inside of your material to store TMyParams. TMyMaterial = class(TGorillaDefaultMaterial) protected FMyParams : TMyParams; /// override the update shader uniform buffers method to register our record in GPU. procedure DoUpdateShaderUniformBuffers(const Context: TContext3D; AProgram : TShaderProgram); override; end; And prepare values for shader: constructor TMyMaterial.Create(const ASource : TGorillaDefaultMaterialSource); begin inherited Create(ASource); FMyParams.MyValue := 0.25; FMyParams.Point := Point3D(1, -10, -1); end; Afterwards we implement our register function: procedure TMyMaterial.DoUpdateShaderUniformBuffers(const Context: TContext3D; AProgram : TShaderProgram); begin if not Assigned(AProgram) then Exit; inherited; /// let's register it in GPU shader. AProgram.RegisterUniformBuffer('MyParams', @FMyParams, SizeOf(FMyParams)); end; In case we have dynamic values and need to modify the record values, we can use the **DoApply()** method. Because the memory is directly linked to the GPU, we can simply modify any value in our record and it will automatically be updated in shader. procedure TGorillaWaterMaterial.DoApply(const Context: TContext3D); begin inherited; FMyParams.MyValue := Random(100) / 100; end; ==== Register a texture variable ==== Registering textures in shader is a little but different, but quite easy. Because the default material manages a pool of textures, we only have to add a texture to it, and the component will do the rest for us. Working further with our //TMyMaterial//, we need also a //TMyMaterialSource// to overwrite the protected **DoCreateDefaultBitmaps()** method. type TMyMaterialSource = class(TGorillaMaterialSource) protected procedure DoCreateDefaultBitmaps(); override; end; [...] procedure TMyMaterialSource.DoCreateDefaultBitmaps(); var LEntry: TGorillaBitmapPoolEntry; begin /// /// adding new textures before calling "inherited" /// LEntry := DoAddOrUpdateBitmapToPool("MYTEXTURE0", TPixelFormatEx.RGBA8, TPixelFormatEx.RGBA, GORILLA_DEFAULT_TEXTURE_DATATYPE, false, true, true); /// in case you need to, modify the wrapping and filtering settings if Assigned(LEntry) then LEntry.SetExtendedProperties( TGorillaTextureWrap.Repeated, TGorillaTextureWrap.Repeated, TGorillaTextureWrap.Repeated, TTextureFilter.Linear, TTextureFilter.Linear); inherited; /// /// modifying default (existing) textures after calling "inherited". /// LEntry := Self.FindBitmapEntryByName(GORILLA_MATERIAL_TEXTURE_NORMALMAP); if Assigned(LEntry) then LEntry.SetExtendedProperties( TGorillaTextureWrap.Repeated, TGorillaTextureWrap.Repeated, TGorillaTextureWrap.Repeated, TTextureFilter.Linear, TTextureFilter.Linear); end; ==== Register a single variable ==== To add individual variables to the shaders you need to override the shader setup method. **__Warning:__ This way adds a single variable to the shader and does not modify the uniform buffer!** ** __Warning:__ Do not use this way to register texture variables! ** (Read more about in the section above.) ^Shader ^Function ^ | VertexShader | DoSetupVertexShader(); | | FragmentShader | DoSetupFragmentShader(); | Then simply use the AddVariables() routine of the shader source: ^Shader ^Function ^ | VertexShader | FVSShaderSource.AddVariables([]); | | FragmentShader | FFSShaderSource.AddVariables([]); | Because variables need an incrementing index on registration, you need to supply the shader source specific variable: ^Shader ^Field ^ | VertexShader | FVSVarIndex | | FragmentShader | FFSVarIndex | Here is a short example: procedure TGorillaMyMaterial.DoSetupFragmentShader(); begin inherited; // use the fragment shader source to add a new variable FFSShaderSource.AddVariables( [ TContextShaderVariable.Create('MyPointF', TContextShaderVariableKind.Float2, FFSVarIndex, 0) ]); inc(FFSVarIndex, 1); end; === Declare the variable in GLSL source code === In the next step you need to add a new uniforms node in the specific shader. To access the node builder in the material, use one of the following variables: ^ Shader ^ Field ^ | VertexShader | VertexShaderNode | | FragmentShader | FragmentShaderNode | We add the new uniform node in the global uniform section of the node-tree to ensure, that is available anywhere in the code. **Take care to declare the variable name with the prefix "_"!** (Due to Firemonkey framework all uniform variables are declared by a leading underscore.) procedure TGorillaMyMaterial.DoCreateFragmentShader(); var LUniform : TGorillaGLSLUniformsNode; begin inherited; LUniform := TGorillaGLSLUniformsNode.Create(FragmentShaderNode); LUniform.AddDeclaration('_MyPointF', TGorillaShaderNodeVariableType.stVec2); FragmentShaderNode.Globals.Uniforms.Add(LUniform); end; You are allowed to add more than one variable in the uniforms node. There is no need to declare a single node for each variable. ==== Adding individual functions ==== To include a user specific function in shader source code, you need to declare a new node class inherited from TGorillaDeclarationNode. Then simply override the ToString() method and return your function declaration in shader language format. In the DoCreateVertexShader() or DoCreateFragmentShader() function you create an instance of your declared node type and add it to the global function section of the node builder. type TGorillaGLSLGetTextureColorFuncNode = class(TGorillaDeclarationNode) protected public function ToString() : String; override; end; function TGorillaGLSLGetTextureColorFuncNode.ToString() : String; begin Result := 'vec4 GetTextureColor(in sampler2D p_Texture, in vec2 p_TexCoord0){'#13#10 + ' return texture2D(p_Texture, p_TexCoord0);'#13#10 + '}'#13#10; end; procedure TGorillaMyMaterial.DoCreateFragmentShader(); var LNode : TGorillaNodeEntity; begin // FragmentShaderNode is the fragment shader node builder LNode := TGorillaGLSLGetTextureColorFuncNode.Create(FragmentShaderNode); FragmentShaderNode.Globals.Functions.Add(LNode); end; ==== Calling an individual functions ==== After we've declared our user specific function, we want to call it in the shader. For that we need a new node. Here the basic class //TGorillaNodeEntity// is quite perfect for the job. Afterwards we have to attach the node to the node-builder again. The insert point depends on the job to do, of course. In our example we've written a function that returns the current texture color. This is called base-color. The default shader declares a local variable "LOCALS.BaseColor" for that. If we set this, it will automatically be used in the color-light-summary. The entry point for this node operation is the surface-shader node in the fragment shader: "FragmentShaderNode.SurfaceShader". __Caution:__ The problem here is, that there is already a node (**TGorillaGLSLGetBaseColorNode**) that computes the "LOCALS.BaseColor" value. So we need to replace it with our node. But we have to ensure the correct position in node hierarchy for a valid shader code output. type TGorillaGLSLCallGetTextureColorNode = class(TGorillaNodeEntity) protected public function ToString() : String; override; end; function TGorillaGLSLCallGetTextureColorNode.ToString() : String; begin Result := 'LOCALS.BaseColor = GetTextureColor(_Texture0, l_TexCoord0);'#13#10; end; procedure TGorillaMyMaterial.DoCreateFragmentShader(); var LNode : TGorillaNodeEntity; LOldIdx : Integer; begin [...] LNode := TGorillaGLSLCallGetTextureColorNode.Create(FragmentShaderNode); /// replace base color request LOldIdx := FragmentShaderNode.SurfaceShader.IndexOf(TGorillaGLSLGetBaseColorNode, ''); if (LOldIdx > -1) then begin /// remove old basecolor node FragmentShaderNode.SurfaceShader.Delete(LOldIdx); FragmentShaderNode.SurfaceShader.Insert(LOldIdx, LNode); end else FragmentShaderNode.SurfaceShader.Insert(0, LNode); end; ==== Changing Shaders at DesignTime ==== Since 0.8.4 it's possible to modify your default shader at designtime, by using published properties *VertexShader* or *SurfaceShader*. Simply select your default material source, go to object inspector and open the text editor of the property. An empty GLSL function should be visible depending on the shader used. For VertexShader: void VertexShader(inout TLocals DATA){ } For SurfaceShader (Fragment/Pixel-Shader): void SurfaceShader(inout TLocals DATA){ } You can then modify or extend the shader functionality. Please have a look a the section [[#tgorillaglobalsnode_globals|Shader-Variables]] for the available fields in TLocals structure. **NOTICE:** //Modifying the vertex position in vertex-shader all 3 fields "DATA.Position", "DATA.TransfVertexPos" and "DATA.WorldViewProjVertPos" need to be modified. Otherwise their basis might not be equal which leads to unexpected effects!// In the following example we've created a wobbling effect in the vertex shader: vec2 DELPHI_HASH2(vec2 n){ return fract(sin(n)*1399763.5453123); } float DELPHI_NOISE(vec2 st){ vec2 i = floor(st); vec2 f = fract(st); vec2 u = f * f * (3.0 - 2.0 * f); float a = dot(DELPHI_HASH2(i + vec2(0.0,0.0)), f - vec2(0.0, 0.0)); float b = dot(DELPHI_HASH2(i + vec2(1.0,0.0)), f - vec2(1.0, 0.0)); float c = dot(DELPHI_HASH2(i + vec2(0.0,1.0)), f - vec2(0.0, 1.0)); float d = dot(DELPHI_HASH2(i + vec2(1.0,1.0)), f - vec2(1.0, 1.0)); return mix(mix(a, b, u.x), mix(c, d, u.x), u.y); } vec3 DELPHI_WOBBLE(vec3 pos, float time, float intensity){ return vec3(pos.x, pos.y + (DELPHI_NOISE(vec2(pos.x, pos.z) + time) * intensity), pos.z); } void VertexShader(inout TLocals DATA){ DATA.Position.xyz = DELPHI_WOBBLE(DATA.Position.xyz, _TimeInfo.y, 0.5); DATA.TransfVertexPos = _ModelMatrix * DATA.Position; DATA.WorldViewProjVertPos = _ModelViewProjectionMatrix * DATA.Position; } ===== Properties ===== Default material component provides a few easy-to-use properties for automatic defines settings. By using the following properties in your default material, you can setup the necessary defines, your shaders need for computation. ^Property^Description^ | UseLighting | Enable or disable lighting shading model computation in shader | | UseTexturing | Enable or disable texturing functionality (using tex2D and tex2DProj in shader) | | UseTexture0 | Enable or disable "_Texture0" uniform variable and accessing Texture property. | | UseVertexColor | Enable or disable to use vertex color rendering. | constructor TMyMaterial.Create(const ASource : TGorillaDefaultMaterialSource); begin inherited; UseTexturing := true; UseTexture0 := true; UseLighting := true; UseVertexColor := false; end;