Bonsoir,
j'ai un souci avec un rendu de shader, que j'ai invariablement noir.
Je force le rendu à "tout les pixel en blanc" au niveau du pixel shader mais rien n'y fait. Et je n'y comprend rien du tout... Surtout qu'avec FX Composer tout est censé être ok.
Si je change l'appel vers un autre shader qui contient *exactement* le même code, j'ai un rendu correct. Le truc ce que je voudrais tout mettre dans le même, par simplicité, et surtout parce qu'une certain valeur est transmise d'une technique à l'autre, et les registres des shaders ne sont qu'en écriture, et pas en lecture, donc ce que je voudrais faire est tout simplement impossible en 2 shaders.
Le shader qui compile bien et qui est censé rendre du blanc:
Le shader qui fonctionne bien et qui contient le même code: on appelle la même technique TetraDOF:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316 float4x4 WorldViewProj : WorldViewProjection; float4x4 WorldViewIT : WorldInverseTranspose; float4x4 WorldView : ViewInverse; float4 MinMaxDist; float4 FocusConst; float4 lightDir : Direction < > = {200.0f, 300.0f, 150.0f, 0.0f}; float4 lightColor : Diffuse < > = {1.0f, 1.0f, 1.0f, 1.0f}; float4 lightAmbient : Ambient < > = {1.0f, 1.0f, 1.0f, 1.0f}; float4 materialDiffuse : Diffuse < > = {1.0f, 1.0f, 1.0f, 1.0f}; float UvOffsetToUse; float4 UvBase[8]; //------------------------------------------------------------------- // Textures (bound to real textures by app) //------------------------------------------------------------------- texture Meshes; texture CircleOfConfusion; texture WorldTex; texture BlurTex; texture FilteredTex0; texture FilteredTex1; texture FilteredTex2; //------------------------------------------------------------------- // Vertex shader input structures //------------------------------------------------------------------- struct vertexInput { float3 position : POSITION; float3 normal : NORMAL; float4 texCoordDiffuse : TEXCOORD0; }; struct VS_INPUT_PT { float4 Position : POSITION; float2 TexCoord : TEXCOORD0; }; //------------------------------------------------------------------- // Vertex shader output (and pixel shader input) structures //------------------------------------------------------------------- struct VS_OUTPUT_PT4 { float4 oPosition : POSITION; float2 oTexCoord0 : TEXCOORD0; float2 oTexCoord1 : TEXCOORD1; float2 oTexCoord2 : TEXCOORD2; float2 oTexCoord3 : TEXCOORD3; }; struct vertexOutput { float4 hPosition : POSITION; float4 texCoordDiffuse : TEXCOORD0; float4 diffAmbColor : COLOR0; float3 oTexCoord1 : TEXCOORD1; }; //------------------------------------------------------------------- // Texture samplers //------------------------------------------------------------------- sampler TextureSampler = sampler_state { texture = <Meshes>; AddressU = CLAMP; AddressV = CLAMP; AddressW = CLAMP; MIPFILTER = LINEAR; MINFILTER = LINEAR; MAGFILTER = LINEAR; }; sampler CircleOfConfusionSampler = sampler_state { Texture = <CircleOfConfusion>; MinFilter = Linear; MagFilter = Linear; MipFilter = None; AddressU = Clamp; AddressV = Clamp; AddressW = Clamp; }; sampler BlurTexSampler = sampler_state { Texture = <BlurTex>; MinFilter = Linear; MagFilter = Linear; MipFilter = Linear; AddressU = Clamp; AddressV = Clamp; }; sampler FilteredTexSampler0 = sampler_state { Texture = <FilteredTex0>; MinFilter = Linear; MagFilter = Linear; MipFilter = NONE; AddressU = Clamp; AddressV = Clamp; }; sampler FilteredTexSampler1 = sampler_state { Texture = <FilteredTex1>; MinFilter = Linear; MagFilter = Linear; MipFilter = NONE; AddressU = Clamp; AddressV = Clamp; }; sampler FilteredTexSampler2 = sampler_state { Texture = <FilteredTex2>; MinFilter = Linear; MagFilter = Linear; MipFilter = NONE; AddressU = Clamp; AddressV = Clamp; }; //------------------------------------------------------------------- // Vertex Shaders (and subroutines) //------------------------------------------------------------------- float ComputeDistance(float4 position) { float dist = dot(position, float4(WorldView[0][2], WorldView[1][2], WorldView[2][2], WorldView[3][2])); //dist = dist / dot(position, float4(WorldView[0][3], WorldView[1][3], WorldView[2][3], WorldView[3][3])); return dist; } vertexOutput VS_TransformAndTexture(vertexInput IN) { vertexOutput OUT; OUT.hPosition = mul( float4(IN.position.xyz , 1.0) , WorldViewProj); OUT.texCoordDiffuse = IN.texCoordDiffuse; float3 worldEyePos = WorldView[3].xyz; float3 worldVertPos = (IN.position).xyz; float4 N = mul(IN.normal, WorldViewIT); //normal vector float3 E = normalize(worldEyePos - worldVertPos); //eye vector float3 L = normalize( -lightDir.xyz); //light vector float3 H = normalize(E + L); //half angle vector float diff = max(0 , dot(N,L)); float4 ambColor = materialDiffuse * lightAmbient; float4 diffColor = materialDiffuse * diff * lightColor ; OUT.diffAmbColor = diffColor + ambColor; float4 lPosition = float4(IN.position, 1.0); float dist = ComputeDistance(lPosition); OUT.oTexCoord1.x = dist*MinMaxDist.y - MinMaxDist.x; OUT.oTexCoord1.yz = FocusConst.xy; return OUT; } VS_OUTPUT_PT4 BlurVS(const VS_INPUT_PT IN) { VS_OUTPUT_PT4 OUT; // Transform vertex position to clip space OUT.oPosition = mul(IN.Position, WorldViewProj); int a = (int)UvOffsetToUse * 4; OUT.oTexCoord0 = IN.TexCoord + UvBase[a ].xy; OUT.oTexCoord1 = IN.TexCoord + UvBase[a + 1].xy; OUT.oTexCoord2 = IN.TexCoord + UvBase[a + 2].xy; OUT.oTexCoord3 = IN.TexCoord + UvBase[a + 3].xy; return OUT; } //------------------------------------------------------------------- // Pixel Shaders //------------------------------------------------------------------- float4 BlurPS(VS_OUTPUT_PT4 IN) : COLOR { // This is a simple blur-shader: we simply average all alpha and color // values together. // get colors and alphas from all 4 texture stages float4 color0 = tex2D(BlurTexSampler, IN.oTexCoord0); float4 color1 = tex2D(BlurTexSampler, IN.oTexCoord1); float4 color2 = tex2D(BlurTexSampler, IN.oTexCoord2); float4 color3 = tex2D(BlurTexSampler, IN.oTexCoord3); // return the average (keeping within the [-2..2] range) return 0.5*( 0.5*(color0 + color1) + 0.5*(color2 + color3) ); } float4 PS_Textured( vertexOutput IN): COLOR { float4 diffuseTexture = tex2D( TextureSampler, IN.texCoordDiffuse ); // return IN.diffAmbColor * diffuseTexture; return float4(1.0f,1.0f,1.0f,1.0f); } //------------------------------------------------------------------- // TECHNIQUES //------------------------------------------------------------------- technique TetraDOF { pass P0 { VertexShader = compile vs_1_1 VS_TransformAndTexture(); PixelShader = compile ps_1_1 PS_Textured(); } } technique Blur { pass P0 { VertexShader = compile vs_1_1 BlurVS(); PixelShader = compile ps_1_1 BlurPS(); // note that these render-state changes are reverted once the effect is complete. AlphaBlendEnable = False; ZEnable = False; CullMode = None; FillMode = Solid; // (even if wireframe is turned on) ColorOp[0] = SelectArg1; ColorArg1[0] = Texture; ColorArg2[0] = Diffuse; ColorOp[1] = Disable; AlphaOp[0] = Disable; } } technique ShowDepthOfField { pass P0 { Sampler[0] = <FilteredTexSampler0>; Sampler[1] = <FilteredTexSampler1>; Sampler[2] = <FilteredTexSampler2>; AlphaBlendEnable = False; ZEnable = False; CullMode = None; FillMode = Solid; // (even if wireframe is turned on) VertexShader = compile vs_1_1 BlurVS(); PixelShader = asm { ; NOTE: This shader exists in HLSL above (see ShowDepthOfFieldPS), ; but is commented out; the assembly version is used here because ; it's the only way to fit this shader in ps1.1. The HLSL-compiled ; version will work if you compile it using ps_2_0; but since the ; assembly version will fit in ps_1_1, it is used here instead. ; Declare pixel shader version ps_1_1 def c0, 0.0f, 0.0f, 0.0f, 0.5f def c1, 0.0f, 0.0f, 0.0f, 0.333333f ; sample all the texture stages tex t0 tex t1 tex t2 ; first interpolate the interpolator: using t0 straight produces ghosting ; since the DoF selection is always hi-res (ie, t0) even for the blurred parts. ; playing with various combinations of t0, t1, t2 shows that the following ; is reasonable (depth-changing edges never get really unblurred) ; and yet only takes a single instruction. lrp r0.a, c0, t2.a, t0.a ; although the following also produces good results (but with a bit of ghosting ; and two instructions) ; r0.a = 0.666*(.5*t2.a + .5*t1.a) + 0.333 * t0.a) ; = 0.333*(t0.a+t1.a+t2.a) ; lrp r0.a, c0, t2.a, t1.a ; lrp r0.a, c1, r0.a, t0.a mov_x2_sat r1.a, r0.a // pretend 0 <= r0.a <= 0.5 lrp r1.rgb, r1.a, t1, t0 // correctly interpolate t0, t1 and store mov_sat r1.a, r0_bx2.a // pretend 0.5 <= r0.a <= 1 lrp r0.rgb, r1.a, t2, t1 // correctly interpolate t1, t2 and store cnd r0.rgb, r0.a, r0, r1 // figure out which case is the true one and select it ; mov r0.rgb, t0.a }; } }
La méthode d'où j'appelle tout ça:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126 float4x4 WorldViewProj : WorldViewProjection; float4x4 WorldViewIT : WorldInverseTranspose; float4x4 WorldView : ViewInverse; float4 MinMaxDist; float4 FocusConst; float4 lightDir : Direction < > = {200.0f, 300.0f, 150.0f, 0.0f}; float4 lightColor : Diffuse < > = {1.0f, 1.0f, 1.0f, 1.0f}; float4 lightAmbient : Ambient < > = {1.0f, 1.0f, 1.0f, 1.0f}; float4 materialDiffuse : Diffuse < > = {1.0f, 1.0f, 1.0f, 1.0f}; //------------------------------------------------------------------- // Textures (bound to real textures by app) //------------------------------------------------------------------- texture Meshes; //------------------------------------------------------------------- // Vertex shader input structures //------------------------------------------------------------------- struct vertexInput { float3 position : POSITION; float3 normal : NORMAL; float4 texCoordDiffuse : TEXCOORD0; }; //------------------------------------------------------------------- // Vertex shader output (and pixel shader input) structures //------------------------------------------------------------------- struct vertexOutput { float4 hPosition : POSITION; float4 texCoordDiffuse : TEXCOORD0; float4 diffAmbColor : COLOR0; float3 oTexCoord1 : TEXCOORD1; }; //------------------------------------------------------------------- // Texture samplers //------------------------------------------------------------------- sampler TextureSampler = sampler_state { texture = <Meshes>; AddressU = CLAMP; AddressV = CLAMP; AddressW = CLAMP; MIPFILTER = LINEAR; MINFILTER = LINEAR; MAGFILTER = LINEAR; }; //------------------------------------------------------------------- // Vertex Shaders (and subroutines) //------------------------------------------------------------------- float ComputeDistance(float4 position) { float dist = dot(position, float4(WorldView[0][2], WorldView[1][2], WorldView[2][2], WorldView[3][2])); //dist = dist / dot(position, float4(WorldView[0][3], WorldView[1][3], WorldView[2][3], WorldView[3][3])); return dist; } vertexOutput VS_TransformAndTexture(vertexInput IN) { vertexOutput OUT; OUT.hPosition = mul( float4(IN.position.xyz , 1.0) , WorldViewProj); OUT.texCoordDiffuse = IN.texCoordDiffuse; float3 worldEyePos = WorldView[3].xyz; float3 worldVertPos = (IN.position).xyz; float4 N = mul(IN.normal, WorldViewIT); //normal vector float3 E = normalize(worldEyePos - worldVertPos); //eye vector float3 L = normalize( -lightDir.xyz); //light vector float3 H = normalize(E + L); //half angle vector float diff = max(0 , dot(N,L)); float4 ambColor = materialDiffuse * lightAmbient; float4 diffColor = materialDiffuse * diff * lightColor ; OUT.diffAmbColor = diffColor + ambColor; float4 lPosition = float4(IN.position, 1.0); float dist = ComputeDistance(lPosition); OUT.oTexCoord1.x = dist*MinMaxDist.y - MinMaxDist.x; OUT.oTexCoord1.yz = FocusConst.xy; return OUT; } //------------------------------------------------------------------- // Pixel Shaders //------------------------------------------------------------------- float4 PS_Textured( vertexOutput IN): COLOR { float4 diffuseTexture = tex2D( TextureSampler, IN.texCoordDiffuse ); return IN.diffAmbColor * diffuseTexture; } //------------------------------------------------------------------- // TECHNIQUES //------------------------------------------------------------------- technique TetraDOF { pass P0 { VertexShader = compile vs_1_1 VS_TransformAndTexture(); PixelShader = compile ps_1_1 PS_Textured(); } }
je switch d'un Effect à l'autre en fonction de mes tests, et je configure les 2 shaders exactement de la même manière partout dans mon code.
Mais le rendu est différent ...
Voilà, je voudrais donc comprendre pourquoi je n'ai qu'un rendu noir ...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174 private static void _render() { int numpasses; while (mIsRunning) { if (mDevice == null) return; try { if (mIsWireFrame) mDevice.RenderState.FillMode = FillMode.WireFrame; else mDevice.RenderState.FillMode = FillMode.Solid; mDOF.SetValue("CircleOfConfusion", mCircleOfConfusionLookup); mDevice.SetRenderTarget(0, mFilterTarget[0]); mDevice.DepthStencilSurface = mDepthTarget; mDevice.Clear(ClearFlags.Target | ClearFlags.ZBuffer, System.Drawing.Color.Orange, 1.0f, 0); mFocusDistance = mFocusDistanceSAVE * 1000.0f * (float)Math.Cos(Environment.TickCount / 25.0f); GenerateCircleOfConfusionTexture(); UpdateCameraParameters(); _UpdateMatrices(); mDevice.BeginScene(); SetupMatrices(mMatrixView, mWorld); mDOF.Technique = "TetraDOF"; mEffectTextureAndLights.Technique = "TetraDOF"; switch (TAG_RENDER) { case TAG_RENDER_DOF: mChoosedEffect = mDOF; break; case TAG_RENDER_TL: mChoosedEffect = mEffectTextureAndLights; break; default: mChoosedEffect = mEffectTextureAndLights; break; } mDevice.VertexFormat = CustomVertex.PositionNormalTextured.Format; foreach (MesheToRender lMesheToRender in mListToRender) { mDevice.SetStreamSource(0, lMesheToRender.getVertexBufferToDisplay(), 0); mChoosedEffect.SetValue("Meshes", lMesheToRender.getTexture()); numpasses = mChoosedEffect.Begin(0); for (int i = 0; i < numpasses; i++) { mChoosedEffect.BeginPass(i); mDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, lMesheToRender.getNumberOfVerticesToDisplay()); mChoosedEffect.EndPass(); } mChoosedEffect.End(); } // On prend la texture generee // et on genere les blurs Matrix lMatView, lMatProj, lMatViewProj, lMatWorldViewProj, lMatWorld; Vector3 lEyePos, lLookAt, lUp; lEyePos.X = 0.0f; lEyePos.Y = 0.0f; lEyePos.Z = -5.0f; lLookAt.X = 0.0f; lLookAt.Y = 0.0f; lLookAt.Z = 0.0f; lUp.X = 0.0f; lUp.Y = 1.0f; lUp.Z = 0.0f; lMatView = Matrix.LookAtLH(lEyePos, lLookAt, lUp); lMatProj = Matrix.OrthoLH(4.0f, 4.0f, 0.2f, 20.0f); lMatViewProj = Matrix.Multiply(lMatView, lMatProj); lMatWorld = Matrix.Scaling(2.0f, 2.0f, 2.0f); lMatViewProj = Matrix.Multiply(lMatWorld, lMatViewProj); mDOF.SetValue("WorldViewProj", lMatViewProj); mDOF.SetValue("UvOffsetToUse", 1.0f); mDevice.VertexFormat = CustomVertex.PositionTextured.Format; mDevice.SetStreamSource(0, mQuadVertexBuffer, 0); mDOF.Technique = "Blur"; Texture lSource; Surface lDestination; for (int i = 1; i < 3; ++i) { for (int j = 0; j < mNumOfFilterSteps; ++j) { lSource = mTempTexture[j % 2]; lDestination = mTempTarget[(j + 1) % 2]; if (j == 0) lSource = mTextureFiltered[i - 1]; else if (j == mNumOfFilterSteps - 1) lDestination = mFilterTarget[i]; mDevice.SetRenderTarget(0, lDestination); mDevice.DepthStencilSurface = null; mDOF.SetValue("BlurTex", lSource); numpasses = mDOF.Begin(0); for (int lPasse = 0; lPasse < numpasses; lPasse++) { mDOF.BeginPass(lPasse); mDevice.DrawPrimitives(PrimitiveType.TriangleFan, 0, 2); mDOF.EndPass(); } mDOF.End(); } } mDevice.SetRenderTarget(0, mBackbufferColor); mDevice.DepthStencilSurface = null; mDevice.VertexFormat = CustomVertex.PositionTextured.Format; mDOF.Technique = "ShowDepthOfField"; // use the original and blurred textures as inputs mDOF.SetValue("FilteredTex0", mTextureFiltered[0]); mDOF.SetValue("FilteredTex1", mTextureFiltered[1]); mDOF.SetValue("FilteredTex2", mTextureFiltered[2]); lMatWorld = Matrix.Scaling(1.0f, 1.0f, 1.0f); lMatWorldViewProj = Matrix.Multiply(lMatWorld, lMatViewProj); mDOF.SetValue("WorldViewProj", lMatWorldViewProj); mDOF.SetValue("UvOffsetToUse", 0.0f); numpasses = mDOF.Begin(0); for (int lPasse = 0; lPasse < numpasses; lPasse++) { mDOF.BeginPass(lPasse); mDevice.DrawPrimitives(PrimitiveType.TriangleFan, 0, 2); mDOF.EndPass(); } mDOF.End(); // mDevice.EndScene(); mDevice.Present(); Application.DoEvents(); } catch (Exception lException) { MessageBox.Show(lException.StackTrace); } } }
Langage: c#
DirectX: 9
Partager