Overriding shader use?

Started by
20 comments, last by ChopperDave 17 years, 12 months ago
I just seem to be full of problems. This quite a learning experience for me (albeit frustrating). For some reason, I have shaders that are being set in my effect file but not being executed. My effect file looks like so:


float4 viewportScale;
float4 viewportBias; 

struct INPUT_PPVS {
  float4 pos : POSITION;
  float2 texCoord : TEXCOORD0;
};

struct OUTPUT_PPVS {
  float4 pos : POSITION;
  float2 texCoord : TEXCOORD0;
};

OUTPUT_PPVS ppvs(INPUT_PPVS v) {
  OUTPUT_PPVS o = (OUTPUT_PPVS) 0;

  o.pos = v.pos * viewportScale + viewportBias;

  o.texCoord = v.texCoord;

  return o;
}


float2 filterSamples[12];

struct INPUT_PPPS {
  float2 texCoord : TEXCOORD0;
};

float4 ppps(INPUT_PPPS v) : COLOR {

  float4 totalColor = tex2D(ColorMapSampler,v.texCoord); //samplers made earlier
  float totalCont = 1.0;
  float2 depthBlur = tex2D(DepthBlurMapSampler,v.texCoord); 
  float cocSize = depthBlur.y * maxCOC;

  for (int i = 0; i < 12; i++) {
    float2 sampleCoord = v.texCoord + filterSamples * cocSize;
    float4 sampleColor = tex2D(ColorMapSampler,sampleCoord);       
    float2 sampleDepthBlur = tex2D(DepthBlurMapSampler,sampleCoord); 
    float sampleCont = (sampleDepthBlur.x > depthBlur.x) ? 1.0 : sampleDepthBlur.y;
    totalColor += sampleColor * sampleCont;
    totalCont += sampleCont;
  }

  return (totalColor/totalCont);
}


vertexshader postprocessvs = compile vs_2_0 ppvs();
pixelshader postprocessps = compile ps_2_0 ppps();

technique SimCOC {
  pass P0 {
	 ...
  }
  pass P1 {
       Sampler[0] = (ColorMapSampler);
       Sampler[1] = (DepthBlurMapSampler);
       ZEnable = False;
       fvf = XYZW | Tex1;
       vertexshader = (postprocessvs);
       pixelshader = (postprocessps);
       
  }
}


In my rendering code I have tried two things for drawing: one using vertices stored in a vertex buffer, and the other using DrawPrimitiveUP using an array of vertices. Here is what the rendering code looks like:

//effect->Begin done elsewhere
effect->SetTexture("colorMap",colorMap);
	effect->SetTexture("depthBlurMap",depthBlurMap);
	
	if(SUCCEEDED(device->BeginScene())) {
		effect->BeginPass(1);
		device->SetStreamSource(0,vb,0,sizeof(Vertex));
		device->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
		effect->EndPass();
		device->EndScene();
	}
	effect->End();


I've also tried this:

effect->SetTexture("colorMap",colorMap);
	effect->SetTexture("depthBlurMap",depthBlurMap);
	
	Vertex vertices[] = {{0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f},
	{1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f},
	{1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f},//x,y,z,w,u,v
	{0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f}};

	if(SUCCEEDED(device->BeginScene())) {
		effect->BeginPass(1);
		device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, &vertices, sizeof(Vertex));
		effect->EndPass();
		device->EndScene();
	}
	effect->End();


The first way neither of the shaders executes. In the second way, the vertex shader will sometimes execute, but only if the pixel shader is deactivated or does next to nothing. The pixel shader runs normally only if the vertex shader is skipped over. What in the world is going on? [Edited by - ChopperDave on April 17, 2006 12:11:45 AM]
Advertisement
You should place all Effect-> calls between the BeginScene and EndScene. Also, the order for the calls to the effect interface is Begin, BeginPass, Draw*Prim, EndPass, End.

So, your code should look something like this:

	effect->SetTexture("colorMap",colorMap);	effect->SetTexture("depthBlurMap",depthBlurMap);		if(SUCCEEDED(device->BeginScene())) {		effect->Begin();		effect->BeginPass(1);		device->SetStreamSource(0,vb,0,sizeof(Vertex));		device->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);		effect->EndPass();		effect->End();		device->EndScene();	}


