void ParallaxFeatHLSL::processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd ) { AssertFatal( GFX->getPixelShaderVersion() >= 2.0, "ParallaxFeatHLSL::processPix - We don't support SM 1.x!" ); MultiLine *meta = new MultiLine; // Order matters... get this first! Var *texCoord = getInTexCoord( "texCoord", "float2", true, componentList ); ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); // We need the negative tangent space view vector // as in parallax mapping we step towards the camera. Var *negViewTS = (Var*)LangElement::find( "negViewTS" ); if ( !negViewTS ) { Var *inNegViewTS = (Var*)LangElement::find( "outNegViewTS" ); if ( !inNegViewTS ) { inNegViewTS = connectComp->getElement( RT_TEXCOORD ); inNegViewTS->setName( "outNegViewTS" ); inNegViewTS->setStructName( "IN" ); inNegViewTS->setType( "float3" ); } negViewTS = new Var( "negViewTS", "float3" ); meta->addStatement( new GenOp( " @ = normalize( @ );\r\n", new DecOp( negViewTS ), inNegViewTS ) ); } // Get the rest of our inputs. Var *parallaxInfo = _getUniformVar( "parallaxInfo", "float", cspPotentialPrimitive ); Var *normalMap = getNormalMapTex(); Var *bumpMapTexture = (Var*)LangElement::find("bumpMapTex"); // Call the library function to do the rest. if (fd.features.hasFeature(MFT_IsDXTnm, getProcessIndex())) { if (mIsDirect3D11) meta->addStatement(new GenOp(" @.xy += parallaxOffsetDxtnm( @, @, @.xy, @, @ );\r\n", texCoord, bumpMapTexture, normalMap, texCoord, negViewTS, parallaxInfo)); else meta->addStatement(new GenOp(" @.xy += parallaxOffsetDxtnm( @, @.xy, @, @ );\r\n", texCoord, normalMap, texCoord, negViewTS, parallaxInfo)); } else { if (mIsDirect3D11) meta->addStatement(new GenOp(" @.xy += parallaxOffset( @, @, @.xy, @, @ );\r\n", texCoord, bumpMapTexture, normalMap, texCoord, negViewTS, parallaxInfo)); else meta->addStatement(new GenOp(" @.xy += parallaxOffset( @, @.xy, @, @ );\r\n", texCoord, normalMap, texCoord, negViewTS, parallaxInfo)); } // TODO: Fix second UV maybe? output = meta; }
void TerrainParallaxMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd ) { if ( LangElement::find( "outNegViewTS" ) ) return; MultiLine *meta = new MultiLine; // Grab the input position. Var *inPos = (Var*)LangElement::find( "inPosition" ); if ( !inPos ) inPos = (Var*)LangElement::find( "position" ); // Get the object space eye position and the // object to tangent transform. Var *eyePos = _getUniformVar( "eyePos", "vec3" , cspPotentialPrimitive ); Var *objToTangentSpace = getOutObjToTangentSpace( componentList, meta,fd ); // Now send the negative view vector in tangent space to the pixel shader. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); Var *outNegViewTS = connectComp->getElement( RT_TEXCOORD ); outNegViewTS->setName( "outNegViewTS" ); outNegViewTS->setType( "vec3" ); meta->addStatement( new GenOp( " @ = @ * vec3( @ - @.xyz );\r\n", outNegViewTS, objToTangentSpace, eyePos, inPos ) ); output = meta; }
void TerrainMacroMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd ) { const S32 detailIndex = getProcessIndex(); // Grab incoming texture coords... the base map feature // made sure this was created. Var *inTex = (Var*)LangElement::find( "texCoord" ); AssertFatal( inTex, "The texture coord is missing!" ); // Grab the input position. Var *inPos = (Var*)LangElement::find( "inPosition" ); if ( !inPos ) inPos = (Var*)LangElement::find( "position" ); // Get the object space eye position. Var *eyePos = _getUniformVar( "eyePos", "float3", cspPotentialPrimitive ); MultiLine *meta = new MultiLine; // Get the distance from the eye to this vertex. Var *dist = (Var*)LangElement::find( "macroDist" ); if ( !dist ) { dist = new Var; dist->setType( "float" ); dist->setName( "macroDist" ); meta->addStatement( new GenOp( " @ = distance( @.xyz, @ );\r\n", new DecOp( dist ), inPos, eyePos ) ); } // grab connector texcoord register ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); Var *outTex = connectComp->getElement( RT_TEXCOORD ); outTex->setName( String::ToString( "macroCoord%d", detailIndex ) ); outTex->setStructName( "OUT" ); outTex->setType( "float4" ); outTex->mapsToSampler = true; // Get the detail scale and fade info. Var *detScaleAndFade = new Var; detScaleAndFade->setType( "float4" ); detScaleAndFade->setName( String::ToString( "macroScaleAndFade%d", detailIndex ) ); detScaleAndFade->uniform = true; detScaleAndFade->constSortPos = cspPotentialPrimitive; // Setup the detail coord. meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, detScaleAndFade ) ); // And sneak the detail fade thru the w detailCoord. meta->addStatement( new GenOp( " @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n", outTex, detScaleAndFade, dist, detScaleAndFade ) ); output = meta; }
void ParallaxFeatGLSL::processVert( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd ) { AssertFatal( GFX->getPixelShaderVersion() >= 2.0, "ParallaxFeatGLSL::processVert - We don't support SM 1.x!" ); MultiLine *meta = new MultiLine; // Add the texture coords. getOutTexCoord( "texCoord", "vec2", true, fd.features[MFT_TexAnim], meta, componentList ); // Grab the input position. Var *inPos = (Var*)LangElement::find( "inPosition" ); if ( !inPos ) inPos = (Var*)LangElement::find( "position" ); // Get the object space eye position and the // object to tangent space transform. Var *eyePos = _getUniformVar( "eyePos", "vec3", cspPrimitive ); Var *objToTangentSpace = getOutObjToTangentSpace( componentList, meta, fd ); // Now send the negative view vector in tangent space to the pixel shader. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); Var *outNegViewTS = connectComp->getElement( RT_TEXCOORD ); outNegViewTS->setName( "outNegViewTS" ); outNegViewTS->setStructName( "OUT" ); outNegViewTS->setType( "vec3" ); meta->addStatement( new GenOp( " @ = tMul( @, float3( @.xyz - @ ) );\r\n", outNegViewTS, objToTangentSpace, inPos, eyePos ) ); // TODO: I'm at a loss at why i need to flip the binormal/y coord // to get a good view vector for parallax. Lighting works properly // with the TS matrix as is... but parallax does not. // // Someone figure this out! // meta->addStatement( new GenOp( " @.y = [email protected];\r\n", outNegViewTS, outNegViewTS ) ); // If we have texture anim matrix the tangent // space view vector may need to be rotated. Var *texMat = (Var*)LangElement::find( "texMat" ); if ( texMat ) { meta->addStatement( new GenOp( " @ = tMul(@, float4(@,0)).xyz;\r\n", outNegViewTS, texMat, outNegViewTS ) ); } output = meta; }
void TerrainDetailMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd ) { const S32 detailIndex = getProcessIndex(); // Grab incoming texture coords... the base map feature // made sure this was created. Var *inTex = (Var*)LangElement::find( "texCoord" ); AssertFatal( inTex, "The texture coord is missing!" ); // Grab the input position. Var *inPos = (Var*)LangElement::find( "inPosition" ); if ( !inPos ) inPos = (Var*)LangElement::find( "position" ); // Get the object space eye position. Var *eyePos = _getUniformVar( "eyePos", "float3", cspPotentialPrimitive ); MultiLine *meta = new MultiLine; // If we have parallax mapping then make sure we've sent // the negative view vector to the pixel shader. if ( fd.features.hasFeature( MFT_TerrainParallaxMap ) && !LangElement::find( "outNegViewTS" ) ) { // Get the object to tangent transform which // will consume 3 output registers. Var *objToTangentSpace = getOutObjToTangentSpace( componentList, meta, fd ); // Now use a single output register to send the negative // view vector in tangent space to the pixel shader. ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); Var *outNegViewTS = connectComp->getElement( RT_TEXCOORD ); outNegViewTS->setName( "outNegViewTS" ); outNegViewTS->setStructName( "OUT" ); outNegViewTS->setType( "float3" ); meta->addStatement( new GenOp( " @ = mul( @, float3( @ - @.xyz ) );\r\n", outNegViewTS, objToTangentSpace, eyePos, inPos ) ); } // Get the distance from the eye to this vertex. Var *dist = (Var*)LangElement::find( "dist" ); if ( !dist ) { dist = new Var; dist->setType( "float" ); dist->setName( "dist" ); meta->addStatement( new GenOp( " @ = distance( @.xyz, @ );\r\n", new DecOp( dist ), inPos, eyePos ) ); } // grab connector texcoord register ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); Var *outTex = connectComp->getElement( RT_TEXCOORD ); outTex->setName( String::ToString( "detCoord%d", detailIndex ) ); outTex->setStructName( "OUT" ); outTex->setType( "float4" ); outTex->mapsToSampler = true; // Get the detail scale and fade info. Var *detScaleAndFade = new Var; detScaleAndFade->setType( "float4" ); detScaleAndFade->setName( String::ToString( "detailScaleAndFade%d", detailIndex ) ); detScaleAndFade->uniform = true; detScaleAndFade->constSortPos = cspPotentialPrimitive; // Setup the detail coord. // // NOTE: You see here we scale the texture coord by 'xyx' // to generate the detail coord. This y is here because // its scale is flipped to correct for the non negative y // in texCoord. // // See TerrainBaseMapFeatHLSL::processVert(). // meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, detScaleAndFade ) ); // And sneak the detail fade thru the w detailCoord. meta->addStatement( new GenOp( " @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n", outTex, detScaleAndFade, dist, detScaleAndFade ) ); output = meta; }
void TerrainBaseMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd ) { MultiLine *meta = new MultiLine; output = meta; // Generate the incoming texture var. Var *inTex; { Var *inPos = (Var*)LangElement::find( "inPosition" ); if ( !inPos ) inPos = (Var*)LangElement::find( "position" ); inTex = new Var( "texCoord", "float3" ); Var *oneOverTerrainSize = _getUniformVar( "oneOverTerrainSize", "float", cspPass ); // NOTE: The y coord here should be negative to have // the texture maps not end up flipped which also caused // normal and parallax mapping to be incorrect. // // This mistake early in development means that the layer // id bilinear blend depends on it being that way. // // So instead i fixed this by flipping the base and detail // coord y scale to compensate when rendering. // meta->addStatement( new GenOp( " @ = @.xyz * float3( @, @, -@ );\r\n", new DecOp( inTex ), inPos, oneOverTerrainSize, oneOverTerrainSize, oneOverTerrainSize ) ); } ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); // Pass the texture coord to the pixel shader. Var *outTex = connectComp->getElement( RT_TEXCOORD ); outTex->setName( "outTexCoord" ); outTex->setStructName( "OUT" ); outTex->setType( "float3" ); outTex->mapsToSampler = true; meta->addStatement( new GenOp( " @.xy = @.xy;\r\n", outTex, inTex ) ); // If this shader has a side projected layer then we // pass the dot product between the +Y and the normal // thru outTexCoord.z for use in blending the textures. if ( fd.features.hasFeature( MFT_TerrainSideProject ) ) { Var *inNormal = (Var*)LangElement::find( "normal" ); meta->addStatement( new GenOp( " @.z = pow( abs( dot( normalize( float3( @.x, @.y, 0 ) ), float3( 0, 1, 0 ) ) ), 10.0 );\r\n", outTex, inNormal, inNormal ) ); } else meta->addStatement( new GenOp( " @.z = 0;\r\n", outTex ) ); // HACK: This is sort of lazy... we generate the tanget // vector here so that we're sure it exists in the parallax // and normal features which will expect "T" to exist. // // If this shader doesn't use it the shader compiler will // optimize away this code. // Var *inTangentZ = getVertTexCoord( "tcTangentZ" ); Var *inTanget = new Var( "T", "float3" ); Var *squareSize = _getUniformVar( "squareSize", "float", cspPass ); meta->addStatement( new GenOp( " @ = normalize( float3( @, 0, @ ) );\r\n", new DecOp( inTanget ), squareSize, inTangentZ ) ); }
void TerrainDetailMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd ) { const U32 detailIndex = getProcessIndex(); // If this is a prepass and we don't have a // matching normal map... we have nothing to do. if ( fd.features.hasFeature( MFT_PrePassConditioner ) && !fd.features.hasFeature( MFT_TerrainNormalMap, detailIndex ) ) return; // Grab incoming texture coords... the base map feature // made sure this was created. Var *inTex = (Var*)LangElement::find( "texCoord" ); AssertFatal( inTex, "The texture coord is missing!" ); // Grab the input position. Var *inPos = (Var*)LangElement::find( "inPosition" ); if ( !inPos ) inPos = (Var*)LangElement::find( "position" ); // Get the object space eye position. Var *eyePos = _getUniformVar( "eyePos", "vec3", cspPotentialPrimitive ); MultiLine *meta = new MultiLine; // Get the distance from the eye to this vertex. Var *dist = (Var*)LangElement::find( "dist" ); if ( !dist ) { dist = new Var; dist->setType( "float" ); dist->setName( "dist" ); meta->addStatement( new GenOp( " @ = distance( @.xyz, @ );\r\n", new DecOp( dist ), inPos, eyePos ) ); } // grab connector texcoord register ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); Var *outTex = connectComp->getElement( RT_TEXCOORD ); outTex->setName( String::ToString( "outDetCoord%d", detailIndex ) ); outTex->setType( "vec4" ); outTex->mapsToSampler = true; // Get the detail scale and fade info. Var *detScaleAndFade = new Var; detScaleAndFade->setType( "vec4" ); detScaleAndFade->setName( String::ToString( "detailScaleAndFade%d", detailIndex ) ); detScaleAndFade->uniform = true; detScaleAndFade->constSortPos = cspPotentialPrimitive; // Setup the detail coord. // // NOTE: You see here we scale the texture coord by 'xyx' // to generate the detail coord. This y is here because // its scale is flipped to correct for the non negative y // in texCoord. // // See TerrainBaseMapFeatHLSL::processVert(). // meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, detScaleAndFade ) ); // And sneak the detail fade thru the w detailCoord. meta->addStatement( new GenOp( " @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n", outTex, detScaleAndFade, dist, detScaleAndFade ) ); output = meta; }