Code: Select all
Cannot compile d3d11 high-level shader Errors:
warning: 'Sample': implicit truncation of vector type
error x3017: 'getTSDetailNormal': cannot implicitly convert from 'const Texture2DArray<float4>' to 'Texture2D<float4>' in D3D11HLSLProgram::compileMicrocode "Pathtofile"\Ogre3DD11HLSLProgram.cpp (line 544)
Here is my code to create mesh and HLMS datablock:
Code: Select all
void TerrainManager::createModuleTerrain(DataInterface::ModuleData* moduleData, tow::ModulePlacementData* placementData)
{
assert(moduleData);
if (moduleData)
{
//Create module terrain mesh
std::string v1planeName = "module_mesh1_" + std::to_string(placementData->x) + "_" + std::to_string(placementData->y);
Ogre::v1::MeshPtr planeMeshV1 = Ogre::v1::MeshManager::getSingleton().createPlane(v1planeName,
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Ogre::Plane(Ogre::Vector3::UNIT_Y, 0.0f), ModuleSize*ModuleTileSize, ModuleSize*ModuleTileSize,
1, 1, true, 1, 1.0f, 1.0f, Ogre::Vector3::UNIT_Z,
Ogre::v1::HardwareBuffer::HBU_STATIC,
Ogre::v1::HardwareBuffer::HBU_STATIC);
std::string v2planeName = "module_mesh2_" + std::to_string(placementData->x) + "_" + std::to_string(placementData->y);
Ogre::MeshPtr planeMesh = Ogre::MeshManager::getSingleton().createManual(
v2planeName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
planeMesh->importV1(planeMeshV1.get(), true, true, true);
planeMeshV1->unload();
Ogre::Item *item = mWorkingSceneMgr->createItem(planeMesh, Ogre::SCENE_STATIC);
Ogre::SceneNode *sceneNode = mWorkingSceneMgr->getRootSceneNode(Ogre::SCENE_STATIC)->createChildSceneNode(Ogre::SCENE_STATIC);
sceneNode->setPosition(Ogre::Vector3(placementData->x*ModuleSize*ModuleTileSize + ModuleSize*ModuleTileSize*0.5f, 0, placementData->y*ModuleSize*ModuleTileSize + ModuleSize*ModuleTileSize*0.5f));
sceneNode->attachObject(item);
//Create material datablock
Ogre::HlmsManager *hlmsManager = Director::getInstance()->getHlmsManager();
Ogre::HlmsTextureManager *hlmsTextureManager = hlmsManager->getTextureManager();
assert(dynamic_cast<Ogre::HlmsPbs*>(hlmsManager->getHlms(Ogre::HLMS_PBS)));
Ogre::HlmsPbs *hlmsPbs = static_cast<Ogre::HlmsPbs*>(hlmsManager->getHlms(Ogre::HLMS_PBS));
std::string hlsmDatablockName = "db_terrain_" + std::to_string(placementData->x) + "_" + std::to_string(placementData->y) + "_" + moduleData->ID.toString();
Ogre::HlmsPbsDatablock* datablock = static_cast<Ogre::HlmsPbsDatablock*>(hlmsPbs->createDatablock(
hlsmDatablockName, hlsmDatablockName, Ogre::HlmsMacroblock(), Ogre::HlmsBlendblock(), Ogre::HlmsParamVec() ));
datablock->setDiffuse(Ogre::Vector3(1.0f, 1.0f, 1.0f));
datablock->setRoughness(0.5f);
datablock->setFresnel(Ogre::Vector3(0.05f, 0.05f, 0.05f), false);
datablock->setWorkflow(Ogre::HlmsPbsDatablock::Workflows::SpecularWorkflow);
//DIFFUSE DETAIL TEXTURES
Ogre::HlmsTextureManager::TextureLocation detailTextureLocation[4];
detailTextureLocation[0] = hlmsTextureManager->createOrRetrieveTexture("theme_1_terrain_diffuse_0.png", Ogre::HlmsTextureManager::TEXTURE_TYPE_DETAIL);
detailTextureLocation[1] = hlmsTextureManager->createOrRetrieveTexture("theme_1_terrain_diffuse_1.png", Ogre::HlmsTextureManager::TEXTURE_TYPE_DETAIL);
detailTextureLocation[2] = hlmsTextureManager->createOrRetrieveTexture("theme_1_terrain_diffuse_2.png", Ogre::HlmsTextureManager::TEXTURE_TYPE_DETAIL);
detailTextureLocation[3] = hlmsTextureManager->createOrRetrieveTexture("theme_1_terrain_diffuse_3.png", Ogre::HlmsTextureManager::TEXTURE_TYPE_DETAIL);
datablock->setTexture(Ogre::PBSM_DETAIL0, detailTextureLocation[0].xIdx, detailTextureLocation[0].texture);
datablock->setTexture(Ogre::PBSM_DETAIL1, detailTextureLocation[1].xIdx, detailTextureLocation[1].texture);
datablock->setTexture(Ogre::PBSM_DETAIL2, detailTextureLocation[2].xIdx, detailTextureLocation[2].texture);
datablock->setTexture(Ogre::PBSM_DETAIL3, detailTextureLocation[3].xIdx, detailTextureLocation[3].texture);
datablock->setDetailMapOffsetScale(0, Ogre::Vector4(0, 0, 10.0f, 10.0f));
datablock->setDetailMapOffsetScale(1, Ogre::Vector4(0, 0, 10.0f, 10.0f));
datablock->setDetailMapOffsetScale(2, Ogre::Vector4(0, 0, 10.0f, 10.0f));
datablock->setDetailMapOffsetScale(3, Ogre::Vector4(0, 0, 10.0f, 10.0f));
//NORMAL DETAIL TEXTURES
Ogre::HlmsTextureManager::TextureLocation detailNormalLocation[4];
detailNormalLocation[0] = hlmsTextureManager->createOrRetrieveTexture("theme_1_terrain_normal_0.dds", Ogre::HlmsTextureManager::TEXTURE_TYPE_DETAIL_NORMAL_MAP);
detailNormalLocation[1] = hlmsTextureManager->createOrRetrieveTexture("theme_1_terrain_normal_1.dds", Ogre::HlmsTextureManager::TEXTURE_TYPE_DETAIL_NORMAL_MAP);
detailNormalLocation[2] = hlmsTextureManager->createOrRetrieveTexture("theme_1_terrain_normal_2.dds", Ogre::HlmsTextureManager::TEXTURE_TYPE_DETAIL_NORMAL_MAP);
detailNormalLocation[3] = hlmsTextureManager->createOrRetrieveTexture("theme_1_terrain_normal_3.dds", Ogre::HlmsTextureManager::TEXTURE_TYPE_DETAIL_NORMAL_MAP);
datablock->setTexture(Ogre::PBSM_DETAIL0_NM, detailNormalLocation[0].xIdx, detailNormalLocation[0].texture);
datablock->setTexture(Ogre::PBSM_DETAIL1_NM, detailNormalLocation[1].xIdx, detailNormalLocation[1].texture);
datablock->setTexture(Ogre::PBSM_DETAIL2_NM, detailNormalLocation[2].xIdx, detailNormalLocation[2].texture);
datablock->setTexture(Ogre::PBSM_DETAIL3_NM, detailNormalLocation[3].xIdx, detailNormalLocation[3].texture);
datablock->setDetailMapOffsetScale(4, Ogre::Vector4(0, 0, 5.0f, 5.0f));
datablock->setDetailMapOffsetScale(5, Ogre::Vector4(0, 0, 5.0f, 5.0f));
datablock->setDetailMapOffsetScale(6, Ogre::Vector4(0, 0, 5.0f, 5.0f));
datablock->setDetailMapOffsetScale(7, Ogre::Vector4(0, 0, 5.0f, 5.0f));
//Get cached module weight map
std::string weightTexName = "mtw_" + std::to_string(placementData->x) + "_" + std::to_string(placementData->y) + "_" + moduleData->ID.toString();
std::string cacheName = weightTexName + "_cac.png";
Ogre::HlmsTextureManager::TextureLocation weightMapLocation = hlmsTextureManager->createOrRetrieveTexture(cacheName, Ogre::HlmsTextureManager::TEXTURE_TYPE_DIFFUSE);
datablock->setTexture(Ogre::PBSM_DETAIL_WEIGHT, weightMapLocation.xIdx, weightMapLocation.texture);
item->setDatablock(datablock);
mItemMaterialMap.insert(std::pair<Ogre::Item*, Ogre::HlmsPbsDatablock*>(item, datablock));
}
}
Code: Select all
// START UNIFORM DECLARATION
struct ShadowReceiverData
{
float4x4 texViewProj;
float2 shadowDepthRange;
float2 padding;
float4 invShadowMapSize;
};
struct Light
{
float3 position;
float3 diffuse;
float3 specular;
};
//Uniforms that change per pass
cbuffer PassBuffer : register(b0)
{
struct PassData
{
//Vertex shader (common to both receiver and casters)
float4x4 viewProj;
//Vertex shader
float4x4 view;
//-------------------------------------------------------------------------
//Pixel shader
float3x3 invViewMatCubemap;
float padding; //Compatibility with GLSL.
float4 ambientUpperHemi;
float4 ambientLowerHemi;
float4 ambientHemisphereDir;
Light lights[1];
} passBuf;
};
//Uniforms that change per Item/Entity, but change very infrequently
struct Material
{
/* kD is already divided by PI to make it energy conserving.
(formula is finalDiffuse = NdotL * surfaceDiffuse / PI)
*/
float4 kD; //kD.w is alpha_test_threshold
float4 kS; //kS.w is roughness
//Fresnel coefficient, may be per colour component (float3) or scalar (float)
//F0.w is transparency
float4 F0;
float4 normalWeights;
float4 cDetailWeights;
float4 detailOffsetScaleD[4];
float4 detailOffsetScaleN[4];
uint4 indices0_3;
//asfloat( indices4_7.w ) contains mNormalMapWeight.
uint4 indices4_7;
};
cbuffer MaterialBuf : register(b1)
{
Material materialArray[273];
};
//Uniforms that change per Item/Entity
cbuffer InstanceBuffer : register(b2)
{
//.x =
//The lower 9 bits contain the material's start index.
//The higher 23 bits contain the world matrix start index.
//
//.y =
//shadowConstantBias. Send the bias directly to avoid an
//unnecessary indirection during the shadow mapping pass.
//Must be loaded with uintBitsToFloat
uint4 worldMaterialIdx[4096];
};
// END UNIFORM DECLARATION
struct PS_INPUT
{
nointerpolation uint drawId : TEXCOORD0;
float3 pos : TEXCOORD1;
float3 normal : TEXCOORD2;
float3 tangent : TEXCOORD3;
nointerpolation float biNormalReflection : TEXCOORD4;
float2 uv0 : TEXCOORD5;
};
#define ROUGHNESS material.kS.w
Texture2DArray textureMaps[3] : register(t1);
SamplerState samplerStates[3] : register(s1);
float3 getTSDetailNormal( SamplerState samplerState, Texture2D normalMap, float3 uv )
{
float3 tsNormal;
//Normal texture must be in U8V8 or BC5 format!
tsNormal.xy = normalMap.Sample( samplerState, uv ).xy;
tsNormal.z = sqrt( max( 0, 1.0 - tsNormal.x * tsNormal.x - tsNormal.y * tsNormal.y ) );
return tsNormal;
}
//Default BRDF
float3 BRDF( float3 lightDir, float3 viewDir, float NdotV, float3 lightDiffuse, float3 lightSpecular, Material material, float3 nNormal , float4 diffuseCol )
{
float3 halfWay= normalize( lightDir + viewDir );
float NdotL = saturate( dot( nNormal, lightDir ) );
float NdotH = saturate( dot( nNormal, halfWay ) );
float VdotH = saturate( dot( viewDir, halfWay ) );
float sqR = ROUGHNESS * ROUGHNESS;
//Roughness/Distribution/NDF term (GGX)
//Formula:
// Where alpha = roughness
// R = alpha^2 / [ PI * [ ( NdotH^2 * (alpha^2 - 1) ) + 1 ]^2 ]
float f = ( NdotH * sqR - NdotH ) * NdotH + 1.0;
float R = sqR / (f * f + 1e-6f);
//Geometric/Visibility term (Smith GGX Height-Correlated)
float Lambda_GGXV = NdotL * sqrt( (-NdotV * sqR + NdotV) * NdotV + sqR );
float Lambda_GGXL = NdotV * sqrt( (-NdotL * sqR + NdotL) * NdotL + sqR );
float G = 0.5 / (( Lambda_GGXV + Lambda_GGXL + 1e-6f ) * 3.141592654);
//Formula:
// fresnelS = lerp( (1 - V*H)^5, 1, F0 )
float fresnelS = material.F0.x + pow( 1.0 - VdotH, 5.0 ) * (1.0 - material.F0.x);
//We should divide Rs by PI, but it was done inside G for performance
float3 Rs = ( fresnelS * (R * G) ) * material.kS.xyz * lightSpecular;
//Diffuse BRDF (*Normalized* Disney, see course_notes_moving_frostbite_to_pbr.pdf
//"Moving Frostbite to Physically Based Rendering" Sebastien Lagarde & Charles de Rousiers)
float energyBias = ROUGHNESS * 0.5;
float energyFactor = lerp( 1.0, 1.0 / 1.51, ROUGHNESS );
float fd90 = energyBias + 2.0 * VdotH * VdotH * ROUGHNESS;
float lightScatter = 1.0 + (fd90 - 1.0) * pow( 1.0 - NdotL, 5.0 );
float viewScatter = 1.0 + (fd90 - 1.0) * pow( 1.0 - NdotV, 5.0 );
float fresnelD = 1.0f - fresnelS;
//We should divide Rd by PI, but it is already included in kD
float3 Rd = (lightScatter * viewScatter * fresnelD) * diffuseCol.xyz * lightDiffuse;
return NdotL * (Rs + Rd);
}
float4 main( PS_INPUT inPs
) : SV_Target0
{
Material material;
float4 outColour;
uint weightMapIdx;
uint detailMapIdx0;
uint detailMapIdx1;
uint detailMapIdx2;
uint detailMapIdx3;
uint detailNormMapIdx0;
uint detailNormMapIdx1;
uint detailNormMapIdx2;
uint detailNormMapIdx3;
float4 diffuseCol;
float3 nNormal;
uint materialId = worldMaterialIdx[inPs.drawId].x & 0x1FFu;
material = materialArray[materialId];
weightMapIdx = material.indices0_3.z & 0x0000FFFFu;
detailMapIdx0 = material.indices0_3.z >> 16u;
detailMapIdx1 = material.indices0_3.w & 0x0000FFFFu;
detailMapIdx2 = material.indices0_3.w >> 16u;
detailMapIdx3 = material.indices4_7.x & 0x0000FFFFu;
detailNormMapIdx0 = material.indices4_7.x >> 16u;
detailNormMapIdx1 = material.indices4_7.y & 0x0000FFFFu;
detailNormMapIdx2 = material.indices4_7.y >> 16u;
detailNormMapIdx3 = material.indices4_7.z & 0x0000FFFFu;
//Prepare weight map for the detail maps.
float4 detailWeights = textureMaps[0].Sample( samplerStates[0], float3(inPs.uv0.xy, weightMapIdx) );
/// Sample detail maps and weight them against the weight map in the next foreach loop.
float4 detailCol0 = textureMaps[1].Sample( samplerStates[1], float3( inPs.uv0.xy * material.detailOffsetScaleD[0].zw + material.detailOffsetScaleD[0].xy, detailMapIdx0 ) );
detailWeights.x *= detailCol0.w;
detailCol0.w = detailWeights.x;
float4 detailCol1 = textureMaps[1].Sample( samplerStates[1], float3( inPs.uv0.xy * material.detailOffsetScaleD[1].zw + material.detailOffsetScaleD[1].xy, detailMapIdx1 ) );
detailWeights.y *= detailCol1.w;
detailCol1.w = detailWeights.y;
float4 detailCol2 = textureMaps[1].Sample( samplerStates[1], float3( inPs.uv0.xy * material.detailOffsetScaleD[2].zw + material.detailOffsetScaleD[2].xy, detailMapIdx2 ) );
detailWeights.z *= detailCol2.w;
detailCol2.w = detailWeights.z;
float4 detailCol3 = textureMaps[1].Sample( samplerStates[1], float3( inPs.uv0.xy * material.detailOffsetScaleD[3].zw + material.detailOffsetScaleD[3].xy, detailMapIdx3 ) );
detailWeights.w *= detailCol3.w;
detailCol3.w = detailWeights.w;
/// 'insertpiece( SampleDiffuseMap )' must've written to diffuseCol. However if there are no
/// diffuse maps, we must initialize it to some value. If there are no diffuse or detail maps,
/// we must not access diffuseCol at all, but rather use material.kD directly (see piece( kD ) ).
diffuseCol = float4( 0.0, 0.0, 0.0, 0.0 );
/// Blend the detail diffuse maps with the main diffuse.
//Normal Non Premultiplied 0
diffuseCol.xyz = lerp( diffuseCol.xyz, detailCol0.xyz, detailCol0.a );
diffuseCol.w = lerp( diffuseCol.w, 1.0, detailCol0.w );
//Normal Non Premultiplied 1
diffuseCol.xyz = lerp( diffuseCol.xyz, detailCol1.xyz, detailCol1.a );
diffuseCol.w = lerp( diffuseCol.w, 1.0, detailCol1.w );
//Normal Non Premultiplied 2
diffuseCol.xyz = lerp( diffuseCol.xyz, detailCol2.xyz, detailCol2.a );
diffuseCol.w = lerp( diffuseCol.w, 1.0, detailCol2.w );
//Normal Non Premultiplied 3
diffuseCol.xyz = lerp( diffuseCol.xyz, detailCol3.xyz, detailCol3.a );
diffuseCol.w = lerp( diffuseCol.w, 1.0, detailCol3.w );
/// Apply the material's diffuse over the textures
diffuseCol.xyz *= material.kD.xyz;
//Normal mapping.
float3 geomNormal = normalize( inPs.normal );
float3 vTangent = normalize( inPs.tangent );
//Get the TBN matrix
float3 vBinormal = normalize( cross( vTangent, geomNormal ) * inPs.biNormalReflection );
float3x3 TBN = float3x3( vTangent, vBinormal, geomNormal );
/// If there is no normal map, the first iteration must
/// initialize nNormal instead of try to merge with it.
/// Blend the detail normal maps with the main normal.
float3 vDetail = getTSDetailNormal( samplerStates[2], textureMaps[2], float3( inPs.uv0.xy * material.detailOffsetScaleN[0].zw + material.detailOffsetScaleN[0].xy, detailNormMapIdx0 ) ) * detailWeights.x ;
nNormal.xy = vDetail.xy;
nNormal.z = vDetail.z + 1.0 - detailWeights.x ;
vDetail = getTSDetailNormal( samplerStates[2], textureMaps[2], float3( inPs.uv0.xy * material.detailOffsetScaleN[1].zw + material.detailOffsetScaleN[1].xy, detailNormMapIdx1 ) ) * detailWeights.y ;
nNormal.xy += vDetail.xy;
nNormal.z *= vDetail.z + 1.0 - detailWeights.y ;
vDetail = getTSDetailNormal( samplerStates[2], textureMaps[2], float3( inPs.uv0.xy * material.detailOffsetScaleN[2].zw + material.detailOffsetScaleN[2].xy, detailNormMapIdx2 ) ) * detailWeights.z ;
nNormal.xy += vDetail.xy;
nNormal.z *= vDetail.z + 1.0 - detailWeights.z ;
vDetail = getTSDetailNormal( samplerStates[2], textureMaps[2], float3( inPs.uv0.xy * material.detailOffsetScaleN[3].zw + material.detailOffsetScaleN[3].xy, detailNormMapIdx3 ) ) * detailWeights.w ;
nNormal.xy += vDetail.xy;
nNormal.z *= vDetail.z + 1.0 - detailWeights.w ;
nNormal = normalize( mul( nNormal, TBN ) );
//Everything's in Camera space
float3 viewDir = normalize( -inPs.pos );
float NdotV = saturate( dot( nNormal, viewDir ) );
float3 finalColour = float3(0, 0, 0);
finalColour += BRDF( passBuf.lights[0].position, viewDir, NdotV, passBuf.lights[0].diffuse, passBuf.lights[0].specular, material, nNormal , diffuseCol.xyzw );
float3 lightDir;
float fDistance;
float3 tmpColour;
float spotCosAngle;
//Point lights
//Spot lights
//spotParams[0].x = 1.0 / cos( InnerAngle ) - cos( OuterAngle )
//spotParams[0].y = cos( OuterAngle / 2 )
//spotParams[0].z = falloff
float3 reflDir = 2.0 * dot( viewDir, nNormal ) * nNormal - viewDir;
float ambientWD = dot( passBuf.ambientHemisphereDir.xyz, nNormal ) * 0.5 + 0.5;
float ambientWS = dot( passBuf.ambientHemisphereDir.xyz, reflDir ) * 0.5 + 0.5;
float3 envColourS = lerp( passBuf.ambientLowerHemi.xyz, passBuf.ambientUpperHemi.xyz, ambientWD );
float3 envColourD = lerp( passBuf.ambientLowerHemi.xyz, passBuf.ambientUpperHemi.xyz, ambientWS );
float NdotL = saturate( dot( nNormal, reflDir ) );
float VdotH = saturate( dot( viewDir, normalize( reflDir + viewDir ) ) );
float fresnelS = material.F0.x + pow( 1.0 - VdotH, 5.0 ) * (1.0 - material.F0.x);
float fresnelD = 1.0f - fresnelS;
finalColour += envColourD * diffuseCol.xyz * fresnelD +
envColourS * material.kS.xyz * fresnelS;
outColour.xyz = finalColour;
outColour.w = 1.0;
return outColour;
}