XNA Game Development Forums
2012/05/22 14:12:18 *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   Home   Help Search Calendar Login Register  
Pages: [1] 2
  Print  
Author Topic: My Shader Hell...  (Read 5369 times)
Nemo Krad
Global Moderator
Hero Member
*****
Offline Offline

Posts: 512


I have seen the fnords


View Profile WWW
« on: 2007/01/05 15:54:07 »

I am trying to use a glass shader for one of my objects and when I try and load the Cube asset I get a System.InvalidOperation exception with the message "The method call is invalid."

I am trying to load the cube map asset like this:
Code:
myCube = myLoader.Load<TextureCube>("Content/Textures/SkyBox/HazyMind/cubeMap");

Where cubeMap is a dds file (converted to xnb at compile time)

The stack trace looks like this:
Code:
   
at Microsoft.Xna.Framework.Graphics.TextureCube.CreateTexture(GraphicsDevice graphicsDevice, Int32 edgeLength, Int32 numberLevels, ResourceUsage usage, SurfaceFormat format, ResourceManagementMode resourceManagementMode)
   at Microsoft.Xna.Framework.Graphics.TextureCube..ctor(GraphicsDevice graphicsDevice, Int32 edgeLength, Int32 numberLevels, ResourceUsage usage, SurfaceFormat format, ResourceManagementMode resourceManagementMode)
   at Microsoft.Xna.Framework.Content.TextureCubeReader.Read(ContentReader input, TextureCube existingInstance)
   at Microsoft.Xna.Framework.Content.ContentReader.InvokeReader[T](ContentTypeReader reader, Object existingInstance)
   at Microsoft.Xna.Framework.Content.ContentReader.ReadObjectInternal[T](Object existingInstance)
   at Microsoft.Xna.Framework.Content.ContentReader.ReadObject[T]()
   at Microsoft.Xna.Framework.Content.ContentReader.ReadAsset[T]()
   at Microsoft.Xna.Framework.Content.ContentManager.Load[T](String assetName)
   at Randomchaos3DEngine.RCShaders.RCShader.LoadGraphicsContent(ContentManager myLoader) in C:\Development\XNA\Projects\Randomchaos3DEngine\Randomchaos3DEngine\RCShader.cs:line 68
   at Randomchaos3DEngine.RCShaders.RCShaderManager.LoadGraphicsContent(ContentManager myLoader) in C:\Development\XNA\Projects\Randomchaos3DEngine\Randomchaos3DEngine\RCShader.cs:line 36
   at Randomchaos3DEngine.RCGame.LoadGraphicsContent(Boolean loadAllContent) in C:\Development\XNA\Projects\Randomchaos3DEngine\Randomchaos3DEngine\RCGame.cs:line 162
   at Microsoft.Xna.Framework.Game.Initialize()
   at Randomchaos3DEngine.RCGame.Initialize() in C:\Development\XNA\Projects\Randomchaos3DEngine\Randomchaos3DEngine\RCGame.cs:line 193
   at Microsoft.Xna.Framework.Game.Run()
   at EngineDemo.EngineDemo.Main() in C:\Development\XNA\Projects\Randomchaos3DEngine\EngineDemo\EngineDemo.cs:line 26

Do I need to create an instance of TexureCube first??
Logged
mikeschuld
Administrator
Sr. Member
*****
Offline Offline

Posts: 389


View Profile WWW
« Reply #1 on: 2007/01/05 17:28:18 »

Not sure about this one. I haven't done any cubemapping since back before I started the first HMEngine in Managed DirectX.
Logged
Nemo Krad
Global Moderator
Hero Member
*****
Offline Offline

Posts: 512


I have seen the fnords


View Profile WWW
« Reply #2 on: 2007/01/06 10:20:22 »

Oh dear that is bad news....

I guess I will just have to plug away until I crack it. I will post up my resolution if and when I find it.

 Wink
Logged
Nemo Krad
Global Moderator
Hero Member
*****
Offline Offline

Posts: 512


I have seen the fnords


View Profile WWW
« Reply #3 on: 2007/01/07 05:13:27 »

Right,

I seem to have gotten over the issue above by swapping my cube for one that came with the FX Composer, I think the cube I am creating is not going down to well, have never created one before so I have no way of knowing what I am doing wrong.

