Overview
When you display your 3D models with X_ITE, by default it will use the Gouraud shader. This is a versatile shader that can cover a lot of your rendering needs. If this is not enough there is also a Phong shader available, adjustable with the browser shading option per scripting.
However, you will often want to perform special effects or special cases for your materials. To do this you will need to write a custom shader.
Example
Download ZIP Archive
Shaders and Shader Definition
WebGL uses the GLSL language to write shaders that can be run across all browsers. With X_ITE you create your own shader using ComposedShader and ShaderPart nodes and than attach the ComposedShader to the shader field of an Appearance node and that is a child’s play with Titania.
X3D
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| #X3D V4.0 utf8
DEF Timer TimeSensor {
loop TRUE
}
Transform {
children Shape {
appearance Appearance {
material ImageTexture {
url "image.png"
}
shaders DEF Shader ComposedShader {
inputOnly SFTime set_time
language "GLSL"
parts [
ShaderPart {
url "data:x-shader/x-vertex,#version 300 es
// Vertex Shader
...
uniform float set_time
...
"
}
ShaderPart {
type "FRAGMENT"
url "data:x-shader/x-fragment,#version 300 es
// Fragment Shader
...
"
}
]
}
}
geometry ElevationGrid { }
}
}
ROUTE Timer.time TO Shader.set_time
|
Once the X3D is defined we can now write the vertex and the fragment shader source. This is a simple example where a texture is applied to the geometry.
Vertex Shader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| #version 300 es
precision mediump float;
uniform mat4 x3d_TextureMatrix [x3d_MaxTextures];
uniform mat4 x3d_ModelViewMatrix;
uniform mat4 x3d_ProjectionMatrix;
in vec4 x3d_TexCoord0;
in vec4 x3d_Vertex;
out vec4 texCoord;
void
main ()
{
texCoord = x3d_TextureMatrix [0] * x3d_TexCoord0;
gl_Position = x3d_ProjectionMatrix * x3d_ModelViewMatrix * x3d_Vertex;
}
|
Fragment Shader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| #version 300 es
precision mediump float;
uniform sampler2D x3d_Texture2D [x3d_MaxTextures];
in vec4 texCoord;
out vec4 x3d_FragColor;
void
main ()
{
x3d_FragColor = texture (x3d_Texture2D [0], vec2 (texCoord));
}
|
Lighting and Transparency
Lighting is enabled if a Material node is used and some lights are on.
Normally the browser automatically determines the alpha treatment based on material, colors, and images, but you can force a alpha mode by setting the alphaMode field of a Appearance node.
Data Type Mapping
A ComposedShader node provides the capability to define custom fields like the Script node it does, these fields are then mapped to GLSL uniform variables. They are automatically updated and can be of any access type (initializeOnly, inputOnly, outputOnly or inputOutput).
Node fields
X3D texture type | GLSL variable type |
---|
X3DTexture2DNode | sampler2D |
X3DTexture3DNode | sampler3D |
X3DEnvironmentTextureNode | samplerCube |
X3D field types to GLSL data types
X3D field type | GLSL variable type | |
---|
SFBool | bool | |
SFColor | vec3 | |
SFColorRGBA | vec4 | |
SFDouble | float | |
SFFloat | float | |
SFImage | int [ ] | (width, height, comp, array) |
SFInt32 | int | |
SFMatrix3d | mat3 | |
SFMatrix3f | mat3 | |
SFMatrix4d | mat4 | |
SFMatrix4f | mat4 | |
SFNode | see node fields table | |
SFRotation | mat3 | 3×3 matrix representation |
SFString | not supported | |
SFTime | float | |
SFVec2d | vec2 | |
SFVec2f | vec2 | |
SFVec3d | vec3 | |
SFVec3f | vec3 | |
SFVec4d | vec4 | |
SFVec4f | vec4 | |
|
MFBool | bool [ ] | |
MFColor | vec3 [ ] | |
MFColorRGBA | vec4 [ ] | |
MFDouble | float [ ] | |
MFFloat | float [ ] | |
MFImage | int [ ] | (width, height, comp, array, width ...) |
MFInt32 | int [ ] | |
MFMatrix3d | mat3 [ ] | |
MFMatrix3f | mat3 [ ] | |
MFMatrix4d | mat4 [ ] | |
MFMatrix4f | mat4 [ ] | |
MFNode | see node fields table | |
MFRotation | mat3 [ ] | 3×3 matrix representation |
MFString | not supported | |
MFTime | float [ ] | |
MFVec2d | vec2 [ ] | |
MFVec2f | vec2 [ ] | |
MFVec3d | vec3 [ ] | |
MFVec3f | vec3 [ ] | |
MFVec4d | vec4 [ ] | |
MFVec4f | vec4 [ ] | |
Built-in Variables
A ComposedShader defines a number of special variables for the various shader stages. These built-in variables have special properties. They are usually for communicating with certain fixed-functionality. By convention, all predefined variables start with »x3d_«; no user-defined variables may start with this.
Type | Name | Comment |
---|
uniform float | x3d_LogarithmicFarFactor1_2 | this is a uniform value for logarithmic depth buffer computed as 1.0 / log2 (farPlane + 1.0). |
|
uniform vec4 | x3d_ClipPlane [x3d_MaxClipPlanes] | clip plane array |
uniform x3d_FogParameters | x3d_Fog | see table »Uniform Struct x3d_FogParameters« |
|
uniform x3d_LightSourceParameters | x3d_LightSource [x3d_MaxLights] | see table »Uniform Struct x3d_LightSourceParameters« |
|
uniform float | x3d_AlphaCutoff | alphaCutoff value from Appearance |
uniform x3d_PointPropertiesParameters | x3d_PointProperties | see table »Uniform Struct x3d_PointPropertiesParameters« |
uniform x3d_LinePropertiesParameters | x3d_LineProperties | see table »Uniform Struct x3d_LinePropertiesParameters« |
uniform x3d_FillPropertiesParameters | x3d_FillProperties | see table »Uniform Struct x3d_FillPropertiesParameters« |
|
uniform x3d_MaterialParameters | x3d_Material | see table »Uniform Struct x3d_MaterialParameters« |
|
uniform sampler2D | x3d_Texture2D [x3d_MaxTextures] | texture from Appearance texture field |
uniform samplerCube | x3d_TextureCube [x3d_MaxTextures] | texture from Appearance texture field |
uniform x3d_TextureCoordinateGeneratorParameters | x3d_TextureCoordinateGenerator [x3d_MaxTextures] | see table »Uniform Struct x3d_TextureCoordinateGeneratorParameters« |
|
uniform ivec4 | x3d_Viewport | viewport position and size |
uniform mat4 | x3d_ProjectionMatrix | projection matrix of the camera |
uniform mat4 | x3d_ModelViewMatrix | this is the product of object's transformation matrix and the inverse x3d_CameraSpaceMatrix |
uniform mat3 | x3d_NormalMatrix | object's normal matrix; this is the inverse transpose of the 3×3 submatrix of x3d_ModelViewMatrix |
uniform mat4 | x3d_TextureMatrix [x3d_MaxTextures] | object's texture matrix defined by nodes derived from X3DTextureTransformNode |
uniform mat4 | x3d_CameraSpaceMatrix | transformation matrix of the camera |
|
attribute float | x3d_FogDepth | fog depth of the vertex overriding Fog.visibilityRange; available if FogCoordinate is attached |
attribute vec4 | x3d_Color | color of the vertex; available if X3DColorNode is attached |
attribute vec4 | x3d_TexCoord0 | texture coordinate of the vertex from channel 0 |
attribute vec4 | x3d_TexCoord1 | texture coordinate of the vertex from channel 1 |
attribute vec3 | x3d_Normal | normal of the vertex |
attribute vec4 | x3d_Vertex | vertex coordinate, required |
Type | Name | Comment |
---|
vec3 | color | |
float | visibilityRange | |
mat3 | matrix | inverse fog space matrix, rotation and scale components |
Type | Name | Comment |
---|
int | type | x3d_DirectionalLight, x3d_PointLight, x3d_SpotLight |
vec3 | color | |
float | ambientIntensity | |
float | intensity | |
vec3 | attenuation | |
vec3 | location | location of light in view space coordinates |
vec3 | direction | |
float | beamWidth | |
float | cutOffAngle | |
float | radius | |
mat3 | matrix | inverse light space matrix, rotation and scale components |
Type | Name |
---|
float | ambientIntensity |
vec3 | diffuseColor |
vec3 | specularColor |
vec3 | emissiveColor |
float | shininess |
float | transparency |
Type | Name |
---|
float | pointSizeScaleFactor |
float | pointSizeMinValue |
float | pointSizeMaxValue |
vec3 | pointSizeAttenuation |
Type | Name |
---|
bool | applied |
int | linetype |
float | lineStippleScale |
sampler2D | texture |
Type | Name |
---|
bool | filled |
bool | hatched |
vec3 | hatchColor |
sampler2D | texture |
Uniform Struct x3d_TextureCoordinateGeneratorParameters
Type | Name |
---|
int | mode |
float | parameter [6] |
ParticleSystem
If the shader node is part of a ParticleSystem node the following attributes and uniforms are available.
Type | Name | Comment |
---|
attribute vec4 | x3d_Particle | vec4 (int life, float lifetime, float elapsedTime, int texCoordIndex0) |
attribute mat4 | x3d_ParticleMatrix | particle matrix, should be multiplied with x3d_Vertex |
uniform sampler2D | x3d_TexCoordRamp | texture coordinate ramp |
build-in | gl_InstanceId | available |
Built-in Constants
Some built-in variables are enumerated and have special values and meanings. The following table list all of them and their corresponding values.
Note: As of version 1.27 these constant are built-in.
Constant | Type | Name | Value | Comment |
---|
X_ITE | | | | defined |
|
x3d_ClipPlane | int | x3d_MaxClipPlanes | 6 | |
|
| int | x3d_MaxLights | 8 | |
x3d_LightType | int | x3d_DirectionalLight | 1 | |
| int | x3d_PointLight | 2 | |
| int | x3d_SpotLight | 3 | |
|
| int | x3d_MaxTextures | 2 | |
Logarithmic Depth Buffer
I assume pretty much every 3D programmer runs into Z-buffer issues sooner or later. Especially when doing planetary rendering; the distant stuff can be a thousand kilometers away but you still would like to see fine details right in front of the camera. First enable the logarithmic depth buffer:
1
2
3
4
5
6
7
8
9
| Script {
url "ecmascript:
function initialize ()
{
Browser .setBrowserOption ('LogarithmicDepthBuffer', true);
}
"
}
|
To address the issue of the depth not being interpolated in perspectively-correct way, add to the fragment shader:
1
2
3
4
5
6
7
8
9
10
11
| #version 300 es
uniform float x3d_LogarithmicFarValue1_2;
void
main ()
{
...
//https://outerra.blogspot.com/2013/07/logarithmic-depth-buffer-optimizations.html
gl_FragDepth = log2 (1.0 + 1.0 / gl_FragCoord .w) * x3d_LogarithmicFarFactor1_2;
}
|
Note: Logarithmic depth buffer is automatically enabled if a GeoViewpoint is bound.
See Also