Page 1 of 1

adding shader variable

Posted: Mon Jan 02, 2017 9:03 pm
by Seven
playing around with the triplaner shader from the forum and trying to add a variable to the shader, but get error

all i add is this
float3 lightPosition;

but i get an error

HLSL Variable to set not found: 'lightPosition'. Available variables are:
'ambient' Registers:[begin:0, count:1]
'baseX' Registers:[begin:0, count:1]
'baseY' Registers:[begin:1, count:1]
'baseZ' Registers:[begin:2, count:1]
'diffuse' Registers:[begin:2, count:1]
'lightDirection' Registers:[begin:4, count:1]
'normalX' Registers:[begin:3, count:1]
'normalY' Registers:[begin:4, count:1]
'normalZ' Registers:[begin:5, count:1]
'specular' Registers:[begin:1, count:1]
'specularPower' Registers:[begin:3, count:1]

Code: Select all

 
//Note this is the 6 textures version, hence, you will need to recompile Irrlicht if you want
//to use it.
 
//And can be reduced further more if you use a single normal map, and sample it from every side
//everytime, leaving space for a shadowmap, the shader does the rest.
 
//More good news: Only PS2 required!
 
float4 ambient;
float4 specular;
float4 diffuse;
float specularPower;
float3 lightDirection;
float3 lightPosition;              // trying to add this variable
 
sampler2D baseX;
sampler2D baseY;
sampler2D baseZ;
sampler2D normalX;
sampler2D normalY;
sampler2D normalZ;
 
 
 
struct PS_INPUT
{
   float4 Position :        POSITION0;
   float2 TexcoordX :       TEXCOORD0;
   float2 TexcoordY :       TEXCOORD1;
   float2 TexcoordZ :       TEXCOORD2;
   float3 viewDirection   : TEXCOORD3;   
   float3x3 tangentSpace :  TEXCOORD4;
};
 
float4 ps_main( PS_INPUT Input ) : COLOR0
{      
   float3 fvLightDirection = normalize( lightDirection );
   float3 fvNormal         = normalize( Input.tangentSpace[2]);
   float3 fvViewDirection  = normalize( Input.viewDirection );
    
   float3 n                = fvNormal;
   n*=n;
   
   float4 fvBaseColor      = tex2D( baseX, Input.TexcoordX )*n.x+
                             tex2D( baseY, Input.TexcoordY )*n.y+
                             tex2D( baseZ, Input.TexcoordZ )*n.z;
 
   float4 fvBaseNormal     = tex2D( normalX, Input.TexcoordX )*n.x+
                             tex2D( normalY, Input.TexcoordY )*n.y+
                             tex2D( normalZ, Input.TexcoordZ )*n.z;
                             
   float3 normal           = normalize(mul(2.0*fvBaseNormal.xyz-1.0,Input.tangentSpace));    
    
   float  fNDotL           = max(0.0,dot( normal, fvLightDirection )); 
   float3 fvReflection     = reflect(fvLightDirection,normal);
   float  fRDotV           = max(0.0, dot( fvReflection, fvViewDirection ) );
                             
   float4 fvTotalAmbient   = ambient * fvBaseColor; 
   float4 fvTotalDiffuse   = diffuse * fNDotL * fvBaseColor; 
   float4 fvTotalSpecular  = specular * pow( fRDotV, specularPower )*fvBaseColor;
   
   float4 color = fvTotalAmbient + fvTotalDiffuse + fvTotalSpecular;
 
 
   return color;
      
}
 
 
 

Re: adding shader variable

Posted: Mon Jan 02, 2017 10:03 pm
by Foaly
If your shader does not use the variable, then the compiler will optimize it away.

Re: adding shader variable

Posted: Mon Jan 02, 2017 10:23 pm
by Seven
I should add that I use setShaderConstant("lightPosition",&myLightPosition); and that is what causes the error in the console window. if I remove some of the other shader variables it will accept this one, but of course the shader is nroken at that point :)

is there a limit to the number of variables for a shader?

Re: adding shader variable

Posted: Tue Jan 03, 2017 6:12 am
by Vectrotek
@Seven:
Unlike GLSL, HLSL is very fussy..
A variable fed from the app MUST DO SOMETHING..

You could add..

Code: Select all

 
float3 DummyVariable;
DummyVariable = lightPosition;
 
BUT.. That's not enough..
In HLSL there MAY NOT be any variables that don't "SOMEHOW TOUCH" the final output..
What I mean is that the variable MUST BE USED somehow.
I could guess how you want to use the LIGHT POSITION in the Light Calculation
but you could get your program running if you have something like..

