Game Development Community

Dynamic Lighting on parallax shader

by Paul Ash · in Torque Game Engine Advanced · 09/09/2007 (11:10 am) · 5 replies

Hello everyone ive been working to add dynamic lighting to the nool parallax shader. so far ive had little luck, here is what i have so far, if anyone can find any issues that would be most helpful


Vertex Shader:
#define IN_HLSL
#include "shdrConsts.h"
#include "shdrLib.h"

struct a2v 
{
	float4 texcoord        : TEXCOORD0;
	float3 lmCoord         : TEXCOORD1;
	float3 tangent         : TEXCOORD2;
	float3 binormal        : TEXCOORD3;
	float3 N               : TEXCOORD4;
	float3 normal          : NORMAL;
	float4 pos             : POSITION;
};

struct v2f
{
	float4 hpos     : POSITION;
	float3 eye      : TEXCOORD0;
	float3 light    : TEXCOORD1;
	float2 texcoord : TEXCOORD2;
	float3 lmcoord  : TEXCOORD3;
};

v2f main(a2v IN,
         uniform float4x4 modelview       : register(VC_WORLD_PROJ),
         uniform float4x4 texMat          : register(VC_TEX_TRANS1),
         uniform float3   lightpos        : register(VC_LIGHT_DIR1),
	   uniform float4   lightPosT       : register(VC_LIGHT_POS1),
         uniform float4   eyePos          : register(VC_EYE_POS),
         uniform float4x4 objTrans        : register(VC_OBJ_TRANS),
	   uniform float4x4 lightingMatrix  : register(VC_LIGHT_TRANS))
{
	v2f OUT;

	// vertex position in object space
	float4 pos=float4(IN.pos.x,IN.pos.y,IN.pos.z,1.0);

	// vertex position in clip space
	OUT.hpos=mul(modelview, pos);

	// copy color and texture coordinates
	OUT.texcoord = mul(texMat, IN.texcoord);
	
	// copy light map texture coordinates
	OUT.lmcoord = getDynamicLightingCoord(IN.pos, lightPosT, objTrans, lightingMatrix);

	// tangent vectors in view space
	float3x3 tangentspace=float3x3(IN.tangent,IN.binormal,IN.normal);

	// vertex position in view space (with model transformations)
	float3 vpos=mul(modelview, pos).xyz;

	// view in tangent space
	float3 objectspace_view_vector = mul( texMat, eyePos ) - IN.pos;
    OUT.eye = mul( tangentspace, objectspace_view_vector );
    OUT.eye = - OUT.eye;
	
	OUT.light.xyz = -lightpos;
	OUT.light.xyz = mul(tangentspace, OUT.light);
	OUT.light = OUT.light / 2.0 + 0.5;

	return OUT;
}


Pixel Shader

#define IN_HLSL
#include "shdrConsts.h"
#include "shdrLib.h"

struct v2f
{
	float4 hpos     : POSITION;
	float3 eye      : TEXCOORD0;
	float3 light    : TEXCOORD1;
	float2 texcoord : TEXCOORD2;
	float3 lmcoord  : TEXCOORD3;
};

float4 main(
	v2f IN,
	uniform sampler2D texmap     : register(S0),
	uniform sampler2D reliefmap  : register(S1),
	uniform sampler3D lightmap   : register(S2),
      uniform float4    lightColor : register(PC_DIFF_COLOR),
	uniform float4    ambient    : register(PC_AMBIENT_COLOR),
	uniform float4    specular   : register(PC_MAT_SPECCOLOR),
	uniform float     shine      : register(PC_MAT_SPECPOWER)
	) : COLOR
{
	const float3 diffuse  = {1,1,1};
	
   	// view and light directions
	float3 v = normalize(IN.eye);
	float3 l = normalize(IN.light);

	float2 uv = IN.texcoord;

	// parallax code
	float height = tex2D(reliefmap,uv).w * 0.06 - 0.03;
	uv += height * v.xy;

	// normal map
	float4 normal=tex2D(reliefmap,uv);
	normal.xyz=normalize(normal.xyz-0.5);
	normal.y=-normal.y;
	
	// color map
	float4 color=tex2D(texmap,uv);
	
	// light map
	float4 lm = getDynamicLighting(lightmap, IN.lmcoord, lightColor);

	// compute diffuse and specular terms
	float diff=saturate(dot(l,normal.xyz));
	float spec=saturate(dot(normalize(l-v),normal.xyz));
	
	// attenuation factor
	float att=1.0-max(0,l.z); att=1.0-att*att;

	// compute final color
	float4 finalcolor;
	finalcolor.xyz = ambient*color.xyz +
		att*(color.xyz*diffuse*diff + 
		specular*pow(spec,shine)) *
		lm;
	finalcolor.w=1.0;

	return finalcolor;
}
Ive worked with GLSL shaders before, just wish they where closer to HLSL haha

#1
09/10/2007 (1:16 am)
There is some documentation on TDN regarding implementing dynamic lights into your custom shaders. It just gives an example from the atlas dynamic lighting, and as a result is a bit confusing (I failed trying to add it into a shader), but might be place to look if you haven't visited it yet. I tried building a dynamiclighting material for a custom shader but it resulted in some bad artifacts in the lighting, like jagged lines that would move when I rotated the camera.
#2
09/10/2007 (7:59 am)
This is a result of using that not so good tutorial on the TDN actually. doesnt work at all best i could do was get it to no scream errors at me. so far ive had no luck with this, and have moved on to trying to get dynamic light working in relief mapping.
#3
09/10/2007 (8:58 am)
I haven't looked at this too closely. But some one idea about what could be going on:

Parallax mapping is going to change the normal of the pixel. So the lighting must take that into consideration. Here's a snippet of a procedural shader with bumpmapping:

float4 attn = tex3D(dlightMap, IN.dlightCoord) * lightColor;
   OUT.col *= attn;
   float4 bumpNormal = tex2D(bumpMap, IN.texCoord);

   float4 bumpDot = saturate( dot(bumpNormal.xyz * 2.0 - 1.0, normalize(IN.lightVec.xyz)) * IN.dlightCoord.w );
   OUT.col *= bumpDot;

There, the lighting vector and newly computed normal are dot product'ed (that's not a word!) and that is used to scale the light contribution.
#4
09/11/2007 (5:50 pm)
Hi Paul,

The shader register VC_LIGHT_DIR1 (used for lightpos) is undefined during dynamic lighting, which is all point based lighting. You're probably looking for the per-vertex vector from the light to the vert.

Try using the Lighting System shader lib function "getDynamicLightingDir" - it returns the lighting vector in the same space the parameters are provided in.
#5
10/03/2007 (11:01 am)
Hi Paul,

i tried to getting it going with no luck, a member call Matt Vitelli did but, i tried and it works great

link to the page is, The shader is at the bottom of the page,

http://www.garagegames.com/mg/forums/result.thread.php?qt=36211