#define CUBEMAP_SIZE 128 #define REDUCED_CUBEMAP_SIZE 4 #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; i++) for (int j = 0; j < RATE; j++) { float2 pos; pos.x = IN.MPos.x + (2*i + 1)/(float)CUBEMAP_SIZE; pos.y = IN.MPos.y - (2*j + 1)/(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); } */ 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); } /// Disc to point form factor float4 Disc2Point_Contr(float3 L, float3 pos, float3 N, float3 V, samplerCUBE SmallEnvMapSampler, samplerCUBE DistanceEnvMapSampler) // Phong-Blinn // L: a hossza lényeges (az egységkocka faláig ér) { float mindist = 1.0; float kd = 0.3; // 0.3 float ks = 0; // 0.5 float shininess = 10; float l = length(L); L = normalize(L); //dw float dw = 4 / (REDUCED_CUBEMAP_SIZE*REDUCED_CUBEMAP_SIZE*l*l*l + 4/3.1416f); //Lin float4 Lin = readCubeMap(SmallEnvMapSampler, L); //r float doy = readDistanceCubeMap(DistanceEnvMapSampler, L); float dxy = length(L * doy - pos); dxy = max(mindist, dxy); //dws float dws = (doy*doy * dw) / (dxy*dxy*(1 - dw/3.1416f) + doy*doy*dw/3.1416f); // localization: //float dws = dw; //L = L * doy - pos; // L: x->y, az objektumtól induljon, ne a középpontból L = normalize(L); float3 H = normalize(L + V); // felezővektor float a = kd * max(dot(N,L),0) + ks * pow(max(dot(N,H),0), shininess); // diffuse + specular // 1.: eddigi //return Lin * a * dws; float ctheta_in = dot(N,L); float ctheta_out = dot(N,V); return Lin * a * dws; } float4 Diffuse_Disc2Point_PS(Shaded_OUT IN, uniform float3 lastCenter, uniform float3 cameraPos, uniform samplerCUBE SmallEnvMapSampler : register(s0), uniform samplerCUBE DistanceEnvMapSampler : register(s1), uniform sampler2D ColorMap : register(s2), ) : COLOR0 { float M = REDUCED_CUBEMAP_SIZE; float3 N = IN.wNormal.xyz; N = normalize( N ); float3 V = normalize(IN.wPos.xyz - cameraPos); float3 pos = IN.wPos.xyz - lastCenter; float4 I = 0; float3 L; float4 Le; float width = 1.0 / M; float d; for (float x = 0.5; x < M; x++) for (float y = 0.5; y < M; y++) { float2 p, tpos; tpos.x = x * width; tpos.y = y * width; p = tpos.xy; p = 2.0 * p - 1.0; //-1..1 float3 L; L = float3(p.x, p.y, 1); I += Disc2Point_Contr( L * 0.75, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler); L = float3(p.x, p.y, -1); I += Disc2Point_Contr( L * 0.75, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler); L = float3(p.x, 1, p.y); I += Disc2Point_Contr( L * 0.75, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler); L = float3(p.x, -1, p.y); I += Disc2Point_Contr( L * 0.75, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler); L = float3(1, p.x, p.y); I += Disc2Point_Contr( L * 0.75, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler); L = float3(-1, p.x, p.y); I += Disc2Point_Contr( L * 0.75, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler); } float kd = 1.0; float indirect = kd * I; } float4 Glossy_Disc2Point_PS(Shaded_OUT IN, uniform float3 lastCenter, uniform float3 cameraPos, 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 V = normalize(IN.wPos.xyz - cameraPos); float3 pos = IN.wPos.xyz - lastCenter; float3 R = reflect( V, N ); float rr = max( max(abs(R.x), abs(R.y)), abs(R.z) ); // select the largest component R /= rr; // scale the largest component to value +/-1 float3 offset1 = float3(1,0,0); float3 offset2 = float3(0,1,0); if (abs(R.x) > abs(R.y) && abs(R.x) > abs(R.z)) offset1 = float3(0,0,1); if (abs(R.y) > abs(R.x) && abs(R.y) > abs(R.z)) offset2 = float3(0,0,1); float4 I = 0; float3 L; float width = 2.0 / M; L = R; I += Disc2Point_Contr( L * 0.75, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler); L = R + offset1 * width; I += Disc2Point_Contr( L * 0.75, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler); L = R - offset1 * width; I += Disc2Point_Contr( L * 0.75, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler); L = R + offset2 * width; I += Disc2Point_Contr( L * 0.75, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler); L = R - offset2 * width; I += Disc2Point_Contr( L * 0.75, pos, N, V, SmallEnvMapSampler, DistanceEnvMapSampler); float kd = 1.0; //return readCubeMap(SmallEnvMapSampler, pos) + lastCenter.x*0.0000000001; return kd * I * 2 * M; }