Shaders work differently in Sunburn?

rated by 0 users
This post has 12 Replies | 3 Followers

Top 25 Contributor
Posts 232
SunBurn_Community_Licensee
SunBurn_Pro_Licensee
2.0 Studios Posted: 02-24-2010 1:49 AM

G'day,

I figured out earlier how to get a shader running through sunburn. But the enviroment map shader behaves diferently in suburn, and I do not understand why.

Here is the shader rendered outside sunburn:
http://imgur.com/R9oYS&FOxzFl&brvod&JFq65


Here is the shader Rendered inside sunburn:

http://imgur.com/R9oYS&FOxzF&brvodl&JFq65

http://imgur.com/R9oYS&FOxzF&brvod&JFq65l

Here is me attempting make it accept shadwos in this shader:

http://i.imgur.com/R9oYS.png

As I move the camera closer to the sphere with my enviroment map on it, the reflection does not change. I can spin around to the front to see the reflection of the skull and it is there (although on the opposite side). But if I move in towards the spehere, the image rendered upon the sphere is always the same size. The sphere is smaller, but the skull rendered is the same. Almost as though my entire screen were a texture, and the sphere was a hole, and the skull was viewed through the hole.

The shadows also appear to render on the opposite side , almost as though I were looking through cloth at silhouettes.

The reflections should get all distorted by the object they are projected on, but are not.


I have no clue as to why the shader does this. As a bonus side note, when I get a small distance from the object, it's broken shadows stop working entirely!

Any help would be appreciated.

Top 10 Contributor
Posts 5,368
Employee
SunBurn_Studio_Licensee

Hi 2.0,

It looks like not all of your shader variables are being set prior to rendering.

Also in the first image the cube map looks like a static cube image, whereas the in-game shots are trying to reflect the scene.  If the shader is reflecting a full dynamic cube map in-game make sure the 6 cube camera locations are setup correctly.  To test the shader alone (without the dynamic cube map), try applying the same static cube map image from the first image.

Let me know if this helps!

Follow me on Twitter – development and personal tweets
Awesome XNA Videos – Lighting, Rendering, and game videos

Top 10 Contributor
Posts 338
SunBurn_Community_Licensee
SunBurn_Pro_Licensee

