#define CUBEMAP_SIZE 64 #define REDUCED_CUBEMAP_SIZE 2 #define RATE 32 float4 readCubeMap(samplerCUBE cm, float3 coord) { float4 color = texCUBElod( cm, float4(coord.xy, -coord.z, 0) ); color.a = 1; return color; } float readDistanceCubeMap(samplerCUBE dcm, float3 coord) { float dist = texCUBElod(dcm, float4(coord.xy, - coord.z, 0)).r; if(dist == 0) dist = 1000000; ///sky return dist; } //////////////////////////// /// Reduce cube map shader /////////////////////////// struct MPos_OUT { float4 VPos : POSITION; float4 MPos : TEXCOORD0; }; float4 ReduceCubeMap_PS(MPos_OUT IN, uniform int nFace, uniform samplerCUBE EnvironmentMapSampler : register(s0) ) : COLOR { float4 color = 0; float3 dir; for (int i = 0; i < RATE/2; i+=1) for (int j = 0; j < RATE/2; j+=1) { float2 pos; pos.x = IN.MPos.x + (4*i + 2)/(float)CUBEMAP_SIZE; pos.y = IN.MPos.y - (4*j + 2)/(float)CUBEMAP_SIZE; // y=-u // "scrambling" if (nFace == 0) dir = float3(1, pos.y, -pos.x); if (nFace == 1) dir = float3(-1, pos.y, pos.x); if (nFace == 2) dir = float3(pos.x, 1, -pos.y); if (nFace == 3) dir = float3(pos.x, -1, pos.y); if (nFace == 4) dir = float3(pos.x, pos.y, 1); if (nFace == 5) dir = float3(-pos.x, pos.y,-1); color += texCUBE( EnvironmentMapSampler, dir); } return color / (RATE * RATE / 4.0); } //////////////// /// Diffuse /////////////// /// Polygon to point form factor float4 Poly2Point_Contr(float3 L, float3 L1, float3 L2, float3 L3, float3 L4, float3 pos, float3 N, samplerCUBE cubemap) { float d; //d = texCUBE(cubemap, L).a; d = readDistanceCubeMap(cubemap, L1); L1 = d * normalize(L1); d = readDistanceCubeMap(cubemap, L2); L2 = d * normalize(L2); d = readDistanceCubeMap(cubemap, L3); L3 = d * normalize(L3); d = readDistanceCubeMap(cubemap, L4); L4 = d * normalize(L4); float3 r1 = normalize(L1 - pos); float3 r2 = normalize(L2 - pos); float3 r3 = normalize(L3 - pos); float3 r4 = normalize(L4 - pos); /* float tri1 = acos(dot(r1, r2)) * dot(cross(r1, r2), N); float tri2 = acos(dot(r2, r3)) * dot(cross(r2, r3), N); float tri3 = acos(dot(r3, r4)) * dot(cross(r3, r4), N); float tri4 = acos(dot(r4, r1)) * dot(cross(r4, r1), N); */ float3 crossP = cross(r1, r2); float r = length(crossP); float dd = dot(r1,r2); float tri1 = acos(dd) * dot(crossP/r, N); crossP = cross(r2, r3); r = length(crossP); dd = dot(r1,r2); float tri2 = acos(dd) * dot(crossP/r, N); crossP = cross(r3, r4); r = length(crossP); dd = dot(r1,r2); float tri3 = acos(dd) * dot(crossP/r, N); crossP = cross(r4, r1); r = length(crossP); dd = dot(r1,r2); float tri4= acos(dd) * dot(crossP/r, N); return max(tri1 + tri2 + tri3 + tri4, 0); //return tri1 + tri2 + tri3 + tri4; } struct Shaded_OUT { float4 vPos : POSITION; float4 wNormal : TEXCOORD0; float4 wPos : TEXCOORD1; }; float4 Diffuse_Poly2Point_PS( Shaded_OUT IN, uniform float3 lastCenter, uniform samplerCUBE SmallEnvMapSampler : register(s0), uniform samplerCUBE DistanceEnvMapSampler : register(s1) ) : COLOR0 { float M = REDUCED_CUBEMAP_SIZE; float3 N = IN.wNormal.xyz; N = normalize( N ); float3 pos = IN.wPos.xyz - lastCenter; float4 I = 0; float4 Le; Le = float4(readCubeMap(SmallEnvMapSampler, float3(1,0,0)).rgb, 1); I += 0.5 * Le * Poly2Point_Contr( float3(1,0,0), float3(1,-0.5,0.5), float3(1,-0.5,-0.5), float3(1,0.5,-0.5), float3(1,0.5,0.5), pos, N, DistanceEnvMapSampler); Le = float4(readCubeMap(SmallEnvMapSampler, float3(-1,0,0)).rgb, 1); I += 0.5 * Le * Poly2Point_Contr( float3(-1,0,0), float3(-1,-0.5,-0.5), float3(-1,-0.5,0.5), float3(-1,0.5,0.5), float3(-1,0.5,-0.5), pos, N, DistanceEnvMapSampler); Le = float4(readCubeMap(SmallEnvMapSampler, float3(0,1,0)).rgb, 1); I += 0.5 * Le * Poly2Point_Contr( float3( 0,1,0), float3( -0.5,1,0.5), float3(0.5,1,0.5), float3(0.5,1,-0.5), float3(-0.5,1,-0.5), pos, N, DistanceEnvMapSampler); Le = float4(readCubeMap(SmallEnvMapSampler, float3(0,-1,0)).rgb, 1); I += 0.5 * Le * Poly2Point_Contr( float3( 0,-1,0), float3( -0.5,-1,-0.5), float3(0.5,-1,-0.5), float3(0.5,-1,0.5), float3(-0.5,-1,0.5), pos, N, DistanceEnvMapSampler); Le = float4(readCubeMap(SmallEnvMapSampler, float3(0,0,1)).rgb, 1); I += 0.5 * Le * Poly2Point_Contr( float3( 0,0,1), float3( -0.5,-0.5,1), float3(0.5,-0.5,1), float3(0.5,0.5,1), float3(-0.5,0.5,1), pos, N, DistanceEnvMapSampler); Le = float4(readCubeMap(SmallEnvMapSampler, float3(0,0,-1)).rgb, 1); I += 0.5 * Le * Poly2Point_Contr( float3( 0,0,-1), float3( 0.5,-0.5,-1), float3(-0.5,-0.5,-1), float3(-0.5,0.5,-1), float3(0.5,0.5,-1), pos, N, DistanceEnvMapSampler); float kd = 0.32; return kd * I; }