Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: data/branches/Shader_HS18/programs/Cg/isosurf.cg @ 12115

Last change on this file since 12115 was 12115, checked in by wiesep, 5 years ago

Changed folder structure, deletet some unused files and cleaned up code

File size: 4.2 KB
Line 
1// Ogre port of Nvidia's IsoSurf.cg file
2// Modified code follows. See http://developer.download.nvidia.com/SDK/10/opengl/samples.html for original
3//
4// Cg port of Yury Uralsky's metaball FX shader
5//
6// Authors: Simon Green and Yury Urlasky
7// Email: sdkfeedback@nvidia.com
8//
9// Copyright (c) NVIDIA Corporation. All rights reserved.
10////////////////////////////////////////////////////////////////////////////////////////////////////
11
12struct SampleData
13{
14        float4 Pos   : POSITION;
15        float3 N     : TEXCOORD0;
16        float2 Field : TEXCOORD1;
17        //float4 Color : COLOR0;
18};
19
20struct SurfaceVertex
21{
22        float4 Pos      : POSITION;
23        float3 N        : TEXCOORD0;
24};
25
26uniform int Num_Metaballs = 2;
27uniform float4 Metaballs[] = {
28        { -0.5, 0, 0, 0.2 },
29        { 0.6, 0, 0, 0.4 },
30};
31
32// Size of the sampling grid
33uniform int3 SizeMask = { 63, 63, 63 };
34uniform int3 SizeShift = { 0, 6, 12 };
35
36uniform float IsoValue = 1.0;
37
38// Metaball function
39// Returns metaball function value in .w and its gradient in .xyz
40
41float4 Metaball(float3 Pos, float3 Center, float RadiusSq)
42{
43        float epsilon = 0.001;
44
45        float3 Dist = Pos - Center;
46        float InvDistSq = 1 / (dot(Dist, Dist) + epsilon);
47
48        float4 o;
49        o.xyz = -2 * RadiusSq * InvDistSq * InvDistSq * Dist;
50        o.w = RadiusSq * InvDistSq;
51        return o;
52}
53
54// Vertex shader
55SampleData mainVS(float4 pos : POSITION,
56                  uniform float4x4 WorldViewProj,
57                  uniform float4x4 origWorldViewIT)
58{
59        SampleData o;
60
61        // Sum up contributions from all metaballs
62        float4 Field = 0;
63        for (int i = 0; i < 2; i++)
64        {
65                Field += Metaball(pos.xyz, Metaballs[i].xyz, Metaballs[i].w);
66        }
67
68        float3x3 WorldViewIT = { origWorldViewIT[0].xyz, origWorldViewIT[1].xyz, origWorldViewIT[2].xyz };
69
70        // Transform position and normals
71        o.Pos = mul(WorldViewProj, pos);
72        o.N = mul(WorldViewIT, Field.xyz);      // we want normals in world space
73        o.Field.x = Field.w;
74
75        // Generate in-out flags
76        o.Field.y = (Field.w < IsoValue) ? 1 : 0;
77
78        //o.Color = (Field*0.5+0.5) * (Field.w / 10.0);
79        return o;
80}
81
82
83
84// Estimate where isosurface intersects grid edge with endpoints v0, v1
85void CalcIntersection(float4 Pos0,
86                                          float3 N0,
87                                          float2 Field0,
88                                          float4 Pos1,
89                                          float3 N1,
90                                          float2 Field1)
91{
92        float t = (IsoValue - Field0.x) / (Field1.x - Field0.x);
93        if ((Field0.x < IsoValue) && (Field1.x > Field0.x))
94        {
95                if (t > 0 && t < 1)
96                {
97                        float4 Pos = lerp(Pos0, Pos1, t);
98                        float3 N = lerp(N0, N1, t);
99                        emitVertex(Pos : POSITION, N : TEXCOORD0);
100                }
101        }
102}
103
104// Geometry shader
105// input: line with adjacency (tetrahedron)
106// outputs: zero, one or two triangles depending if isosurface intersects tetrahedron
107LINE_ADJ
108TRIANGLE_OUT
109void mainGS(
110        AttribArray<float4> Pos : POSITION,
111        AttribArray<float3> N : TEXCOORD0,
112        AttribArray<float2> Field : TEXCOORD1
113        )
114{
115        // construct index for this tetrahedron
116        unsigned int index = (int(Field[0].y) << 3) |
117                                (int(Field[1].y) << 2) |
118                                (int(Field[2].y) << 1) |
119                                 int(Field[3].y);
120
121        // don't bother if all vertices out or all vertices inside isosurface
122        if (index > 0 && index < 15)
123        {
124                //Uber-compressed version of the edge table.
125                unsigned int edgeListHex[] =
126                        {0x0001cde0, 0x98b08c9d, 0x674046ce, 0x487bc480,
127                        0x21301d2e, 0x139bd910, 0x26376e20, 0x3b700000};
128
129                unsigned int edgeValFull = edgeListHex[index/2];
130                unsigned int edgeVal = (index % 2 == 1) ? (edgeValFull & 0xFFFF) : ((edgeValFull >> 16) & 0xFFFF);
131                int4 e0 = int4((edgeVal >> 14) & 0x3, (edgeVal >> 12) & 0x3, (edgeVal >> 10) & 0x3, (edgeVal >> 8) & 0x3);
132                int4 e1 = int4((edgeVal >> 6) & 0x3, (edgeVal >> 4) & 0x3, (edgeVal >> 2) & 0x3, (edgeVal >> 0) & 0x3);
133
134                CalcIntersection(Pos[e0.x], N[e0.x], Field[e0.x], Pos[e0.y], N[e0.y], Field[e0.y]);
135                CalcIntersection(Pos[e0.z], N[e0.z], Field[e0.z], Pos[e0.w], N[e0.w], Field[e0.w]);
136                CalcIntersection(Pos[e1.x], N[e1.x], Field[e1.x], Pos[e1.y], N[e1.y], Field[e1.y]);
137
138                // Emit additional triangle, if necessary
139                if (e1.z != -1) {
140                        CalcIntersection(Pos[e1.z], N[e1.z], Field[e1.z], Pos[e1.w], N[e1.w], Field[e1.w]);
141                }
142        }
143}
144
145// Pixel shader
146float4 mainPS(float3 N : TEXCOORD0) : COLOR
147{
148        //Sanitize input
149        N = normalize(N);
150        float3 L = float3(0, 0, 1);
151        //return float4(N*0.5+0.5, 1);
152        float3 materials[2] = { float3(1, 1, 1), float3(0, 0, 0.5)};
153        float nDotL = dot( N, L);
154        return float4(abs(nDotL) * materials[nDotL < 0.0], 0.1);
155}
Note: See TracBrowser for help on using the repository browser.