ในหนึ่งในสไลด์จาก PowerPoint "DirectX 11 Rendering in Battlefield 3" ฉันสังเกตเห็นรหัส folowing:
struct Light {
float3 pos; float sqrRadius;
float3 color; float invSqrRadius;
}
ฉันไม่เข้าใจว่าทำไมพวกเขาถึงจัดเก็บรัศมีกำลังสองและแม้แต่อินเวอร์สสแควร์สแควร์ (ซึ่งฉันเชื่อว่าเป็นรัศมี 1 กำลังสอง) แทนที่จะเก็บรัศมี พวกเขาใช้ข้อมูลนี้ในการคำนวณอย่างไร ยิ่งไปกว่านั้นแล้วไฟทรงกรวยและไฟเส้นคืออะไร? struct นี้จะต้องมีเฉพาะสำหรับไฟจุดฉันไม่เห็นมันทำงานได้สำหรับประเภทอื่น - มีข้อมูลไม่เพียงพอ ถึงกระนั้นฉันก็ชอบที่จะรู้ว่าพวกเขาใช้สี่เหลี่ยมนั้นและ InvSquare อย่างไร
ปรับปรุง:ตกลงฉันได้รับมันในที่สุด
นี่คือสมการการลดทอนแสงแบบคลาสสิกซึ่งหาได้ง่ายในเน็ต:
float3 lightVector = lightPosition - surfacePosition;
float attenuation = saturate(1 - length(lightVector)/lightRadius);
มันค่อนข้างมีราคาแพงเช่นเดียวกับlength(lightVector)
การทำสิ่งนี้:
length(lightVector) = sqrt(dot(lightVector, lightVector);
ยิ่งไปกว่านั้นการดำเนินงานของแผนก(/lightRadius)
ก็มีค่าใช้จ่ายค่อนข้างสูง
แทนที่จะคำนวณการลดทอนแสงด้วยวิธีนี้คุณสามารถคำนวณด้วยวิธีต่อไปนี้ซึ่งจะเร็วกว่ามาก:
attenuation = saturate(1 - dot(lightVector, lightVector)*invRadiusSqr);
โดยที่ invRadiusSqr สามารถคำนวณล่วงหน้าได้ที่ระดับ CPU และส่งผ่านเป็นค่าคงที่ shader
ยิ่งไปกว่านั้นคุณจะได้รับการลดทอนของแสงแบบสมการกำลังสอง (แทนที่จะเป็นเส้นตรงในกรณีเดิม) ซึ่งดียิ่งขึ้นเนื่องจากแสง IRL แสดงให้เห็นว่ามีการตกหล่นแบบสมการกำลังสอง
ขอบคุณทุกคนสำหรับความช่วยเหลือของคุณ!