shader surface scattering(ARB): Unterschied zwischen den Versionen
(Die Seite wurde neu angelegt: =Surface Scattering= Zurück zur Shadersammlung {|{{Prettytable_B1}} width=100% !width=60%|Beschreibung !width=20%|Autor !width=20%|Version |- |Die Dicke des Materi...) |
DGLBot (Diskussion | Beiträge) K (Der Ausdruck ''<cpp>(.*?)</cpp>'' wurde ersetzt mit ''<source lang="cpp">$1</source>''.) |
||
(5 dazwischenliegende Versionen von einem anderen Benutzer werden nicht angezeigt) | |||
Zeile 6: | Zeile 6: | ||
!width=20%|Version | !width=20%|Version | ||
|- | |- | ||
− | | | + | |Bestimmt die Distanz, die Licht durch ein Material zurücklegt. |
|dj3hut1 | |dj3hut1 | ||
|1.0 | |1.0 | ||
Zeile 22: | Zeile 22: | ||
In der Grafikprogrammierung nennt sich diese Technik 'Surface Scattering' und lässt sich mit Shadern realisieren. | In der Grafikprogrammierung nennt sich diese Technik 'Surface Scattering' und lässt sich mit Shadern realisieren. | ||
− | Im ersten Pass wird, ähnlich wie beim [[Shadowmapping]], die Szene aus der Sicht der Lichtquelle gerendert und die Entfernungen vom Licht zum Objekt in einer Textur gespeichert. | + | Im ersten Pass wird, ähnlich wie beim [[Shadowmapping]], die Szene aus der Sicht der Lichtquelle gerendert und die Entfernungen vom Licht zum Objekt in einer Textur gespeichert ( erster Eintrittspunkt des Lichtes in Objekt ). |
Diese werden dann im nächsten Pass mit den Tiefenwerten aus der Sicht des Betrachters verglichen und man erhält für jede Stelle die Länge des Weges, den das Licht im Material zurückgelegt hat. | Diese werden dann im nächsten Pass mit den Tiefenwerten aus der Sicht des Betrachters verglichen und man erhält für jede Stelle die Länge des Weges, den das Licht im Material zurückgelegt hat. | ||
==Besondere Vorraussetzungen== | ==Besondere Vorraussetzungen== | ||
Für die Shader werden nur die Erweiterungen [[GL_ARB_fragment_program]] und [[GL_ARB_vertex_program]] benötigt. | Für die Shader werden nur die Erweiterungen [[GL_ARB_fragment_program]] und [[GL_ARB_vertex_program]] benötigt. | ||
+ | |||
+ | Nach dem ersten Renderpass muss der Inhalt des [[Framebuffer]]s mit [[glCopyTexSubImage]] in einer Textur gespeichert werden, die als Parameter an das zweite [[#scattering2.fp|Fragmentprogramm]] übergeben wird. | ||
+ | [[#scattering2.vp|scattering2.fp]] erhält mittels [[glProgramLocalParameterARB]] die [[Light Space|Light Space Matrix]] und die [[Light Texture Space|Light Texture Space Matrix]] ( MVP gemappt auf [0,1] ) aus dem ersten Renderpass. | ||
==Code== | ==Code== | ||
=== scattering1.vp === | === scattering1.vp === | ||
− | <cpp>!!ARBvp1.0 | + | <source lang="cpp">!!ARBvp1.0 |
ATTRIB iPos = vertex.position; | ATTRIB iPos = vertex.position; | ||
Zeile 76: | Zeile 79: | ||
MOV oPrC, color.x; | MOV oPrC, color.x; | ||
− | END</cpp> | + | END</source> |
+ | |||
+ | === scattering1.fp === | ||
+ | <source lang="cpp">!!ARBfp1.0 | ||
+ | |||
+ | ATTRIB iPrC = fragment.color.primary; | ||
+ | |||
+ | OUTPUT oCol = result.color; | ||
+ | OUTPUT oDep = result.depth; | ||
+ | |||
+ | #simply put input color to output color | ||
+ | MOV oCol, iPrC; | ||
+ | |||
+ | END</source> | ||
+ | |||
+ | === scattering2.vp === | ||
+ | <source lang="cpp">!!ARBvp1.0 | ||
+ | |||
+ | ATTRIB iPos = vertex.position; | ||
+ | |||
+ | OUTPUT oPos = result.position; | ||
+ | OUTPUT oTeC = result.texcoord; | ||
+ | OUTPUT oFoC = result.fogcoord; | ||
+ | |||
+ | PARAM mvp[4] = { state.matrix.mvp }; | ||
+ | PARAM mv[4] = { state.matrix.modelview }; | ||
+ | |||
+ | #transformed vertex position | ||
+ | TEMP tv; | ||
+ | |||
+ | #vertex in light space | ||
+ | TEMP pLight; | ||
+ | |||
+ | #length of vertex-vector in light space | ||
+ | TEMP temp; | ||
+ | |||
+ | #texcoord for lightDepthTex | ||
+ | TEMP texCoord; | ||
+ | |||
+ | #transform vertex with mvp | ||
+ | DP4 tv.x, iPos, mvp[0]; | ||
+ | DP4 tv.y, iPos, mvp[1]; | ||
+ | DP4 tv.z, iPos, mvp[2]; | ||
+ | DP4 tv.w, iPos, mvp[3]; | ||
+ | |||
+ | #evaluate vertex in light space (0-3 mv of light ) | ||
+ | DP4 pLight.x, iPos, program.local[0]; | ||
+ | DP4 pLight.y, iPos, program.local[1]; | ||
+ | DP4 pLight.z, iPos, program.local[2]; | ||
+ | DP4 pLight.w, iPos, program.local[3]; | ||
+ | |||
+ | #length of vector in light space | ||
+ | DP3 temp.x, pLight, pLight; | ||
+ | RSQ temp.x, temp.x; | ||
+ | RCP temp.x, temp.x; | ||
+ | |||
+ | #evaluate texcoords for lightDepthTex (4-7 mvp of light, light texture space ) | ||
+ | DP4 texCoord.x, iPos, program.local[4]; | ||
+ | DP4 texCoord.y, iPos, program.local[5]; | ||
+ | DP4 texCoord.z, iPos, program.local[6]; | ||
+ | DP4 texCoord.w, iPos, program.local[7]; | ||
+ | |||
+ | #transformed vertex position | ||
+ | MOV oPos, tv; | ||
+ | |||
+ | #length of vector in light space | ||
+ | MOV oFoC, temp.x; | ||
+ | |||
+ | #texcoord for lightDepthTex | ||
+ | MOV oTeC, texCoord; | ||
+ | |||
+ | END</source> | ||
+ | |||
+ | === scattering2.fp === | ||
+ | <source lang="cpp">!!ARBfp1.0 | ||
+ | |||
+ | #distance of light to exit point | ||
+ | ATTRIB d_o = fragment.fogcoord; | ||
+ | |||
+ | #texcoord for entry point | ||
+ | ATTRIB texCoord = fragment.texcoord; | ||
+ | |||
+ | OUTPUT oCol = result.color; | ||
+ | |||
+ | #well known constant | ||
+ | PARAM E = { 2.718281828 }; | ||
+ | |||
+ | #distance from light to entry point | ||
+ | TEMP d_i; | ||
+ | |||
+ | #depth of material | ||
+ | TEMP dm; | ||
+ | |||
+ | #lookup distance from light to entry point | ||
+ | TXP d_i, texCoord, texture[0], 2D; | ||
+ | |||
+ | #rescaling of distance of entry point ( see scattering1.vp ) | ||
+ | MUL d_i.x, d_i.x, 50; | ||
+ | ADD d_i.x, d_i.x, 65; | ||
+ | |||
+ | #depth of material, substract distance of exit and entry point | ||
+ | ADD dm.x, d_o.x, -d_i.x; | ||
+ | |||
+ | #map to 1, 0 with e^-x² | ||
+ | MUL dm.x, dm.x, -dm.x; | ||
+ | MUL dm.x, dm.x, 0.001; | ||
+ | POW dm.x, E.x, dm.x; | ||
+ | |||
+ | #map distance to greyscale | ||
+ | MOV oCol.r, dm.x; | ||
+ | MOV oCol.g, dm.x; | ||
+ | MOV oCol.b, dm.x; | ||
+ | |||
+ | END</source> |
Aktuelle Version vom 10. März 2009, 19:52 Uhr
Inhaltsverzeichnis
Surface Scattering
Zurück zur Shadersammlung
Beschreibung | Autor | Version |
---|---|---|
Bestimmt die Distanz, die Licht durch ein Material zurücklegt. | dj3hut1 | 1.0 |
Bilder
Beschreibung
Viele Materialien, wie z.B. Glas, Pergament, Haut, Edelsteine, Alabaster oder Pflanzenblätter, sind lichtdurchlässig, d.h. wenn man sie gegen das Licht hält, leuchten sie abhängig von der Materialdicke verschieden stark. In der Grafikprogrammierung nennt sich diese Technik 'Surface Scattering' und lässt sich mit Shadern realisieren.
Im ersten Pass wird, ähnlich wie beim Shadowmapping, die Szene aus der Sicht der Lichtquelle gerendert und die Entfernungen vom Licht zum Objekt in einer Textur gespeichert ( erster Eintrittspunkt des Lichtes in Objekt ). Diese werden dann im nächsten Pass mit den Tiefenwerten aus der Sicht des Betrachters verglichen und man erhält für jede Stelle die Länge des Weges, den das Licht im Material zurückgelegt hat.
Besondere Vorraussetzungen
Für die Shader werden nur die Erweiterungen GL_ARB_fragment_program und GL_ARB_vertex_program benötigt.
Nach dem ersten Renderpass muss der Inhalt des Framebuffers mit glCopyTexSubImage in einer Textur gespeichert werden, die als Parameter an das zweite Fragmentprogramm übergeben wird. scattering2.fp erhält mittels glProgramLocalParameterARB die Light Space Matrix und die Light Texture Space Matrix ( MVP gemappt auf [0,1] ) aus dem ersten Renderpass.
Code
scattering1.vp
!!ARBvp1.0
ATTRIB iPos = vertex.position;
ATTRIB iPrC = vertex.color.primary;
OUTPUT oPos = result.position;
OUTPUT oPrC = result.color.primary;
PARAM mvp[4] = { state.matrix.mvp };
PARAM mv[4] = { state.matrix.modelview };
#vector in light texture space
TEMP ltsv;
#vector in light space
TEMP lsv;
#output color
TEMP color;
#simple vertex transformation
DP4 ltsv.x, iPos, mvp[0];
DP4 ltsv.y, iPos, mvp[1];
DP4 ltsv.z, iPos, mvp[2];
DP4 ltsv.w, iPos, mvp[3];
MOV oPos, ltsv;
#vertex in light space
DP4 lsv.x, iPos, mv[0];
DP4 lsv.y, iPos, mv[1];
DP4 lsv.z, iPos, mv[2];
DP4 lsv.w, iPos, mv[3];
#length of vector in light space ( light source is in (0, 0, 0) )
DP3 color.x, lsv, lsv;
RSQ color.x, color.x;
RCP color.x, color.x;
#scale to [1, 0], values dependent from application
ADD color.x, color.x, -65;
MUL color.x, color.x, 0.02;
#save length value in output color
MOV oPrC, color.x;
END
scattering1.fp
!!ARBfp1.0
ATTRIB iPrC = fragment.color.primary;
OUTPUT oCol = result.color;
OUTPUT oDep = result.depth;
#simply put input color to output color
MOV oCol, iPrC;
END
scattering2.vp
!!ARBvp1.0
ATTRIB iPos = vertex.position;
OUTPUT oPos = result.position;
OUTPUT oTeC = result.texcoord;
OUTPUT oFoC = result.fogcoord;
PARAM mvp[4] = { state.matrix.mvp };
PARAM mv[4] = { state.matrix.modelview };
#transformed vertex position
TEMP tv;
#vertex in light space
TEMP pLight;
#length of vertex-vector in light space
TEMP temp;
#texcoord for lightDepthTex
TEMP texCoord;
#transform vertex with mvp
DP4 tv.x, iPos, mvp[0];
DP4 tv.y, iPos, mvp[1];
DP4 tv.z, iPos, mvp[2];
DP4 tv.w, iPos, mvp[3];
#evaluate vertex in light space (0-3 mv of light )
DP4 pLight.x, iPos, program.local[0];
DP4 pLight.y, iPos, program.local[1];
DP4 pLight.z, iPos, program.local[2];
DP4 pLight.w, iPos, program.local[3];
#length of vector in light space
DP3 temp.x, pLight, pLight;
RSQ temp.x, temp.x;
RCP temp.x, temp.x;
#evaluate texcoords for lightDepthTex (4-7 mvp of light, light texture space )
DP4 texCoord.x, iPos, program.local[4];
DP4 texCoord.y, iPos, program.local[5];
DP4 texCoord.z, iPos, program.local[6];
DP4 texCoord.w, iPos, program.local[7];
#transformed vertex position
MOV oPos, tv;
#length of vector in light space
MOV oFoC, temp.x;
#texcoord for lightDepthTex
MOV oTeC, texCoord;
END
scattering2.fp
!!ARBfp1.0
#distance of light to exit point
ATTRIB d_o = fragment.fogcoord;
#texcoord for entry point
ATTRIB texCoord = fragment.texcoord;
OUTPUT oCol = result.color;
#well known constant
PARAM E = { 2.718281828 };
#distance from light to entry point
TEMP d_i;
#depth of material
TEMP dm;
#lookup distance from light to entry point
TXP d_i, texCoord, texture[0], 2D;
#rescaling of distance of entry point ( see scattering1.vp )
MUL d_i.x, d_i.x, 50;
ADD d_i.x, d_i.x, 65;
#depth of material, substract distance of exit and entry point
ADD dm.x, d_o.x, -d_i.x;
#map to 1, 0 with e^-x²
MUL dm.x, dm.x, -dm.x;
MUL dm.x, dm.x, 0.001;
POW dm.x, E.x, dm.x;
#map distance to greyscale
MOV oCol.r, dm.x;
MOV oCol.g, dm.x;
MOV oCol.b, dm.x;
END