But this has moved me on to another issue....
My glass.fx shader does not seem to be behaving at all, all I get is the black mask of the mesh with no effect on it at all.
Could one of you guys be so kind as to have a look at the shader and my code and tell me where I am going wrong?

First up, the shader:
Code:
float Script : STANDARDSGLOBAL <
    string UIWidget = "none";
    string ScriptClass = "object";
    string ScriptOrder = "standard";
    string ScriptOutput = "color";
    string Script = "Technique=dx9;";
> = 0.8;

/************* TWEAKABLES **************/

float4x4 worldIT : WorldInverseTranspose;
float4x4 wvp : WorldViewProjection;
float4x4 world : World;
float4x4 viewI : ViewInverse;

float reflectStrength
<
    string UIWidget = "slider";
    float UIMin = 0.0;
    float UIMax = 2.0;
    float UIStep = 0.01;
    string UIName =  "Reflection";
> = 1.0;

float refractStrength
<
    string UIWidget = "slider";
    float UIMin = 0.0;
    float UIMax = 2.0;
    float UIStep = 0.01;
    string UIName =  "Refraction";
> = 1.0;

half3 etas
<
    string UIName = "Refraction indices";
> = { 0.80, 0.82, 0.84 };

texture cubeMap : Environment
<
string ResourceName = "default_reflection.dds";
string ResourceType = "Cube";
>;

texture fresnelTex : Environment
<
string ResourceType = "2D";
string function = "generateFresnelTex";

float2 Dimensions = { 256.0f, 1.0f};
>;

samplerCUBE environmentMapSampler = sampler_state
{
Texture = <cubeMap>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
};

sampler2D fresnelSampler = sampler_state
{
Texture = <fresnelTex>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = None;
};

/************* DATA STRUCTS **************/

/* data from application vertex buffer */
struct appdata {
    float4 Position : POSITION;
    float4 UV : TEXCOORD0;
    float3 Normal : NORMAL;
};

/* data passed from vertex shader to pixel shader */
struct vertexOutput {
    float4 HPosition : POSITION;
    float4 TexCoord : TEXCOORD0;
    float3 WorldNormal : TEXCOORD1;
    float3 WorldView : TEXCOORD2;
};

/*********** vertex shader ******/

vertexOutput mainVS(appdata IN,
    uniform float4x4 WorldViewProj,
    uniform float4x4 WorldIT,
    uniform float4x4 World,
    uniform float4x4 viewI
) {
    vertexOutput OUT;
    float3 normal = normalize(IN.Normal);
    OUT.WorldNormal = mul(normal, (float3x3) WorldIT);
    float3 Pw = mul(IN.Position, World).xyz;
    OUT.TexCoord = IN.UV;
    OUT.WorldView = viewI[3].xyz - Pw;
    OUT.HPosition = mul(IN.Position, WorldViewProj);
    return OUT;
}

/********* pixel shader ********/

// modified refraction function that returns boolean for total internal reflection
float3
refract2( float3 I, float3 N, float eta, out bool fail )
{
float IdotN = dot(I, N);
float k = 1 - eta*eta*(1 - IdotN*IdotN);
// return k < 0 ? (0,0,0) : eta*I - (eta*IdotN + sqrt(k))*N;
fail = k < 0;
return eta*I - (eta*IdotN + sqrt(k))*N;
}

// approximate Fresnel function
float fresnel(float NdotV, float bias, float power)
{
   return bias + (1.0-bias)*pow(1.0 - max(NdotV, 0), power);
}

// function to generate a texture encoding the Fresnel function
float4 generateFresnelTex(float NdotV : POSITION) : COLOR
{
return fresnel(NdotV, 0.2, 4.0);
}