Hope this helps.
Sirob Yes.» - status: Work-O-Rama.
I don't do effect->Begin and End within the begin and end scenes because I use the same technique on both render passes, just a different pass from that technique. I went ahead and tried it your way anyways, and it had no effect.

Any other ideas?
You should only be calling BeginScene and EndScene once per frame. Any DX call should ultimatly be between the two calls. An EndScene should be followed by a Present call.

If you want to perform two passes, just do them both between your begin/end scene calls.

Hope this helps.
Sirob Yes.» - status: Work-O-Rama.
No dice that way either. I'm totally baffled. Anything else I might be doing?
What are your values for viewportScale and viewportBia during this call?
Scale is (800.0,600.0,1.0,1.0) and bias is (-0.5,-0.5,0,0). I'm not sure how that matters seeing as how the shader doesn't even execute (I put in breakpoints to debug). Let me know what you come up with.
OK. I still haven't gotten my post process shaders to execute and I don't know why. Here is what my code looks like:
void render() {float zfoc;float* LVals = DOF->getLensValues();ID3DXEffect* fx = DOF->getEffect();	if(SUCCEEDED(DOF->sceneRender())) {	for (int i = 0; i < 4; i++) {		fx->SetMatrix("worldViewProj", &worldViewProj);		fx->SetMatrix("worldView",&worldView);		fx->SetVector("ambMat",&ambMat);		fx->SetVector("difMat",&difMat);								zfoc = (float)(fabs(1/((1/LVals[FLENS]) - (1/dist))) + dist);		fx->SetFloat("zFocus",zfoc);		fx->CommitChanges();					meshes->DrawSubset(0);	}	DOF->postProcess();}	device->Present(NULL,NULL,NULL,NULL);}//In the DOF objectHRESULT DepthOfField::sceneRender() {	UINT passes;	device->SetRenderTarget(0,colorMapSurf);	device->SetRenderTarget(1,depthBlurMapSurf);		device->Clear(NULL,0,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1,0);	if(SUCCEEDED(device->BeginScene())) {		effect->Begin(&passes,0);		effect->BeginPass(0);		return S_OK;	}	else		return E_FAIL;}void DepthOfField::postProcess() {	effect->EndPass();		device->SetRenderTarget(0,originalSurf);	device->SetRenderTarget(1,NULL);	device->Clear(NULL,0,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1,0);	effect->SetTexture("colorMap",colorMap);	effect->SetTexture("depthBlurMap",depthBlurMap);		effect->BeginPass(1);		device->SetFVF(VertexFVF);	device->SetStreamSource(0,vb,0,sizeof(Vertex));	device->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);	effect->EndPass();	effect->End();	device->EndScene();}//And in my effect filevertexshader scenerendervs = compile vs_2_0 srvs();pixelshader scenerenderps = compile ps_2_0 srps();vertexshader postprocessvs = compile vs_2_0 ppvs();pixelshader postprocessps = compile ps_2_0 ppps();technique SimCOC {  pass P0 {       fvf = XYZ | Normal | Tex1;       ZEnable = True;       vertexshader = (scenerendervs);       pixelshader = (scenerenderps);  }  pass P1 {       Sampler[0] = (ColorMapSampler);       Sampler[1] = (DepthBlurMapSampler);       ZEnable = False;       fvf = XYZRHW | Tex1;       vertexshader = (postprocessvs);       pixelshader = (postprocessps);         }}

The scene render pass works perfectly, but the shaders in the post process pass don't even execute (I used breakpoints to check). What is going on?
Your FVF contains XYZRHW. If you use pretransformed vertices the vertex shader will never called. Any vertex data you provide is passed direct to the next pipeline stage.
I see what you're saying. Unfortunately, that had no effect (I switched it to XYZ). Any other ideas?

Maybe showing my vertex struct will help:
struct Vertex {	float x;	float y;	float z;	float w;	float u;	float v;	Vertex(){};	Vertex(float x,float y,float z,float w,float u,float v){		x = x;		x = y;		z = z;		w = w;		u = u;		v = v;	};};

This topic is closed to new replies.

Advertisement