Code: Select all

 
DummyVariable *= 0.00000001; // This is to get it as close to ZERO as possible because DummyVariable = 0; would cause the same error..
// Then, (just as a temporary measure near the end) do something like..
color.x += DummyVariable.x; // Which wouldn't really change the colour..
color.y += DummyVariable.y;
color.z += DummyVariable.z;
// This would fool HLSL into believing that you had USED the variable..
// Now at least it should compile, and you could now continue to work
// the "Position"  into your "Lighting" function..
 
// This is one of those things in HLSL that has caused many headaches!
// (I know..)
 
 
I hope it compiles now.. Let me know..

Re: adding shader variable

Posted: Tue Jan 03, 2017 6:26 am
by Vectrotek
Here is a copy of your code, but with a little something added..
Replace yours with this and see if it works..

Code: Select all

 
 
//Note this is the 6 textures version, hence, you will need to recompile Irrlicht if you want
//to use it.
 
//And can be reduced further more if you use a single normal map, and sample it from every side
//everytime, leaving space for a shadowmap, the shader does the rest.
 
//More good news: Only PS2 required!
 
 float4 ambient;
 float4 specular;
 float4 diffuse;
 float specularPower;
 float3 lightDirection;
 float3 lightPosition;              // trying to add this variable
 
 sampler2D baseX;
 sampler2D baseY;
 sampler2D baseZ;
 sampler2D normalX;
 sampler2D normalY;
 sampler2D normalZ;
 
 struct PS_INPUT
  {float4 Position :        POSITION0;
   float2 TexcoordX :       TEXCOORD0;
   float2 TexcoordY :       TEXCOORD1;
   float2 TexcoordZ :       TEXCOORD2;
   float3 viewDirection   : TEXCOORD3;   
   float3x3 tangentSpace :  TEXCOORD4;
  };
 
 float4 ps_main( PS_INPUT Input ) : COLOR0
  {float3 fvLightDirection = normalize( lightDirection );
   float3 fvNormal         = normalize( Input.tangentSpace[2]);
   float3 fvViewDirection  = normalize( Input.viewDirection );
   float3 n                = fvNormal;
   n *= n;
   float4 fvBaseColor      = tex2D( baseX, Input.TexcoordX )*n.x+
                             tex2D( baseY, Input.TexcoordY )*n.y+
                             tex2D( baseZ, Input.TexcoordZ )*n.z;
 
   float4 fvBaseNormal     = tex2D( normalX, Input.TexcoordX )*n.x+
                             tex2D( normalY, Input.TexcoordY )*n.y+
                             tex2D( normalZ, Input.TexcoordZ )*n.z;
   float3 normal           = normalize(mul(2.0*fvBaseNormal.xyz-1.0,Input.tangentSpace));    
   float  fNDotL           = max(0.0,dot( normal, fvLightDirection )); 
   float3 fvReflection     = reflect(fvLightDirection,normal);
   float  fRDotV           = max(0.0, dot( fvReflection, fvViewDirection ) );
   float4 fvTotalAmbient   = ambient * fvBaseColor; 
   float4 fvTotalDiffuse   = diffuse * fNDotL * fvBaseColor; 
   float4 fvTotalSpecular  = specular * pow( fRDotV, specularPower )*fvBaseColor;
   float4 color = fvTotalAmbient + fvTotalDiffuse + fvTotalSpecular;
 
   // * * * * * * * * * * * * * * * * * * *
   // TRY ADDING THIS..
   float3 DummyVariable;
   DummyVariable = lightPosition;
   DummyVariable *= 0.000000001;
   color.x += DummyVariable.x;
   color.y += DummyVariable.y;
   color.z += DummyVariable.z;  // Edited to "+="..
   // Which doesn't do much but fools the HLSL Compiler..
   // * * * * * * * * * * * * * * * * * * *
 
   return color;
  }
 

Re: adding shader variable

Posted: Tue Jan 03, 2017 12:10 pm
by Mel
As people is telling you, you must do something with the variable for it to work, in HLSL the unused variables are automatically removed from the generated code.

Looks like you're trying to add a point light to the shader, i'd do it in the vertex shader, there you could calculate the point light direction, and pass it to the pixel shader, then do the whole lighting equation on that point light, and add it to the final result :)

Good luck!

Re: adding shader variable

Posted: Thu Jan 05, 2017 1:40 am
by Seven
like a charm. thanks for the help!

Re: adding shader variable

Posted: Wed Jan 11, 2017 12:31 am
by Seven
everything working well but would be simpler to pass a structure instead of individual variables. Is it possible to pass the point light as such?

Re: adding shader variable

Posted: Wed Jan 11, 2017 8:18 pm
by Mel
There should be little diference, but passing the variables one by one allows for some optimizations to take place sooner, or even at all.