This project is read-only.

Xen 1.6 shader system (beta)

May 16, 2009 at 6:26 AM

Xen 1.6 is out, and includes a major reworking of the shader system (now with source).
Because of this, I anticipate there will be bugs. So please let me know if some of your code doesn't work, or something unexpected occurs.

Thanks.

May 16, 2009 at 9:43 AM

Prebuild failed

 

Build FAILED.

"E:\Мои проекты\xen16\xen\prebuild\sln\prebuild.sln" (Rebuild target) (1) ->
"E:\Мои проекты\xen16\xen\src\Xen.Ex\Xen.Ex.csproj" (Rebuild target) (5) ->
(CoreCompile target) ->
  Graphics2D\SpriteElement.cs(877,16): error CS0234: The type or namespace name
 'NonInstancingSprite' does not exist in the namespace 'Xen.Ex.Graphics2D' (are
 you missing an assembly reference?)
  Graphics2D\SpriteElement.cs(877,72): error CS0234: The type or namespace name
 'NonInstancingSprite' does not exist in the namespace 'Xen.Ex.Graphics2D' (are
 you missing an assembly reference?)
  Graphics2D\SpriteElement.cs(944,16): error CS0234: The type or namespace name
 'InstancingSprite' does not exist in the namespace 'Xen.Ex.Graphics2D' (are yo
u missing an assembly reference?)
  Graphics2D\SpriteElement.cs(944,69): error CS0234: The type or namespace name
 'InstancingSprite' does not exist in the namespace 'Xen.Ex.Graphics2D' (are yo
u missing an assembly reference?)
  Graphics2D\SpriteElement.cs(953,16): error CS0234: The type or namespace name
 'NonInstancingSprite' does not exist in the namespace 'Xen.Ex.Graphics2D' (are
 you missing an assembly reference?)
  Graphics2D\SpriteElement.cs(953,72): error CS0234: The type or namespace name
 'NonInstancingSprite' does not exist in the namespace 'Xen.Ex.Graphics2D' (are
 you missing an assembly reference?)

May 16, 2009 at 9:46 AM
Edited May 16, 2009 at 10:03 AM

Can you open Shader.fx.cs in Xen.Ex/Graphics2D and tell me what it says? (it should have written any exceptions as comments)

Thanks.

 

[Edit] I just realised it isn't using an invariant culture (again, *sigh*) I seem to always forget that. That is probably very likely the cause.
I've updated it with a change to force an invariant culture.

May 16, 2009 at 10:02 AM

Yep, just looked into it - problem was with some russian letters in folder name.

Thanks! :)

May 16, 2009 at 10:06 AM

You're right. I can reproduce it too :-)

May 16, 2009 at 10:13 AM

Huh. Odd.

It doesn't seem to be a problem with my code. When ShaderCompiler.CompileFromFile() is run, it passes in 'Мои проекты', and then the include handler runs with 'Мои проекты'. :-/
So it seems the shader compiler doesn't work with unicode file paths. 

I'll have a look and see if it's possible to use non-unicode paths in some way.

May 16, 2009 at 10:16 AM

On this shader custom tool gives an error. I know it's pretty badly written but previous tool worked on it without any problems:

 

//CompilerOptions = ParentNamespace

float4x4 WorldViewProjection : WORLDVIEWPROJECTION;
float4x4 World : WORLD;
//float4x4 View : VIEW;
//float4x4 Projection : PROJECTION;
float3 EyePosition : VIEWPOINT;
float4 DiffuseLightColor;
float3 LightPosition;

float LayerOneSharp; // This sharpens the edges of the layer, valid values are between 0 and 1. 0.6 is a good start
float LayerOneRough; // This sets the bleed of the layer. youd want this pretty wide, so 0.05 is a good start
float LayerOneContrib; // This is a multiplier for the final layer contribution, 0-1 is valid closer to 1 blows out the layer so, 0.05 is good
//Layer two also uses a specular function, it can provide a specular highlight or an additional paint layer
float LayerTwoSharp; //This should be very sharp 0.85 is a good default
float LayerTwoRough; //Highlight should be small 5.0f-10.0f is good start.
float LayerTwoContrib; //0.3 f wil get you pretty close to white without blowing the highlight out. Set it to 0 if you don't want a spec highlight
float EdgeOffset;

float4 blendMatrices[72*3];