a full tutorial on this is at DiamondWare (http://diamondware.noads.biz/index.html) or you can get the 3.1 code directly from me at http://homepage.ntlworld.com/dugdiamond/binaries/DCM_HDR.rar.

Each face of the cube must be drawn from its' normal point of view. this requires the scene to be rendered SEVEN times; once for each of the cubemapfaces - these are passed into the custom shader, and then once the the final rendered scene.

The shader code demonstrates how to handle RealTime Dynamic Cubemapping & HDR-Bloom.

To get this to work in Sunburn, you could simple draw the scene similar to the ReflectRefraction Demo, but use the my shader instead of a reflaction plane.

Top 25 Contributor
Posts 232
SunBurn_Community_Licensee
SunBurn_Pro_Licensee

Hey, thanks for the responses.

But exactly what I am doing works perfectly outside of sunburn. I calculate my enviroment map 6 times correctly.  I've switched my dynamic map for a static one here:

http://i.imgur.com/oizC7.png

And you can probably see my problem. The cube map is not being distorted or stretched to cover the sphere. It is just impossibly flat.

Second of all, you can see the shadow as a line of darkness with a round bump in it. That round bump is an object that is behind the sphere (another sphere that is just part of my scene). But I am viewing this spehere from the front, so how is a shadow being cast on the wrong side? The camera is slightly below the ground, which is why you cannot see the ground.


I'll double check what I am passing in though.

//----------------------------------------------------- EDIT: Odd  progress.

Ok ok. I changed the way I am doing things, and cube maps work again (dynamically reflecting a spining skull a small distance away)
http://i.imgur.com/1SbF3.png

I loaded the effect via a .mat file.

            SASTestingEffect = g_ContentLoader.GeneralContent.Load<DeferredSasEffect>("Cube Mapping\\SASBall");

Then I wrote a function to use this effect:


        public void UpdateSASShader(SceneObject in_SceneObject, ISceneState in_Scenestate, Matrix in_WorldMatrix)
        {

//Change some graphics card settings here...
//Start my SAS effect...
//Iterate through the passes and rendarablemeshes in the scene object...
//End my SAS effect///
}

And it works! Now my next step is to get Shadows casted from the skull onto the terrain around, and shadows from the terrain and objects around, cast onto the skull. I assume I need more passes in my shader... Where can I pull these from?
 

Top 25 Contributor
Posts 232
SunBurn_Community_Licensee
SunBurn_Pro_Licensee

Ok now I can completely confused.

I seem to be passing in the shader through sunburn just so that I can bypass sunburn and render it with XNA. My skull will render with cube mapping but will not cast shadows nor will it receive shadows, which was very easy to do without sunburn.

If I attempt to use another object to render cube mapping with instead of the skull, the cube map is not distorted to fit the object it is being drawn on. It is just as though the object is a hole in in a texture looking through at another texture.

If I attempt to use the sunburn deferred lighting system on my skull I get this:

The vertex channel "TextureCoordinate0" is of type System.Single.  CalculateTangentFrames requires that the vertex channel indicated by the textureCoordinateChannelName parameter be of type Vector2

This is all very frustrating. There are loads of tutorials on cube mapping everywhere else, but not much helpfull info on dealing with suburn.

So I guess my number 1 question would be, how do I get sunburn lighting and shadows onto an object that is being effect by another shader?
 

Top 10 Contributor
Posts 5,368
Employee
SunBurn_Studio_Licensee

Hi 2.0,

2.0 Studios:
Now my next step is to get Shadows casted from the skull onto the terrain around, and shadows from the terrain and objects around, cast onto the skull. I assume I need more passes in my shader... Where can I pull these from?

With deferred the lighting and shadows are automatically generated for you, you only need to sample the results during the final composition pass using:


    // sample the pre-generated deferred lighting textures - use SunBurn's
    // multisampling helper function for anti-aliasing (only recommended for
    // deferred buffers).

    LightingMRTData data;
    data.lightingDiffuse = MultiSampleGBuffer(SceneLightingDiffuseSampler, screenuvlinear, screenuvcentroid);
    data.lightingSpecular = MultiSampleGBuffer(SceneLightingSpecularSampler, screenuvlinear, screenuvcentroid);
   
    // unpack the lighting data using SunBurn's helper function.   
    float3 lightingdiffuse = 0.0f;
    float3 lightingspecular = 0.0f;
    LoadLightingData(data, lightingdiffuse, lightingspecular);


Make sure these calls are included in your shader.

Please note there is a shadow technique you can define, but this is only for when your shader transforms vertices in a non-standard way (ie: not by using the World, View, Projection) - this is useful for things like morphing and terrains, but is not necessary in most shaders.

2.0 Studios:
If I attempt to use another object to render cube mapping with instead of the skull, the cube map is not distorted to fit the object it is being drawn on. It is just as though the object is a hole in in a texture looking through at another texture.

Make sure the cubemap is being generated at the new object's location - for this type of reflection to work the scene must be generated from the location of the object using the reflection.

Also make sure your shader is using the world space normals to lookup into the cubemap.  SunBurn's deferred rendering uses view-space normals, so the sample shader code uses them too - you cannot use these to sample the cubemap instead calculate a world-space normal for sampling.

2.0 Studios:
The vertex channel "TextureCoordinate0" is of type System.Single.  CalculateTangentFrames requires that the vertex channel indicated by the textureCoordinateChannelName parameter be of type Vector2

What modeling app are you using?  Is the file in X or FBX format?

I've never seen a single channel texture channel before, though it is possible I guess.  Try re-exporting the model.

Follow me on Twitter – development and personal tweets
Awesome XNA Videos – Lighting, Rendering, and game videos

Top 25 Contributor
Posts 232
SunBurn_Community_Licensee
SunBurn_Pro_Licensee

My other team member (which started this post) will probably reply in 10 hours or so but i can answer a few things...

We are using FBX for our model format and we are exporting them from Maya 2010.
So I understand that those calls must be in our shader but I was also wondering if we had to have all the techniques (i.e. Depth, GBuffer, Shadow) written too for the lighting and shadowing to work. (I thought that the depth pass was for making subsequent renders faster?

Sorry we are causing you so much trouble our shader knowledge is limited enough to write Depth Of Field and Cube map shaders and many post effects but neither of us is quite that good with the whole linking and materials etc...

 

Top 25 Contributor
Posts 232
SunBurn_Community_Licensee
SunBurn_Pro_Licensee

Ok, with your help we have gotten further.

http://i.imgur.com/3ineX.jpg

Daniel has merged most of the Enviromap shader into the Blend shader you guys have provided. Now it can be rendered with shadows, accepting shadows and it's funky broken cube mapping  using the .mat file system or just loading the effect.

JohnK "bobthecbuilder":
SunBurn's deferred rendering uses view-space normals

This may explain why the cube map was acting odd for me distorting the shadows, and not distorting the cube mapping on Daniel's Attempt. So we added some new View and Project matrices that are updated with Scenestate.View and SceneState.Projection.

This got us the cube map to wrap around the sphere correctly. But it does not distort when you move around like cube mapping should.

If you would like to have a look, we are happy to send it to you. Our experience in 3D and shaders is still rather small, although growing heaps.

Thankyou for all your help so far :)

-- Jarryd

 

 

 



 

Top 10 Contributor
Posts 5,368
Employee
SunBurn_Studio_Licensee

It sounds like the normals are still not in world space, or that the cameras generating the cubemap faces are rotating with the view (the cameras should stay locked on the major axes).

To convert the view normals to world space try this:


// define the following global variable - this is automatically connected to SunBurn via SAS...
float3x3 viewToWorld : VIEWINVERSE;

// then in your shader code...
float3 worldnormal = mul(viewnormal,
viewToWorld);


Follow me on Twitter – development and personal tweets
Awesome XNA Videos – Lighting, Rendering, and game videos

Top 10 Contributor
Posts 708
SunBurn_Community_Licensee
SunBurn_Contributor

JohnK "bobthecbuilder":


// define the following global variable - this is automatically connected to SunBurn via SAS...
float3x3 viewToWorld : VIEWINVERSE;

// then in your shader code...
float3 worldnormal = mul(viewnormal,
viewToWorld);


I tried to  add this, and it had a positive effect on the reflection. However when I "nod" with the camera up and down, it has an effect on the reflection of the cube-map. It seems I'm still using a view-space variable...

snippet of my VertexShader:

    float4 worldPosition = mul(input.position, _World);
    float3 worldNormal = mul(input.normal, viewToWorld);
 
	output.worldNormal = worldNormal;
 
	output.viewPosition = worldPosition;
 
    output.position = mul(mul(worldPosition, _View), _Projection);
 
    output.diffuseCoord = input.diffuseCoord;
    
 
    float3 eyePosition = mul(-_View._m30_m31_m32, transpose(_View));
 
    float3 viewVector = output.viewPosition - eyePosition;
    
    output.Reflection = reflect(viewVector, worldNormal); 
 
    output.Fresnel = saturate(1 + dot(normalize(viewVector), worldNormal));
    
    float lightAmount = max(dot(worldNormal, DirectionalLightDirection), 0);
 
    output.Lighting = AmbientLightColor + lightAmount * DirectionalLightColor;

Any ideas?

Contributor on the SunBurn sgMotion Animation Library open source project.

Top 10 Contributor
Posts 5,368
Employee
SunBurn_Studio_Licensee

Hi Tom,

Here's the problem:

Tom:
   float4 worldPosition = mul(input.position, _World);
   float3 worldNormal = mul(input.normal, viewToWorld);

The normal from the vertex stream is in mesh space and needs to be converted to world space (same as the position), you'll need to use the _World transform on it as well.

The quote from above regarding view-space normals is related to normals stored in SunBurn's deferred g-buffer.  All data from the vertex stream is in mesh space.

Let me know if this helps!

Follow me on Twitter – development and personal tweets
Awesome XNA Videos – Lighting, Rendering, and game videos

Top 10 Contributor
Posts 708
SunBurn_Community_Licensee
SunBurn_Contributor

I originally used _World at that part of the code, but that didn't work either. So changing it back is not the complete fix, maybe less broken :P

Contributor on the SunBurn sgMotion Animation Library open source project.

Top 10 Contributor
Posts 708
SunBurn_Community_Licensee
SunBurn_Contributor

The reflection part seems to be working right now...which is nice. However for some reason my Fresnel is always 1...(see above for code) the dot product seems to return 0 from every angle...I have no idea why?

Contributor on the SunBurn sgMotion Animation Library open source project.

Page 1 of 1 (13 items) | RSS