Low Level Material bug

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


Post Reply
aymar
Greenskin
Posts: 145
Joined: Fri Jun 12, 2015 6:53 pm
Location: Florianopolis, Brazil
x 17

Low Level Material bug

Post by aymar »

I've created a low level material to render my terrain, here are the scripts:

new_terra_vp.hlsl

Code: Select all

struct VS_INPUT {
    float4 position : POSITION;
    float3 normal : NORMAL;

    float2 biomeNoise : TEXCOORD0;
    float4 biomePartOne : TEXCOORD1;
    float4 biomePartTwo : TEXCOORD2;
};

struct VS_OUTPUT {
    float4 position_WS : TEXCOORD0;
    float3 normal_WS : TEXCOORD1;

    float4 position_WVPS : TEXCOORD2;

    float2 biomeNoise : TEXCOORD3;
    float4 biomePartOne : TEXCOORD4;
    float4 biomePartTwo : TEXCOORD5;

    float4 position : SV_Position;
};

VS_OUTPUT terrain_vp(VS_INPUT input,
    uniform float4x4 worldViewProj,
    uniform float4x4 world)
{
    VS_OUTPUT output;

    output.position_WS = mul(world, input.position);
    Output. normal_WS = mul((float3x3) world, input. normal);

    output.position_WVPS = mul(worldViewProj, input.position);

    output.biomeNoise = input.biomeNoise;
    output.biomePartOne = input.biomePartOne;
    output.biomePartTwo = input.biomePartTwo;

    output.position = output.position_WVPS;

    return output;
}
new_terrain_fp.hlsl

Code: Select all

#include "new_terrain_utils.hlsl"
#include "worldtime.hlsl"

struct PS_INPUT {
    float4 position_WS : TEXCOORD0;
    float3 normal_WS : TEXCOORD1;

    float4 position_WVPS : TEXCOORD2;

    float2 biomeNoise : TEXCOORD3;
    float4 biomePartOne : TEXCOORD4;
    float4 biomePartTwo : TEXCOORD5;
};

struct PS_OUTPUT {
    float4 color : SV_Target0;
    float depth : SV_Depth;
};

struct BiomeContribution {
    float4 color;
    float4 normal;
};

SamplerState textureSampler : register(s0);

Texture2D deadGrass : register(t0);
Texture2D deadGrassNrm : register(t1);

Texture2D grass : register(t2);
Texture2D grassNrm : register(t3);

Texture2D desert : register(t4);
Texture2D desertNrm : register(t5);

Texture2D pebbles : register(t6);
Texture2D pebblesNrm : register(t7);

Texture2D gravel : register(t8);
Texture2D gravelNrm : register(t9);

Texture2D cliff : register(t10);
Texture2D cliffNrm : register(t11);


BiomeContribution getGrasslandsContribution(BiomeContribution contribution, float3 uvw, float3x3 tbnMatrix, float biomeNoise, float alpha) {
    float baseTileSize = 4.0;
	float4 baseDiffuseSpecular = getSample4D(deadGrass, textureSampler, uvw/baseTileSize);
	float3 baseNormal_TS = getSampleNm(deadGrassNrm, textureSampler, uvw/baseTileSize);

	float layer0TileSize = 4.0;
	float4 layer0DiffuseSpecular = getSample4D(grass, textureSampler, uvw/baseTileSize);
	float3 layer0Normal_TS = getSampleNm(grassNrm, textureSampler, uvw/layer0TileSize);

	float layer0Alpha = smoothstep(0.45, 0.48, biomeNoise);
	float4 diffuseSpecular = lerp(baseDiffuseSpecular, layer0DiffuseSpecular, layer0Alpha);
	float3 normal_TS = lerp(baseNormal_TS, layer0Normal_TS, layer0Alpha);

    contribution.color += lerp(baseDiffuseSpecular, layer0DiffuseSpecular, layer0Alpha) * alpha;
    contribution.normal += float4(mul(normal_TS, tbnMatrix), 0.0) * alpha;

    return contribution;
}

