Terrain Light

Started by
13 comments, last by Medo Mex 10 years, 9 months ago

Okay, so I have the following Pixel Shader for terrain texturing, unfortunately, it seems that I can't apply another shader (light shader) using LPD3DXEFFECT.

How do I apply effect file (light.fx) to the terrain as well for light?


ps_1_4

////////////////////////////////
// r0: alphamaps
// r1 - r4: textures
// r5: detail map
////////////////////////////////

// Sample textures
texld r0, t0 // scale 1
texld r1, t1 // scale 2
texld r2, t2 // scale 2
texld r3, t3 // scale 2
texld r4, t4 // scale 2
texld r5, t5 // scale 16

mul r1, r1, r0.x // multiply 1st tex with blendmap (red channel) and store result in 1st
lrp r2, r0.y, r2, r1 // lerp 2nd with 1st (blendmap green channel as factor) and store in 2nd
lrp r3, r0.z, r3, r2 // lerp 3rd with 2nd (blendmap blue channel as factor) and store in 3rd
lrp r0, r0.w, r4, r3 // lerp 4th with 3rd (blendmap alpha channel as factor) and store result in blendmap
mul r0, r5, r0 // multiply detail...

Advertisement

Wow, what light.fx?

You're not giving us enough information huh.png !

Well assuming that light.fx calculates the directional lighting (a guess, I don't have any information!!!), you could copy the essentials from the light.fx to your shader.

And between, why are you using the assembly? And not hlsl? I find hlsl easier to manage.

FastCall22: "I want to make the distinction that my laptop is a whore-box that connects to different network"

Blog about... stuff (GDNet, WordPress): www.gamedev.net/blog/1882-the-cuboid-zone/, cuboidzone.wordpress.com/

@Migi0027: Light.fx is light shader that I want to apply to the terrain (It doesn't matter directional, point, spot, etc...)

What matters is that I want the terrain to support both texture splatting and light as well, I have 2 shader for both (the above one and light.fx)

I want to convert the above code from assemly to HLSL so I can use it in my light shader.

First of all, do you understand the shader above?

FastCall22: "I want to make the distinction that my laptop is a whore-box that connects to different network"

Blog about... stuff (GDNet, WordPress): www.gamedev.net/blog/1882-the-cuboid-zone/, cuboidzone.wordpress.com/

I want to convert the above code from assemly to HLSL so I can use it in my light shader

Have you tried? What was the result?

FastCall22: "I want to make the distinction that my laptop is a whore-box that connects to different network"

Blog about... stuff (GDNet, WordPress): www.gamedev.net/blog/1882-the-cuboid-zone/, cuboidzone.wordpress.com/

@Migi0027: I'm getting started with shaders, so I'm not sure how to convert the above assembly to HLSL.

Since i am bored i get you started a bit:


float4x4 WorldViewProj;
float4x4 World;
 
texture r0_tex;
sampler r0_samp  = sampler_state
{
    Texture     = <r0_tex>;
    MIPFILTER   = LINEAR;
    MAGFILTER   = LINEAR;
    MINFILTER   = LINEAR;
};
 
texture r1_tex;
sampler r1_samp  = sampler_state
{
    Texture     = <r1_tex>;
    MIPFILTER   = LINEAR;
    MAGFILTER   = LINEAR;
    MINFILTER   = LINEAR;
};
 
texture r2_tex;
sampler r2_samp  = sampler_state
{
    Texture     = <r2_tex>;
    MIPFILTER   = LINEAR;
    MAGFILTER   = LINEAR;
    MINFILTER   = LINEAR;
};
 
texture r3_tex;
sampler r3_samp  = sampler_state
{
    Texture     = <r3_tex>;
    MIPFILTER   = LINEAR;
    MAGFILTER   = LINEAR;
    MINFILTER   = LINEAR;
};
 
texture r4_tex;
sampler r4_samp  = sampler_state
{
    Texture     = <r4_tex>;
    MIPFILTER   = LINEAR;
    MAGFILTER   = LINEAR;
    MINFILTER   = LINEAR;
};
 
texture r5_tex;
sampler r5_samp  = sampler_state
{
    Texture     = <r5_tex>;
    MIPFILTER   = LINEAR;
    MAGFILTER   = LINEAR;
    MINFILTER   = LINEAR;
};
 
struct VERTEX
{
    float3 Pos : POSITION;
    float3 Normal : NORMAL;
    float2 TexCoord : TEXCOORD0;
};
 
struct VS_OUTPUT
{
    float4 Pos : POSITION;
    float3 PosWorld : TEXCOORD0;
    float3 NormalWorld : TEXCOORD1;
    float2 TexCoord : TEXCOORD2;
};
 
struct PS_OUTPUT
{
    float4 Color : COLOR0;
};
 
void VertexProgram( in VERTEX IN, out VS_OUTPUT OUT )
{
     OUT.Pos = mul( float4(IN.Pos, 1.0f), WorldViewProj );
     OUT.PosWorld = mul( float4(IN.Pos, 1.0f), World );
     OUT.NormalWorld = mul( float4(IN.Normal, 0.0f), World );
     OUT.TexCoord = IN.TexCoord;
}
 
void PixelProgram( in VS_OUTPUT IN, out PS_OUTPUT OUT )
{
    float r0TexCoordScale = 1.0f;
    float r1TexCoordScale = 2.0f;
    float r2TexCoordScale = 2.0f;
    float r3TexCoordScale = 2.0f;
    float r4TexCoordScale = 2.0f;
    float r5TexCoordScale = 16.0f;
 
     float4 r0 = tex2D( r0_samp, IN.TexCoord * r0TexCoordScale );
     float4 r1 = tex2D( r1_samp, IN.TexCoord * r1TexCoordScale );
     float4 r2 = tex2D( r2_samp, IN.TexCoord * r2TexCoordScale );
     float4 r3 = tex2D( r3_samp, IN.TexCoord * r3TexCoordScale );
     float4 r4 = tex2D( r4_samp, IN.TexCoord * r4TexCoordScale );
     float4 r5 = tex2D( r5_samp, IN.TexCoord * r5TexCoordScale );
 
    r1 = r1 * r0.x;
    r2 = lerp( r2, r1, r0.y );
    r3 = lerp( r3, r2, r0.z );
    r0 = lerp( r4, r3, r0.w );
    r5 = r5 * r0;
 
    OUT.Color = float4(r5.xyz, 1.0f);
}
 
technique TerrainTech
{
    pass p0
    {
        VertexShader = compile vs_3_0 VertexProgram();
        PixelShader  = compile ps_3_0 PixelProgram();
    }
}

1. Note that i have done this by hand, so it might contain typos.

2. You must add your lightning calculations.

3. Might not work as i did not test it.

@belfegor: I have made modifications to correct the code, it works, but I notice that the terrain quality is not same, it's too bright.

Before, it was much better.

Why it got too bright? I want to get the same as the old results...

[attachment=16962:before_after.png]

Here is the shader code (Modified):


float4x4 World;
float4x4 WorldViewProj;

texture r0_tex;
sampler r0_samp  = sampler_state
{
    Texture     = <r0_tex>;
    MIPFILTER   = LINEAR;
    MAGFILTER   = LINEAR;
    MINFILTER   = LINEAR;
};

texture r1_tex;
sampler r1_samp  = sampler_state
{
    Texture     = <r1_tex>;
    MIPFILTER   = LINEAR;
    MAGFILTER   = LINEAR;
    MINFILTER   = LINEAR;
};

texture r2_tex;
sampler r2_samp  = sampler_state
{
    Texture     = <r2_tex>;
    MIPFILTER   = LINEAR;
    MAGFILTER   = LINEAR;
    MINFILTER   = LINEAR;
};

texture r3_tex;
sampler r3_samp  = sampler_state
{
    Texture     = <r3_tex>;
    MIPFILTER   = LINEAR;
    MAGFILTER   = LINEAR;
    MINFILTER   = LINEAR;
};

texture r4_tex;
sampler r4_samp  = sampler_state
{
    Texture     = <r4_tex>;
    MIPFILTER   = LINEAR;
    MAGFILTER   = LINEAR;
    MINFILTER   = LINEAR;
};

texture r5_tex;
sampler r5_samp  = sampler_state
{
    Texture     = <r5_tex>;
    MIPFILTER   = LINEAR;
    MAGFILTER   = LINEAR;
    MINFILTER   = LINEAR;
};

struct VERTEX
{
    float3 Pos : POSITION;
    float2 TexCoord : TEXCOORD0;
    float3 Normal : NORMAL;
};

struct VS_OUTPUT
{
    float4 Pos : POSITION;
    float3 PosWorld : TEXCOORD0;
    float3 NormalWorld : TEXCOORD1;
    float2 TexCoord : TEXCOORD2;
};

VS_OUTPUT VertexProgram( VERTEX IN )
{
     VS_OUTPUT OUT;
     OUT = (VS_OUTPUT)0;
     OUT.Pos = mul( float4(IN.Pos, 1.0f), WorldViewProj );
     OUT.PosWorld = mul( float4(IN.Pos, 1.0f), World );
     OUT.NormalWorld = mul( float4(IN.Normal, 0.0f), World );
     OUT.TexCoord = IN.TexCoord;
     return OUT;
}

float4 PixelProgram( VS_OUTPUT IN ) : COLOR
{
     float r0TexCoordScale = 1.0f;
     float r1TexCoordScale = 70.0f;
     float r2TexCoordScale = 70.0f;
     float r3TexCoordScale = 70.0f;
     float r4TexCoordScale = 70.0f;
     float r5TexCoordScale = 4000.0f;

     float4 r0 = tex2D( r0_samp, IN.TexCoord * r0TexCoordScale );
     float4 r1 = tex2D( r1_samp, IN.TexCoord * r1TexCoordScale );
     float4 r2 = tex2D( r2_samp, IN.TexCoord * r2TexCoordScale );
     float4 r3 = tex2D( r3_samp, IN.TexCoord * r3TexCoordScale );
     float4 r4 = tex2D( r4_samp, IN.TexCoord * r4TexCoordScale );
     float4 r5 = tex2D( r5_samp, IN.TexCoord * r5TexCoordScale );

     r1 = r1 * r0.x;
     r2 = lerp ( r0.y, r2, r1 );
     r3 = lerp ( r0.z, r3, r2 );
     r0 = lerp ( r0.w, r4, r3 );
     r5 = r5 * r0;

     return float4(r5.xyz, 1.0f);
}

technique TerrainTech
{
    pass p0
    {
        VertexShader = compile vs_3_0 VertexProgram();
        PixelShader  = compile ps_3_0 PixelProgram();
    }
}

Show the cpp code where you set textures.

@belfegor: C++:

device->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
device->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);
device->SetSamplerState(1, D3DSAMP_ADDRESSW, D3DTADDRESS_MIRROR);
device->SetSamplerState(2, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
device->SetSamplerState(2, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);
device->SetSamplerState(2, D3DSAMP_ADDRESSW, D3DTADDRESS_MIRROR);
device->SetSamplerState(3, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
device->SetSamplerState(3, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);
device->SetSamplerState(3, D3DSAMP_ADDRESSW, D3DTADDRESS_MIRROR);
device->SetSamplerState(4, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
device->SetSamplerState(4, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);
device->SetSamplerState(4, D3DSAMP_ADDRESSW, D3DTADDRESS_MIRROR);
device->SetSamplerState(5, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
device->SetSamplerState(5, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);
device->SetSamplerState(5, D3DSAMP_ADDRESSW, D3DTADDRESS_MIRROR);
device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
device->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
device->SetTextureStageState(2, D3DTSS_TEXCOORDINDEX, 0);
device->SetTextureStageState(3, D3DTSS_TEXCOORDINDEX, 0);
device->SetTextureStageState(4, D3DTSS_TEXCOORDINDEX, 0);
device->SetTextureStageState(5, D3DTSS_TEXCOORDINDEX, 0);

// Textures
device->SetTexture(0, texBlendingMap);
device->SetTexture(1, tex1);
device->SetTexture(2, tex2);
device->SetTexture(3, tex3);
device->SetTexture(4, tex4);
device->SetTexture(5, texDetailMap);

D3DXHANDLE hTechnique;
hTechnique = pEffect->GetTechniqueByName("TerrainTech");
if (FAILED(pEffect->SetTechnique(hTechnique)))
    return;

pEffect->SetTexture("r0_tex", texDetailMap);
pEffect->SetTexture("r1_tex", tex1);
pEffect->SetTexture("r2_tex", tex2);
pEffect->SetTexture("r3_tex", tex3);
pEffect->SetTexture("r4_tex", tex4);
pEffect->SetTexture("r5_tex", texDetailMap);

device->SetPixelShader(NULL);
device->SetVertexShader(NULL);

D3DXMATRIX matWorldViewProj = terrain->worldMatrix() * camera->viewMatrix() * camera->projectionMatrix();
D3DXMATRIX matWorld = terrain->worldMatrix();

pEffect->SetMatrix("WorldViewProj", &matWorldViewProj);
pEffect->SetMatrix("World", &matWorld);

UINT passes = 0;
pEffect->Begin(&passes, 0);
pEffect->BeginPass(0);

// Render terrain
terrain->render();

pEffect->EndPass();
pEffect->End();

This topic is closed to new replies.

Advertisement