float4 mainPS(vertexOutput IN,
    uniform samplerCUBE EnvironmentMap,
    uniform half reflectStrength,
    uniform half refractStrength,
    uniform half3 etas
    ) : COLOR
{
    half3 N = normalize(IN.WorldNormal);
    float3 V = normalize(IN.WorldView);
   
  // reflection
    half3 R = reflect(-V, N);
    half4 reflColor = texCUBE(EnvironmentMap, R);

// half fresnel = fresnel(dot(N, V), 0.2, 4.0);
half fresnel = tex2D(fresnelSampler, dot(N, V));

// wavelength colors
const half4 colors[3] = {
    { 1, 0, 0, 0 },
    { 0, 1, 0, 0 },
    { 0, 0, 1, 0 },
};
       
// transmission
  half4 transColor = 0;
  bool fail = false;
    for(int i=0; i<3; i++) {
    half3 T = refract2(-V, N, etas[i], fail);
    transColor += texCUBE(EnvironmentMap, T) * colors[i];
}

    return lerp(transColor*refractStrength, reflColor*reflectStrength, fresnel);
}

/*************/

technique dx9 <
string Script = "Pass=p0;";
> {
pass p0  <
string Script = "Draw=geometry;";
> {
        VertexShader = compile vs_2_0 mainVS(wvp,worldIT,world,viewI);
        PixelShader = compile ps_2_0 mainPS(environmentMapSampler,reflectStrength, refractStrength,etas);
}
}

/***************************** eof ***/
As before with my bloom.fx shader I have simply taken the one from the nVidia FX Composer.

Here are my calls:-

In LoadGraphicsContent of the shader I am loading the cube and fresnel, I dont think I have ot but it behaves the same even if I dont:
Code:
    myCube = myLoader.Load<TextureCube>("Content/Textures/SkyBox/HazyMind/default_reflection");
    myFresnel = myLoader.Load<Texture2D>("Content/Textures/SkyBox/HazyMind/fresnel");

In SetParameters of the shader:
Code:
if (myEffect.Parameters["worldIT"] != null)
                myEffect.Parameters["worldIT"].SetValue(Matrix.Transpose(Matrix.Invert(World)));
            if (myEffect.Parameters["wvp"] != null)
                myEffect.Parameters["wvp"].SetValue(World * RCCameraManager.ActiveCamera.View * RCCameraManager.ActiveCamera.Projection);
            if (myEffect.Parameters["world"] != null)
                myEffect.Parameters["world"].SetValue(World);
            if (myEffect.Parameters["viewI"] != null)
                myEffect.Parameters["viewI"].SetValue(Matrix.Invert(RCCameraManager.ActiveCamera.View));
            if (myEffect.Parameters["cubeMap"] != null)
                myEffect.Parameters["cubeMap"].SetValue(myCube);
            if (myEffect.Parameters["fresnelTex"] != null)
                myEffect.Parameters["fresnelTex"].SetValue(myFresnel);
            if (myEffect.Parameters["reflectStrength"] != null)
                myEffect.Parameters["reflectStrength"].SetValue(1.0f);
            if (myEffect.Parameters["refractStrength"] != null)
                myEffect.Parameters["refractStrength"].SetValue(1.0f);
            if (myEffect.Parameters["etas"] != null)
                myEffect.Parameters["etas"].SetValue(new Vector3(0.80f, 0.82f, 0.84f));

Thanks in advance for putting up with my noob obsession with shaders  Grin
Logged
mikeschuld
Administrator
Sr. Member
*****
Offline Offline

Posts: 389


View Profile WWW
« Reply #4 on: 2007/01/07 17:25:25 »

Perhaps you should just wait it out till one or two more tutorials and I'll teach you how to do one yourself Smiley For now though I gotta finish up the logic in the octree but I'm sure someone will look at it for you.
Logged
Chr0n1x
Global Moderator
Sr. Member
*****
Offline Offline

Posts: 307


View Profile WWW
« Reply #5 on: 2007/01/07 18:33:13 »

The .dds files you use, are they from the FX Composer resource? Or self-made?
[EDIT]
Just to note before I say this, those strings in the shader file are for FX Composer only. Thats why if you notice, FX Composer is calling a function named GenerateFresnelTex. MAking me think thats where your problem lies, you need to figure out how to generate that texture.
(That glass shader in FX composer seems more like an off silverware shader Wink or a pearl shader.)
« Last Edit: 2007/01/07 18:40:22 by Chr0n1x » Logged

Nemo Krad
Global Moderator
Hero Member
*****
Offline Offline

Posts: 512


I have seen the fnords


View Profile WWW
« Reply #6 on: 2007/01/08 01:40:34 »

Mike,