BiomeContribution getDesertContribution(BiomeContribution contribution, float3 uvw, float3x3 tbnMatrix, float biomeNoise, float alpha) {
    float baseTileSize = 12.0;
	float4 baseDiffuseSpecular = getSample4D(desert, textureSampler, uvw/baseTileSize);
	float3 baseNormal_TS = getSampleNm(desertNrm, textureSampler, uvw/baseTileSize);

	float layer0TileSize = 4.0;
	float4 layer0DiffuseSpecular = getSample4D(pebbles, textureSampler, uvw/baseTileSize);
	float3 layer0Normal_TS = getSampleNm(pebblesNrm, textureSampler, uvw/layer0TileSize);

	float layer0Alpha = smoothstep(0.40, 0.45, biomeNoise);
	float4 diffuseSpecular = lerp(baseDiffuseSpecular, layer0DiffuseSpecular, layer0Alpha);
	float3 normal_TS = lerp(baseNormal_TS, layer0Normal_TS, layer0Alpha);

    contribution.color += lerp(baseDiffuseSpecular, layer0DiffuseSpecular, layer0Alpha) * alpha;
    contribution.normal += float4(mul(normal_TS, tbnMatrix), 0.0) * alpha;

    return contribution;
}

BiomeContribution getDunesContribution(BiomeContribution contribution, float3 uvw, float3x3 tbnMatrix, float biomeNoise, float alpha) {
    float baseTileSize = 8.0;
	float4 baseDiffuseSpecular = getSample4D(pebbles, textureSampler, uvw/baseTileSize);
	float3 baseNormal_TS = getSampleNm(pebblesNrm, textureSampler, uvw/baseTileSize);

	float layer0TileSize = 8.0;
	float4 layer0DiffuseSpecular = getSample4D(desert, textureSampler, uvw/baseTileSize);
	float3 layer0Normal_TS = getSampleNm(desertNrm, textureSampler, uvw/layer0TileSize);

	float layer0Alpha = smoothstep(0.33, 0.40, biomeNoise);
	float4 diffuseSpecular = lerp(baseDiffuseSpecular, layer0DiffuseSpecular, layer0Alpha);
	float3 normal_TS = lerp(baseNormal_TS, layer0Normal_TS, layer0Alpha);

    contribution.color += lerp(baseDiffuseSpecular, layer0DiffuseSpecular, layer0Alpha) * alpha;
    contribution.normal += float4(mul(normal_TS, tbnMatrix), 0.0) * alpha;

    return contribution;
}

BiomeContribution getRocksContribution(BiomeContribution contribution, float3 uvw, float3x3 tbnMatrix, float biomeNoise, float alpha) {
    float baseTileSize = 8.0;
	float4 baseDiffuseSpecular = getSample4D(pebbles, textureSampler, uvw/baseTileSize);
	float3 baseNormal_TS = getSampleNm(pebblesNrm, textureSampler, uvw/baseTileSize);

	float layer0TileSize = 8.0;
	float4 layer0DiffuseSpecular = getSample4D(gravel, textureSampler, uvw/baseTileSize);
	float3 layer0Normal_TS = getSampleNm(gravelNrm, textureSampler, uvw/layer0TileSize);

	float layer0Alpha = smoothstep(0.3, 0.7, biomeNoise);
	float4 diffuseSpecular = lerp(baseDiffuseSpecular, layer0DiffuseSpecular, layer0Alpha);
	float3 normal_TS = lerp(baseNormal_TS, layer0Normal_TS, layer0Alpha);

    contribution.color += lerp(baseDiffuseSpecular, layer0DiffuseSpecular, layer0Alpha) * alpha;
    contribution.normal += float4(mul(normal_TS, tbnMatrix), 0.0) * alpha;

    return contribution;
}

