269
edits
Line 200: | Line 200: | ||
=== Utility functions === | === Utility functions === | ||
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : <tt>gbuffer-functions.frag</tt> and <tt>gbuffer-encode.frag</tt>. | |||
==== gbuffer-encode.frag ==== | |||
;<tt>void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)</tt> | |||
:Used to encode all the values of the G-Buffer in material shaders | |||
==== gbuffer-functions.frag ==== | |||
;<tt>vec2 normal_encode(vec3 n)</tt> | |||
:Used to compress normals into the G-Buffer in material shaders. Normally called from <tt>encode_gbuffer()</tt> | |||
;<tt>vec3 normal_decode(vec2 enc)</tt> | |||
:Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders | |||
;<tt>vec3 float_to_color(in float f)</tt> | |||
:Encode float values in the range [0..1] in the 24 bits of a color. This function is used by <tt>encode_gbuffer()</tt> if the <tt>/sim/rendering/use-color-for_depth</tt> is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders. | |||
;<tt>float color_to_float(vec3 color)</tt> | |||
:Decode float values in the range [0..1] from the 24 bits of a color. This function is used by <tt>position()</tt> if the <tt>/sim/rendering/use-color-for_depth</tt> is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders. | |||
;<tt>vec3 position( vec3 viewDir, float depth )</tt> | |||
:Reconstruct eye space position from the view direction and the depth read from the depth buffer | |||
;<tt>vec3 position( vec3 viewDir, vec3 depthColor )</tt> | |||
:Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer | |||
;<tt>vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )</tt> | |||
:Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of <tt>/sim/rendering/use-color-for_depth</tt>) at a given fragment on screen, given by <tt>coords</tt> | |||
==== Usage ==== | |||
For material shaders, it is necessary to provide both <tt>gbuffer-functions.frag</tt> and <tt>gbuffer-encode.frag</tt> in the effect file, like this : | |||
<pre > | |||
<program> | |||
<vertex-shader>Shaders/ubershader.vert</vertex-shader> | |||
<fragment-shader>Shaders/ubershader-gbuffer.frag</fragment-shader> | |||
<fragment-shader>Shaders/gbuffer-functions.frag</fragment-shader> | |||
<fragment-shader>Shaders/gbuffer-encode.frag</fragment-shader> | |||
</program> | |||
</pre> | |||
For fullscreen passes shaders, only <tt>gbuffer-functions.frag</tt> should be provided, like this : | |||
<pre > | |||
<program> | |||
<vertex-shader>Shaders/sunlight.vert</vertex-shader> | |||
<fragment-shader>Shaders/sunlight.frag</fragment-shader> | |||
<fragment-shader>Shaders/gbuffer-functions.frag</fragment-shader> | |||
</program> | |||
</pre> | |||
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed : | |||
<pre> | |||
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth); | |||
main() { | |||
vec3 normal; | |||
vec3 color; | |||
int mId; | |||
float specular; | |||
float shininess; | |||
float emission; | |||
float depth; | |||
// Do shader computations | |||
encode_gbuffer(normal, color, mId, specular, shininess, emission, depth); | |||
} | |||
</pre> | |||
=== Geometry Stage === | === Geometry Stage === |
edits