FXComposer超入門11
ディファードレンダリングとかディファードシェーディングとかいうやつをしてみる。
1.シーンに板と球とトーラスを追加する。
2.下の絵1のようになる。
3.[Effects]にある[DefaultEffect]と[Materials]にある[DefaultMaterial]を削除する。
4.[Effects]に空のCgFXを追加する。
5.下のコード1を追加したCgFXにコピペする。
/* % Description of my shader. % Second line of description for my shader. keywords: material classic date: YYMMDD */ //------------------------------------------ // Script //------------------------------------------ float Script : STANDARDSGLOBAL < string UIWidget = "none"; string ScriptClass = "scene"; string ScriptOrder = "standard"; string ScriptOutput = "color"; string Script = "Technique=DeferredRendering;"; > = 0.8; //------------------------------------------- // Global variable : Transform //------------------------------------------- float4x4 gWVP : WorldViewProjection <string UIWidget="none";>; float4x4 gWorld : World <string UIWidget="none";>; float4x4 gView : View <string UIWidget="none";>; float4x4 gProj : Projection <string UIWidget="none";>; //-------------------------------------------- // Global variable : Camera //-------------------------------------------- float4 gCameraPosition : POSITION < string UIWidget = "float"; string UIName = "Camera Pos"; string Object = "PerspectiveCamera"; string Space = "World"; > = { 10, 10, 10, 1 }; //-------------------------------------------- // Global variable //-------------------------------------------- // light info #define LIGHT_NUM (3) struct LightInfomation { float4 WorldPosition; float4 Color; }; LightInfomation gLight[LIGHT_NUM] = { { float4(0,0,30,1), float4(1,0,0,1) }, { float4(0,30,0,1), float4(0,1,0,1) }, { float4(30,0,0,1), float4(0,0,1,1) } }; float4 ClearColor < string UIWidget = "color"; string UIName = "Clear Color"; > = { 0.0, 0.0, 0.0, 1.f }; float ClearDepth < string UIWidget = "none"; > = 1.0; float2 ViewportSize : VIEWPORTPIXELSIZE < string UIWidget = "none"; string UIName = "Screen Size"; >; //-------------------------------------- // texture and sampler //-------------------------------------- // Final Image texture FinalScreen : RENDERCOLORTARGET < float2 ViewPortRatio = { 1.0, 1.0}; int MipLevels = 1; string Format = "X8R8G8B8"; string UIWidget = "none"; >; sampler2D FinalScreenSampler = sampler_state { texture = <FinalScreen>; WrapS = ClampToEdge; WrapT = ClampToEdge; MinFilter = Linear; MagFilter = Linear; }; // Final ZBuffer texture FinalZBuffer : RENDERDEPTHSTENCILTARGET < float2 ViewPortRatio = { 1.0, 1.0 }; int MipLevels = 1; string Format = "D24S8"; string UIWidget = "none"; >; sampler2D FinalZBufferSampler = sampler_state { texture = <FinalZBuffer>; WrapS = ClampToEdge; WrapT = ClampToEdge; MinFilter = Linear; MagFilter = Linear; }; // Final Image texture TemporaryScreen : RENDERCOLORTARGET < float2 ViewPortRatio = { 1.0, 1.0}; int MipLevels = 1; string Format = "X8R8G8B8"; string UIWidget = "none"; >; sampler2D TemporaryScreenSampler = sampler_state { texture = <TemporaryScreen>; WrapS = ClampToEdge; WrapT = ClampToEdge; MinFilter = Linear; MagFilter = Linear; }; // Position GBuffer texture PositionGBuffer : RENDERCOLORTARGET < float2 ViewPortRatio = { 1.0, 1.0}; int MipLevels = 1; string Format = "X8R8G8B8"; string UIWidget = "none"; >; sampler2D PositionGBufferSampler = sampler_state { texture = <PositionGBuffer>; WrapS = ClampToEdge; WrapT = ClampToEdge; MinFilter = Linear; MagFilter = Linear; }; // Normal GBuffer texture NormalGBuffer : RENDERCOLORTARGET < float2 ViewPortRatio = { 1.0, 1.0}; int MipLevels = 1; string Format = "X8R8G8B8"; string UIWidget = "none"; >; sampler2D NormalGBufferSampler = sampler_state { texture = <NormalGBuffer>; WrapS = ClampToEdge; WrapT = ClampToEdge; MinFilter = Linear; MagFilter = Linear; }; // Diffuse GBuffer texture DiffuseGBuffer : RENDERCOLORTARGET < float2 ViewPortRatio = { 1.0, 1.0}; int MipLevels = 1; string Format = "X8R8G8B8"; string UIWidget = "none"; >; sampler2D DiffuseGBufferSampler = sampler_state { texture = <DiffuseGBuffer>; WrapS = ClampToEdge; WrapT = ClampToEdge; MinFilter = Linear; MagFilter = Linear; }; // Depth GBuffer texture DepthGBuffer : RENDERDEPTHSTENCILTARGET < float2 ViewPortRatio = { 1.0, 1.0}; int MipLevels = 1; string Format = "D24S8"; string UIWidget = "none"; >; sampler2D DepthGBufferSampler = sampler_state { texture = <DepthGBuffer>; WrapS = ClampToEdge; WrapT = ClampToEdge; MinFilter = Linear; MagFilter = Linear; }; //-------------------------------------- // structure //-------------------------------------- //------------------------- // GBuffer // input struct GBufferInput { float4 Position : POSITION; float2 TexCoord : TEXCOORD0; float3 Normal : NORMAL; }; // vertex to pixel struct GBufferV2P { float4 Position : POSITION; float2 TexCoord : TEXCOORD0; float4 ViewPosition : TEXCOORD1; float3 ViewNormal : TEXCOORD2; float4 DiffuseColor : TEXCOORD3; }; // output struct GBufferOutput { float4 Position : COLOR0; float4 Normal : COLOR1; float4 DiffuseAlbedo : COLOR2; }; //------------------------ // Lighting // input struct LightingInput { float4 Position : POSITION; float2 TexCoord : TEXCOORD0; }; // vertex to pixel struct LightingV2P { float4 Position : POSITION; float2 TexCoord : TEXCOORD0; }; //------------------------ // make Screen // input struct ScreenInput { float4 Position : POSITION; float2 TexCoord : TEXCOORD0; }; // vertex to pixel struct ScreenV2P { float4 Position : POSITION; float2 TexCoord : TEXCOORD0; }; //-------------------------------------- // GBuffer pass //-------------------------------------- GBufferV2P GBufferVS(GBufferInput IN) { GBufferV2P OUT = (GBufferV2P)0; float4 world_position = mul(gWorld, IN.Position); float4 view_position = mul(gView, world_position); float4 proj_position = mul(gProj, view_position); float3 world_normal = mul((float3x3)gWorld, IN.Normal); float3 view_normal = mul((float3x3)gView, world_normal); OUT.Position = proj_position; OUT.TexCoord = IN.TexCoord; OUT.ViewNormal = view_normal; OUT.ViewPosition = view_position; OUT.DiffuseColor = float4(1.0,1.0,1.0,1.0); return OUT; } GBufferOutput GBufferPS(GBufferV2P IN) { GBufferOutput OUT = (GBufferOutput)0; //float depth = IN.ViewPosition.z/IN.ViewPosition.w; // convert from [-1,1] to [0,1] float3 normal = normalize( IN.ViewNormal ) * 0.5 + 0.5; OUT.Position = IN.ViewPosition; OUT.Normal = float4(normal, 1.0); OUT.DiffuseAlbedo = IN.DiffuseColor; return OUT; } //--------------------------------------- // Lighting pass //--------------------------------------- LightingV2P LightingVS(LightingInput IN) { LightingV2P OUT = (LightingV2P)0; OUT.Position = float4(IN.Position.xyz,1); OUT.TexCoord = float2(IN.TexCoord.xy); return OUT; } float4 LightingPS(LightingV2P IN) : COLOR0 { float3 view_position = tex2D( PositionGBufferSampler, IN.TexCoord).rgb; float3 view_normal = float3(0,0,0); float4 normal = tex2D( NormalGBufferSampler, IN.TexCoord ); // convert from [0,1] to [-1,1] view_normal = normal.rgb * 2.0 - 1.0; float4(view_normal,1); float4 depth = tex2D( DepthGBufferSampler, IN.TexCoord ); float4 color = float4(0,0,0,0); float3 view_camera_pos = mul((float3x3)gView, gCameraPosition.xyz); float3 eye_direction = normalize( view_camera_pos - view_position ); float4 diffuse = tex2D( DiffuseGBufferSampler, IN.TexCoord ); for(int i = 0; i < LIGHT_NUM; ++i) { float3 light_direction = mul((float3x3)gView,gLight[i].WorldPosition.xyz) - view_position; float3 L = normalize( light_direction ); float attenuation = 1.f/length( light_direction ); //color.rgb += attenuation * gLight[i].Color.rgb * diffuse.rgb * max( dot( L, world_normal ), 0 ); color.rgb += gLight[i].Color.rgb * diffuse.rgb * max( dot( L, view_normal ), 0 ); color.a = 1.0; } return color; } //--------------------------------------- // make Screen //--------------------------------------- ScreenV2P ScreenVS(ScreenInput IN) { ScreenV2P OUT = (ScreenV2P)0; OUT.Position = float4(IN.Position.xyz,1); OUT.TexCoord = float2(IN.TexCoord.xy); return OUT; } float4 ScreenPS(ScreenV2P IN) : COLOR0 { return tex2D(TemporaryScreenSampler, IN.TexCoord); } //---------------------------------------- // Deferred Rendering technique //---------------------------------------- technique DeferredRendering < string Script = "RenderColorTarget0=FinalScreen;" "RenderColorTarget1=;" "RenderColorTarget2=;" "RenderDepthStencilTarget=FinalZBuffer;" "ClearSetColor=ClearColor;" "ClearSetDepth=ClearDepth;" "Clear=Color;" "Clear=Depth;" "ScriptExternal=color;" "Pass=GBuffer;" "Pass=Lighting;" "Pass=Screen"; > { pass GBuffer < string Script = "RenderColorTarget0=PositionGBuffer;" "RenderColorTarget1=NormalGBuffer;" "RenderColorTarget2=DiffuseGBuffer;" "RenderDepthStencilTarget=DepthGBuffer;" "ClearSetColor=ClearColor;" "ClearSetDepth=ClearDepth;" "Clear=Color;" "Clear=Depth;" "Draw=Geometry;"; > { CullFaceEnable = true; ZEnable = true; ZWriteEnable = true; DepthTestEnable = true; DepthFunc = Less; DepthMask = true; BlendEnable = false; VertexProgram = compile vp40 GBufferVS(); FragmentProgram = compile fp40 GBufferPS(); } pass Lighting < string Script = "RenderColorTarget0=TemporaryScreen;" "RenderColorTarget1=;" "RenderColorTarget2=;" "RenderDepthStencilTarget=;" "ClearSetColor=ClearColor;" "ClearSetDepth=ClearDepth;" "Clear=Color;" "Clear=Depth;" "Draw=Buffer"; > { ZEnable = false; DepthTestEnable = false; DepthMask = false; ZWriteEnable = false; CullFaceEnable = false; BlendEnable = false; DepthFunc = LEqual; VertexProgram = compile vp40 LightingVS(); FragmentProgram = compile fp40 LightingPS(); } pass Screen < string Script = "RenderColorTarget0=;" "RenderColorTarget1=;" "RenderColorTarget2=;" "RenderDepthStencilTarget=;" "ClearSetColor=ClearColor;" "ClearSetDepth=ClearDepth;" "Clear=Color;" "Clear=Depth;" "Draw=Buffer"; > { ZEnable = false; DepthTestEnable = false; DepthMask = false; ZWriteEnable = false; CullFaceEnable = false; BlendEnable = false; DepthFunc = LEqual; VertexProgram = compile vp40 ScreenVS(); FragmentProgram = compile fp40 ScreenPS(); } }
6.下の絵2のようになることを確認する。
7.おしまい。