BiomeContribution getCliffContribution(BiomeContribution contribution, float3 uvw, float3x3 tbnMatrix, float3 normal_WS) {
    float cliff0TileSize = 32.0;
	float4 cliff0DiffuseSpecular = getTriplanarSample4D(gravel, textureSampler, uvw/cliff0TileSize, normal_WS);
	float3 cliff0Normal_TS = getTriplanarSampleNm(gravelNrm, textureSampler, uvw/cliff0TileSize, normal_WS);

	float cliff1TileSize = 36.0;
	float4 cliff1DiffuseSpecular = getTriplanarSample4D(cliff, textureSampler, uvw/cliff1TileSize, normal_WS);
	float3 cliff1Normal_TS = getTriplanarSampleNm(cliffNrm, textureSampler, uvw/cliff1TileSize, normal_WS);

	float cliff0Alpha = 1.0 - smoothstep(0.77, 0.82, normal_WS.y);
	float cliff1Alpha = 1.0 - smoothstep(0.26, 0.34, normal_WS.y);

	float4 diffuseSpecular = lerp(cliff0DiffuseSpecular, cliff1DiffuseSpecular, cliff1Alpha);
	float3 normal_TS = lerp(cliff0Normal_TS, cliff1Normal_TS, cliff1Alpha);
    float4 normal = float4(mul(normal_TS, tbnMatrix) , 1.0);

    contribution.color = lerp(diffuseSpecular, contribution.color, normal_WS.y);
    contribution.normal = lerp(normal, contribution.normal, normal_WS.y);

    return contribution;
}

float3 blinnPhong(float3 lightDirection, float3 viewDirection, float3 ambientColor, float4 diffuseColorAndSpecular, float4 normal) {
    float3 halfVector = normalize( lightDirection + viewDirection );

    float diffuseTerm = saturate( dot(normal.xyz, lightDirection) );
    float specularTerm = pow( saturate( dot(normal.xyz, halfVector) ) , 40 ) * ceil( diffuseTerm );

    return saturate( ambientColor + diffuseTerm ) * diffuseColorAndSpecular.xyz + (specularTerm * diffuseColorAndSpecular.w);
}

PS_OUTPUT terrainPassOne_fp(PS_INPUT input,
    uniform float4x4 view,
    uniform float3 viewDirection,
    uniform float3 ambientLight,
    uniform float worldTime)
{
  PS_OUTPUT output;

  output.depth = input.position_WVPS.z / 1000.0;

  float3 normal_VS = mul(view, float4(normalize(input.normal_WS), 0.0)).xyz;
  float3 binormal_VS = normalize(cross(float3(-1.0, 0.0, 0.0), normal_VS));
  float3 tangent_VS = cross(binormal_VS, normal_VS);
  float3x3 tbnMatrix_VS = float3x3(tangent_VS, binormal_VS, normal_VS);

  float3 uvw = input.position_WS.xyz;
  float3 normal = input.normal_WS;

  float biomeNoise = input.biomeNoise.x;

  BiomeContribution contribution;
  contribution.color = float4( 0.0 , 0.0 , 0.0 , 0.0 );
  contribution.normal = float4( 0.0 , 0.0 , 0.0 , 0.0 );

  contribution = getGrasslandsContribution(contribution, uvw, tbnMatrix_VS, biomeNoise, input.biomePartOne.x);
  contribution = getDesertContribution(contribution, uvw, tbnMatrix_VS, biomeNoise, input.biomePartOne.y);
  contribution = getDunesContribution(contribution, uvw, tbnMatrix_VS, biomeNoise, input.biomePartOne.z);
  contribution = getRocksContribution(contribution, uvw, tbnMatrix_VS, biomeNoise, input.biomePartOne.w);
  contribution = getRocksContribution(contribution, uvw, tbnMatrix_VS, biomeNoise, input.biomePartTwo.x);
  contribution = getRocksContribution(contribution, uvw, tbnMatrix_VS, biomeNoise, input.biomePartTwo.y);
  contribution = getCliffContribution(contribution, uvw, tbnMatrix_VS, normal);

  float3 lightDirection = getSunDirection( worldTime );

  float3 finalColor = blinnPhong(lightDirection, viewDirection, ambientLight, contribution.color, contribution.normal);

  output.color = float4( finalColor , 1.0 );

  return output;
}
new_terrain.program

Code: Select all

vertex_program NewTerrainVP hlsl {
	source new_terrain_vp.hlsl
	entry_point terrain_vp
	target vs_5_0

	default_params {
		param_named_auto world world_matrix
		param_named_auto worldViewProj worldviewproj_matrix
	}
}

