Gave it a try had the same error, it seems any reference to x inside of the for loop combined with the if causes the trouble, if you remove either it works thats why I thought it was a depth of complexity issue.
If you want detail on code here is that detail and an explanation as to whats going on. To skip plot go down to the line of *****.
This is something I have been playing around with, it under no circumstances does what I had desired at the moment but your welcome to pick at it. The idea was to project a texture onto the surrounding environment (ideally a cube light sort of deal) so that I can project a disco ball or some funky colours everywhere within a falloff range. So I started out trying to get a basic projector to work. It did work but the lighting on the wall was flat and destroyed the illusion of depth created by the parallax relief mapping I had implemented.
The aim being to find a way to make the projectors lighting work with the normal map of the wall and its heightmap to create accurate depth on the surface based on the projectors position. Obviously at this point I am just getting a framework with which to play around with values to try and get that to happen I have never done a stencil buffer trick before but I was going to look into that when I got this working.
I am not sure if its possible to figure out how the walls UV texture is mapped in order to handle throwing its normals to display the image correctly, but you dont learn without trying.
********************************************************************
Here are all my constants and the projected textures sampler state.
float4x4 WorldViewProj; //World * View * Projection Matrixfloat4x4 World; //World matrix of objectfloat4 EyePos; //Position of eye in world space//PARALLAX REQSfloat4 LightPos[6]; //Light position in world spacefloat4 LightColor[6]; //Color of the lighttexture ColorMap; //Color texturetexture NormalMap; //Normal map texturetexture HeightMap; //Height map texturetexture ColorMap2; //Color texturetexture NormalMap2; //Normal map texturetexture HeightMap2; //Height map texturetexture BlendMap; //The map for blending the two effectsfloat Falloff[6]; // Distance until light begins to fallofffloat Ambient; // Ambient amount of lightingfloat DepthScale = 0.04f; //Depth of the parallax mapfloat Bias = 0.02f; //Bias of the parallax map//PROJECTIVE TEX REQSfloat4x4 TexTransform[3]; //Texture transformation matrixtexture ProjTex; //The projected image, could be seperated for multiple types.float3 ProjectorPos[3]; //World position of the projection matrixfloat ProjFalloff[3]; //Degree to which the image attenuates over distanceint totalProjections;//PROJECTIVE TEX REQsampler ProjTexSampler = sampler_state{ Texture = <ProjTex>; MinFilter = anisotropic; MagFilter = anisotropic; MipFilter = anisotropic; AddressU = Border; AddressV = Border;};
Here are my relevant structures.
////////////////////////////////////////////////////////////////Structures////////////////////////////////////////////////////////////////Application to vertex shaderstruct A2V_AdvancedLight{ float4 Position : POSITION; float3 Normal : NORMAL; float2 TexCoord0 : TEXCOORD0; float3 Tangent : TANGENT; float3 Binormal : BINORMAL;};//PROJECTIVE TEX REQS////////////////////////////////////////////////////////////// Structures////////////////////////////////////////////////////////////struct V2P_Projection{ float4 Position : POSITION; float2 TexCoord0 : TEXCOORD0; float4 TexCoordProj[3] :TEXCOORD1; float3 ProjVec[3] : TEXCOORD4; float3 ViewDir : TEXCOORD7;};
Here are my shaders.
////////////////////////////////////////////////////////////// Vertex Shader PROJECTIVE TEX////////////////////////////////////////////////////////////void VS_PT(in A2V_AdvancedLight IN, out V2P_Projection OUT){ //Transform the position from view space to homogeneous projection space OUT.Position = mul(IN.Position, WorldViewProj); //Compute world space position float4 WorldPos = mul(IN.Position, World); //Calculate Binormal and set Tangent Binormal and Normal matrix float3x3 TBNMatrix = mul(float3x3(IN.Binormal, IN.Tangent , IN.Normal), (float3x3)World); //Compute view direction * TBN Matrix OUT.ViewDir = mul(TBNMatrix, EyePos - WorldPos); for(int x=0; x < totalProjections; x++) { //Position to projection vector OUT.ProjVec[x] = mul(IN.Position.xyz, (float3x3)World) - ProjectorPos[x]; //Compute projection direction * TBN Matrix OUT.ProjVec[x] = mul(TBNMatrix, OUT.ProjVec[x]); //Need to calculate the texture coordinates between persons positon and their transformations position to work out actual location. OUT.TexCoordProj[x] = mul(IN.Position, TexTransform[0]); } //Copy the texture coordinate as is OUT.TexCoord0 = IN.TexCoord0;}////////////////////////////////////////////////////////////// Pixel Shader PROJECTIVE TEX////////////////////////////////////////////////////////////float4 PS_PT(in V2P_Projection IN) : COLOR { IN.ViewDir = normalize(IN.ViewDir); //We need to define everything ready for our loop. float Height; float2 TexCorrected; float4 ProjC; float3 Normal; float LenSq; float Attn; float Diffuse; float4 finalColor; finalColor = 0; //We need to sort the blend map vector BlendMapV = tex2D( BlendMapSampler, IN.TexCoord0);//Here is the for loop that crashes things. for(int x = 0; x < totalProjections; x++) { float4 ProjLight = tex2Dproj(ProjTexSampler, IN.TexCoordProj[x]);//Remove this if and it works with x mentioned inside the loop. if (IN.TexCoordProj[x].w < 0.0) { //We do not modify the projection at all if we are the opposite direction from it. finalColor += 0.5; } else {//Remove any mention of x inside the if and it works. Height = DepthScale * tex2D(heightSampler, IN.TexCoordProj[0]) - Bias; //Compute the new texture coorddinate to use TexCorrected = Height * IN.ViewDir + IN.ProjVec[0]; //Pixel to light vector LenSq = dot( IN.ProjVec[0], IN.ProjVec[0] ); IN.ProjVec[0] = normalize( IN.ProjVec[0] ); //Compute the light's attenuation Attn = min((ProjFalloff[0]* ProjFalloff[0]) / LenSq, 1.0f); //Compute the diffuse lighting amount Diffuse = Attn * saturate(dot(TexCorrected, IN.ProjVec[0])); //Lighting amount * Texture Color * Light Color ProjC = ProjLight * Diffuse; //Combinant of the two based on the blend map------------- finalColor += ProjC; } } //Return the combinant of the two based on the blend map------------- return finalColor;}
and finally the technique is below.
////////////////////////////////////////////////////////////////Technique//////////////////////////////////////////////////////////////technique ParallaxMapPointLightBlend{ pass p0 { vertexshader = compile vs_3_0 VS_P(); pixelshader = compile ps_3_0 PS_PBM(); } pass p1 { ALPHABLENDENABLE = TRUE; SRCBLEND = ONE; DESTBLEND = ONE; VertexShader = compile vs_3_0 VS_PT(); PixelShader = compile ps_3_0 PS_PT(); }}
To clarify I am not desperate for help in getting the full effect to work. I just need to be able to figure out why the pixel shader cant have a nested if use the x variable from the for loop.