Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Phil_GDM

Alter Hase

  • »Phil_GDM« ist der Autor dieses Themas

Beiträge: 443

Wohnort: Graz

Beruf: Student-Softwareentwicklung u. Wissensmanagement

  • Private Nachricht senden

1

09.10.2006, 18:49

Parallax Mapping, es will einfach nicht

Hi Leute.
Also langsam bringt mich die Shader-Programmiererei zum verzweifeln ;).
Irgendwie will absolut garnichts auf anhieb klappen.

So genug gejammert, auf zu meinem Problem.
Wie schon im Topic angedeuted, möchte ich (seit einigen Tagen) Parallax Mapping implementieren, bisher jedoch ohne Erfolg.

Der Shader sieht so aus.

C-/C++-Quelltext

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
float4x4 mvp            :   WorldViewProjection;
float4x4 m              :   World;
float3   camera_pos     :   CameraPosition;
float3   vLight_Pos = {0.0, 0.0, -40.0};
float3   vFactors = { 0.02, -0.01, 0.5 };
int min_samples = 3;
int max_samples = 20;

float parallax_ammount = 0.5;

texture texmap : DIFFUSE
<
    string ResourceName = "rockwall.jpg";
    string ResourceType = "2D";
>;

texture reliefmap : NORMAL
<
    string ResourceName = "rockwall.tga";
    string ResourceType = "2D";
>;


sampler texmap_sampler = sampler_state
{
    Texture   = <texmap>;
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};

sampler reliefmap_sampler = sampler_state
{
    Texture   = <reliefmap>;
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};

struct vertex
{
    float3          position                : POSITION;
    float2          texcoord                : TEXCOORD0;
    float3          normal                  : NORMAL;
    float3          tangent                 : TANGENT;
    float3          binormal                : BINORMAL;
};

struct vs_out
{
    float4          position                : POSITION;
    float2          texcoord                : TEXCOORD0;
    float3          view_dir_ts             : TEXCOORD1;
    float3          normal_ts               : TEXCOORD2;
};

vs_out vertex_shader(vertex IN) 
{
    vs_out OUT;
    
    float3 vertex_position_ws   = mul(float4(IN.position, 1), m).xyz;
    float3 view_direction_ws    = camera_pos - vertex_position_ws;
    
    float3x3 tangent_to_world;
    tangent_to_world[0] = mul(IN.tangent, m);
    tangent_to_world[1] = mul(IN.binormal, m);
    tangent_to_world[2] = mul(IN.normal, m);
    
    float3x3 world_to_tangent = transpose(tangent_to_world);
    
    OUT.position = mul(float4(IN.position, 1), mvp);
    OUT.texcoord = IN.texcoord;
    
    float3x3 modelrot;
    modelrot[0] = m[0];
    modelrot[1] = m[1];
    modelrot[2] = m[2];
    
    float3 normal_temp = mul(float4(IN.normal, 1), modelrot).xyz;
    
    OUT.view_dir_ts     = mul(view_direction_ws, world_to_tangent);
    OUT.normal_ts       = mul(normal_temp, world_to_tangent);
    
    return OUT;
}

float4 pixel_shader(vs_out IN) : COLOR
{

    float3 normal_ts = normalize(IN.normal_ts);
    float3 view_dir_ts = normalize(IN.view_dir_ts);
    
    //Get height from Height|Normal - map

    float height = tex2D(reliefmap_sampler, IN.texcoord);
    
    //Calculate Texture offset

    float2 offset = (view_dir_ts * parallax_ammount * (height)).xy;
    
    return tex2D(texmap_sampler, IN.texcoord + offset);
    
    
    //output difference between eye and view-vector in Tangentspace

    //float temp = 1- dot(normal_ts, view_dir_ts);

    //return float4(temp, temp, temp, 0);

}


technique PrallaxMapping
{
    pass Diff
    {
        VertexShader = compile vs_3_0 vertex_shader();
        PixelShader = compile ps_3_0 pixel_shader();
    }
}


Das Ergebnis, dass mir dieser Shader bringt, sieht so aus:
Ergebnisbild

Das sind die verwendete Height/Normal-map sowie die Textur:
Texturen

