Hi guys,
I'm getting stuck on this one and feel ashamed not moving on with such a simple thing.
I got most of what implies making a Deferred Shader that uses all the great built in lighting, specular, depth SunBurn features but I can't get a result for a simple diffuse shader.
Let me explain, until now, in my project, I renderered my sun (Billboarded Quad) using a simple BasicEffect outside of RenderManager because it got lit by himself: I have Directional light which direction changes depending on camera position centered on the sun position.
But I am rewriting the whole Entity/Rendering part of my game engine (for float precision errors avoidance) and therefore started making some trials and seeking the web for a simple Diffuse deferred shader.
'Til now, I couldn't get it to work. Either I see nothing or nothing.
Could anyone point me to the right direction please? :)
I've stripped down a shader of mine (original coming from the Blend example) to use a simple diffuse:
Did a quick test, and it displays a diffuse texture just fine. I hope this is what you needed. :)
#include <DeferredHelper.fx>
float4x4 _World : WORLD;
float4x4 _View : VIEW;
float4x4 _Projection : PROJECTION;
float3 AmbientLighting
<
string SasBindAddress = "Sas.AmbientLight[0].Color";
> = 0;
float Time
string SasBindAddress = "Sas.Time.Now";
float TimeLast
string SasBindAddress = "Sas.Time.Last";
texture2D SceneLightingDiffuseMap : SCENELIGHTINGDIFFUSEMAP;
texture2D SceneLightingSpecularMap : SCENELIGHTINGSPECULARMAP;
sampler SceneLightingDiffuseSampler = sampler_state
{
Texture = <SceneLightingDiffuseMap>;
MipFilter = NONE;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = Clamp;
AddressV = Clamp;
};
sampler SceneLightingSpecularSampler = sampler_state
Texture = <SceneLightingSpecularMap>;
struct InputData
float4 position : POSITION;
float3 normal : NORMAL;
float2 uvCoord : TEXCOORD0;
struct ShaderLink
// used by the gpu for rasterizing the geometry.
// used to sample diffuse textures.
// used to calculate depth and fog.
float4 viewPosition : TEXCOORD1;
// used by the g-buffer for lighting.
float3 viewNormal : TEXCOORD2;
// used to multisample the deferred lighting textures.
float4 projectionPosition : TEXCOORD3;
float4 projectionPositionCentroid : TEXCOORD4_centroid;
ShaderLink BlendMapVS(InputData input)
ShaderLink output;
// calculate data for the pixel shader.
output.position = mul(input.position, _World);
output.position = mul(output.position, _View);
output.viewPosition = output.position;
output.position = mul(output.position, _Projection);
output.projectionPosition = output.position;
output.projectionPositionCentroid = output.position;
output.viewNormal = mul(input.normal, (float3x3)_World);
output.viewNormal = mul(output.viewNormal, (float3x3)_View);
output.uvCoord = input.uvCoord;
return output;
}
float4 BlendMapDepthPassPS(ShaderLink input) : COLOR
return 0;
SceneMRTData BlendMapGBufferPassPS(ShaderLink input)
// deferred data.
float depth = input.viewPosition.z / _FarClippingDistance;
float3 viewnormal = normalize(input.viewNormal);
// no spec/fres.
float specpower = 0.0f;
float3 fresnel_bias_offset_microfacet = 0.0f;
// use the shader helper function to automatically pack deferred
// data into the correct formats and g-buffers.
return SaveSceneData(viewnormal, depth, specpower, fresnel_bias_offset_microfacet.xyz);
texture2D DiffuseTexture;
sampler DiffuseSampler = sampler_state
Texture = <DiffuseTexture>;
AddressU = Wrap;
AddressV = Wrap;
float4 BlendMapFinalPassPS(ShaderLink input) : COLOR
float4 diffuse = tex2D(DiffuseSampler, input.uvCoord);
// calculate the screen-space uv coordinates used to sample
// from the full-screen deferred lighting textures.
float2 screenuvlinear = GetScreenUV(input.projectionPosition);
float2 screenuvcentroid = GetScreenUV(input.projectionPositionCentroid);
// 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);
// apply the unpacked lighting and SunBurn's automatic fog to the
// diffuse, and return the full material color.
float4 material = 0.0f;
material.xyz = LightMaterial(diffuse, float3(0.0f, 0.0f, 0.0f), lightingdiffuse + AmbientLighting, lightingspecular);
material.xyz = FogMaterial(material.xyz, input.viewPosition);
return material;
technique BlendMap_Depth_Technique
pass P0
VertexShader = compile vs_3_0 BlendMapVS();
PixelShader = compile ps_3_0 BlendMapDepthPassPS();
technique BlendMap_GBuffer_Technique
PixelShader = compile ps_3_0 BlendMapGBufferPassPS();
technique BlendMap_Final_Technique
PixelShader = compile ps_3_0 BlendMapFinalPassPS();
Contributor on the SunBurn sgMotion Animation Library open source project.
For a simple diffuse shader you can remove the wobble code (4 lines in the vertex shader) from the Custom Effects example wobble shader.
Let me know if this helps!
Follow me on Twitter – development and personal tweetsAwesome XNA Videos – Lighting, Rendering, and game videos
Hi Philippe,
Yes, that's the awesome part of SunBurn's deferred rendering it provides automatic lighting to custom shaders.
It also has built-in functions (via the shader library) for automatic fog, blending direct and ambient lighting, control over the automatic specular / fresnel power and amount, and more.
Tom,
I'm trying to do a simple shader myself. I have a thread here about what I am trying to accomplish.
I am using forward rendering, and I have applied a diffuse, specular, emissive, and normal map to my model. I want to light it using a custom shader so that the lights I use to light my model do not light other models nearby.
I want to use three point lights to do this.
I feel like your code here is a good start for that shader. How would I add a point light to this shader code? I am very inexperienced with shaders. Also, would the light I add in this shader use the materials I assigned to the model?
Hi,
the shader code I posted above is a Deferred shader. Since you're using Forward rendering, they are not compatible. I have not really done any multi light forward shaders so I can't really help you on that either I'm afraid.