I know you are busy mate, but thank for having a look. The Octree Tut was again a good solid tut, you may want to express a bit more clearly where the code sits in what class as you are creating them, other than that it's all good and I got it going fine. Had to tweak it a bit as my version of the HM engine is evolving a bit, probably due for a rewrite actually.

Cant wait to see your version of a glass shader Smiley 
I would like to know where I am going wrong trying to add this shader to the engine, I find that by fixing things, especially if I have broken them a good way to learn, just I am a bit stuck with this due to my lack of understanding.

Chr0n1x,

I have taken both of the .dds files from FX composer as I was struggling with my own versions of them (the cube map would not load).

If the fresnel is calculated then should I be passing the texture?

The thing that gets me is that if I use my cube map along with the given fresnel in FX Composer, it all works fine, yet when I try to use it in the engine it's not working (cant even load it!) so this makes me think that the files and shader are fine and it is my parameter loading that is wrong... But for the life of me I cant see where I am going wrong.

I understand that the elements in <> are for the FX Composer IDE and not part of the shader, I have left them in because I am lazy  Embarrassed

Thanks for taking the time guys, if you have any more ideas or suggestions I am all ears Smiley
« Last Edit: 2007/01/09 03:44:41 by Nemo Krad » Logged
Nemo Krad
Global Moderator
Hero Member
*****
Offline Offline

Posts: 512


I have seen the fnords


View Profile WWW
« Reply #7 on: 2007/01/10 13:50:40 »

 Grin

I have found out why my cube map was falling over with the System.InvalidOperation exception, my cube map was not power of 2, I re did it at 1024x1024 and it loads!

But my shader is still failing, all I get is the black unlit model, very depressing....
 Cry

If any one can help me with my shader I will pay you one hundred billion pounds (thats even more in US$! Smiley)...... well maybe not that much, I might just say thanks....
« Last Edit: 2007/01/10 13:52:51 by Nemo Krad » Logged
Nemo Krad
Global Moderator
Hero Member
*****
Offline Offline

Posts: 512


I have seen the fnords


View Profile WWW
« Reply #8 on: 2007/01/15 07:00:28 »

I have been given a working example of this shader (Thanks to Leaf. on MSDN http://www.divshare.com/download/48898-40c

But the way he is applying the shader is a little different to Mike.
Code:
        public void RenderChildren(GraphicsDevice myDevice)
        {
            RCShader shader = RCShaderManager.GetShader(myShader);
            shader.SetParameters(this, this.LightPosition);
           
            foreach (ModelMesh mesh in myModel.Meshes)
            {

                myDevice.Indices = mesh.IndexBuffer;
                shader.Effect.Begin();

                foreach (EffectPass pass in shader.Effect.CurrentTechnique.Passes)
                {
                    pass.Begin();

                    foreach (ModelMeshPart part in mesh.MeshParts)
                    {
                        myDevice.VertexDeclaration = part.VertexDeclaration;
                        myDevice.Vertices[0].SetSource(mesh.VertexBuffer, part.StreamOffset, part.VertexStride);

                        myDevice.Textures[0] = ((BasicEffect)part.Effect).Texture;

                        myDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, part.BaseVertex, 0, part.NumVertices, part.StartIndex, part.PrimitiveCount);

                    }
                    pass.End();
                }
                shader.Effect.End();
            }
        }

Where Leaf is doing it like this
Code:
                effect = content.Load<Effect>("Assets/Goal3_Solution");
                skull = content.Load<Model>("Assets/skullocc");

                envMap = content.Load<TextureCube>("Assets/LobbyCube");
                effect.Parameters["EnvironmentMap"].SetValue(envMap);
               

                foreach (ModelMesh mesh in skull.Meshes)
                {
                    foreach (ModelMeshPart part in mesh.MeshParts)
                    {
                        part.Effect = effect;
                    }
                }

Can anyone tell me or advise me on how I can get this effect to work in the HM XNA Engine?

Being the noob that I am I don't understand why Mike applies the shader the way he does, I know he wants more control over the rendering pipe but it seems as though we have lost some functionality. I know this is probably not the case and I am just not grasping fully what is going on here, but if someone could explain a bit more to me that would be great.

