diff --git a/Engine/source/materials/processedShaderMaterial.cpp b/Engine/source/materials/processedShaderMaterial.cpp index 410773d7e..8a704c6e2 100644 --- a/Engine/source/materials/processedShaderMaterial.cpp +++ b/Engine/source/materials/processedShaderMaterial.cpp @@ -389,11 +389,9 @@ void ProcessedShaderMaterial::_determineFeatures( U32 stageNum, // cannot do on SM 2.0 and below. if ( shaderVersion > 2.0f ) { - // Only allow parallax if we have a normal map and - // we're not using DXTnm compression. + if ( mMaterial->mParallaxScale[stageNum] > 0.0f && - fd.features[ MFT_NormalMap ] && - !fd.features[ MFT_IsDXTnm ] ) + fd.features[ MFT_NormalMap ] ) fd.features.addFeature( MFT_Parallax ); // If not parallax then allow per-pixel specular if diff --git a/Engine/source/shaderGen/HLSL/bumpHLSL.cpp b/Engine/source/shaderGen/HLSL/bumpHLSL.cpp index 2d6dc8464..b167db102 100644 --- a/Engine/source/shaderGen/HLSL/bumpHLSL.cpp +++ b/Engine/source/shaderGen/HLSL/bumpHLSL.cpp @@ -345,8 +345,16 @@ void ParallaxFeatHLSL::processPix( Vector &componentList, Var *normalMap = getNormalMapTex(); // Call the library function to do the rest. - meta->addStatement( new GenOp( " @.xy += parallaxOffset( @, @.xy, @, @ );\r\n", - texCoord, normalMap, texCoord, negViewTS, parallaxInfo ) ); + if(fd.features.hasFeature( MFT_IsDXTnm, getProcessIndex() )) + { + meta->addStatement( new GenOp( " @.xy += parallaxOffsetDxtnm( @, @.xy, @, @ );\r\n", + texCoord, normalMap, texCoord, negViewTS, parallaxInfo ) ); + } + else + { + meta->addStatement( new GenOp( " @.xy += parallaxOffset( @, @.xy, @, @ );\r\n", + texCoord, normalMap, texCoord, negViewTS, parallaxInfo ) ); + } // TODO: Fix second UV maybe? diff --git a/Engine/source/terrain/hlsl/terrFeatureHLSL.cpp b/Engine/source/terrain/hlsl/terrFeatureHLSL.cpp index 6c94e0743..37ad1730d 100644 --- a/Engine/source/terrain/hlsl/terrFeatureHLSL.cpp +++ b/Engine/source/terrain/hlsl/terrFeatureHLSL.cpp @@ -456,8 +456,16 @@ void TerrainDetailMapFeatHLSL::processPix( Vector &component Var *normalMap = _getNormalMapTex(); // Call the library function to do the rest. - meta->addStatement( new GenOp( " @.xy += parallaxOffset( @, @.xy, @, @.z * @ );\r\n", - inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend ) ); + if(fd.features.hasFeature( MFT_IsDXTnm, detailIndex ) ) + { + meta->addStatement( new GenOp( " @.xy += parallaxOffsetDxtnm( @, @.xy, @, @.z * @ );\r\n", + inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend ) ); + } + else + { + meta->addStatement( new GenOp( " @.xy += parallaxOffset( @, @.xy, @, @.z * @ );\r\n", + inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend ) ); + } } // If this is a prepass then we skip color. diff --git a/Templates/Empty/game/shaders/common/torque.hlsl b/Templates/Empty/game/shaders/common/torque.hlsl index 3821ce693..1d253936b 100644 --- a/Templates/Empty/game/shaders/common/torque.hlsl +++ b/Templates/Empty/game/shaders/common/torque.hlsl @@ -151,6 +151,21 @@ float2 parallaxOffset( sampler2D texMap, float2 texCoord, float3 negViewTS, floa return offset; } +/// Same as parallaxOffset but for dxtnm where depth is stored in the red channel instead of the alpha +float2 parallaxOffsetDxtnm(sampler2D texMap, float2 texCoord, float3 negViewTS, float depthScale) +{ + float depth = tex2D(texMap, texCoord).r; + float2 offset = negViewTS.xy * (depth * depthScale); + + for (int i = 0; i < PARALLAX_REFINE_STEPS; i++) + { + depth = (depth + tex2D(texMap, texCoord + offset).r) * 0.5; + offset = negViewTS.xy * (depth * depthScale); + } + + return offset; +} + /// The maximum value for 16bit per component integer HDR encoding. static const float HDR_RGB16_MAX = 100.0; diff --git a/Templates/Full/game/shaders/common/torque.hlsl b/Templates/Full/game/shaders/common/torque.hlsl index 3821ce693..1d253936b 100644 --- a/Templates/Full/game/shaders/common/torque.hlsl +++ b/Templates/Full/game/shaders/common/torque.hlsl @@ -151,6 +151,21 @@ float2 parallaxOffset( sampler2D texMap, float2 texCoord, float3 negViewTS, floa return offset; } +/// Same as parallaxOffset but for dxtnm where depth is stored in the red channel instead of the alpha +float2 parallaxOffsetDxtnm(sampler2D texMap, float2 texCoord, float3 negViewTS, float depthScale) +{ + float depth = tex2D(texMap, texCoord).r; + float2 offset = negViewTS.xy * (depth * depthScale); + + for (int i = 0; i < PARALLAX_REFINE_STEPS; i++) + { + depth = (depth + tex2D(texMap, texCoord + offset).r) * 0.5; + offset = negViewTS.xy * (depth * depthScale); + } + + return offset; +} + /// The maximum value for 16bit per component integer HDR encoding. static const float HDR_RGB16_MAX = 100.0;