ใช่แล้วเอ็นจิ้นเกมโดยทั่วไปจะมีความแตกต่างหลากหลาย รูปแบบทั่วไปคือ:
ในขณะที่กำลังเริ่มเครื่องยนต์และโหลดโลกของเกมเตรียม shaders ทั้งหมดที่คุณจะใช้สำหรับการเรนเดอร์ โดย "เตรียมความพร้อม" ฉันหมายถึงโหลดเข้าสู่หน่วยความจำรวบรวมถ้าจำเป็นและทำการโทรทั้งหมดID3D11Device::CreatePixelShader
และที่คล้ายกันเพื่อรับวัตถุ D3D shader ที่จัดสรรและพร้อมใช้งาน เก็บวัตถุในอาร์เรย์หรือโครงสร้างข้อมูลอื่น ๆ
โดยปกติแล้วคุณจะมีความสัมพันธ์แบบหนึ่งต่อหนึ่งระหว่างจุดยอดและตัวแบ่งพิกเซลที่ออกแบบมาเพื่อทำงานร่วมกัน ฉันคิดว่ามันเป็นวัตถุชิ้นเดียวซึ่งฉันเพิ่งเรียกว่า "shader" แม้ว่ามันจะมีจุดยอดและ shader พิกเซลจริง ๆ (และอาจเป็นรูปเรขาคณิต / ตัวเรือ / โดเมนด้วย
แต่ละเฟรมเมื่อคุณพบรายการของวัตถุ (ตาข่าย) ที่จะแสดงผลให้เรียงลำดับพวกเขาด้วย shader แนวคิดคือการลดจำนวนครั้งที่คุณสลับเฉดในเฟรมโดยการวาดวัตถุทั้งหมดด้วย shader ที่กำหนดเข้าด้วยกัน เพราะนี่คือการเปลี่ยนเฉดสีคือการดำเนินการค่อนข้างแพง (แม้ว่าคุณอย่างแน่นอนสามารถทำมันได้หลายร้อยหรือเป็นพัน ๆ ครั้งต่อกรอบดังนั้นมันไม่ได้จริงๆว่าแพง)
ในความเป็นจริงคุณสามารถไปอีกขั้นหนึ่งและเรียงลำดับ mesh โดย shader แรกและวัสดุวินาที โดย "วัสดุ" ฉันหมายถึงการรวมกันของ shader และชุดของพื้นผิวและพารามิเตอร์ของมัน มักจะมีพื้นผิวและพารามิเตอร์ตัวเลข Shaders (เก็บไว้ในบัฟเฟอร์คงที่) ที่ป้อนเข้าดังนั้นตัวอย่างเช่นวัสดุอิฐและวัสดุแอสฟัลต์อาจใช้รหัส shader เดียวกันกับพื้นผิวที่แตกต่างกัน
ในการวาดเพียงแค่วนรอบตัวติดตั้งแต่ละส่วนในID3D11DeviceContext
, ตั้งค่าพารามิเตอร์ใด ๆ (บัฟเฟอร์คงที่, พื้นผิว ฯลฯ ) จากนั้นจึงวาดวัตถุ ใน pseudocode รวมถึงความแตกต่างของเฉดสี / วัสดุที่ฉันพูดถึง:
for each shader:
// Set the device context to use this shader
pContext->VSSetShader(shader.pVertexShader);
pContext->PSSetShader(shader.pPixelShader);
for each material that uses this shader:
// Set the device context to use any constant buffers, textures, samplers,
// etc. needed for this material
pContext->VSSetConstantBuffers(...);
pContext->PSSetConstantBuffers(...);
pContext->PSSetShaderResources(...);
pContext->PSSetSamplers(...);
for each mesh that uses this material:
// Set any constant buffers containing parameters specific to the mesh
// (e.g. world matrix)
pContext->VSSetConstantBuffers(...);
// Set the context to use the vertex & index buffers for this mesh
pContext->IASetInputLayout(mesh.pInputLayout);
pContext->IASetVertexBuffers(...);
pContext->IASetIndexBuffer(...);
pContext->IASetPrimitiveTopology(...)
// Draw it
pContext->DrawIndexed(...)
ยังมีอีกหลายสิ่งที่สามารถพูดได้เกี่ยวกับการจัดการวัตถุ, ตาข่าย, เงา, รูปแบบการป้อนข้อมูล, บัฟเฟอร์คงที่ ฯลฯ แต่นี่น่าจะเพียงพอสำหรับคุณในการเริ่มต้น :)