• Advertisement
Sign in to follow this  

Terrain Light

This topic is 1640 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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...

 

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

@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.

Share this post


Link to post
Share on other sites

 

 

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?

Share this post


Link to post
Share on other sites

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.

Edited by belfegor

Share this post


Link to post
Share on other sites

@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();
    }
}
Edited by Medo3337

Share this post


Link to post
Share on other sites
@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();

Share this post


Link to post
Share on other sites

Since you are using d3dxeffect you should remove some redundant lines that might cause some conflicts, i chop it up for you:

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);

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();

Share this post


Link to post
Share on other sites

I am sorry, i have overlooked mirror address mode. Set it like this in effect file if you want mirroring:

texture r0_tex;
sampler r0_samp  = sampler_state
{
    Texture     = <r0_tex>;
    MIPFILTER   = LINEAR;
    MAGFILTER   = LINEAR;
    MINFILTER   = LINEAR;
    ADDRESSU = MIRROR;
    ADDRESSV = MIRROR;
};
... same for the rest

As to why is brighter, i don't know, this should be same as with asm shader.

 

Maybe reverse order in lerp functions:

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

Share this post


Link to post
Share on other sites

@belfegor: That resolved the bright problem, now I notice that the only texture that appear on the mesh is tex1 + detail map

 

I don't see other textures on the terrain even the blend map is correct and works with the old assembly shader.

Share this post


Link to post
Share on other sites

Resolved! I was setting the detail map as the first texture instead of the blending map.

 

Will I be able to set a different detail map for each texture if I multiplied each texture with a different detail map?

 

Thanks happy.png

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement