Goed, weer een eind verder met het project 'ik wil wel eens weten hoe 3D werkt'. Deze keer heb ik weer een probleem. De shaders hebben er geen zin in op Radeons. Jep, "Radeons". Je kunt gewoon met zekerheid stellen dat als je een Radeon hebt, de boel niet werkt:
Maar zelfs de simpelste Per Pixel Shading werkt alleen op NVIDIA's:
Aangezien ik alleen maar die 9600GT binnen bereik heb, kan ik niet even makkelijk een avondje de code langslopen. Met degene van de HD4890 ben ik nu dus via mail (dat werkt handig zeg
) alles aan het langsgaan. Probeersels als: zet de kleur eens op float4(1,1,1,1), zet fog uit, zet schaduwen uit, etc.
Even een voorbeeld op NVIDIA's:

En op ATI's:

Jep, het dak en de plantenbakken. Die gebruiken Per Vertex. De rest (per pixel (normal)(specular)) is foetsie. Als ik naar het aantal triangles kijk, zie ik dat de draw calls (binnen view) wel uitgevoerd worden. Daardoor kloppen de framerates ook aardig.
Heb op internet verder niets kunnen vinden over bijvoorbeeld andere registers (of enig andere hack) op ATI's. Ook als ik zijn kaart zelf de *.fxo laat maken, gebeurt dit. Als ik met D3DXSHADER_DEBUG de output controleer, is alles goed.
De Intel is een verhaal apart in PerPixel. Die krijgt het niet eens voor elkaar om de interpolatie (tussen VS en PS) goed te doen. Heb er even geen screen van (die dingen hebben ze op school), maar de strepen en artifacts zitten overal overheen. Zelfde voor lerp(), wat net zo goed interpolatie is. Nog nooit zoiets vaags gezien. Maar het werkt beter dan op de ATI's.
En omdat ik er niet meer uitkom, vraag ik het hier. Laten we hopen dat hier zat mensen zijn die Per Pixel Lighting wèl op ATI's aan de praat krijgen.
Als er meer code nodig is, zegt het maar. Beetje huiverig om de hele zooi (ja, het is veel) hier te dumpen.
- NVIDIA GeForce 9600GT: 100% Pass.
- NVIDIA GeForce GTX460: 100% Pass.
- NVIDIA GeForce GT240M: 100% Pass.
- ATI Radeon HD4800 Series (HD4870): Passes Vertex Shading, fails Pixel Shading.
- ATI Radeon HD4800 Series (HD4890): Passes Vertex Shading, fails Pixel Shading.
- AMD Radeon HD5700 Series (HD5770): Passes Vertex Shading, fails Pixel Shading.
- Intel Q45 Express Chipset: Mostly Pass, but shows artifacts on interpolated surfaces or when using saturate() or lerp().
C++:
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
| VS_OUTPUT_PERVERTEX VertexVS(float3 positionin : POSITION0,float2 coordin : TEXCOORD0,float3 normalin : NORMAL0) { VS_OUTPUT_PERVERTEX outVS = (VS_OUTPUT_PERVERTEX)0; // Standaard verwerking outVS.position = mul(float4(positionin,1.0f),WorldViewProj); outVS.coord = coordin; // Mul met lightpos, dan coords verschuiven, zodat we coords relatief aan licht op texels hebben outVS.projcoord = mul(mul(float4(positionin,1.0f), LightWorldViewProj),ShadowOffset); // Aangezien we per vertex een kleur geven, bereken dat laatste hier alvast float3 positionworld = mul(float4(positionin,1.0f),World); float3 normalworld = normalize(mul(normalin,(float3x3)World)); float dist = distance(camerapos,positionworld); // En gooi het in de functies float3 diffuse = calculateDiffuse(normalworld,lightdir); // Tel het op zodat we kleurtje hebben van deze vertex outVS.color = diffuse + lightambient; outVS.fog = calculateFog(dist); // En stuur de boel naar Pixel Shader return outVS; } PS_OUTPUT VertexPS(float3 colorin : COLOR0,float2 coordin : TEXCOORD0,float4 projcoordin : TEXCOORD1,float fogin : FOG0) { PS_OUTPUT outPS = (PS_OUTPUT)0; // Functie float3 shadow = calculateShadowPCF(projcoordin); // En dan hebben we kleur float4 texColor = tex2D(DiffuseS, coordin); outPS.color.rgb = lerp(shadow*texColor.rgb*colorin,fogcolor,fogin); outPS.color.a = texColor.a; return outPS; } |
Maar zelfs de simpelste Per Pixel Shading werkt alleen op NVIDIA's:
C++:
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
| VS_OUTPUT_PERPIXEL PixelVS(float3 positionin : POSITION0,float2 coordin : TEXCOORD0,float3 normalin : NORMAL0) { VS_OUTPUT_PERPIXEL outVS = (VS_OUTPUT_PERPIXEL)0; // Standaard verwerking outVS.position = mul(float4(positionin,1.0f),WorldViewProj); outVS.positionworld = mul(float4(positionin,1.0f),World); outVS.normalworld = mul(normalin,(float3x3)World); outVS.coord = coordin; // Mul met lightpos, dan coords verschuiven, zodat we coords relatief aan licht op texels hebben outVS.projcoord = mul(mul(float4(positionin,1.0f), LightWorldViewProj),ShadowOffset); // En doorgeven aan de pixelshader, die per pixel de kleur berekent return outVS; } PS_OUTPUT PixelPS(float3 positionworldin : POSITION1,float3 normalworldin : NORMAL0,float2 coordin : TEXCOORD0,float4 projcoordin : TEXCOORD1) { PS_OUTPUT outPS = (PS_OUTPUT)0; // Prepwork voor functies normalworldin = normalize(normalworldin); float dist = distance(camerapos,positionworldin); // Functies float fog = calculateFog(dist); float3 diffuse = calculateDiffuse(normalworldin,lightdir); float3 shadow = calculateShadowPCF(projcoordin); // En dan eindelijk hebben we kleur float4 texColor = tex2D(DiffuseS, coordin); outPS.color.rgb = lerp(shadow*texColor.rgb*(diffuse + lightambient),fogcolor,fog); outPS.color.a = texColor.a; return outPS; } |
Aangezien ik alleen maar die 9600GT binnen bereik heb, kan ik niet even makkelijk een avondje de code langslopen. Met degene van de HD4890 ben ik nu dus via mail (dat werkt handig zeg
Even een voorbeeld op NVIDIA's:

En op ATI's:

Jep, het dak en de plantenbakken. Die gebruiken Per Vertex. De rest (per pixel (normal)(specular)) is foetsie. Als ik naar het aantal triangles kijk, zie ik dat de draw calls (binnen view) wel uitgevoerd worden. Daardoor kloppen de framerates ook aardig.
Heb op internet verder niets kunnen vinden over bijvoorbeeld andere registers (of enig andere hack) op ATI's. Ook als ik zijn kaart zelf de *.fxo laat maken, gebeurt dit. Als ik met D3DXSHADER_DEBUG de output controleer, is alles goed.
De Intel is een verhaal apart in PerPixel. Die krijgt het niet eens voor elkaar om de interpolatie (tussen VS en PS) goed te doen. Heb er even geen screen van (die dingen hebben ze op school), maar de strepen en artifacts zitten overal overheen. Zelfde voor lerp(), wat net zo goed interpolatie is. Nog nooit zoiets vaags gezien. Maar het werkt beter dan op de ATI's.
En omdat ik er niet meer uitkom, vraag ik het hier. Laten we hopen dat hier zat mensen zijn die Per Pixel Lighting wèl op ATI's aan de praat krijgen.
Als er meer code nodig is, zegt het maar. Beetje huiverig om de hele zooi (ja, het is veel) hier te dumpen.