fragment_program NewTerrainPassOne hlsl {
	source new_terrain_pass_one.hlsl
	entry_point terrainPassOne_fp
	target ps_5_0

	default_params {
		param_named_auto view view_matrix
		param_named_auto viewDirection view_direction
		param_named ambientLight float3 0 0 0
		param_named worldTime float 12
	}
}
new_terrain.material

Code: Select all

material new_terrain_mat {
	technique {
		pass {			
			vertex_program_ref NewTerrainVP {}
			fragment_program_ref NewTerrainPassOne {}
				
			texture_unit deadGrass {
				texture GrassDead02_DIFF.dds 2d 0
				filtering anisotropic
				max_anisotropy 8
			}

			texture_unit deadGrassNrm {
				texture GrassDead02_NRM.dds 2d 0
				filtering anisotropic
				max_anisotropy 8
			}

			texture_unit grass {
				texture Grass01_DIFF.dds 2d 0
				filtering anisotropic
				max_anisotropy 8
			}

			texture_unit grassNrm {
				texture Grass01_NRM.dds 2d 0
				filtering anisotropic
				max_anisotropy 8
			}

			texture_unit desert {
				texture desert01_DIFF.dds 2d 0
				filtering anisotropic
				max_anisotropy 8
			}

			texture_unit desertNrm {
				texture desert01_NRM.dds 2d 0
				filtering anisotropic
				max_anisotropy 8
			}

			texture_unit pebbles {
				texture terrain_sandPebbles01_DIFF.dds 2d 0
				filtering anisotropic
				max_anisotropy 8
			}

			texture_unit pebblesNrm {
				texture terrain_sandPebbles01_NRM.dds 2d 0
				filtering anisotropic
				max_anisotropy 8
			}

			texture_unit gravel {
				texture gravel_DIFF.dds 2d 0
				filtering anisotropic
				max_anisotropy 8
			}

			texture_unit gravelNrm {
				texture gravel_NRM.dds 2d 0
				filtering anisotropic
				max_anisotropy 8
			}

			texture_unit cliff {
				texture cliff_DIFF.dds 2d 0
				filtering anisotropic
				max_anisotropy 8
			}

			texture_unit cliffNrm {
				texture cliff_NRM.dds 2d 0
				filtering anisotropic
				max_anisotropy 8
			}
		}
	}
}
Then I generate terrain pages using manual object and set this material to it.

The problem I'm getting is that for some reason random pages of the terrain receive the textures out of order and then render normal maps as diffuses, diffuse map as normals, etc.
aymar
Greenskin
Posts: 145
Joined: Fri Jun 12, 2015 6:53 pm
Location: Florianopolis, Brazil
x 17

Re: Low Level Material bug

Post by aymar »

Causing the following bug:

Image

Image

Am I doing anything wrong?

Thanks.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5298
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1279
Contact:

Re: Low Level Material bug

Post by dark_sylinc »

Two things:

1. There is a known Ogre issue when using low level materials in the same scene pass as with Hlms materials that could be causing trouble. The PSO source code update will fix it; but until then the best workaround (in case this problem is affecting you) is to issue multiple scene passes to separate low level materials from Hlms rendering:

Code: Select all

pass render_scene
{
	//Render the Hlms stuff
	rq_first	0
	rq_last	250
}
pass render_scene
{
	//I assume you've put your low level material in the RQ #250
	rq_first	250
	rq_last	251
}
pass render_scene
{
	//Render the remaining stuff (skip this if you don't use these RQs)
	rq_first	251
	rq_last	max
}
2. You write to SV_Depth directly. Unless you really, really know what you're doing, it could really screw up rendering (and btw you should render the terrain last because writing to SV_Depth == many optimizations will be turned off on the GPU until the next depth clear). You shouldn't normally output to SV_Depth at all. This is very likely causing you rendering problems.

3. Running the infoQ set to Warning may yield more information. Also you should look more into why the DEBUG build crashes for you. Getting it to run is important as DEBUG will issue a lot of asserts that will help you catch setup mistakes.
aymar
Greenskin
Posts: 145
Joined: Fri Jun 12, 2015 6:53 pm
Location: Florianopolis, Brazil
x 17

Re: Low Level Material bug

Post by aymar »

I'm already rendering them in different render passes, so that's probably not the issue.
Post Reply