PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Frage zu Shader


TheFallenAngel
2005-09-17, 13:37:19
Hallo,

Ich & ein Kollege möchten einen bereits exisitierenden ARB Fragment
Shader zwecks kompatibilität mit älterer Grafik HW auf die NV_texture_shader extension von OpenGL umbauen. Das Fragment Programm
ist eigentlich sehr einfach:

Es gibt 2 3D texturen, die auf Textureinheit 0 und 1 liegen. Weiters
leigt auf Einheit 3 eine 2D Textur. Die 3D Texturen werden im Format GL_UNSIGNED_BYTE, die 2D Textur als RGBA auf die Grafikkarte geladen. Die Werte die Textureinheit 0 und 1 liefern dienen uns dann
als Texturkoordinaten für Einheit 3. Der somit bestimmte RGBA Wert
der 2D Textur ist das Endergebnis des Fragment Shaders.
Um die Sache mit der NV_texture_shader Erweiterung über die Bühne zu
bringen haben wir uns folgendes überlegt:
Wir haben die 3 Texturen, wie oben beschrieben. In Stage 0 und 1
führen wir einen standard Texture Lookup durch. Mittels GL_DOT_PRODUCT_NV mit einem Vektor (1,0,0,0) filtern wir die Ausgabe
von Stage 0 auf die Rot-Komponente. In Stage 3 berechnen wir nochmals
das Komponentenweise Produkt, jedoch mittels GL_DOT_PRODUCT_TEXTURE_2D_NV,
um 2 Werte als Texturekoordinaten für die 3. Textureinheit zu nützen.
Im Folgenden habe ich zuerst den funktionierenden ARB Shader Code
angefügt, danach den NV_texture_shader "Code" der jedoch nicht ganz
funktioniert

***************ARB Shader*************************
!!ARBfp1.0 \n\
TEMP R0;\n\
TEX R0.x, fragment.texcoord[0], texture[0], 3D;\n\
TEX R0.y, fragment.texcoord[0], texture[1], 3D;\n\
TEX result.color, R0, texture[3], 2D;\n\
END";

**************NV_texture_shader*******************

float constant[] = {1.0, 0.0, 0.0};
glEnable(GL_TEXTURE_SHADER_NV);
glEnable(GL_REGISTER_COMBINERS_NV);

// stage 0 --> swizzle
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_3D);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D);
glDisable(GL_TEXTURE_3D);

// stage 1 --> swizzle
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_3D);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D);
glDisable(GL_TEXTURE_3D);

// state 2 --> get r for dependent texture lookup
glActiveTextureARB(GL_TEXTURE2_ARB);
glMultiTexCoord3fv(GL_TEXTURE2_ARB, constant);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV,
GL_DOT_PRODUCT_NV); glTexEnvi(GL_TEXTURE_SHADER_NV,
GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB);

// stage 3 --> get r for dependent texture lookup and lookup in transfer
glActiveTextureARB(GL_TEXTURE3_ARB);
glMultiTexCoord3fv(GL_TEXTURE3_ARB, constant);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,
GL_TEXTURE1_ARB); glTexEnvi(GL_TEXTURE_SHADER_NV,
GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_2D_NV);


// put alpha and rgb of texture unit 3 to output
glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, 0);
glFinalCombinerInputNV(GL_VARIABLE_A_NV, GL_ZERO,
GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_ZERO,
GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_C_NV, GL_ZERO,
GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_D_NV, GL_TEXTURE3_ARB,
GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_G_NV, GL_TEXTURE3_ARB,
GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);

glDisable(GL_REGISTER_COMBINERS_NV);
glDisable(GL_TEXTURE_SHADER_NV);

Wir glauben, dass das Problem folgendes ist: Das dot product wird NICHT 7
mit der Konstante und der 3D Textur berechnet, sondern mit der 2D
und der 3D Textur, was dann zu einem falschen Lookup in der 2D Textur
führt.

Danke für die Hilfe

zeckensack
2005-09-17, 16:19:20
Ich bin jetzt nicht so wirklich firm in NV_ts, aber das hier kam mir komisch vor:
glEnable(GL_TEXTURE_3D);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D);
glDisable(GL_TEXTURE_3D);

// stage 1 --> swizzle
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_3D);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D);
glDisable(GL_TEXTURE_3D);Wenn NV_ts (wie ARB_fp) ignoriert, welche targets enabled sind, dann wäre es egal. Aber überflüssig ist es trotzdem.
Ansonsten halte dich an jra101. Evtl ist es wirklich ein Bug im Treiber.