This project is read-only.

An error in custom shader

Jun 2, 2009 at 2:14 PM


I tried to use custom shader from (topic of how to use skybox in XNA).

I added this sample .fx file to Project, using custom tool (XenFX).

but an error occured in .fx.cs

// Unhandled exception in XenFX:
//System.NullReferenceException: ??????????????? ?????????????????
//   ?? Xen.Graphics.ShaderSystem.CustomTool.Dom.ShaderBytes.ExtractBytes() ?? ...XenPath...\src\Xen.Graphics.ShaderSystem\Xen.Graphics.ShaderSystem.CustomTool\Dom\ShaderBytes.cs:? 75
//   ?? Xen.Graphics.ShaderSystem.CustomTool.Dom.ShaderBytes.Setup(IShaderDom shader) ?? ...XenPath...\src\Xen.Graphics.ShaderSystem\Xen.Graphics.ShaderSystem.CustomTool\Dom\ShaderBytes.cs:? 36
//   ?? Xen.Graphics.ShaderSystem.CustomTool.Dom.ShaderDom..ctor(SourceShader source, String techniqueName, Platform platform, CompileDirectives directives) ?? ...XenPath...\xen\src\Xen.Graphics.ShaderSystem\Xen.Graphics.ShaderSystem.CustomTool\Dom\ShaderDom.cs:? 77
//   ?? Xen.Graphics.ShaderSystem.CustomTool.Dom.SourceDom..ctor(SourceShader shader, String baseNamespace, CodeDomProvider provider) ?? ...XenPath...\src\Xen.Graphics.ShaderSystem\Xen.Graphics.ShaderSystem.CustomTool\Dom\Dom.cs:? 76
//   ?? Xen.Graphics.ShaderSystem.CustomTool.ShaderCodeGenerator.GenerateCode(String inputFileName, String inputFileContent, String fileNameSpace, CodeDomProvider codeProvider) ?? ...XenPath...\src\Xen.Graphics.ShaderSystem\Xen.Graphics.ShaderSystem.CustomTool\PluginEntry.cs:? 40

I don't know what i missed. I want to use Skybox...


Jun 3, 2009 at 3:31 AM


Thanks for reporting this. It's a bug on my part,
Don't worry, It's easy to fix!

When I built the system, I assumed that the vertex shader and pixel shader definition were case sensitive, but it seems they are not.
So simply change:

        vertexShader = compile vs_2_0 SkyboxVertexShader();
        pixelShader = compile ps_2_0 SkyboxPixelShader();


        VertexShader = compile vs_2_0 SkyboxVertexShader();
        PixelShader = compile ps_2_0 SkyboxPixelShader();

(Note that 'vertexShader' becomes 'VertexShader' with a capital V)
Do this and it should work fine! (I'll fix this in the next update)

Also, I suggest you add the VIEW / PROJECTION semantics, as Xen deals with these matrices for you:

uniform extern float4x4 ViewMatrix : VIEW;
uniform extern float4x4 ProjectionMatrix : PROJECTION;


Jun 3, 2009 at 5:19 AM


I tried to, and successed converting shader.

but using this shader, It looks Sphere of Gray, not Skybox.

this is my source 


In Load Method ------

skytexture = content.Load<TextureCube>(@"Textures\uffizi_cross"); // load texture

skysphere.ModelData = content.Load<ModelData>(@"Models\SphereHighPoly");  // load model data

In Draw Method ------

Skysphere.SkyboxTechnique shader = null;
shader = state.GetShader<Skysphere.SkyboxTechnique>();
shader.SkyboxTexture = skytexture;


I tried to change [shader.Bind(state); ] -> [// shader.Bind(state); ], Result was same.

It looks like a shader does not work. My way is wrong?

(and I have more question,  are VIEW and PROJECTION parameters automatically substitutied by Xen?)

Jun 3, 2009 at 5:30 AM
Edited Jun 3, 2009 at 5:32 AM


Yes, VIEW / PROJECTION are substituted, but only when you mark them with the semantics I mentioned in my earlier reply.

I can see the problem you are having.
When using a Model in xen, it internally will use a MaterialShader, as defined by the geometry in the mesh.

So you want to override this, and use your own shader. This can be done by using a 'shader provider' which lets you customize the shader used by the model.
You set this up when creating the ModelInstance, something like this:

	//This is an example!
	//create a shader
	var myShader = new FillSolidColour();
	//setup the shader, etc.
	myShader.FillColour = new Vector4(1,2,3,4);

	//create the model
	ModelInstance myModel;
	myModel = new ModelInstance();
	//add to content, etc.

	//create a 'shader provider' that uses 'myShader'
	var shaderProvider = new ModelInstanceShaderProvider(myShader);
	//set the model to use the shader provider
	//The model will now use the shader instead of it's own MaterialShader!

OR.. The other option, you could manually draw the geometry stored within the ModelData, something like this:

	foreach (var mesh in myModel.ModelData.Meshes)
		foreach (var geometry in mesh.Geometry)
			geometry.Vertices.Draw(state, geometry.Indices, PrimitiveType.TriangleList);
Jun 3, 2009 at 1:33 PM

thanks! You are kindly.

I tried to that

---------------------------------------- ( I edited fx file, marked VIEW, PROJECTION)

shader = state.GetShader<Skysphere.SkyboxTechnique>();
shader.SkyboxTexture = skytexture;
var provider = new ModelInstanceShaderProvider<Skysphere.SkyboxTechnique>(shader); /// ModelInstanceShaderProvider(shader) is occured compile error.


but in this case, Skysphere is not appear in screen. <- this fx file is not available in the Xen?

Sorry to be a lot of questions. but I want to know more about Xen.


Jun 3, 2009 at 11:37 PM

One thing to note, changes to render state in a shader are ignored by xen. There are many reasons for this (which I won't list right now)

So, the shader you have tries to set the CullMode to None and disable depth writing.
In order to replicate this, you would do something like the following:


	state.RenderState.DepthColourCull.CullMode = CullMode.None;
	state.RenderState.DepthColourCull.DepthWriteEnabled = false;

	//.. do your rendering as before...

	state.PopRenderState(); //reset the state to what it was when PushRenderState() was called

Jun 4, 2009 at 1:20 AM

Good! It's works perfectly. Thanks!