Normalenvektor und Tangentenvektor scheinen richtig zu sein. Hier ist ein Bild welches zeigt, wie groß die Differenz zwischen View- und Normalvektor im Tangentenraum sind verteilt über die Kugel sind.
Je kleiner der Differenzwinkel, desto dunkler die Stelle:
Bild

Hat jemand von euch eine Vermutng worand es liegen kann?

PS: Diese Shader Try'n Error Programmierung nervt mich. Gibt es irgendeine bessere möglichkeit, Shader zu testen, debuggen...? Gabs von NVidia nicht mal einen Shader Debugger?

mfg Philipp

Beiträge: 774

Beruf: Student

  • Private Nachricht senden

2

10.10.2006, 08:40

Im August06-DirectX-Sdk is glaub ich ein Shaderdebugger dabei

Phil_GDM

Alter Hase

  • »Phil_GDM« ist der Autor dieses Themas

Beiträge: 443

Wohnort: Graz

Beruf: Student-Softwareentwicklung u. Wissensmanagement

  • Private Nachricht senden

3

10.10.2006, 10:24

Der funktioniert bei mir nicht.

mfg Philipp

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

4

10.10.2006, 12:46

normales parallax mapping erzielt (im gegensatz zu z.B. parallax occlusion) bei hochfrequenten texturen keine schönen ergebnisse (weil zu ungenau)

spiel mal mit den werten (z.B. parallax_amount = 0.02) und verwende eine niederfrequentere ("sanftere/weichere") höhentextur.
außerdem würd ich zum testen nicht gleich eine kugel verwenden, sondern lieber einen würfel ;)

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

5

10.10.2006, 16:52

Parallax-Shader funktionieren doch normalerweise mit einer Art Raytracing, um zu bestimmen, welche Stelle auf der unebenen Oberfläche getroffen wird. Damit funktioniert es definitiv, ich habe schon einige Beispielprogramme mit dieser Technik gesehen. Soweit ich weiß setzt es aber PS 2.0 voraus.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

10.10.2006, 17:03

urpsrünglich bezeichnet parallax mapping genau das, was er gemacht hat. also nur offset anhand der view direction und höhe -> geringe genauigkeit (meistens kombiniert man das dann mit normalmapping für die beleuchtung) -> funzt entsprechend nur mit niederfrequenten höhentexturen...
für z.B. glatte steinmauern reicht es aber aus um schöne ergebnisse zu erzielen und ist dabei noch sehr schnell.
um die genauigkeit zu erhöhen, kann man beim normalen parallax mapping z.B. mehrere samples nehmen.

dann gibts da noch haufenweise verbesserungen (relief mapping, steep parallax mapping, offset limiting...)

moderne varianten, wie z.B. das oben genannte parallax occlusion mapping verwenden meist auf raytracing basierte ansätze -> präzise -> self shadowing -> etc.

Phil_GDM

Alter Hase

  • »Phil_GDM« ist der Autor dieses Themas

Beiträge: 443

Wohnort: Graz

Beruf: Student-Softwareentwicklung u. Wissensmanagement

  • Private Nachricht senden

7

11.10.2006, 11:56

Danke für die Tipps, es lag wirklich am Faktor und daran, dass die Textur nicht wirklich geeignet ist wie man hier sieht.

Es geht! zumindest einigermaßen

Also wird's im Endeffekt wohl doch das parallax occlusion Mapping werden.

mfg Philipp

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

11.10.2006, 12:11

wie gesagt, probiers erst mit einer geeigneten textur und passenden einstellungen und schau ob dir das ergebnis nicht schon ausreicht, bevor du dich daran machst parallax occlusion mapping zu implementieren ;)

ansonsten:
http://www.ati.com/developer/SIGGRAPH05/…on%20mapping%22

hf ;)

Osram

Alter Hase

Beiträge: 889

Wohnort: Weissenthurm

Beruf: SW Entwickler

  • Private Nachricht senden

9

14.10.2006, 15:54

Wenn Du Shader entwickelst, ist MSVC8 Scheisse. Nimm MSVC7.X, falls Du das hast. Der Debugger (PiX) aus dem letzten DX SDK funktioniert für mich auch nicht.
"Games are algorithmic entertainment."

Werbeanzeige