Thanks in advance.
Logged
Nemo Krad
Global Moderator
Hero Member
*****
Offline Offline

Posts: 512


I have seen the fnords


View Profile WWW
« Reply #9 on: 2007/01/16 07:53:05 »

Finally got this shader working, though to do so I replaced Mike's model drawing method with the one I got of Leaf. But I am sure this will all come out in the wash when Mike moved on to such shader techniques, so I will keep my mouth shut now Smiley

I think it looks dead good though, my tiny mind is so easily pleaed.....

The shader I used is here:
http://www.randomchaos.co.uk/XNA/shaders/glass.fx





Logged
Chr0n1x
Global Moderator
Sr. Member
*****
Offline Offline

Posts: 307


View Profile WWW
« Reply #10 on: 2007/01/16 17:59:09 »

That looks pretty nice, still confused why the nvidia glass shader has strong elements of single color in some areas (see 3rd image), but thats a problem with the shader.
Nice work.
Logged

Nemo Krad
Global Moderator
Hero Member
*****
Offline Offline

Posts: 512


I have seen the fnords


View Profile WWW
« Reply #11 on: 2007/01/17 01:21:18 »

I think it is supposed to. Unless I don't get quite what you mean. Its the way it is lensing the cube map. It looks OK to me when you have it on your screen, I guess it's harder to see from a still image. Have a go with it.
Logged
Droxx
Newbie
*
Offline Offline

Posts: 6


View Profile
« Reply #12 on: 2007/01/18 23:33:31 »

Just wanted to say thanks Nemo Krad, I've been following along the last couple of days. I too am struggling with shaders (or at least porting the output of composer/rendermonkey to something that actually works). I think a lot of folks diving into XNA are going to hit a wall in this area. I've spent the last two evenings trying to add a skybox to the tutorial 11 code, and I finally realized that the issue was with the TransformTexture shader, not a bug in my code.

Anyway, keep those awesome tutorials coming Mike!
Logged
Nemo Krad
Global Moderator
Hero Member
*****
Offline Offline

Posts: 512


I have seen the fnords


View Profile WWW
« Reply #13 on: 2007/01/19 01:11:02 »

Droxx,

No worries, its why we join forums like this to get help and where possible help others.

Glad my input has been of some use Smiley
Logged
Nemo Krad
Global Moderator
Hero Member
*****
Offline Offline

Posts: 512


I have seen the fnords


View Profile WWW
« Reply #14 on: 2007/02/09 05:03:36 »

This may well be a silly question but...

In an earlier post on this thread I altered mikes render children method to a basic render method to get my shader working
http://www.thehazymind.com/smf/index.php/topic,97.msg5638.html#msg5638

I have just got a book on Programming Vertex and Pixel Shaders and it describes having to create a Vertex Declaration, which Mike does but my basic version does not. Can anyone explain why this is so? Is the declaration done in the background?

Any one know?
Logged
Pages: [1] 2
  Print  
 
Jump to:  

Related Topics
Subject Started by Replies Views Last post
Shader compiler General Discussion endre 2 2368 Last post 2006/08/12 01:24:40
by Chr0n1x
Shader implemented fixed function Hazy Mind XNA Engine mikeschuld 2 2359 Last post 2006/11/07 02:07:22
by mikeschuld
Shader tutorials General Discussion endre 2 2242 Last post 2006/12/22 18:12:48
by mikeschuld
What's wrong with my shader? :'( Hazy Mind XNA Engine EclipsE 6 2640 Last post 2007/03/06 15:43:17
by EclipsE
Bumpmap Shader General Discussion « 1 2 3 4 5 » Nemo Krad 70 21691 Last post 2007/09/06 13:15:22
by Nemo Krad
Point Light Shader General Discussion Nemo Krad 0 2041 Last post 2007/03/18 07:18:13
by Nemo Krad
Model & Shader Problems Hazy Mind XNA Engine Themodem 5 2071 Last post 2007/03/26 11:12:53
by Tiago
Playing with lighting : intermediate shader techniques? Hazy Mind XNA Engine 5parrowhawk 3 2308 Last post 2009/03/18 23:04:27
by Chr0n1x
Powered by MySQL Powered by PHP Powered by SMF 1.1.12 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Page created in 0.324 seconds with 19 queries.