1
0
Fork 0

Bump map shader contributed by Emilian Huminiuc. Should be inherited from to be used in models.

This commit is contained in:
fredb 2010-03-16 07:21:47 +00:00
parent 553d6f2c21
commit 27968d4da9
3 changed files with 210 additions and 0 deletions

104
Effects/bumpspec.eff Normal file
View file

@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Bump and specular effect
parameters :
texture[0] -> colormap
texture[2] -> normal map + specularity in alpha channel
eg :
in model.xml :
<effect>
<inherits-from>Aircraft/A320/Models/Effects/bumpspec</inherits-from>
<object-name>Fuselage</object-name>
</effect>
in Aircraft/A320/Models/Effects/a320_bumpspec.eff ( or whatever, private to the model )
<PropertyList>
<name>Aircraft/A320/Models/Effects/a320_bumpspec</name>
<inherits-from>Effects/bumpspec</inherits-from>
<parameters>
<texture n="2">
<image>Aircraft/A320/Models/Effects/textures/a320_normals.png</image>
<filter>linear-mipmap-linear</filter>
<wrap-s>repeat</wrap-s>
<wrap-t>repeat</wrap-t>
<internal-format>normalized</internal-format>
</texture>
</parameters>
</PropertyList>
-->
<PropertyList>
<name>Effects/bumpspec</name>
<inherits-from>Effects/model-default</inherits-from>
<generate>
<normal type="int">15</normal>
<tangent type="int">6</tangent>
<binormal type="int">7</binormal>
</generate>
<technique n="10">
<predicate>
<and>
<property>/sim/rendering/shader-effects</property>
<or>
<less-equal>
<value type="float">2.0</value>
<glversion/>
</less-equal>
<and>
<extension-supported>GL_ARB_shader_objects</extension-supported>
<extension-supported>GL_ARB_shading_language_100</extension-supported>
<extension-supported>GL_ARB_vertex_shader</extension-supported>
<extension-supported>GL_ARB_fragment_shader</extension-supported>
</and>
</or>
</and>
</predicate>
<pass>
<texture-unit>
<unit>0</unit>
<image><use>texture[0]/image</use></image>
<filter><use>texture[0]/filter</use></filter>
<wrap-s><use>texture[0]/wrap-s</use></wrap-s>
<wrap-t><use>texture[0]/wrap-t</use></wrap-t>
<internal-format><use>texture[1]/internal-format</use></internal-format>
</texture-unit>
<texture-unit>
<unit>1</unit>
<image><use>texture[2]/image</use></image>
<filter><use>texture[2]/filter</use></filter>
<wrap-s><use>texture[2]/wrap-s</use></wrap-s>
<wrap-t><use>texture[2]/wrap-t</use></wrap-t>
<internal-format><use>texture[2]/internal-format</use></internal-format>
</texture-unit>
<program>
<vertex-shader n="0">Shaders/bumpspec.vert</vertex-shader>
<fragment-shader n="0">Shaders/bumpspec.frag</fragment-shader>
<uniform>
<name>tex_color</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>tex_normal</name>
<type>sampler-2d</type>
<value type="int">1</value>
</uniform>
<uniform>
<name>tex_specular</name>
<type>sampler-2d</type>
<value type="int">2</value>
</uniform>
</program>
<uniform>
<name>tex_color</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>tex_normal</name>
<type>sampler-2d</type>
<value type="int">1</value>
</uniform>
</pass>
</technique>
</PropertyList>

53
Shaders/bumpspec.frag Normal file
View file

@ -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);
}

53
Shaders/bumpspec.vert Normal file
View file

@ -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;
}