[3004] | 1 | // input
|
---|
| 2 | struct vtxin
|
---|
| 3 | {
|
---|
| 4 | float4 position: POSITION;
|
---|
| 5 | float3 normal: NORMAL;
|
---|
| 6 | float4 color: COLOR0;
|
---|
| 7 | float4 texCoord: TEXCOORD0;
|
---|
| 8 | };
|
---|
| 9 |
|
---|
| 10 | // vtx output
|
---|
| 11 | struct vtxout
|
---|
| 12 | {
|
---|
| 13 | float4 position: POSITION; // eye space
|
---|
| 14 | float4 texCoord: TEXCOORD0;
|
---|
| 15 |
|
---|
| 16 | float4 color: COLOR0;
|
---|
| 17 | float4 worldPos: TEXCOORD1; // world position
|
---|
| 18 | float3 normal: TEXCOORD2;
|
---|
[3017] | 19 | float4 projPos: TEXCOORD3;
|
---|
[3004] | 20 | };
|
---|
| 21 |
|
---|
| 22 |
|
---|
| 23 | // fragment input
|
---|
| 24 | struct fragin
|
---|
| 25 | {
|
---|
| 26 | float4 color: COLOR0;
|
---|
| 27 | float4 position: POSITION; // eye space
|
---|
| 28 | float4 texCoord: TEXCOORD0;
|
---|
| 29 |
|
---|
[3017] | 30 | float4 winPos: WPOS;
|
---|
[3004] | 31 | float4 worldPos: TEXCOORD1; // world position
|
---|
| 32 | float3 normal: TEXCOORD2;
|
---|
[3017] | 33 | float4 projPos: TEXCOORD3;
|
---|
[3004] | 34 | };
|
---|
| 35 |
|
---|
| 36 |
|
---|
| 37 | struct pixel
|
---|
| 38 | {
|
---|
[3005] | 39 | float4 col: COLOR0;
|
---|
[3017] | 40 | float3 norm: COLOR1;
|
---|
[3009] | 41 | float3 pos: COLOR2;
|
---|
[3004] | 42 | };
|
---|
| 43 |
|
---|
| 44 | #pragma position_invariant vtx
|
---|
| 45 |
|
---|
| 46 | vtxout vtx(vtxin IN,
|
---|
| 47 | const uniform float4x4 ModelViewProj,
|
---|
| 48 | uniform float4x4 ModelView)
|
---|
| 49 | {
|
---|
| 50 | vtxout OUT;
|
---|
| 51 |
|
---|
| 52 | OUT.color = IN.color;
|
---|
| 53 | OUT.texCoord = IN.texCoord;
|
---|
| 54 |
|
---|
| 55 | //OUT.worldPos = mul(glstate.matrix.inverse.projection, OUT.position);
|
---|
| 56 | OUT.worldPos = mul(ModelView, IN.position);
|
---|
| 57 | // transform the vertex position into eye space
|
---|
| 58 | OUT.position = mul(glstate.matrix.mvp, IN.position);
|
---|
| 59 |
|
---|
| 60 | OUT.normal = IN.normal;
|
---|
[3017] | 61 | OUT.projPos = OUT.position;
|
---|
[3004] | 62 |
|
---|
| 63 | return OUT;
|
---|
| 64 | }
|
---|
| 65 |
|
---|
| 66 |
|
---|
| 67 | // bilinear interpolation
|
---|
[2999] | 68 | inline float3 Interpol(float2 w, float3 bl, float3 br, float3 tl, float3 tr)
|
---|
| 69 | {
|
---|
| 70 | float3 x1 = lerp(bl, tl, w.y);
|
---|
| 71 | float3 x2 = lerp(br, tr, w.y);
|
---|
| 72 | float3 v = lerp(x1, x2, w.x);
|
---|
| 73 |
|
---|
| 74 | return v;
|
---|
[3004] | 75 | }
|
---|
| 76 |
|
---|
[3017] | 77 | //#pragma position_invariant fragtex
|
---|
[3004] | 78 |
|
---|
| 79 | pixel fragtex(fragin IN,
|
---|
| 80 | uniform sampler2D dirtTex,
|
---|
| 81 | uniform sampler2D tex,
|
---|
| 82 | uniform float3 eyePos,
|
---|
[2999] | 83 | uniform float3 bl,
|
---|
| 84 | uniform float3 br,
|
---|
[3004] | 85 | uniform float3 tl,
|
---|
| 86 | uniform float3 tr
|
---|
| 87 | )
|
---|
| 88 | {
|
---|
| 89 | float4 texColor = tex2D(tex, IN.texCoord.xy);
|
---|
| 90 |
|
---|
| 91 | // account for alpha blending
|
---|
| 92 | if (texColor.w < 0.5f) discard;
|
---|
| 93 |
|
---|
| 94 | pixel pix;
|
---|
| 95 |
|
---|
| 96 | // save color in first render target
|
---|
| 97 | // hack: use combination of emmisive + diffuse (emmisive used as constant ambient term)
|
---|
| 98 | pix.col = (glstate.material.emission + glstate.material.diffuse) * texColor;
|
---|
[3017] | 99 | // save world space normal in rt
|
---|
| 100 | pix.norm = IN.normal;
|
---|
[3004] | 101 |
|
---|
| 102 | // hack: squeeze some information about ambient into the texture
|
---|
| 103 | //pix.col.w = glstate.material.emission.x;
|
---|
| 104 |
|
---|
| 105 | // compute eye linear depth
|
---|
[3017] | 106 | const float4 projPos = IN.projPos / IN.projPos.w;
|
---|
| 107 |
|
---|
| 108 | float2 screenCoord = projPos.xy * 0.5f + 0.5f;
|
---|
| 109 |
|
---|
| 110 | const float3 viewVec = Interpol(screenCoord, bl, br, tl, tr);
|
---|
| 111 | const float invMagView = 1.0f / length(viewVec);
|
---|
| 112 | // note: has to done in this order, otherwise strange precision problems!
|
---|
| 113 | pix.col.w = invMagView * length(eyePos - IN.worldPos.xyz);
|
---|
[3004] | 114 |
|
---|
| 115 | return pix;
|
---|
| 116 | }
|
---|
| 117 |
|
---|
| 118 |
|
---|
| 119 | pixel frag(fragin IN,
|
---|
| 120 | uniform float3 eyePos,
|
---|
[2999] | 121 | uniform float3 bl,
|
---|
[3004] | 122 | uniform float3 br,
|
---|
| 123 | uniform float3 tl,
|
---|
| 124 | uniform float3 tr)
|
---|
| 125 | {
|
---|
| 126 | pixel pix;
|
---|
| 127 |
|
---|
| 128 | // hack: use comination of emmisive + diffuse (emmisive used as constant ambient term)
|
---|
| 129 | pix.col = glstate.material.diffuse + glstate.material.emission;
|
---|
| 130 |
|
---|
[3017] | 131 | pix.norm = IN.normal;
|
---|
[3004] | 132 |
|
---|
| 133 | // hack: squeeze some information about the ambient term into the target
|
---|
| 134 | //pix.col.w = glstate.material.emission.x;
|
---|
| 135 |
|
---|
[3009] | 136 | // compute eye linear depth and scale with lenght to avoid sqr root in pixel shader
|
---|
[3017] | 137 | const float4 projPos = IN.projPos / IN.projPos.w;
|
---|
| 138 |
|
---|
[3004] | 139 | float2 screenCoord = projPos.xy * 0.5f + 0.5f;
|
---|
| 140 | const float magView = length(Interpol(screenCoord, bl, br, tl, tr));
|
---|
[3017] | 141 | pix.col.w = length(eyePos - IN.worldPos.xyz) / magView;
|
---|
[3004] | 142 |
|
---|
| 143 | return pix;
|
---|
[2928] | 144 | } |
---|