texture2D ModelTexture;
sampler2D TextureSampler = sampler_state
{
 Texture = (ModelTexture);
};

struct VS_INPUT
{
 float4 Position : POSITION0;
 float3 Normal : NORMAL0;
 float2 Texcoord : TEXCOORD0;

};

struct VS_INPUT1
{
 float4 Position : POSITION0;
 float3 Normal : NORMAL0;
 float2 Texcoord : TEXCOORD0;
 float4 weights : BLENDWEIGHT;
 int4 indices : BLENDINDICES;
};

struct VS_OUTPUT1
{
 float4 Position : POSITION0;
 float3 Normal : TEXCOORD1;
 float3 ViewDirection : TEXCOORD2;
 float3 LightDirection : TEXCOORD3;
 float2 Texcoord : TEXCOORD0;
};

struct VS_OUTPUT2
{
 float4 Position : POSITION0;
 float4 Normal : TEXCOORD1;
};

VS_OUTPUT1 Transform(VS_INPUT Input)
{
 //float4x4 WorldViewProjection = mul(mul(World, View), Projection);
 float3 ObjectPosition = mul(Input.Position, World);
 
 VS_OUTPUT1 Output;
 Output.Normal = mul(Input.Normal, World);
 Output.Position = mul(Input.Position, WorldViewProjection);
 
 Output.ViewDirection = EyePosition - ObjectPosition;
 Output.LightDirection = LightPosition - ObjectPosition;
 Output.Texcoord = Input.Texcoord;
 
 return Output;
}

VS_OUTPUT1 TransformBlend(VS_INPUT1 Input)
{
 //float4x4 WorldViewProjection = mul(mul(World, View), Projection);
 
 float4x3 blendMatrix = transpose(float3x4(
  blendMatrices[Input.indices.x*3+0] * Input.weights.x + blendMatrices[Input.indices.y*3+0] * Input.weights.y + blendMatrices[Input.indices.z*3+0] * Input.weights.z + blendMatrices[Input.indices.w*3+0] * Input.weights.w,
  blendMatrices[Input.indices.x*3+1] * Input.weights.x + blendMatrices[Input.indices.y*3+1] * Input.weights.y + blendMatrices[Input.indices.z*3+1] * Input.weights.z + blendMatrices[Input.indices.w*3+1] * Input.weights.w,
  blendMatrices[Input.indices.x*3+2] * Input.weights.x + blendMatrices[Input.indices.y*3+2] * Input.weights.y + blendMatrices[Input.indices.z*3+2] * Input.weights.z + blendMatrices[Input.indices.w*3+2] * Input.weights.w
  ));
   
 float4 blendPosition = float4(mul(Input.Position, blendMatrix).xyz,1);
 
 float3 ObjectPosition = mul(Input.Position, World);
 
 VS_OUTPUT1 Output;
 Output.Normal = mul(Input.Normal, World);
 Output.Position = mul(blendPosition, WorldViewProjection);
 
 Output.ViewDirection = EyePosition - ObjectPosition;
 Output.LightDirection = LightPosition - ObjectPosition;
 Output.Texcoord = Input.Texcoord;
 
 return Output;
}

VS_OUTPUT2 Outline(VS_INPUT Input)
{
 //float4x4 WorldViewProjection = mul(mul(World, View), Projection);
 
 VS_OUTPUT2 Output;
 Output.Normal = mul(Input.Normal, World);
 Output.Position = mul(Input.Position, WorldViewProjection)+(mul(EdgeOffset, mul(Input.Normal, WorldViewProjection)));
 
 return Output;
}

VS_OUTPUT2 OutlineBlend(VS_INPUT1 Input)
{
 //float4x4 WorldViewProjection = mul(mul(World, View), Projection);
 
 float4x3 blendMatrix = transpose(float3x4(
  blendMatrices[Input.indices.x*3+0] * Input.weights.x + blendMatrices[Input.indices.y*3+0] * Input.weights.y + blendMatrices[Input.indices.z*3+0] * Input.weights.z + blendMatrices[Input.indices.w*3+0] * Input.weights.w,
  blendMatrices[Input.indices.x*3+1] * Input.weights.x + blendMatrices[Input.indices.y*3+1] * Input.weights.y + blendMatrices[Input.indices.z*3+1] * Input.weights.z + blendMatrices[Input.indices.w*3+1] * Input.weights.w,
  blendMatrices[Input.indices.x*3+2] * Input.weights.x + blendMatrices[Input.indices.y*3+2] * Input.weights.y + blendMatrices[Input.indices.z*3+2] * Input.weights.z + blendMatrices[Input.indices.w*3+2] * Input.weights.w
  ));
   
 float4 blendPosition = float4(mul(Input.Position, blendMatrix).xyz,1);
 
 VS_OUTPUT2 Output;
 Output.Normal = mul(Input.Normal, World);
 Output.Position = mul(blendPosition, WorldViewProjection)+(mul(EdgeOffset, mul(Input.Normal, WorldViewProjection)));
 
 return Output;
}

