1095
1119
if (p->state->unit[i].light_enabled) {
1096
1120
struct ureg half = undef;
1097
1121
struct ureg att = undef, VPpli = undef;
1122
struct ureg dist = undef;
1101
if (p->state->unit[i].light_eyepos3_is_zero) {
1102
/* Can used precomputed constants in this case.
1103
* Attenuation never applies to infinite lights.
1105
VPpli = register_param3(p, STATE_INTERNAL,
1106
STATE_LIGHT_POSITION_NORMALIZED, i);
1108
if (!p->state->material_shininess_is_zero) {
1109
if (p->state->light_local_viewer) {
1110
struct ureg eye_hat = get_eye_position_normalized(p);
1112
emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat);
1113
emit_normalize_vec3(p, half, half);
1116
half = register_param3(p, STATE_INTERNAL,
1117
STATE_LIGHT_HALF_VECTOR, i);
1122
struct ureg Ppli = register_param3(p, STATE_INTERNAL,
1123
STATE_LIGHT_POSITION, i);
1124
struct ureg V = get_eye_position(p);
1125
struct ureg dist = get_temp(p);
1127
VPpli = get_temp(p);
1129
/* Calculate VPpli vector
1131
emit_op2(p, OPCODE_SUB, VPpli, 0, Ppli, V);
1133
/* Normalize VPpli. The dist value also used in
1134
* attenuation below.
1136
emit_op2(p, OPCODE_DP3, dist, 0, VPpli, VPpli);
1137
emit_op1(p, OPCODE_RSQ, dist, 0, dist);
1138
emit_op2(p, OPCODE_MUL, VPpli, 0, VPpli, dist);
1140
/* Calculate attenuation:
1142
if (!p->state->unit[i].light_spotcutoff_is_180 ||
1143
p->state->unit[i].light_attenuated) {
1144
att = calculate_light_attenuation(p, i, VPpli, dist);
1147
/* Calculate viewer direction, or use infinite viewer:
1149
if (!p->state->material_shininess_is_zero) {
1152
if (p->state->light_local_viewer) {
1153
struct ureg eye_hat = get_eye_position_normalized(p);
1154
emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat);
1157
struct ureg z_dir = swizzle(get_identity_param(p),X,Y,W,Z);
1158
emit_op2(p, OPCODE_ADD, half, 0, VPpli, z_dir);
1161
emit_normalize_vec3(p, half, half);
1164
release_temp(p, dist);
1125
if (p->state->unit[i].light_eyepos3_is_zero) {
1126
VPpli = register_param3(p, STATE_INTERNAL,
1127
STATE_LIGHT_POSITION_NORMALIZED, i);
1129
struct ureg Ppli = register_param3(p, STATE_INTERNAL,
1130
STATE_LIGHT_POSITION, i);
1131
struct ureg V = get_eye_position(p);
1133
VPpli = get_temp(p);
1136
/* Calculate VPpli vector
1138
emit_op2(p, OPCODE_SUB, VPpli, 0, Ppli, V);
1140
/* Normalize VPpli. The dist value also used in
1141
* attenuation below.
1143
emit_op2(p, OPCODE_DP3, dist, 0, VPpli, VPpli);
1144
emit_op1(p, OPCODE_RSQ, dist, 0, dist);
1145
emit_op2(p, OPCODE_MUL, VPpli, 0, VPpli, dist);
1148
/* Calculate attenuation:
1150
att = calculate_light_attenuation(p, i, VPpli, dist);
1151
release_temp(p, dist);
1153
/* Calculate viewer direction, or use infinite viewer:
1155
if (!p->state->material_shininess_is_zero) {
1156
if (p->state->light_local_viewer) {
1157
struct ureg eye_hat = get_eye_position_normalized(p);
1159
emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat);
1160
emit_normalize_vec3(p, half, half);
1161
} else if (p->state->unit[i].light_eyepos3_is_zero) {
1162
half = register_param3(p, STATE_INTERNAL,
1163
STATE_LIGHT_HALF_VECTOR, i);
1165
struct ureg z_dir = swizzle(get_identity_param(p),X,Y,W,Z);
1167
emit_op2(p, OPCODE_ADD, half, 0, VPpli, z_dir);
1168
emit_normalize_vec3(p, half, half);
1167
1172
/* Calculate dot products:
1308
1313
struct ureg input;
1310
1315
if (p->state->fog_source_is_depth) {
1311
input = get_eye_position_z(p);
1317
switch (p->state->fog_distance_mode) {
1318
case FDM_EYE_RADIAL: /* Z = sqrt(Xe*Xe + Ye*Ye + Ze*Ze) */
1319
input = get_eye_position(p);
1320
emit_op2(p, OPCODE_DP3, fog, WRITEMASK_X, input, input);
1321
emit_op1(p, OPCODE_RSQ, fog, WRITEMASK_X, fog);
1322
emit_op1(p, OPCODE_RCP, fog, WRITEMASK_X, fog);
1324
case FDM_EYE_PLANE: /* Z = Ze */
1325
input = get_eye_position_z(p);
1326
emit_op1(p, OPCODE_MOV, fog, WRITEMASK_X, input);
1328
case FDM_EYE_PLANE_ABS: /* Z = abs(Ze) */
1329
input = get_eye_position_z(p);
1330
emit_op1(p, OPCODE_ABS, fog, WRITEMASK_X, input);
1332
default: assert(0); break; /* can't happen */
1314
1337
input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X);
1338
emit_op1(p, OPCODE_ABS, fog, WRITEMASK_X, input);
1317
/* result.fog = {abs(f),0,0,1}; */
1318
emit_op1(p, OPCODE_ABS, fog, WRITEMASK_X, input);
1319
1341
emit_op1(p, OPCODE_MOV, fog, WRITEMASK_YZW, get_identity_param(p));