Implemented 
That is, we have a new way to access in shader code useful utilities
vec4 position_world_to_eye_space(vec4 position_world);
vec4 position_eye_to_world_space(vec4 position_eye);
vec3 direction_world_to_eye_space(vec3 direction_world);
vec3 direction_eye_to_world_space(vec3 direction_eye);
and in effect you can get direction from camera to the point you’re rendering, in world space, in any shader (like the one attached using TCastleBackground.SetEffects
) and … do anything with this direction. Like query a cubemap (defined from 6 separate files, or a file format like DDS).
As usual, this was just committed to CGE master branch, and will be soon available in our downloads. You can observer this page, when it will no longer show commit “Support TEffectNode.SetShaderLibraries” then it is part of the downloads.
Below is a preliminary news (to post on Castle Game Engine – Open-Source 3D and 2D Game Engine one weekend) with details about this feature:
“Shader libraries” to enhance your shader effects in the future, for now: to get extra 4 GLSL functions to convert world<->eye space
We have added a new way to add additional functionality to your shaders, as defined using shader effects (our recommended way to write shader code in Castle Game Engine).
The Effect
node ([cgeref id=TEffectNode] in Pascal) gets additional property shaderLibraries
(string list). In Pascal you set it like this:
MyEffectNode.SetShaderLibraries(['castle-shader:/EyeWorldSpace.glsl']);
Right now, the castle-shader:/EyeWorldSpace.glsl
is the only possible value you can put there. But the system may be more flexible in the future, allowing us to expose more GLSL libraries (from the engine, using castle-shader:/
; other ideas may appear; note that you don’t need this to reuse shader setup in your own application, since you can just reuse own TEffectPartNode
multiple times).
Each “shader library” may define additional GLSL functions. It can also use PLUG_xxx
of the shader, thus augmenting the rendering or computation. The uniform values necessary for the library are automatically passed by the engine, so you don’t need to know/do anything more to use it.
The castle-shader:/EyeWorldSpace.glsl
, in particular, defines 4 new GLSL functions, available in both fragment and vertex stages:
vec4 position_world_to_eye_space(vec4 position_world);
vec4 position_eye_to_world_space(vec4 position_eye);
vec3 direction_world_to_eye_space(vec3 direction_world);
vec3 direction_eye_to_world_space(vec3 direction_eye);
Use them in your own shader code in your own EffectPart
nodes. Just make “forward declaration” for them first, like this (effect makes fog depending on point height in world space):
vec4 position_eye_to_world_space(vec4 position_eye);
// Save value obtained in PLUG_fragment_eye_space to use in PLUG_fragment_modify.
vec4 vertex_world;
// Get the vertex position in world space.
void PLUG_fragment_eye_space(
const vec4 vertex_eye,
inout vec3 normal_eye)
{
vertex_world = position_eye_to_world_space(vertex_eye);
}
// Make lower things enveloped in fog (turn into gray).
void PLUG_fragment_modify(
inout vec4 fragment_color)
{
const float fog_y_start = 0.5;
const float fog_y_max = -5.0;
if (vertex_world.y < fog_y_start) {
const vec4 bottom_fog_color = vec4(0.1, 0.1, 0.5, 1);
float factor = max(0.0,
(vertex_world.y - fog_y_max) /
(fog_y_start - fog_y_max));
fragment_color = mix(bottom_fog_color, fragment_color, factor);
}
}
The X3D file demonstrating this feature is in demo-models/compositing_shaders/fog_using_shader_library.x3dv at master · castle-engine/demo-models · GitHub
The Pascal example demonstrating this feature is in castle-engine/examples/viewport_and_scenes/shader_effects_on_background at master · castle-engine/castle-engine · GitHub . The “Effect: cube map” is using this to get 3D direction from camera to rendered point, in world space, and then use this direction to query a cubemap (loaded from DDS).
This deprecates: our Viewpoint.camera*Matrix
events. Their usage in practice was only to pass new uniforms to the shaders, but they were complicated to use, needed X3D Viewpoint node, routes, passing events… The new thing is trivial to setup if you already have code dealing with shaders using TEffectPartNode, in Pascal or in X3D. And it is trivial to implement too, it just does literally what you expect, i.e. adds extra GLSL code and makes sure it receives proper input (uniforms).