struct PS_INPUT
{
 float3 Normal : TEXCOORD1;
 float3 ViewDirection : TEXCOORD2;
 float3 LightDirection : TEXCOORD3;
 float2 Texcoord : TEXCOORD0;
};

float4 Cel(PS_INPUT Input) : COLOR0
{
 float3 Normal = normalize(Input.Normal);
 float3 ViewDirection = normalize(Input.ViewDirection);
 float3 NLightDirection = normalize(Input.LightDirection);
 
 float oneW = 0.18f * ( 1.0f - LayerOneSharp );
 float twoW = 0.18f * ( 1.0f - LayerTwoSharp );
 
 float NDotL = dot(Normal, NLightDirection);
 float3 Reflection = normalize(2.0f * NDotL * Normal - NLightDirection);
 
 float4 layerOneColor = smoothstep(0.72f-oneW, 0.72f+oneW, pow(saturate(dot(Reflection, ViewDirection)), LayerOneRough));
 float4 layerTwoColor = smoothstep(0.72f-twoW, 0.72f+twoW, pow(saturate(dot(Reflection, ViewDirection)), LayerTwoRough));
 
 float4 baseColor = tex2D(TextureSampler, Input.Texcoord) * DiffuseLightColor;
 
 float4 color = (baseColor + LayerOneContrib*layerOneColor) + LayerTwoContrib*layerTwoColor;
 color.a = 1.0;
 
 return color;
}

float4 Black() : COLOR
{
  return float4(0.0f, 0.0f, 0.0f, 1.0f);
}

technique ToonShading
{
 pass
 {
  VertexShader = compile vs_3_0 Transform();
  PixelShader = compile ps_3_0 Cel();
  //CullMode = CCW;
 }
}

technique ToonShadingBlend
{
 pass
 {
  VertexShader = compile vs_2_0 TransformBlend();
  PixelShader = compile ps_2_0 Cel();
  //CullMode = CCW;
 }
}

technique ToonOutline
{
 pass
 {
  VertexShader = compile vs_3_0 Outline();
  PixelShader = compile ps_3_0 Black();
  //CullMode = CW;
 }
}

technique ToonOutlineBlend
{
 pass
 {
  VertexShader = compile vs_2_0 OutlineBlend();
  PixelShader = compile ps_2_0 Black();
  //CullMode = CW;
 }
}

May 16, 2009 at 10:36 AM

Got it. There was a little mistake in some of my preshader code, where in the pixel preshader it was accessing vertex preshader data.
(That shader has a pixel preshader but not a vertex preshader, so it got a null reference exception).

Thank you again! :-)

May 16, 2009 at 10:46 AM

Beautiful!

Is there a way we can get a fix to unicode pathnames? Sometimes shaders get compiled, sometimes not.

If I put Xen into afolder with a russian name, Xen.Ex/Shaders/Depth.fx and Simple.fx are compiled, DepthInstance.fx doesnt - Can't open the file or something.

May 16, 2009 at 11:01 AM
Edited May 16, 2009 at 11:46 PM

No problem.
The fix was actually quite simple, instead of passing in the full path of the shader file into ShaderCompiler.CompileFromFile(), I tried just passing in the filename without directory. Works fine, because then the Include Handler doesn't get the full (corrupt) path.

The problem was with Instancing shaders for the xbox. These use #include <asm_vfetch> to tell the compiler to use vfetch (and include the macro). This required an Include Handler class, which was being passed in the corrupt directory.

So all good :-) Thank you very much for helping me track these down so quickly

May 16, 2009 at 11:12 AM

Not a problem at all. :)

I'll let you know if I dig anything else.