From 27968d4da915759b411fc63f19318dfe58e19703 Mon Sep 17 00:00:00 2001 From: fredb Date: Tue, 16 Mar 2010 07:21:47 +0000 Subject: [PATCH] Bump map shader contributed by Emilian Huminiuc. Should be inherited from to be used in models. --- Effects/bumpspec.eff | 104 ++++++++++++++++++++++++++++++++++++++++++ Shaders/bumpspec.frag | 53 +++++++++++++++++++++ Shaders/bumpspec.vert | 53 +++++++++++++++++++++ 3 files changed, 210 insertions(+) create mode 100644 Effects/bumpspec.eff create mode 100644 Shaders/bumpspec.frag create mode 100644 Shaders/bumpspec.vert diff --git a/Effects/bumpspec.eff b/Effects/bumpspec.eff new file mode 100644 index 000000000..1fa9fd0c9 --- /dev/null +++ b/Effects/bumpspec.eff @@ -0,0 +1,104 @@ + + + + Effects/bumpspec + Effects/model-default + + 15 + 6 + 7 + + + + + /sim/rendering/shader-effects + + + 2.0 + + + + GL_ARB_shader_objects + GL_ARB_shading_language_100 + GL_ARB_vertex_shader + GL_ARB_fragment_shader + + + + + + + 0 + texture[0]/image + texture[0]/filter + texture[0]/wrap-s + texture[0]/wrap-t + texture[1]/internal-format + + + 1 + texture[2]/image + texture[2]/filter + texture[2]/wrap-s + texture[2]/wrap-t + texture[2]/internal-format + + + Shaders/bumpspec.vert + Shaders/bumpspec.frag + + tex_color + sampler-2d + 0 + + + tex_normal + sampler-2d + 1 + + + tex_specular + sampler-2d + 2 + + + + tex_color + sampler-2d + 0 + + + tex_normal + sampler-2d + 1 + + + + diff --git a/Shaders/bumpspec.frag b/Shaders/bumpspec.frag new file mode 100644 index 000000000..49ec8188e --- /dev/null +++ b/Shaders/bumpspec.frag @@ -0,0 +1,53 @@ +// -*- mode: C; -*- +// Licence: GPL v2 +// Authors: Original code by Thorsten Jordan, Luis Barrancos and others (dangerdeep.sf.net) +// Modified by Emilian Huminiuc (emilianh@gmail.com) (i4dnf on the flightgear forums). +// fixme: maybe lookup texmap is faster than pow(). Quick tests showed that this is not the case... + +uniform sampler2D tex_color; // (diffuse) color map, RGB +uniform sampler2D tex_normal; // normal map, RGB + A Specular + + +varying vec4 ecPosition; +varying vec3 lightdir, halfangle; + +void main() +{ + // get and normalize vector to light source + vec3 L = normalize(lightdir); + + // get and normalize normal vector from texmap + vec4 v = texture2D(tex_normal, gl_TexCoord[0].st); + vec3 N = normalize(vec3(v.xyz * 2.0 - 1.0)); + N.y = -N.y; + if (!gl_FrontFacing) + N = -N; + + // compute specular color + // get and normalize half angle vector + vec3 H = normalize(halfangle); + + // compute resulting specular color + vec3 specular_color = vec3(gl_FrontMaterial.specular) * + pow(max(dot(H, N), 0.0), gl_FrontMaterial.shininess); + + // compute diffuse color + vec3 diffuse_color = vec3(texture2D(tex_color, gl_TexCoord[0].st)); + + // handle ambient + diffuse_color = diffuse_color * mix(max(dot(L, N), 0.0), 0.6, gl_LightSource[0].ambient.r); + + specular_color = specular_color * v.a; + + // final color of fragment + vec3 final_color = clamp((diffuse_color + specular_color) * vec3(gl_LightSource[0].diffuse /*light_color*/), 0.0, 1.0); + + float fog_factor; + float fogCoord = ecPosition.z; + const float LOG2 = 1.442695; + fog_factor = exp2(-gl_Fog.density * gl_Fog.density * fogCoord * fogCoord * LOG2); + fog_factor = clamp(fog_factor, 0.0, 1.0); + + // output color is a mix between fog and final color + gl_FragColor = vec4(mix(vec3(gl_Fog.color), final_color, fog_factor), 1.0); +} diff --git a/Shaders/bumpspec.vert b/Shaders/bumpspec.vert new file mode 100644 index 000000000..9b49dcce6 --- /dev/null +++ b/Shaders/bumpspec.vert @@ -0,0 +1,53 @@ +// -*- mode: C; -*- +// Licence: GPL v2 +// Authors: Original code by Thorsten Jordan, Luis Barrancos and others (dangerdeep.sf.net) +// Modified by Emilian Huminiuc (emilianh@gmail.com) (i4dnf on the flightgear forums). + +/* input: +gl_Vertex +gl_Normal (tangentz) +gl_MultiTexCoord0 (texcoord) +tangentx_righthanded (tangentx,righthanded-factor) +*/ + +/* can we give names to default attributes? or do we need to use named attributes for that? +how to give named attributes with vertex buffer objects? +we could assign them to a variable, but would that be efficient? an unnecessary copy. +but the shader compiler should be able to optimize that... +the way should be to use vertex attributes (together with vertex arrays or VBOs), +that have a name and use that name here. +until then, access sources directly or via a special variable. +*/ + +varying vec4 ecPosition; +varying vec3 lightdir, halfangle; +attribute vec4 tangent, binormal; + +void main() +{ + ecPosition = gl_ModelViewMatrix * gl_Vertex; + + // compute direction to light in object space (L) + vec3 lightpos_obj = vec3(gl_ModelViewMatrixInverse * gl_LightSource[0].position); + vec3 lightdir_obj = normalize(lightpos_obj); + + // direction to viewer (E) + // compute direction to viewer (E) in object space (mvinv*(0,0,0,1) - inputpos) + vec3 viewerdir_obj = normalize(vec3(gl_ModelViewMatrixInverse[3]) - vec3(gl_Vertex)); + + // compute halfangle vector (H = ||L+E||) + vec3 halfangle_obj = normalize(viewerdir_obj + lightdir_obj); + + // transform light direction to tangent space + lightdir.x = dot(tangent, lightdir_obj); + lightdir.y = dot(binormal, lightdir_obj); + lightdir.z = dot(gl_Normal, lightdir_obj); + + halfangle.x = dot(tangent, halfangle_obj); + halfangle.y = dot(binormal, halfangle_obj); + halfangle.z = dot(gl_Normal, halfangle_obj); + + // finally compute position + gl_Position = ftransform(); + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; +}