views:

256

answers:

3

Hi all.

I'm currently working on a project using C++ and DirectX9 and I'm looking into creating a light source which varies in colour as time goes on.

I know C++ has a timeGetTime() function, but was wondering if anyone knows of a function in HLSL that will allow me to do this?

Regards. Mike.

+4  A: 

I am not familiar with HLSL, but I am with GLSL.

Shaders have no concept of 'time' or 'frames'. Vertex shader "understands" vertices to render, and pixel shader "understands" textures to render.

Your only option is to pass a variable to the shader program, in GLSL it is called a 'uniform', but I am not sure about HLSL.

I'm looking into creating a light source which varies in colour as time goes on.

There is no need to pass anything with that, though. You can directly set the light source's color (at least, you can in OpenGL). Simply change the light color on the rendering scene and the shader should pick it up from the built-in uniforms.

LiraNuna
+1  A: 

Nope. Shaders are essentially "one-way". The CPU can affect what's happening on the GPU (specify which shader program to run, upload textures and constants and such), but the GPU can not access anything on the CPU side of the fence. If the GPU (and your shader) needs a piece of data, it must be set by the CPU as a constant or written as a texture (or as part of the vertex data)

jalf
+4  A: 

Use a shader constant in HLSL (see this introduction). Here is example HLSL code that uses timeInSeconds to modify the texture coordinate:

// HLSL
float4x4 view_proj_matrix; 
float4x4 texture_matrix0; 
// My time in seconds, passed in by CPU program
float    timeInSeconds;

struct VS_OUTPUT 
{ 
   float4 Pos     : POSITION; 
   float3 Pshade  : TEXCOORD0; 
}; 


VS_OUTPUT main (float4 vPosition : POSITION) 
{ 
   VS_OUTPUT Out = (VS_OUTPUT) 0;  

   // Transform position to clip space 
   Out.Pos = mul (view_proj_matrix, vPosition); 

   // Transform Pshade 
   Out.Pshade = mul (texture_matrix0, vPosition);

   // Transform according to time
   Out.Pshade = MyFunctionOfTime( Out.Pshade, timeInSeconds );

   return Out; 
}

And then in your rendering (CPU) code before you call Begin() on the effect you should call:

// C++
myLightSourceTime = GetTime(); // Or system equivalent here:
m_pEffect->SetFloat ("timeInSeconds ", &myLightSourceTime);

If you don't understand the concept of shader constants, have a quick read of the PDF. You can use any HLSL data type as a constant (eg bool, float, float4, float4x4 and friends).

Justicle
Thanks everyone - These answers explain it perfectly :)
Mike