• Advertisement
Sign in to follow this  

Material Layering question

This topic is 1401 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

Hey guys, I've got three quick questions on the implementation of material layering.

I know you can either do some offline compositing (as MJP suggested) or do it using a limited amount of layers during runtime (as UE4 seems to do it).

I'm currently looking into the latter case....

 

Question 1: The material layering in the shader works by linearly interpolating the material attributes & textures, correct ? So you'd just do something like: 

float3 DiffMap_0 = DiffuseMap_Layer0.Sample(DiffuseMapSampler, input.TexCoord).rgb;
float3 DiffMap_1 = DiffuseMap_Layer1.Sample(DiffuseMapSampler, input.TexCoord).rgb;
float3 DiffuseAlbedo = lerp(DiffMap_0, DiffMap_1, material_DiffBlendFactor.x);

Question 2: The problem you're facing now is that you'd need to (assuming a layer limit of 4) have 4 instances of every material property + 4 times the Textures you'd normally have, right ? I'm just wondering if that isn't memory bandwidth overkill...? I assume I'd have to make permutations of the shader that declares how many layers are used to decrease this for most materials that don't use the full 4 layers but still....worst case scenario would be 4 times the memory bandwidth of regular shading.

 

Question 3: Should the blending parameters extend to things like roughness,...? or should these parameters blend using a specular blend factor ? Or just a global blend mask/factor for the entire layer ? How much is overkill ?

Edited by lipsryme

Share this post


Link to post
Share on other sites
Advertisement

You can combine several images (offline) into a single texture, if that's practical, and use texcoord offsets to sample.

 

If the number of layers is per-frame (or even if it isn't I suppose), you can probably setup a single shader routine with one of the arguments being a uniform argument that you set each render. Then compile an array of shaders, one per numLayers value.

Edited by Buckeye

Share this post


Link to post
Share on other sites

Question 1: The material layering in the shader works by linearly interpolating the material attributes & textures, correct ? So you'd just do something like: 





float3 DiffMap_0 = DiffuseMap_Layer0.Sample(DiffuseMapSampler, input.TexCoord).rgb;
float3 DiffMap_1 = DiffuseMap_Layer1.Sample(DiffuseMapSampler, input.TexCoord).rgb;
float3 DiffuseAlbedo = lerp(DiffMap_0, DiffMap_1, material_DiffBlendFactor.x);

that's just one way to do it, linear is usually the least natural looking way of blending layers. but you can just as good go for a selection way of blending

float4 DiffMap_0 = DiffuseMap_Layer0.Sample(DiffuseMapSampler, input.TexCoord); 
float4 DiffMap_1 = DiffuseMap_Layer1.Sample(DiffuseMapSampler, input.TexCoord); 
DiffMap_0.a*=(1.f-material_DiffBlendFactor.x);  //edited, here just alpha should be multiplied, while aplha is e.g. a heightmap
DiffMap_1.a*=material_DiffBlendFactor.x;
float3 DiffuseAlbedo = DiffMap_0.a>DiffMap_1.a?DiffMap_0:DiffMap_1;

this will lead to a more natural looking mix (e.g. if you blend a sand and stone layer), yet it will have hard borders. you can go for more advanced ways of blending, some lerps inbetween selections etc.

 

2. the simple solution is to use a texture array and pass to the shader how many iteration it need to go over the array to accumulate/blend/select all layers you supply.

 

3. that's purely depends on your demands to visual quality. the proper way would probably be to make shading etc. on the individual layer and blend just the final results. blending source data will never be correct. it boils down to what will make your eye happy.

Edited by Krypt0n

Share this post


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

  • Advertisement